Index: tests/corelib_2/list_concurrent_modify_test.dart |
diff --git a/tests/corelib_2/list_concurrent_modify_test.dart b/tests/corelib_2/list_concurrent_modify_test.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4d5de96960294fd7bf28aad23e3826c9f3fa08ed |
--- /dev/null |
+++ b/tests/corelib_2/list_concurrent_modify_test.dart |
@@ -0,0 +1,100 @@ |
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+import "dart:collection"; |
+import "dart:typed_data"; |
+import "package:expect/expect.dart"; |
+ |
+void main() { |
+ // Growable lists. Initial length 0. |
+ testConcurrentModification(new List()); |
+ testConcurrentModification(new List<int>().toList()); |
+ testConcurrentModification(new List<int>(0).toList()); |
+ testConcurrentModification(new List.filled(0, null, growable: true)); |
+ testConcurrentModification([]); |
+ testConcurrentModification(new List.from(const [])); |
+ testConcurrentModification(new MyList([])); |
+ testConcurrentModification(new MyList<int>([]).toList()); |
+ |
+ testConcurrentModification(new Uint8List(0).toList()); |
+ testConcurrentModification(new Int8List(0).toList()); |
+ testConcurrentModification(new Uint16List(0).toList()); |
+ testConcurrentModification(new Int16List(0).toList()); |
+ testConcurrentModification(new Uint32List(0).toList()); |
+ testConcurrentModification(new Int32List(0).toList()); |
+ |
+ testConcurrentAddSelf([]); |
+ testConcurrentAddSelf([1, 2, 3]); |
+} |
+ |
+void testConcurrentModification(List<int> list) { |
+ // add, removeLast. |
+ list.clear(); |
+ list.addAll([1, 2, 3, 2, 7, 9, 9, 7, 2, 3, 2, 1]); |
+ |
+ // Operations that change the length cause ConcurrentModificationError. |
+ void testModification(action()) { |
+ testIterator(int when) { |
+ list.length = 4; |
+ list.setAll(0, [0, 1, 2, 3]); |
+ Expect.throws(() { |
+ for (var element in list) { |
+ if (element == when) action(); |
+ } |
+ }, (e) => e is ConcurrentModificationError); |
+ } |
+ |
+ testForEach(int when) { |
+ list.length = 4; |
+ list.setAll(0, [0, 1, 2, 3]); |
+ Expect.throws(() { |
+ list.forEach((var element) { |
+ if (element == when) action(); |
+ }); |
+ }, (e) => e is ConcurrentModificationError); |
+ } |
+ |
+ // Test the change at different points of the iteration. |
+ testIterator(0); |
+ testIterator(1); |
+ testIterator(3); |
+ testForEach(0); |
+ testForEach(1); |
+ testForEach(3); |
+ } |
+ |
+ testModification(() => list.add(5)); |
+ testModification(() => list.addAll([5, 6])); |
+ testModification(() => list.removeLast()); |
+ for (int i = 0; i < 4; i++) { |
+ testModification(() => list.remove(i)); |
+ testModification(() => list.removeAt(i)); |
+ testModification(() => list.removeWhere((x) => x == i)); |
+ testModification(() => list.retainWhere((x) => x != i)); |
+ testModification(() => list.insert(i, 5)); |
+ testModification(() => list.insertAll(i, [5, 6])); |
+ testModification(() => list.removeRange(i, i + 1)); |
+ testModification(() => list.replaceRange(i, i + 1, [5, 6])); |
+ } |
+} |
+ |
+testConcurrentAddSelf(List list) { |
+ Expect.throws(() { |
+ list.addAll(list); |
+ }, (e) => e is ConcurrentModificationError, "testConcurrentAddSelf($list)"); |
+} |
+ |
+class MyList<E> extends ListBase<E> { |
+ List<E> _source; |
+ MyList(this._source); |
+ int get length => _source.length; |
+ void set length(int length) { |
+ _source.length = length; |
+ } |
+ |
+ E operator [](int index) => _source[index]; |
+ void operator []=(int index, E value) { |
+ _source[index] = value; |
+ } |
+} |