Chromium Code Reviews| 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 |