| OLD | NEW | 
|    1 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file |    1 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file | 
|    2 // for details. All rights reserved. Use of this source code is governed by a |    2 // for details. All rights reserved. Use of this source code is governed by a | 
|    3 // BSD-style license that can be found in the LICENSE file. |    3 // BSD-style license that can be found in the LICENSE file. | 
|    4  |    4  | 
|    5 // Sanity check on the growing behavior of a growable list. |    5 // Sanity check on the growing behavior of a growable list. | 
|    6  |    6  | 
|    7 import "package:expect/expect.dart"; |    7 import "package:expect/expect.dart"; | 
|    8 import "dart:collection" show IterableBase; |    8 import "dart:collection" show EfficientLengthIterable; | 
|    9  |    9  | 
|   10 // Iterable generating numbers in range [0..count). |   10 // Iterable generating numbers in range [0..count). | 
|   11 // May perform callback at some point underways. |   11 // May perform callback at some point underways. | 
|   12 class TestIterableBase extends IterableBase<int> { |   12 class TestIterableBase extends Iterable<int> { | 
|   13   final int length; |   13   final int length; | 
|   14   final int count; |   14   final int count; | 
|   15   // call [callback] if generating callbackIndex. |   15   // call [callback] if generating callbackIndex. | 
|   16   final int callbackIndex; |   16   final int callbackIndex; | 
|   17   final Function callback; |   17   final Function callback; | 
|   18   TestIterableBase(this.length, this.count, |   18   TestIterableBase(this.length, this.count, | 
|   19                    this.callbackIndex, this.callback); |   19                    this.callbackIndex, this.callback); | 
|   20   Iterator<int> get iterator => new CallbackIterator(this); |   20   Iterator<int> get iterator => new CallbackIterator(this); | 
|   21 } |   21 } | 
|   22  |   22  | 
|   23 class TestIterable extends TestIterableBase { |   23 class TestIterable extends TestIterableBase { | 
|   24   TestIterable(count, [callbackIndex = -1, callback]) |   24   TestIterable(count, [callbackIndex = -1, callback]) | 
|   25       : super(-1, count, callbackIndex, callback); |   25       : super(-1, count, callbackIndex, callback); | 
|   26   int get length => throw "SHOULD NOT BE CALLED"; |   26   int get length => throw "SHOULD NOT BE CALLED"; | 
|   27 } |   27 } | 
|   28  |   28  | 
|   29 // Implement Set for private EfficientLength interface. |  | 
|   30 class EfficientTestIterable extends TestIterableBase |   29 class EfficientTestIterable extends TestIterableBase | 
|   31                             implements Set<int> { |   30                             implements EfficientLengthIterable<int> { | 
|   32   EfficientTestIterable(length, count, [callbackIndex = -1, callback]) |   31   EfficientTestIterable(length, count, [callbackIndex = -1, callback]) | 
|   33       : super(length, count, callbackIndex, callback); |   32       : super(length, count, callbackIndex, callback); | 
|   34   // Avoid warnings because we don't actually implement Set. |   33   // Avoid warnings because we don't actually implement Set. | 
|   35   noSuchMethod(i) => super.noSuchMethod(i); |   34   noSuchMethod(i) => super.noSuchMethod(i); | 
|   36 } |   35 } | 
|   37  |   36  | 
|   38 class CallbackIterator implements Iterator<int> { |   37 class CallbackIterator implements Iterator<int> { | 
|   39   TestIterableBase _iterable; |   38   TestIterableBase _iterable; | 
|   40   int _current = null; |   39   int _current = null; | 
|   41   int _nextIndex = 0; |   40   int _nextIndex = 0; | 
|   42   CallbackIterator(this._iterable); |   41   CallbackIterator(this._iterable); | 
|   43   bool moveNext() { |   42   bool moveNext() { | 
|   44     if (_nextIndex >= _iterable.count) { |   43     if (_nextIndex >= _iterable.count) { | 
|   45       _current = null; |   44       _current = null; | 
|   46       return false; |   45       return false; | 
|   47     } |   46     } | 
|   48     _current = _nextIndex; |   47     _current = _nextIndex; | 
|   49     _nextIndex++; |   48     _nextIndex++; | 
|   50     if (_current == _iterable.callbackIndex) { |   49     if (_current == _iterable.callbackIndex) { | 
|   51       _iterable.callback(); |   50       _iterable.callback(); | 
|   52     } |   51     } | 
|   53     return true; |   52     return true; | 
|   54   } |   53   } | 
|   55   int get current => _current; |   54   int get current => _current; | 
|   56 } |   55 } | 
|   57  |   56  | 
|   58  |   57  | 
|   59 void main() { |   58 void main() { | 
|   60   // Without EfficientLength interface |   59   // Without EfficientLengthIterable interface | 
|   61   { |   60   { | 
|   62     // Change length of list after 20 additions. |   61     // Change length of list after 20 additions. | 
|   63     var l = []; |   62     var l = []; | 
|   64     var ci = new TestIterable(257, 200, () { |   63     var ci = new TestIterable(257, 200, () { | 
|   65       l.add("X"); |   64       l.add("X"); | 
|   66     }); |   65     }); | 
|   67     Expect.throws(() { |   66     Expect.throws(() { | 
|   68       l.addAll(ci); |   67       l.addAll(ci); | 
|   69     }, (e) => e is ConcurrentModificationError); |   68     }, (e) => e is ConcurrentModificationError); | 
|   70   } |   69   } | 
|   71  |   70  | 
|   72   { |   71   { | 
|   73     // Change length of list after 20 additions. |   72     // Change length of list after 20 additions. | 
|   74     var l = []; |   73     var l = []; | 
|   75     var ci = new TestIterable(257, 200, () { |   74     var ci = new TestIterable(257, 200, () { | 
|   76       l.length = 0; |   75       l.length = 0; | 
|   77     }); |   76     }); | 
|   78     Expect.throws(() { |   77     Expect.throws(() { | 
|   79       l.addAll(ci); |   78       l.addAll(ci); | 
|   80     }, (e) => e is ConcurrentModificationError); |   79     }, (e) => e is ConcurrentModificationError); | 
|   81   } |   80   } | 
|   82  |   81  | 
|   83   // With EfficientLength interface (uses length). |   82   // With EfficientLengthIterable interface (uses length). | 
|   84   { |   83   { | 
|   85     // Change length of list after 20 additions. |   84     // Change length of list after 20 additions. | 
|   86     var l = []; |   85     var l = []; | 
|   87     var ci = new EfficientTestIterable(257, 257, 20, () { |   86     var ci = new EfficientTestIterable(257, 257, 20, () { | 
|   88       l.add("X"); |   87       l.add("X"); | 
|   89     }); |   88     }); | 
|   90     Expect.throws(() { |   89     Expect.throws(() { | 
|   91       l.addAll(ci); |   90       l.addAll(ci); | 
|   92     }, (e) => e is ConcurrentModificationError); |   91     }, (e) => e is ConcurrentModificationError); | 
|   93   } |   92   } | 
| (...skipping 30 matching lines...) Expand all  Loading... | 
|  124     Expect.throws(() { l.addAll(l); }, (e) => e is ConcurrentModificationError); |  123     Expect.throws(() { l.addAll(l); }, (e) => e is ConcurrentModificationError); | 
|  125   } |  124   } | 
|  126  |  125  | 
|  127   { |  126   { | 
|  128     // Adding to yourself. |  127     // Adding to yourself. | 
|  129     var l = [1, 2, 3]; |  128     var l = [1, 2, 3]; | 
|  130     Expect.throws(() { l.addAll(l); }, (e) => e is ConcurrentModificationError); |  129     Expect.throws(() { l.addAll(l); }, (e) => e is ConcurrentModificationError); | 
|  131   } |  130   } | 
|  132 } |  131 } | 
|  133  |  132  | 
| OLD | NEW |