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 import "dart:collection"; | 5 import "dart:collection"; |
6 import "dart:typed_data"; | 6 import "dart:typed_data"; |
7 import "package:expect/expect.dart"; | 7 import "package:expect/expect.dart"; |
8 | 8 |
9 void main() { | 9 void main() { |
10 // Typed lists - fixed length and can only contain integers. | 10 // Typed lists - fixed length and can only contain integers. |
11 testTypedList(new Uint8List(4)); | 11 testTypedList(new Uint8List(4)); |
12 testTypedList(new Int8List(4)); | 12 testTypedList(new Int8List(4)); |
13 testTypedList(new Uint16List(4)); | 13 testTypedList(new Uint16List(4)); |
14 testTypedList(new Int16List(4)); | 14 testTypedList(new Int16List(4)); |
15 testTypedList(new Uint32List(4)); | 15 testTypedList(new Uint32List(4)); |
16 testTypedList(new Int32List(4)); | 16 testTypedList(new Int32List(4)); |
17 testTypedList(new Uint8List(4).toList(growable: false)); | 17 testTypedList(new Uint8List(4).toList(growable: false)); |
18 testTypedList(new Int8List(4).toList(growable: false)); | 18 testTypedList(new Int8List(4).toList(growable: false)); |
19 testTypedList(new Uint16List(4).toList(growable: false)); | 19 testTypedList(new Uint16List(4).toList(growable: false)); |
20 testTypedList(new Int16List(4).toList(growable: false)); | 20 testTypedList(new Int16List(4).toList(growable: false)); |
21 testTypedList(new Uint32List(4).toList(growable: false)); | 21 testTypedList(new Uint32List(4).toList(growable: false)); |
22 testTypedList(new Int32List(4).toList(growable: false)); | 22 testTypedList(new Int32List(4).toList(growable: false)); |
23 | 23 |
24 // Fixed length lists, length 4. | 24 // Fixed length lists, length 4. |
25 testFixedLengthList(new List(4)); | 25 testFixedLengthList(<T>() => new List(4)); |
26 testFixedLengthList(new List(4).toList(growable: false)); | 26 testFixedLengthList(<T>() => new List<T>(4).toList(growable: false)); |
27 testFixedLengthList((new List()..length = 4).toList(growable: false)); | 27 testFixedLengthList(<T>() => (new List<T>()..length = 4).toList(growable: fals e)); |
28 // ListBase implementation of List. | 28 // ListBase implementation of List. |
29 testFixedLengthList(new MyFixedList(new List(4))); | 29 testFixedLengthList(<T>() => new MyFixedList(new List(4))); |
30 testFixedLengthList(new MyFixedList(new List(4)).toList(growable: false)); | 30 testFixedLengthList(<T>() => new MyFixedList<T>(new List(4)).toList(growable: false)); |
31 | 31 |
32 // Growable lists. Initial length 0. | 32 // Growable lists. Initial length 0. |
33 testGrowableList(new List()); | 33 testGrowableList(<T>() => new List()); |
34 testGrowableList(new List().toList()); | 34 testGrowableList(<T>() => new List<T>().toList()); |
35 testGrowableList(new List(0).toList()); | 35 testGrowableList(<T>() => new List<T>(0).toList()); |
36 testGrowableList(new List.filled(0, null, growable: true)); | 36 testGrowableList(<T>() => new List.filled(0, null, growable: true)); |
37 testGrowableList([]); | 37 testGrowableList(<T>() => []); |
38 testGrowableList((const []).toList()); | 38 testGrowableList(<T>() => new List.from(const [])); |
39 testGrowableList(new MyList([])); | 39 testGrowableList(<T>() => new MyList([])); |
40 testGrowableList(new MyList([]).toList()); | 40 testGrowableList(<T>() => new MyList<T>([]).toList()); |
41 | 41 |
42 testTypedGrowableList(new Uint8List(0).toList()); | 42 testTypedGrowableList(new Uint8List(0).toList()); |
43 testTypedGrowableList(new Int8List(0).toList()); | 43 testTypedGrowableList(new Int8List(0).toList()); |
44 testTypedGrowableList(new Uint16List(0).toList()); | 44 testTypedGrowableList(new Uint16List(0).toList()); |
45 testTypedGrowableList(new Int16List(0).toList()); | 45 testTypedGrowableList(new Int16List(0).toList()); |
46 testTypedGrowableList(new Uint32List(0).toList()); | 46 testTypedGrowableList(new Uint32List(0).toList()); |
47 testTypedGrowableList(new Int32List(0).toList()); | 47 testTypedGrowableList(new Int32List(0).toList()); |
48 | 48 |
49 testListConstructor(); | 49 testListConstructor(); |
50 | 50 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 testRangeErrors(new Uint8List.view(new Uint8List(3).buffer), "typed-list"); | 133 testRangeErrors(new Uint8List.view(new Uint8List(3).buffer), "typed-list"); |
134 testRangeErrors([1, 2, 3, 4, 5].sublist(1, 3), "sub-list"); | 134 testRangeErrors([1, 2, 3, 4, 5].sublist(1, 3), "sub-list"); |
135 } | 135 } |
136 | 136 |
137 void testLength(int length, List list) { | 137 void testLength(int length, List list) { |
138 Expect.equals(length, list.length); | 138 Expect.equals(length, list.length); |
139 (length == 0 ? Expect.isTrue : Expect.isFalse)(list.isEmpty); | 139 (length == 0 ? Expect.isTrue : Expect.isFalse)(list.isEmpty); |
140 (length != 0 ? Expect.isTrue : Expect.isFalse)(list.isNotEmpty); | 140 (length != 0 ? Expect.isTrue : Expect.isFalse)(list.isNotEmpty); |
141 } | 141 } |
142 | 142 |
143 void testTypedLengthInvariantOperations(List list) { | 143 void testTypedLengthInvariantOperations(List<int> list) { |
144 // length | 144 // length |
145 Expect.equals(list.length, 4); | 145 Expect.equals(list.length, 4); |
146 // operators [], []=. | 146 // operators [], []=. |
147 for (int i = 0; i < 4; i++) list[i] = 0; | 147 for (int i = 0; i < 4; i++) list[i] = 0; |
148 list[0] = 4; | 148 list[0] = 4; |
149 Expect.listEquals([4, 0, 0, 0], list); | 149 Expect.listEquals([4, 0, 0, 0], list); |
150 list[1] = 7; | 150 list[1] = 7; |
151 Expect.listEquals([4, 7, 0, 0], list); | 151 Expect.listEquals([4, 7, 0, 0], list); |
152 list[3] = 2; | 152 list[3] = 2; |
153 Expect.listEquals([4, 7, 0, 2], list); | 153 Expect.listEquals([4, 7, 0, 2], list); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
250 Expect.isTrue(list.any(matchAll)); | 250 Expect.isTrue(list.any(matchAll)); |
251 Expect.isTrue(list.any(matchSome)); | 251 Expect.isTrue(list.any(matchSome)); |
252 Expect.isTrue(list.any(matchSomeFirst)); | 252 Expect.isTrue(list.any(matchSomeFirst)); |
253 Expect.isTrue(list.any(matchSomeLast)); | 253 Expect.isTrue(list.any(matchSomeLast)); |
254 Expect.isFalse(list.any(matchNone)); | 254 Expect.isFalse(list.any(matchNone)); |
255 | 255 |
256 // Argument checking isn't implemented for typed arrays in browsers, | 256 // Argument checking isn't implemented for typed arrays in browsers, |
257 // so it's moved to the method below for now. | 257 // so it's moved to the method below for now. |
258 } | 258 } |
259 | 259 |
260 void testLengthInvariantOperations(List list) { | 260 void testUntypedListTests(List list) { |
261 testTypedLengthInvariantOperations(list); | |
262 // Tests that need untyped lists. | 261 // Tests that need untyped lists. |
263 list.setAll(0, [0, 1, 2, 3]); | 262 list.setAll(0, [0, 1, 2, 3]); |
264 Expect.equals(-1, list.indexOf(100)); | 263 Expect.equals(-1, list.indexOf(100)); |
265 Expect.equals(-1, list.lastIndexOf(100)); | 264 Expect.equals(-1, list.lastIndexOf(100)); |
266 list[2] = new Yes(); | 265 list[2] = new Yes(); |
267 Expect.equals(2, list.indexOf(100)); | 266 Expect.equals(2, list.indexOf(100)); |
268 Expect.equals(2, list.lastIndexOf(100)); | 267 Expect.equals(2, list.lastIndexOf(100)); |
269 list[3] = new Yes(); | 268 list[3] = new Yes(); |
270 Expect.equals(2, list.indexOf(100)); | 269 Expect.equals(2, list.indexOf(100)); |
271 Expect.equals(3, list.lastIndexOf(100)); | 270 Expect.equals(3, list.lastIndexOf(100)); |
272 list[2] = 2; | 271 list[2] = 2; |
273 Expect.equals(3, list.indexOf(100)); | 272 Expect.equals(3, list.indexOf(100)); |
274 Expect.equals(3, list.lastIndexOf(100)); | 273 Expect.equals(3, list.lastIndexOf(100)); |
275 list[3] = 3; | 274 list[3] = 3; |
276 Expect.equals(-1, list.indexOf(100)); | 275 Expect.equals(-1, list.indexOf(100)); |
277 Expect.equals(-1, list.lastIndexOf(100)); | 276 Expect.equals(-1, list.lastIndexOf(100)); |
277 } | |
278 | |
279 void testLengthInvariantOperations(List<int> list) { | |
280 testTypedLengthInvariantOperations(list); | |
281 | |
282 Expect.throws(() { | |
283 testUntypedListTests(list); | |
284 }, (e) => e is TypeError, 'List<int> cannot store non-ints'); | |
278 | 285 |
279 // Argument errors on bad indices. List is still [0, 1, 2, 3]. | 286 // Argument errors on bad indices. List is still [0, 1, 2, 3]. |
280 testArgumentError(action()) { | 287 testArgumentError(action()) { |
281 Expect.throws(action, (e) => e is ArgumentError); | 288 Expect.throws(action, (e) => e is ArgumentError); |
282 } | 289 } |
283 | 290 |
284 // Direct indices (0 <= index < length). | 291 // Direct indices (0 <= index < length). |
285 testArgumentError(() => list[-1]); | 292 testArgumentError(() => list[-1]); |
286 testArgumentError(() => list[4]); | 293 testArgumentError(() => list[4]); |
287 testArgumentError(() => list[-1] = 99); | 294 testArgumentError(() => list[-1] = 99); |
(...skipping 16 matching lines...) Expand all Loading... | |
304 // for setAll, end is implicitly start + values.length. | 311 // for setAll, end is implicitly start + values.length. |
305 testArgumentError(() => list.setAll(-1, [])); | 312 testArgumentError(() => list.setAll(-1, [])); |
306 testArgumentError(() => list.setAll(5, [])); | 313 testArgumentError(() => list.setAll(5, [])); |
307 testArgumentError(() => list.setAll(2, [1, 2, 3])); | 314 testArgumentError(() => list.setAll(2, [1, 2, 3])); |
308 testArgumentError(() => list.fillRange(-1, 2)); | 315 testArgumentError(() => list.fillRange(-1, 2)); |
309 testArgumentError(() => list.fillRange(-1, 5)); | 316 testArgumentError(() => list.fillRange(-1, 5)); |
310 testArgumentError(() => list.fillRange(2, 5)); | 317 testArgumentError(() => list.fillRange(2, 5)); |
311 testArgumentError(() => list.fillRange(4, 2)); | 318 testArgumentError(() => list.fillRange(4, 2)); |
312 } | 319 } |
313 | 320 |
314 void testTypedList(List list) { | 321 void testTypedList(List<int> list) { |
315 testTypedLengthInvariantOperations(list); | 322 testTypedLengthInvariantOperations(list); |
316 testCannotChangeLength(list); | 323 testCannotChangeLength(list); |
317 } | 324 } |
318 | 325 |
319 void testFixedLengthList(List list) { | 326 void testFixedLengthList(List<T> Function<T>() createList) { |
320 testLengthInvariantOperations(list); | 327 testLengthInvariantOperations(createList()); |
321 testCannotChangeLength(list); | 328 testCannotChangeLength(createList()); |
329 testUntypedListTests(createList()); | |
322 } | 330 } |
323 | 331 |
324 void testCannotChangeLength(List list) { | 332 void testCannotChangeLength(List<int> list) { |
325 isUnsupported(action()) { | 333 isUnsupported(action()) { |
326 Expect.throws(action, (e) => e is UnsupportedError); | 334 Expect.throws(action, (e) => e is UnsupportedError); |
327 } | 335 } |
328 | 336 list.setAll(0, [0, 1, 2, 3]); |
329 isUnsupported(() => list.add(0)); | 337 isUnsupported(() => list.add(0)); |
330 isUnsupported(() => list.addAll([0])); | 338 isUnsupported(() => list.addAll([0])); |
331 isUnsupported(() => list.removeLast()); | 339 isUnsupported(() => list.removeLast()); |
332 isUnsupported(() => list.insert(0, 1)); | 340 isUnsupported(() => list.insert(0, 1)); |
333 isUnsupported(() => list.insertAll(0, [1])); | 341 isUnsupported(() => list.insertAll(0, [1])); |
334 isUnsupported(() => list.clear()); | 342 isUnsupported(() => list.clear()); |
335 isUnsupported(() => list.remove(1)); | 343 isUnsupported(() => list.remove(1)); |
336 isUnsupported(() => list.removeAt(1)); | 344 isUnsupported(() => list.removeAt(1)); |
337 isUnsupported(() => list.removeRange(0, 1)); | 345 isUnsupported(() => list.removeRange(0, 1)); |
338 isUnsupported(() => list.replaceRange(0, 1, [])); | 346 isUnsupported(() => list.replaceRange(0, 1, [])); |
339 } | 347 } |
340 | 348 |
341 void testTypedGrowableList(List list) { | 349 void testTypedGrowableList(List<int> list) { |
342 testLength(0, list); | 350 testLength(0, list); |
343 // set length. | 351 // set length. |
344 list.length = 4; | 352 list.length = 4; |
345 testLength(4, list); | 353 testLength(4, list); |
346 | 354 |
347 testTypedLengthInvariantOperations(list); | 355 testTypedLengthInvariantOperations(list); |
348 | 356 |
349 testGrowableListOperations(list); | 357 testGrowableListOperations(list); |
350 } | 358 } |
351 | 359 |
352 void testGrowableList(List list) { | 360 void testGrowableList(List<T> Function<T>() createList) { |
361 List<int> list = createList(); | |
353 testLength(0, list); | 362 testLength(0, list); |
354 // set length. | |
355 list.length = 4; | 363 list.length = 4; |
356 testLength(4, list); | 364 testLength(4, list); |
357 | 365 |
358 testLengthInvariantOperations(list); | 366 testLengthInvariantOperations(list); |
367 testGrowableListOperations(list); | |
359 | 368 |
360 testGrowableListOperations(list); | 369 List listDynamic = createList(); |
370 testLength(0, listDynamic); | |
371 listDynamic.length = 4; | |
372 testLength(4, listDynamic); | |
373 | |
374 testUntypedListTests(listDynamic); | |
361 } | 375 } |
362 | 376 |
363 void testGrowableListOperations(List list) { | 377 void testGrowableListOperations(List<int> list) { |
364 // add, removeLast. | 378 // add, removeLast. |
365 list.clear(); | 379 list.clear(); |
366 testLength(0, list); | 380 testLength(0, list); |
367 list.add(4); | 381 list.add(4); |
368 testLength(1, list); | 382 testLength(1, list); |
369 Expect.equals(4, list.removeLast()); | 383 Expect.equals(4, list.removeLast()); |
370 testLength(0, list); | 384 testLength(0, list); |
371 | 385 |
372 for (int i = 0; i < 100; i++) { | 386 for (int i = 0; i < 100; i++) { |
373 list.add(i); | 387 list.add(i); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
468 | 482 |
469 list.replaceRange(2, 3, [5, 5, 5]); | 483 list.replaceRange(2, 3, [5, 5, 5]); |
470 Expect.listEquals([1, 2, 5, 5, 5, 0, 0, 7, 2, 3, 2, 1], list); | 484 Expect.listEquals([1, 2, 5, 5, 5, 0, 0, 7, 2, 3, 2, 1], list); |
471 | 485 |
472 list.replaceRange(2, 4, [6, 6]); | 486 list.replaceRange(2, 4, [6, 6]); |
473 Expect.listEquals([1, 2, 6, 6, 5, 0, 0, 7, 2, 3, 2, 1], list); | 487 Expect.listEquals([1, 2, 6, 6, 5, 0, 0, 7, 2, 3, 2, 1], list); |
474 | 488 |
475 list.replaceRange(6, 8, []); | 489 list.replaceRange(6, 8, []); |
476 Expect.listEquals([1, 2, 6, 6, 5, 0, 2, 3, 2, 1], list); | 490 Expect.listEquals([1, 2, 6, 6, 5, 0, 2, 3, 2, 1], list); |
477 | 491 |
478 // Operations that change the length cause ConcurrentModificationError. | |
Jennifer Messerly
2017/08/25 18:08:57
these were split into a new test
| |
479 void testConcurrentModification(action()) { | |
480 testIterator(int when) { | |
481 list.length = 4; | |
482 list.setAll(0, [0, 1, 2, 3]); | |
483 Expect.throws(() { | |
484 for (var element in list) { | |
485 if (element == when) action(); | |
486 } | |
487 }, (e) => e is ConcurrentModificationError); | |
488 } | |
489 | |
490 testForEach(int when) { | |
491 list.length = 4; | |
492 list.setAll(0, [0, 1, 2, 3]); | |
493 Expect.throws(() { | |
494 list.forEach((var element) { | |
495 if (element == when) action(); | |
496 }); | |
497 }, (e) => e is ConcurrentModificationError); | |
498 } | |
499 | |
500 // Test the change at different points of the iteration. | |
501 testIterator(0); | |
502 testIterator(1); | |
503 testIterator(3); | |
504 testForEach(0); | |
505 testForEach(1); | |
506 testForEach(3); | |
507 } | |
508 | |
509 testConcurrentModification(() => list.add(5)); | |
510 testConcurrentModification(() => list.addAll([5, 6])); | |
511 testConcurrentModification(() => list.removeLast()); | |
512 for (int i = 0; i < 4; i++) { | |
513 testConcurrentModification(() => list.remove(i)); | |
514 testConcurrentModification(() => list.removeAt(i)); | |
515 testConcurrentModification(() => list.removeWhere((x) => x == i)); | |
516 testConcurrentModification(() => list.retainWhere((x) => x != i)); | |
517 testConcurrentModification(() => list.insert(i, 5)); | |
518 testConcurrentModification(() => list.insertAll(i, [5, 6])); | |
519 testConcurrentModification(() => list.removeRange(i, i + 1)); | |
520 testConcurrentModification(() => list.replaceRange(i, i + 1, [5, 6])); | |
521 } | |
522 | |
523 // Any operation that doesn't change the length should be safe for iteration. | 492 // Any operation that doesn't change the length should be safe for iteration. |
524 testSafeConcurrentModification(action()) { | 493 testSafeConcurrentModification(action()) { |
525 list.length = 4; | 494 list.length = 4; |
526 list.setAll(0, [0, 1, 2, 3]); | 495 list.setAll(0, [0, 1, 2, 3]); |
527 for (var i in list) { | 496 for (var i in list) { |
528 action(); | 497 action(); |
529 } | 498 } |
530 list.forEach((e) => action()); | 499 list.forEach((e) => action()); |
531 } | 500 } |
532 | 501 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
624 }); | 593 }); |
625 // Not negative. | 594 // Not negative. |
626 Expect.throws(() { | 595 Expect.throws(() { |
627 new List.filled(-2, 42); | 596 new List.filled(-2, 42); |
628 }); | 597 }); |
629 // Not null. | 598 // Not null. |
630 Expect.throws(() { | 599 Expect.throws(() { |
631 new List.filled(null, 42); | 600 new List.filled(null, 42); |
632 }); | 601 }); |
633 } | 602 } |
OLD | NEW |