| 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 | 8 |
| 9 void main() { | 9 void main() { |
| 10 testConstructor(); | 10 testConstructor(); |
| 11 | 11 |
| 12 bool checked = false; | 12 bool checked = false; |
| 13 assert((checked = true)); | 13 assert((checked = true)); |
| 14 // Concurrent modification checks are only guaranteed in checked mode. | 14 // Concurrent modification checks are only guaranteed in checked mode. |
| 15 if (checked) testConcurrentModification(); | 15 if (checked) testConcurrentModification(); |
| 16 } | 16 } |
| 17 | 17 |
| 18 // Iterable generating numbers in range [0..count). | 18 // Iterable generating numbers in range [0..count). |
| 19 // May perform callback at some point underways. | 19 // May perform callback at some point underways. |
| 20 class TestIterableBase extends Iterable<int> { | 20 class TestIterableBase extends Iterable<int> { |
| 21 final int length; | 21 final int length; |
| 22 final int count; | 22 final int count; |
| 23 // call [callback] if generating callbackIndex. | 23 // call [callback] if generating callbackIndex. |
| 24 final int callbackIndex; | 24 final int callbackIndex; |
| 25 final Function callback; | 25 final Function callback; |
| 26 TestIterableBase(this.length, this.count, | 26 TestIterableBase(this.length, this.count, this.callbackIndex, this.callback); |
| 27 this.callbackIndex, this.callback); | |
| 28 Iterator<int> get iterator => new CallbackIterator(this); | 27 Iterator<int> get iterator => new CallbackIterator(this); |
| 29 } | 28 } |
| 30 | 29 |
| 31 class TestIterable extends TestIterableBase { | 30 class TestIterable extends TestIterableBase { |
| 32 TestIterable(count, [callbackIndex = -1, callback]) | 31 TestIterable(count, [callbackIndex = -1, callback]) |
| 33 : super(-1, count, callbackIndex, callback); | 32 : super(-1, count, callbackIndex, callback); |
| 34 int get length => throw "SHOULD NOT BE CALLED"; | 33 int get length => throw "SHOULD NOT BE CALLED"; |
| 35 } | 34 } |
| 36 | 35 |
| 37 // Implement Set for private EfficientLength interface. | 36 // Implement Set for private EfficientLength interface. |
| 38 class EfficientTestIterable extends TestIterableBase | 37 class EfficientTestIterable extends TestIterableBase implements Set<int> { |
| 39 implements Set<int> { | |
| 40 EfficientTestIterable(length, count, [callbackIndex = -1, callback]) | 38 EfficientTestIterable(length, count, [callbackIndex = -1, callback]) |
| 41 : super(length, count, callbackIndex, callback); | 39 : super(length, count, callbackIndex, callback); |
| 42 // Avoid warnings because we don't actually implement Set. | 40 // Avoid warnings because we don't actually implement Set. |
| 43 noSuchMethod(i) => super.noSuchMethod(i); | 41 noSuchMethod(i) => super.noSuchMethod(i); |
| 44 } | 42 } |
| 45 | 43 |
| 46 class CallbackIterator implements Iterator<int> { | 44 class CallbackIterator implements Iterator<int> { |
| 47 TestIterableBase _iterable; | 45 TestIterableBase _iterable; |
| 48 int _current = null; | 46 int _current = null; |
| 49 int _nextIndex = 0; | 47 int _nextIndex = 0; |
| 50 CallbackIterator(this._iterable); | 48 CallbackIterator(this._iterable); |
| 51 bool moveNext() { | 49 bool moveNext() { |
| 52 if (_nextIndex >= _iterable.count) { | 50 if (_nextIndex >= _iterable.count) { |
| 53 _current = null; | 51 _current = null; |
| 54 return false; | 52 return false; |
| 55 } | 53 } |
| 56 _current = _nextIndex; | 54 _current = _nextIndex; |
| 57 _nextIndex++; | 55 _nextIndex++; |
| 58 if (_current == _iterable.callbackIndex) { | 56 if (_current == _iterable.callbackIndex) { |
| 59 _iterable.callback(); | 57 _iterable.callback(); |
| 60 } | 58 } |
| 61 return true; | 59 return true; |
| 62 } | 60 } |
| 61 |
| 63 int get current => _current; | 62 int get current => _current; |
| 64 } | 63 } |
| 65 | 64 |
| 66 void testConstructor() { | 65 void testConstructor() { |
| 67 // Constructor can make both growable and fixed-length lists. | 66 // Constructor can make both growable and fixed-length lists. |
| 68 testGrowable(list) { | 67 testGrowable(list) { |
| 69 Expect.isTrue(list is List<int>); | 68 Expect.isTrue(list is List<int>); |
| 70 Expect.isFalse(list is List<String>); | 69 Expect.isFalse(list is List<String>); |
| 71 int length = list.length; | 70 int length = list.length; |
| 72 list.add(42); | 71 list.add(42); |
| 73 Expect.equals(list.length, length + 1); | 72 Expect.equals(list.length, length + 1); |
| 74 } | 73 } |
| 75 | 74 |
| 76 testFixedLength(list) { | 75 testFixedLength(list) { |
| 77 Expect.isTrue(list is List<int>); | 76 Expect.isTrue(list is List<int>); |
| 78 int length = list.length; | 77 int length = list.length; |
| 79 Expect.throws(() { list.add(42); }, null, "adding to fixed-length list"); | 78 Expect.throws(() { |
| 79 list.add(42); |
| 80 }, null, "adding to fixed-length list"); |
| 80 Expect.equals(length, list.length); | 81 Expect.equals(length, list.length); |
| 81 } | 82 } |
| 82 | 83 |
| 83 bool checked = false; | 84 bool checked = false; |
| 84 assert((checked = true)); | 85 assert((checked = true)); |
| 85 testThrowsOrTypeError(fn, test, [name]) { | 86 testThrowsOrTypeError(fn, test, [name]) { |
| 86 Expect.throws(fn, checked ? null : test, | 87 Expect.throws( |
| 87 checked ? name : "$name w/ TypeError"); | 88 fn, checked ? null : test, checked ? name : "$name w/ TypeError"); |
| 88 } | 89 } |
| 90 |
| 89 testFixedLength(new List<int>(0)); | 91 testFixedLength(new List<int>(0)); |
| 90 testFixedLength(new List<int>(5)); | 92 testFixedLength(new List<int>(5)); |
| 91 testFixedLength(new List<int>.filled(5, null)); // default growable: false. | 93 testFixedLength(new List<int>.filled(5, null)); // default growable: false. |
| 92 testGrowable(new List<int>()); | 94 testGrowable(new List<int>()); |
| 93 testGrowable(new List<int>()..length = 5); | 95 testGrowable(new List<int>()..length = 5); |
| 94 testGrowable(new List<int>.filled(5, null, growable: true)); | 96 testGrowable(new List<int>.filled(5, null, growable: true)); |
| 95 Expect.throws(() => new List<int>(-1), (e) => e is ArgumentError, "-1"); | 97 Expect.throws(() => new List<int>(-1), (e) => e is ArgumentError, "-1"); |
| 96 // There must be limits. Fix this test if we ever allow 10^30 elements. | 98 // There must be limits. Fix this test if we ever allow 10^30 elements. |
| 97 Expect.throws(() => new List<int>(0x1000000000000000000000000000000), | 99 Expect.throws(() => new List<int>(0x1000000000000000000000000000000), |
| 98 (e) => e is ArgumentError, "bignum"); | 100 (e) => e is ArgumentError, "bignum"); |
| 99 Expect.throws(() => new List<int>(null), (e) => e is ArgumentError, "null"); | 101 Expect.throws(() => new List<int>(null), (e) => e is ArgumentError, "null"); |
| 100 testThrowsOrTypeError(() => new List([] as Object), // Cast to avoid warning. | 102 testThrowsOrTypeError( |
| 101 (e) => e is ArgumentError, 'list'); | 103 () => new List([] as Object), // Cast to avoid warning. |
| 102 testThrowsOrTypeError(() => new List([42] as Object), | 104 (e) => e is ArgumentError, |
| 103 (e) => e is ArgumentError, "list2"); | 105 'list'); |
| 106 testThrowsOrTypeError( |
| 107 () => new List([42] as Object), (e) => e is ArgumentError, "list2"); |
| 104 } | 108 } |
| 105 | 109 |
| 106 void testConcurrentModification() { | 110 void testConcurrentModification() { |
| 107 // Without EfficientLength interface | 111 // Without EfficientLength interface |
| 108 { | 112 { |
| 109 // Change length of list after 200 additions. | 113 // Change length of list after 200 additions. |
| 110 var l = []; | 114 var l = []; |
| 111 var ci = new TestIterable(257, 200, () { | 115 var ci = new TestIterable(257, 200, () { |
| 112 l.add("X"); | 116 l.add("X"); |
| 113 }); | 117 }); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 Expect.throws(() { | 151 Expect.throws(() { |
| 148 l.addAll(ci); | 152 l.addAll(ci); |
| 149 }, (e) => e is ConcurrentModificationError, "cm4"); | 153 }, (e) => e is ConcurrentModificationError, "cm4"); |
| 150 } | 154 } |
| 151 | 155 |
| 152 { | 156 { |
| 153 // Length 500, only 250 elements. | 157 // Length 500, only 250 elements. |
| 154 var l = []; | 158 var l = []; |
| 155 var ci = new EfficientTestIterable(500, 250); | 159 var ci = new EfficientTestIterable(500, 250); |
| 156 l.addAll(ci); | 160 l.addAll(ci); |
| 157 Expect.listEquals(new List.generate(250, (x)=>x), l, "cm5"); | 161 Expect.listEquals(new List.generate(250, (x) => x), l, "cm5"); |
| 158 } | 162 } |
| 159 | 163 |
| 160 { | 164 { |
| 161 // Length 250, but 500 elements. | 165 // Length 250, but 500 elements. |
| 162 var l = []; | 166 var l = []; |
| 163 var ci = new EfficientTestIterable(250, 500); | 167 var ci = new EfficientTestIterable(250, 500); |
| 164 l.addAll(ci); | 168 l.addAll(ci); |
| 165 Expect.listEquals(new List.generate(500, (x)=>x), l, "cm6"); | 169 Expect.listEquals(new List.generate(500, (x) => x), l, "cm6"); |
| 166 } | 170 } |
| 167 | 171 |
| 168 { | 172 { |
| 169 // Adding to yourself. | 173 // Adding to yourself. |
| 170 var l = [1]; | 174 var l = [1]; |
| 171 Expect.throws(() { l.addAll(l); }, | 175 Expect.throws(() { |
| 172 (e) => e is ConcurrentModificationError, "cm7"); | 176 l.addAll(l); |
| 177 }, (e) => e is ConcurrentModificationError, "cm7"); |
| 173 } | 178 } |
| 174 | 179 |
| 175 { | 180 { |
| 176 // Adding to yourself. | 181 // Adding to yourself. |
| 177 var l = [1, 2, 3]; | 182 var l = [1, 2, 3]; |
| 178 Expect.throws(() { l.addAll(l); }, | 183 Expect.throws(() { |
| 179 (e) => e is ConcurrentModificationError, "cm8"); | 184 l.addAll(l); |
| 185 }, (e) => e is ConcurrentModificationError, "cm8"); |
| 180 } | 186 } |
| 181 } | 187 } |
| 182 | |
| OLD | NEW |