Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(700)

Unified Diff: test/codegen/corelib/list_test.dart

Issue 1945153002: Add corelib tests (Closed) Base URL: https://github.com/dart-lang/dev_compiler@master
Patch Set: error_test and range_error_test now pass Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « test/codegen/corelib/list_sublist_test.dart ('k') | test/codegen/corelib/list_to_string2_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/codegen/corelib/list_test.dart
diff --git a/test/codegen/corelib/list_test.dart b/test/codegen/corelib/list_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..a72a189dde51aabb9261ee4c47a14c6916d32d1a
--- /dev/null
+++ b/test/codegen/corelib/list_test.dart
@@ -0,0 +1,591 @@
+// 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() {
+ // Typed lists - fixed length and can only contain integers.
+ testTypedList(new Uint8List(4));
+ testTypedList(new Int8List(4));
+ testTypedList(new Uint16List(4));
+ testTypedList(new Int16List(4));
+ testTypedList(new Uint32List(4));
+ testTypedList(new Int32List(4));
+ testTypedList(new Uint8List(4).toList(growable: false));
+ testTypedList(new Int8List(4).toList(growable: false));
+ testTypedList(new Uint16List(4).toList(growable: false));
+ testTypedList(new Int16List(4).toList(growable: false));
+ testTypedList(new Uint32List(4).toList(growable: false));
+ testTypedList(new Int32List(4).toList(growable: false));
+
+ // Fixed length lists, length 4.
+ testFixedLengthList(new List(4));
+ testFixedLengthList(new List(4).toList(growable: false));
+ testFixedLengthList((new List()..length = 4).toList(growable: false));
+ // ListBase implementation of List.
+ testFixedLengthList(new MyFixedList(new List(4)));
+ testFixedLengthList(new MyFixedList(new List(4)).toList(growable: false));
+
+ // Growable lists. Initial length 0.
+ testGrowableList(new List());
+ testGrowableList(new List().toList());
+ testGrowableList(new List(0).toList());
+ testGrowableList(new List.filled(0, null, growable: true));
+ testGrowableList([]);
+ testGrowableList((const []).toList());
+ testGrowableList(new MyList([]));
+ testGrowableList(new MyList([]).toList());
+
+ testTypedGrowableList(new Uint8List(0).toList());
+ testTypedGrowableList(new Int8List(0).toList());
+ testTypedGrowableList(new Uint16List(0).toList());
+ testTypedGrowableList(new Int16List(0).toList());
+ testTypedGrowableList(new Uint32List(0).toList());
+ testTypedGrowableList(new Int32List(0).toList());
+
+ testListConstructor();
+
+ testErrors();
+}
+
+void testErrors() {
+ // Regression for issue http://dartbug.com/24295
+ testIndexError(list, index, name) {
+ try {
+ list[list.length];
+ } catch (err, s) {
+ Expect.isTrue(err is RangeError, "$name[$index]");
+ Expect.equals(list.length, err.invalidValue, "$name[$index] value");
+ Expect.equals(list.length - 1, err.end, "$name[$index] end");
+ Expect.equals(0, err.start, "$name[$index] start");
+ }
+ }
+ testIndex(list, name) {
+ testIndexError(list, list.length, name); // Just too big.
+ testIndexError(list, -1, name); // Negative.
+ testIndexError(list, 0x123456789, name); // > 2^32.
+ testIndexError(list, -0x123456789, name); // < -2^32.
+ }
+
+ // Slices.
+ testSliceError(list, start, end, name) {
+ name = "$name[$start:$end]";
+ var realError;
+ try {
+ RangeError.checkValidRange(start, end, list.length);
+ } catch (e) {
+ realError = e;
+ }
+ var result;
+ try {
+ result = list.sublist(start, end);
+ } catch (actualError) {
+ Expect.isNotNull(realError, "$name should not fail");
+ Expect.isTrue(actualError is RangeError, "$name is-error: $actualError");
+ Expect.equals(realError.name, actualError.name, "$name name");
+ Expect.equals(realError.invalidValue, actualError.invalidValue,
+ "$name[0:l+1] value");
+ Expect.equals(realError.start, actualError.start, "$name[0:l+1] start");
+ Expect.equals(realError.end, actualError.end, "$name[0:l+1] end");
+ return;
+ }
+ // Didn't throw.
+ Expect.isNull(realError, "$name should fail");
+ Expect.equals(end - start, result.length, "$name result length");
+ }
+
+ testSlice(list, name) {
+ testSliceError(list, 0, list.length, name); // Should not fail.
+ testSliceError(list, 0, list.length + 1, name);
+ testSliceError(list, 0, 0x123456789, name);
+ testSliceError(list, -1, list.length, name);
+ testSliceError(list, -0x123456789, list.length, name);
+ testSliceError(list, list.length + 1, list.length + 1, name);
+ testSliceError(list, -1, null, name);
+ if (list.length > 0) {
+ testSliceError(list, list.length, list.length - 1, name);
+ }
+ }
+
+ testRangeErrors(list, name) {
+ testIndex(list, "$name#${list.length} index");
+ testSlice(list, "$name#${list.length} slice");
+ }
+ // Empty lists.
+ testRangeErrors([], "list");
+ testRangeErrors(new List(0), "fixed-list");
+ testRangeErrors(const [], "const-list");
+ testRangeErrors(new List.unmodifiable([]), "unmodifiable");
+ testRangeErrors(new Uint8List(0), "typed-list");
+ testRangeErrors(new Uint8List.view(new Uint8List(0).buffer), "typed-list");
+ testRangeErrors([1, 2, 3].sublist(1, 1), "sub-list");
+ // Non-empty lists.
+ testRangeErrors([1, 2, 3], "list");
+ testRangeErrors(new List(3), "fixed-list");
+ testRangeErrors(const [1, 2, 3], "const-list");
+ testRangeErrors(new List.unmodifiable([1, 2, 3]), "unmodifiable");
+ testRangeErrors(new Uint8List(3), "typed-list");
+ testRangeErrors(new Uint8List.view(new Uint8List(3).buffer), "typed-list");
+ testRangeErrors([1, 2, 3, 4, 5].sublist(1, 3), "sub-list");
+}
+
+void testLength(int length, List list) {
+ Expect.equals(length, list.length);
+ (length == 0 ? Expect.isTrue : Expect.isFalse)(list.isEmpty);
+ (length != 0 ? Expect.isTrue : Expect.isFalse)(list.isNotEmpty);
+}
+
+void testTypedLengthInvariantOperations(List list) {
+ // length
+ Expect.equals(list.length, 4);
+ // operators [], []=.
+ for (int i = 0; i < 4; i++) list[i] = 0;
+ list[0] = 4;
+ Expect.listEquals([4, 0, 0, 0], list);
+ list[1] = 7;
+ Expect.listEquals([4, 7, 0, 0], list);
+ list[3] = 2;
+ Expect.listEquals([4, 7, 0, 2], list);
+
+ for (int i = 0; i < list.length; i++) {
+ list[i] = i;
+ }
+
+ // indexOf, lastIndexOf
+ for (int i = 0; i < 4; i++) {
+ Expect.equals(i, list[i]);
+ Expect.equals(i, list.indexOf(i));
+ Expect.equals(i, list.lastIndexOf(i));
+ }
+
+ // setRange.
+ list.setRange(0, 4, [3, 2, 1, 0]);
+ Expect.listEquals([3, 2, 1, 0], list);
+
+ list.setRange(1, 4, list);
+ Expect.listEquals([3, 3, 2, 1], list);
+
+ list.setRange(0, 3, list, 1);
+ Expect.listEquals([3, 2, 1, 1], list);
+ list.setRange(0, 3, list, 1);
+ Expect.listEquals([2, 1, 1, 1], list);
+
+ list.setRange(2, 4, list, 0);
+ Expect.listEquals([2, 1, 2, 1], list);
+
+ // setAll.
+ list.setAll(0, [3, 2, 0, 1]);
+ Expect.listEquals([3, 2, 0, 1], list);
+ list.setAll(1, [0, 1]);
+ Expect.listEquals([3, 0, 1, 1], list);
+
+ // fillRange.
+ list.fillRange(1, 3, 7);
+ Expect.listEquals([3, 7, 7, 1], list);
+ list.fillRange(0, 0, 9);
+ Expect.listEquals([3, 7, 7, 1], list);
+ list.fillRange(4, 4, 9);
+ Expect.listEquals([3, 7, 7, 1], list);
+ list.fillRange(0, 4, 9);
+ Expect.listEquals([9, 9, 9, 9], list);
+
+ // sort.
+ list.setRange(0, 4, [3, 2, 1, 0]);
+ list.sort();
+ Expect.listEquals([0, 1, 2, 3], list);
+ list.setRange(0, 4, [1, 2, 3, 0]);
+ list.sort();
+ Expect.listEquals([0, 1, 2, 3], list);
+ list.setRange(0, 4, [1, 3, 0, 2]);
+ list.sort((a, b) => b - a); // reverse compare.
+ Expect.listEquals([3, 2, 1, 0], list);
+ list.setRange(0, 4, [1, 2, 3, 0]);
+ list.sort((a, b) => b - a);
+ Expect.listEquals([3, 2, 1, 0], list);
+
+ // Some Iterable methods.
+
+ list.setRange(0, 4, [0, 1, 2, 3]);
+ // map.
+ testMap(val) {return val * 2 + 10; }
+ List mapped = list.map(testMap).toList();
+ Expect.equals(mapped.length, list.length);
+ for (var i = 0; i < list.length; i++) {
+ Expect.equals(mapped[i], list[i] * 2 + 10);
+ }
+
+ matchAll(val) => true;
+ matchSome(val) { return (val == 1 || val == 2); }
+ matchSomeFirst(val) { return val == 0; }
+ matchSomeLast(val) { return val == 3; }
+ matchNone(val) => false;
+
+ // where.
+ Iterable filtered = list.where(matchSome);
+ Expect.equals(filtered.length, 2);
+
+ // every
+ Expect.isTrue(list.every(matchAll));
+ Expect.isFalse(list.every(matchSome));
+ Expect.isFalse(list.every(matchNone));
+
+ // any
+ Expect.isTrue(list.any(matchAll));
+ Expect.isTrue(list.any(matchSome));
+ Expect.isTrue(list.any(matchSomeFirst));
+ Expect.isTrue(list.any(matchSomeLast));
+ Expect.isFalse(list.any(matchNone));
+
+ // Argument checking isn't implemented for typed arrays in browsers,
+ // so it's moved to the method below for now.
+}
+
+void testLengthInvariantOperations(List list) {
+ testTypedLengthInvariantOperations(list);
+ // Tests that need untyped lists.
+ list.setAll(0, [0, 1, 2, 3]);
+ Expect.equals(-1, list.indexOf(100));
+ Expect.equals(-1, list.lastIndexOf(100));
+ list[2] = new Yes();
+ Expect.equals(2, list.indexOf(100));
+ Expect.equals(2, list.lastIndexOf(100));
+ list[3] = new Yes();
+ Expect.equals(2, list.indexOf(100));
+ Expect.equals(3, list.lastIndexOf(100));
+ list[2] = 2;
+ Expect.equals(3, list.indexOf(100));
+ Expect.equals(3, list.lastIndexOf(100));
+ list[3] = 3;
+ Expect.equals(-1, list.indexOf(100));
+ Expect.equals(-1, list.lastIndexOf(100));
+
+ // Argument errors on bad indices. List is still [0, 1, 2, 3].
+ testArgumentError(action()) {
+ Expect.throws(action, (e) => e is ArgumentError);
+ }
+
+ // Direct indices (0 <= index < length).
+ testArgumentError(() => list[-1]);
+ testArgumentError(() => list[4]);
+ testArgumentError(() => list[-1] = 99);
+ testArgumentError(() => list[4] = 99);
+ testArgumentError(() => list.elementAt(-1));
+ testArgumentError(() => list.elementAt(4));
+ // Ranges (0 <= start <= end <= length).
+ testArgumentError(() => list.sublist(-1, 2));
+ testArgumentError(() => list.sublist(-1, 5));
+ testArgumentError(() => list.sublist(2, 5));
+ testArgumentError(() => list.sublist(4, 2));
+ testArgumentError(() => list.getRange(-1, 2));
+ testArgumentError(() => list.getRange(-1, 5));
+ testArgumentError(() => list.getRange(2, 5));
+ testArgumentError(() => list.getRange(4, 2));
+ testArgumentError(() => list.setRange(-1, 2, [1, 2, 3]));
+ testArgumentError(() => list.setRange(-1, 5, [1, 2, 3, 4, 5, 6]));
+ testArgumentError(() => list.setRange(2, 5, [1, 2, 3]));
+ testArgumentError(() => list.setRange(4, 2, [1, 2]));
+ // for setAll, end is implictly start + values.length.
+ testArgumentError(() => list.setAll(-1, []));
+ testArgumentError(() => list.setAll(5, []));
+ testArgumentError(() => list.setAll(2, [1, 2, 3]));
+ testArgumentError(() => list.fillRange(-1, 2));
+ testArgumentError(() => list.fillRange(-1, 5));
+ testArgumentError(() => list.fillRange(2, 5));
+ testArgumentError(() => list.fillRange(4, 2));
+}
+
+void testTypedList(List list) {
+ testTypedLengthInvariantOperations(list);
+ testCannotChangeLength(list);
+}
+
+void testFixedLengthList(List list) {
+ testLengthInvariantOperations(list);
+ testCannotChangeLength(list);
+}
+
+void testCannotChangeLength(List list) {
+ isUnsupported(action()) {
+ Expect.throws(action, (e) => e is UnsupportedError);
+ }
+ isUnsupported(() => list.add(0));
+ isUnsupported(() => list.addAll([0]));
+ isUnsupported(() => list.removeLast());
+ isUnsupported(() => list.insert(0, 1));
+ isUnsupported(() => list.insertAll(0, [1]));
+ isUnsupported(() => list.clear());
+ isUnsupported(() => list.remove(1));
+ isUnsupported(() => list.removeAt(1));
+ isUnsupported(() => list.removeRange(0, 1));
+ isUnsupported(() => list.replaceRange(0, 1, []));
+}
+
+void testTypedGrowableList(List list) {
+ testLength(0, list);
+ // set length.
+ list.length = 4;
+ testLength(4, list);
+
+ testTypedLengthInvariantOperations(list);
+
+ testGrowableListOperations(list);
+}
+
+void testGrowableList(List list) {
+ testLength(0, list);
+ // set length.
+ list.length = 4;
+ testLength(4, list);
+
+ testLengthInvariantOperations(list);
+
+ testGrowableListOperations(list);
+}
+
+void testGrowableListOperations(List list) {
+ // add, removeLast.
+ list.clear();
+ testLength(0, list);
+ list.add(4);
+ testLength(1, list);
+ Expect.equals(4, list.removeLast());
+ testLength(0, list);
+
+ for (int i = 0; i < 100; i++) {
+ list.add(i);
+ }
+
+ Expect.equals(list.length, 100);
+ for (int i = 0; i < 100; i++) {
+ Expect.equals(i, list[i]);
+ }
+
+ Expect.equals(17, list.indexOf(17));
+ Expect.equals(17, list.lastIndexOf(17));
+ Expect.equals(-1, list.indexOf(999));
+ Expect.equals(-1, list.lastIndexOf(999));
+
+ Expect.equals(99, list.removeLast());
+ testLength(99, list);
+
+ // remove.
+ Expect.isTrue(list.remove(4));
+ testLength(98, list);
+ Expect.isFalse(list.remove(4));
+ testLength(98, list);
+ list.clear();
+ testLength(0, list);
+
+ list.add(4);
+ list.add(4);
+ testLength(2, list);
+ Expect.isTrue(list.remove(4));
+ testLength(1, list);
+ Expect.isTrue(list.remove(4));
+ testLength(0, list);
+ Expect.isFalse(list.remove(4));
+ testLength(0, list);
+
+ // removeWhere, retainWhere
+ for (int i = 0; i < 100; i++) {
+ list.add(i);
+ }
+ testLength(100, list);
+ list.removeWhere((int x) => x.isOdd);
+ testLength(50, list);
+ for (int i = 0; i < list.length; i++) {
+ Expect.isTrue(list[i].isEven);
+ }
+ list.retainWhere((int x) => (x % 3) == 0);
+ testLength(17, list);
+ for (int i = 0; i < list.length; i++) {
+ Expect.isTrue((list[i] % 6) == 0);
+ }
+
+ // insert, remove, removeAt
+ list.clear();
+ testLength(0, list);
+
+ list.insert(0, 0);
+ Expect.listEquals([0], list);
+
+ list.insert(0, 1);
+ Expect.listEquals([1, 0], list);
+
+ list.insert(0, 2);
+ Expect.listEquals([2, 1, 0], list);
+
+ Expect.isTrue(list.remove(1));
+ Expect.listEquals([2, 0], list);
+
+ list.insert(1, 1);
+ Expect.listEquals([2, 1, 0], list);
+
+ list.removeAt(1);
+ Expect.listEquals([2, 0], list);
+
+ list.removeAt(1);
+ Expect.listEquals([2], list);
+
+ // insertAll
+ list.insertAll(0, [1, 2, 3]);
+ Expect.listEquals([1, 2, 3, 2], list);
+
+ list.insertAll(2, []);
+ Expect.listEquals([1, 2, 3, 2], list);
+
+ list.insertAll(4, [7, 9]);
+ Expect.listEquals([1, 2, 3, 2, 7, 9], list);
+
+ // addAll
+ list.addAll(list.reversed.toList());
+ Expect.listEquals([1, 2, 3, 2, 7, 9, 9, 7, 2, 3, 2, 1], list);
+
+ list.addAll([]);
+ Expect.listEquals([1, 2, 3, 2, 7, 9, 9, 7, 2, 3, 2, 1], list);
+
+ // replaceRange
+ list.replaceRange(3, 7, [0, 0]);
+ Expect.listEquals([1, 2, 3, 0, 0, 7, 2, 3, 2, 1], list);
+
+ list.replaceRange(2, 3, [5, 5, 5]);
+ Expect.listEquals([1, 2, 5, 5, 5, 0, 0, 7, 2, 3, 2, 1], list);
+
+ list.replaceRange(2, 4, [6, 6]);
+ Expect.listEquals([1, 2, 6, 6, 5, 0, 0, 7, 2, 3, 2, 1], list);
+
+ list.replaceRange(6, 8, []);
+ Expect.listEquals([1, 2, 6, 6, 5, 0, 2, 3, 2, 1], list);
+
+ // Operations that change the length cause ConcurrentModificationError.
+ void testConcurrentModification(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);
+ }
+
+ testConcurrentModification(() => list.add(5));
+ testConcurrentModification(() => list.addAll([5, 6]));
+ testConcurrentModification(() => list.removeLast());
+ for (int i = 0; i < 4; i++) {
+ testConcurrentModification(() => list.remove(i));
+ testConcurrentModification(() => list.removeAt(i));
+ testConcurrentModification(() => list.removeWhere((x) => x == i));
+ testConcurrentModification(() => list.retainWhere((x) => x != i));
+ testConcurrentModification(() => list.insert(i, 5));
+ testConcurrentModification(() => list.insertAll(i, [5, 6]));
+ testConcurrentModification(() => list.removeRange(i, i + 1));
+ testConcurrentModification(() => list.replaceRange(i, i + 1, [5, 6]));
+ }
+
+ // Any operation that doesn't change the length should be safe for iteration.
+ testSafeConcurrentModification(action()) {
+ list.length = 4;
+ list.setAll(0, [0, 1, 2, 3]);
+ for (var i in list) {
+ action();
+ }
+ list.forEach((e) => action());
+ }
+
+ testSafeConcurrentModification(() {
+ list.add(5);
+ list.removeLast();
+ });
+ testSafeConcurrentModification(() {
+ list.add(list[0]);
+ list.removeAt(0);
+ });
+ testSafeConcurrentModification(() {
+ list.insert(0, list.removeLast());
+ });
+ testSafeConcurrentModification(() {
+ list.replaceRange(1, 3, list.sublist(1, 3).reversed);
+ });
+
+ // Argument errors on bad indices for methods that are only allowed
+ // on growable lists.
+ list.length = 4;
+ list.setAll(0, [0, 1, 2, 3]);
+ testArgumentError(action()) {
+ Expect.throws(action, (e) => e is ArgumentError);
+ }
+
+ // Direct indices (0 <= index < length).
+ testArgumentError(() => list.removeAt(-1));
+ testArgumentError(() => list.removeAt(4));
+ // Direct indices including end (0 <= index <= length).
+ testArgumentError(() => list.insert(-1, 0));
+ testArgumentError(() => list.insert(5, 0));
+ testArgumentError(() => list.insertAll(-1, [0]));
+ testArgumentError(() => list.insertAll(5, [0]));
+ testArgumentError(() => list.insertAll(-1, [0]));
+ testArgumentError(() => list.insertAll(5, [0]));
+ // Ranges (0 <= start <= end <= length).
+ testArgumentError(() => list.removeRange(-1, 2));
+ testArgumentError(() => list.removeRange(2, 5));
+ testArgumentError(() => list.removeRange(-1, 5));
+ testArgumentError(() => list.removeRange(4, 2));
+ testArgumentError(() => list.replaceRange(-1, 2, [9]));
+ testArgumentError(() => list.replaceRange(2, 5, [9]));
+ testArgumentError(() => list.replaceRange(-1, 5, [9]));
+ testArgumentError(() => list.replaceRange(4, 2, [9]));
+}
+
+class Yes {
+ operator ==(var other) => true;
+ int get hashCode => 0;
+}
+
+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; }
+}
+
+class MyFixedList<E> extends ListBase<E> {
+ List<E> _source;
+ MyFixedList(this._source);
+ int get length => _source.length;
+ void set length(int length) { throw new UnsupportedError("Fixed length!"); }
+ E operator[](int index) => _source[index];
+ void operator[]=(int index, E value) { _source[index] = value; }
+}
+
+void testListConstructor() {
+ Expect.throws(() { new List(0).add(4); }); // Is fixed-length.
+ Expect.throws(() { new List(-2); }); // Not negative. /// 01: ok
+ Expect.throws(() { new List(null); }); // Not null.
+ Expect.listEquals([4], new List()..add(4));
+ Expect.throws(() { new List.filled(0, 42).add(4); }); // Is fixed-length.
+ Expect.throws(() { new List.filled(-2, 42); }); // Not negative.
+ Expect.throws(() { new List.filled(null, 42); }); // Not null.
+}
« no previous file with comments | « test/codegen/corelib/list_sublist_test.dart ('k') | test/codegen/corelib/list_to_string2_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698