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

Unified Diff: test/codegen/corelib/map_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/map_remove_test.dart ('k') | test/codegen/corelib/map_to_string_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: test/codegen/corelib/map_test.dart
diff --git a/test/codegen/corelib/map_test.dart b/test/codegen/corelib/map_test.dart
new file mode 100644
index 0000000000000000000000000000000000000000..dff5e618c8dbf4c94dcd0481fba1586f5dec45f9
--- /dev/null
+++ b/test/codegen/corelib/map_test.dart
@@ -0,0 +1,965 @@
+// 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.
+
+library map_test;
+import "package:expect/expect.dart";
+import 'dart:collection';
+import 'dart:convert' show JSON;
+
+Map newJsonMap()
+ => JSON.decode('{}');
+Map newJsonMapCustomReviver()
+ => JSON.decode('{}', reviver: (key, value) => value);
+
+void main() {
+ test(new HashMap());
+ test(new LinkedHashMap());
+ test(new SplayTreeMap());
+ test(new SplayTreeMap(Comparable.compare));
+ test(new MapView(new HashMap()));
+ test(new MapView(new SplayTreeMap()));
+ test(new MapBaseMap());
+ test(new MapMixinMap());
+ test(newJsonMap());
+ test(newJsonMapCustomReviver());
+ testLinkedHashMap();
+ testMapLiteral();
+ testNullValue();
+ testTypes();
+
+ testWeirdStringKeys(new Map());
+ testWeirdStringKeys(new Map<String, String>());
+ testWeirdStringKeys(new HashMap());
+ testWeirdStringKeys(new HashMap<String, String>());
+ testWeirdStringKeys(new LinkedHashMap());
+ testWeirdStringKeys(new LinkedHashMap<String, String>());
+ testWeirdStringKeys(new SplayTreeMap());
+ testWeirdStringKeys(new SplayTreeMap<String, String>());
+ testWeirdStringKeys(new MapBaseMap<String, String>());
+ testWeirdStringKeys(new MapMixinMap<String, String>());
+ testWeirdStringKeys(newJsonMap());
+ testWeirdStringKeys(newJsonMapCustomReviver());
+
+ testNumericKeys(new Map());
+ testNumericKeys(new Map<num, String>());
+ testNumericKeys(new HashMap());
+ testNumericKeys(new HashMap<num, String>());
+ testNumericKeys(new HashMap.identity());
+ testNumericKeys(new HashMap<num, String>.identity());
+ testNumericKeys(new LinkedHashMap());
+ testNumericKeys(new LinkedHashMap<num, String>());
+ testNumericKeys(new LinkedHashMap.identity());
+ testNumericKeys(new LinkedHashMap<num, String>.identity());
+ testNumericKeys(new MapBaseMap<num, String>());
+ testNumericKeys(new MapMixinMap<num, String>());
+ testNumericKeys(newJsonMap());
+ testNumericKeys(newJsonMapCustomReviver());
+
+ testNaNKeys(new Map());
+ testNaNKeys(new Map<num, String>());
+ testNaNKeys(new HashMap());
+ testNaNKeys(new HashMap<num, String>());
+ testNaNKeys(new LinkedHashMap());
+ testNaNKeys(new LinkedHashMap<num, String>());
+ testNaNKeys(new MapBaseMap<num, String>());
+ testNaNKeys(new MapMixinMap<num, String>());
+ testNaNKeys(newJsonMap());
+ testNaNKeys(newJsonMapCustomReviver());
+ // Identity maps fail the NaN-keys tests because the test assumes that
+ // NaN is not equal to NaN.
+
+ testIdentityMap(new Map.identity());
+ testIdentityMap(new HashMap.identity());
+ testIdentityMap(new LinkedHashMap.identity());
+ testIdentityMap(new HashMap(equals: identical,
+ hashCode: identityHashCode));
+ testIdentityMap(new LinkedHashMap(equals: identical,
+ hashCode: identityHashCode));
+ testIdentityMap(new HashMap(equals: (x, y) => identical(x, y),
+ hashCode: (x) => identityHashCode(x)));
+ testIdentityMap(new LinkedHashMap(equals: (x, y) => identical(x, y),
+ hashCode: (x) => identityHashCode(x)));
+
+ testCustomMap(new HashMap(equals: myEquals, hashCode: myHashCode,
+ isValidKey: (v) => v is Customer));
+ testCustomMap(new LinkedHashMap(equals: myEquals, hashCode: myHashCode,
+ isValidKey: (v) => v is Customer));
+ testCustomMap(new HashMap<Customer,dynamic>(equals: myEquals,
+ hashCode: myHashCode));
+
+ testCustomMap(new LinkedHashMap<Customer,dynamic>(equals: myEquals,
+ hashCode: myHashCode));
+
+ testIterationOrder(new LinkedHashMap());
+ testIterationOrder(new LinkedHashMap.identity());
+ testIterationOrder(newJsonMap());
+ testIterationOrder(newJsonMapCustomReviver());
+
+ testOtherKeys(new SplayTreeMap<int, int>());
+ testOtherKeys(new SplayTreeMap<int, int>((int a, int b) => a - b,
+ (v) => v is int));
+ testOtherKeys(new SplayTreeMap((int a, int b) => a - b,
+ (v) => v is int));
+ testOtherKeys(new HashMap<int, int>());
+ testOtherKeys(new HashMap<int, int>.identity());
+ testOtherKeys(new HashMap<int, int>(hashCode: (v) => v.hashCode,
+ isValidKey: (v) => v is int));
+ testOtherKeys(new HashMap(equals: (int x, int y) => x == y,
+ hashCode: (int v) => v.hashCode,
+ isValidKey: (v) => v is int));
+ testOtherKeys(new LinkedHashMap<int, int>());
+ testOtherKeys(new LinkedHashMap<int, int>.identity());
+ testOtherKeys(new LinkedHashMap<int, int>(hashCode: (v) => v.hashCode,
+ isValidKey: (v) => v is int));
+ testOtherKeys(new LinkedHashMap(equals: (int x, int y) => x == y,
+ hashCode: (int v) => v.hashCode,
+ isValidKey: (v) => v is int));
+ testOtherKeys(new MapBaseMap<int, int>());
+ testOtherKeys(new MapMixinMap<int, int>());
+ testOtherKeys(newJsonMap());
+ testOtherKeys(newJsonMapCustomReviver());
+
+ testUnmodifiableMap(const {1 : 37});
+ testUnmodifiableMap(new UnmodifiableMapView({1 : 37}));
+ testUnmodifiableMap(new UnmodifiableMapBaseMap([1, 37]));
+
+ testFrom();
+}
+
+
+void test(Map map) {
+ testDeletedElement(map);
+ testMap(map, 1, 2, 3, 4, 5, 6, 7, 8);
+ map.clear();
+ testMap(map, "value1", "value2", "value3", "value4", "value5",
+ "value6", "value7", "value8");
+}
+
+void testLinkedHashMap() {
+ LinkedHashMap map = new LinkedHashMap();
+ Expect.equals(false, map.containsKey(1));
+ map[1] = 1;
+ map[1] = 2;
+ testLength(1, map);
+}
+
+void testMap(Map map, key1, key2, key3, key4, key5, key6, key7, key8) {
+ int value1 = 10;
+ int value2 = 20;
+ int value3 = 30;
+ int value4 = 40;
+ int value5 = 50;
+ int value6 = 60;
+ int value7 = 70;
+ int value8 = 80;
+
+ testLength(0, map);
+
+ map[key1] = value1;
+ Expect.equals(value1, map[key1]);
+ map[key1] = value2;
+ Expect.equals(false, map.containsKey(key2));
+ testLength(1, map);
+
+ map[key1] = value1;
+ Expect.equals(value1, map[key1]);
+ // Add enough entries to make sure the table grows.
+ map[key2] = value2;
+ Expect.equals(value2, map[key2]);
+ testLength(2, map);
+ map[key3] = value3;
+ Expect.equals(value2, map[key2]);
+ Expect.equals(value3, map[key3]);
+ map[key4] = value4;
+ Expect.equals(value3, map[key3]);
+ Expect.equals(value4, map[key4]);
+ map[key5] = value5;
+ Expect.equals(value4, map[key4]);
+ Expect.equals(value5, map[key5]);
+ map[key6] = value6;
+ Expect.equals(value5, map[key5]);
+ Expect.equals(value6, map[key6]);
+ map[key7] = value7;
+ Expect.equals(value6, map[key6]);
+ Expect.equals(value7, map[key7]);
+ map[key8] = value8;
+ Expect.equals(value1, map[key1]);
+ Expect.equals(value2, map[key2]);
+ Expect.equals(value3, map[key3]);
+ Expect.equals(value4, map[key4]);
+ Expect.equals(value5, map[key5]);
+ Expect.equals(value6, map[key6]);
+ Expect.equals(value7, map[key7]);
+ Expect.equals(value8, map[key8]);
+ testLength(8, map);
+
+ map.remove(key4);
+ Expect.equals(false, map.containsKey(key4));
+ testLength(7, map);
+
+ // Test clearing the table.
+ map.clear();
+ testLength(0, map);
+ Expect.equals(false, map.containsKey(key1));
+ Expect.equals(false, map.containsKey(key2));
+ Expect.equals(false, map.containsKey(key3));
+ Expect.equals(false, map.containsKey(key4));
+ Expect.equals(false, map.containsKey(key5));
+ Expect.equals(false, map.containsKey(key6));
+ Expect.equals(false, map.containsKey(key7));
+ Expect.equals(false, map.containsKey(key8));
+
+ // Test adding and removing again.
+ map[key1] = value1;
+ Expect.equals(value1, map[key1]);
+ testLength(1, map);
+ map[key2] = value2;
+ Expect.equals(value2, map[key2]);
+ testLength(2, map);
+ map[key3] = value3;
+ Expect.equals(value3, map[key3]);
+ map.remove(key3);
+ testLength(2, map);
+ map[key4] = value4;
+ Expect.equals(value4, map[key4]);
+ map.remove(key4);
+ testLength(2, map);
+ map[key5] = value5;
+ Expect.equals(value5, map[key5]);
+ map.remove(key5);
+ testLength(2, map);
+ map[key6] = value6;
+ Expect.equals(value6, map[key6]);
+ map.remove(key6);
+ testLength(2, map);
+ map[key7] = value7;
+ Expect.equals(value7, map[key7]);
+ map.remove(key7);
+ testLength(2, map);
+ map[key8] = value8;
+ Expect.equals(value8, map[key8]);
+ map.remove(key8);
+ testLength(2, map);
+
+ Expect.equals(true, map.containsKey(key1));
+ Expect.equals(true, map.containsValue(value1));
+
+ // Test Map.forEach.
+ Map otherMap = new Map();
+ void testForEachMap(key, value) {
+ otherMap[key] = value;
+ }
+ map.forEach(testForEachMap);
+ Expect.equals(true, otherMap.containsKey(key1));
+ Expect.equals(true, otherMap.containsKey(key2));
+ Expect.equals(true, otherMap.containsValue(value1));
+ Expect.equals(true, otherMap.containsValue(value2));
+ Expect.equals(2, otherMap.length);
+
+ otherMap.clear();
+ Expect.equals(0, otherMap.length);
+
+ // Test Collection.keys.
+ void testForEachCollection(value) {
+ otherMap[value] = value;
+ }
+ Iterable keys = map.keys;
+ keys.forEach(testForEachCollection);
+ Expect.equals(true, otherMap.containsKey(key1));
+ Expect.equals(true, otherMap.containsKey(key2));
+ Expect.equals(true, otherMap.containsValue(key1));
+ Expect.equals(true, otherMap.containsValue(key2));
+ Expect.equals(true, !otherMap.containsKey(value1));
+ Expect.equals(true, !otherMap.containsKey(value2));
+ Expect.equals(true, !otherMap.containsValue(value1));
+ Expect.equals(true, !otherMap.containsValue(value2));
+ Expect.equals(2, otherMap.length);
+ otherMap.clear();
+ Expect.equals(0, otherMap.length);
+
+ // Test Collection.values.
+ Iterable values = map.values;
+ values.forEach(testForEachCollection);
+ Expect.equals(true, !otherMap.containsKey(key1));
+ Expect.equals(true, !otherMap.containsKey(key2));
+ Expect.equals(true, !otherMap.containsValue(key1));
+ Expect.equals(true, !otherMap.containsValue(key2));
+ Expect.equals(true, otherMap.containsKey(value1));
+ Expect.equals(true, otherMap.containsKey(value2));
+ Expect.equals(true, otherMap.containsValue(value1));
+ Expect.equals(true, otherMap.containsValue(value2));
+ Expect.equals(2, otherMap.length);
+ otherMap.clear();
+ Expect.equals(0, otherMap.length);
+
+ // Test Map.putIfAbsent.
+ map.clear();
+ Expect.equals(false, map.containsKey(key1));
+ map.putIfAbsent(key1, () => 10);
+ Expect.equals(true, map.containsKey(key1));
+ Expect.equals(10, map[key1]);
+ Expect.equals(10,
+ map.putIfAbsent(key1, () => 11));
+
+ // Test Map.addAll.
+ map.clear();
+ otherMap.clear();
+ otherMap[99] = 1;
+ otherMap[50] = 50;
+ otherMap[1] = 99;
+ map.addAll(otherMap);
+ Expect.equals(3, map.length);
+ Expect.equals(1, map[99]);
+ Expect.equals(50, map[50]);
+ Expect.equals(99, map[1]);
+ otherMap[50] = 42;
+ map.addAll(new HashMap.from(otherMap));
+ Expect.equals(3, map.length);
+ Expect.equals(1, map[99]);
+ Expect.equals(42, map[50]);
+ Expect.equals(99, map[1]);
+ otherMap[99] = 7;
+ map.addAll(new SplayTreeMap.from(otherMap));
+ Expect.equals(3, map.length);
+ Expect.equals(7, map[99]);
+ Expect.equals(42, map[50]);
+ Expect.equals(99, map[1]);
+ otherMap.remove(99);
+ map[99] = 0;
+ map.addAll(otherMap);
+ Expect.equals(3, map.length);
+ Expect.equals(0, map[99]);
+ Expect.equals(42, map[50]);
+ Expect.equals(99, map[1]);
+ map.clear();
+ otherMap.clear();
+ map.addAll(otherMap);
+ Expect.equals(0, map.length);
+}
+
+void testDeletedElement(Map map) {
+ map.clear();
+ for (int i = 0; i < 100; i++) {
+ map[1] = 2;
+ testLength(1, map);
+ map.remove(1);
+ testLength(0, map);
+ }
+ testLength(0, map);
+}
+
+void testMapLiteral() {
+ Map m = {"a": 1, "b" : 2, "c": 3 };
+ Expect.equals(3, m.length);
+ int sum = 0;
+ m.forEach((a, b) {
+ sum += b;
+ });
+ Expect.equals(6, sum);
+
+ List values = m.keys.toList();
+ Expect.equals(3, values.length);
+ String first = values[0];
+ String second = values[1];
+ String third = values[2];
+ String all = "${first}${second}${third}";
+ Expect.equals(3, all.length);
+ Expect.equals(true, all.contains("a", 0));
+ Expect.equals(true, all.contains("b", 0));
+ Expect.equals(true, all.contains("c", 0));
+}
+
+void testNullValue() {
+ Map m = {"a": 1, "b" : null, "c": 3 };
+
+ Expect.equals(null, m["b"]);
+ Expect.equals(true, m.containsKey("b"));
+ Expect.equals(3, m.length);
+
+ m["a"] = null;
+ m["c"] = null;
+ Expect.equals(null, m["a"]);
+ Expect.equals(true, m.containsKey("a"));
+ Expect.equals(null, m["c"]);
+ Expect.equals(true, m.containsKey("c"));
+ Expect.equals(3, m.length);
+
+ m.remove("a");
+ Expect.equals(2, m.length);
+ Expect.equals(null, m["a"]);
+ Expect.equals(false, m.containsKey("a"));
+}
+
+void testTypes() {
+ testMap(Map<num, String> map) {
+ Expect.isTrue(map is Map<num, String>);
+ Expect.isTrue(map is! Map<String, dynamic>);
+ Expect.isTrue(map is! Map<dynamic, int>);
+
+ // Use with properly typed keys and values.
+ map[42] = "text1";
+ map[43] = "text2";
+ map[42] = "text3";
+ Expect.equals("text3", map.remove(42));
+ Expect.equals(null, map[42]);
+ map[42] = "text4";
+
+ // Ensure that "containsKey", "containsValue" and "remove"
+ // accepts any object.
+ for (var object in [true, null, new Object()]) {
+ Expect.isFalse(map.containsKey(object));
+ Expect.isFalse(map.containsValue(object));
+ Expect.isNull(map.remove(object));
+ Expect.isNull(map[object]);
+ }
+ }
+ testMap(new HashMap<int, String>());
+ testMap(new LinkedHashMap<int, String>());
+ testMap(new SplayTreeMap<int, String>());
+ testMap(new SplayTreeMap<int, String>(Comparable.compare));
+ testMap(new SplayTreeMap<int, String>((int a, int b) => a.compareTo(b)));
+ testMap(new HashMap<num, String>());
+ testMap(new LinkedHashMap<num, String>());
+ testMap(new SplayTreeMap<num, String>());
+ testMap(new SplayTreeMap<num, String>(Comparable.compare));
+ testMap(new SplayTreeMap<num, String>((num a, num b) => a.compareTo(b)));
+}
+
+void testWeirdStringKeys(Map map) {
+ // Test weird keys.
+ var weirdKeys = const [
+ 'hasOwnProperty',
+ 'constructor',
+ 'toLocaleString',
+ 'propertyIsEnumerable',
+ '__defineGetter__',
+ '__defineSetter__',
+ '__lookupGetter__',
+ '__lookupSetter__',
+ 'isPrototypeOf',
+ 'toString',
+ 'valueOf',
+ '__proto__',
+ '__count__',
+ '__parent__',
+ ''];
+ Expect.isTrue(map.isEmpty);
+ for (var key in weirdKeys) {
+ Expect.isFalse(map.containsKey(key));
+ Expect.equals(null, map[key]);
+ var value = 'value:$key';
+ map[key] = value;
+ Expect.isTrue(map.containsKey(key));
+ Expect.equals(value, map[key]);
+ Expect.equals(value, map.remove(key));
+ Expect.isFalse(map.containsKey(key));
+ Expect.equals(null, map[key]);
+ }
+ Expect.isTrue(map.isEmpty);
+
+}
+
+void testNumericKeys(Map map) {
+ var numericKeys = const [
+ double.INFINITY,
+ double.NEGATIVE_INFINITY,
+ 0,
+ 0.0,
+ -0.0 ];
+
+ Expect.isTrue(map.isEmpty);
+ for (var key in numericKeys) {
+ Expect.isFalse(map.containsKey(key));
+ Expect.equals(null, map[key]);
+ var value = 'value:$key';
+ map[key] = value;
+ Expect.isTrue(map.containsKey(key));
+ Expect.equals(value, map[key]);
+ Expect.equals(value, map.remove(key));
+ Expect.isFalse(map.containsKey(key));
+ Expect.equals(null, map[key]);
+ }
+ Expect.isTrue(map.isEmpty);
+}
+
+void testNaNKeys(Map map) {
+ Expect.isTrue(map.isEmpty);
+ // Test NaN.
+ var nan = double.NAN;
+ Expect.isFalse(map.containsKey(nan));
+ Expect.equals(null, map[nan]);
+
+ map[nan] = 'value:0';
+ Expect.isFalse(map.containsKey(nan));
+ Expect.equals(null, map[nan]);
+ testLength(1, map);
+
+ map[nan] = 'value:1';
+ Expect.isFalse(map.containsKey(nan));
+ Expect.equals(null, map[nan]);
+ testLength(2, map);
+
+ Expect.equals(null, map.remove(nan));
+ testLength(2, map);
+
+ var count = 0;
+ map.forEach((key, value) {
+ if (key.isNaN) count++;
+ });
+ Expect.equals(2, count);
+
+ map.clear();
+ Expect.isTrue(map.isEmpty);
+}
+
+void testLength(int length, Map map) {
+ Expect.equals(length, map.length);
+ Expect.equals(length, map.keys.length);
+ Expect.equals(length, map.values.length);
+ // Check being-empty.
+ var ifEmpty = (length == 0) ? Expect.isTrue : Expect.isFalse;
+ var ifNotEmpty = (length != 0) ? Expect.isTrue : Expect.isFalse;
+ ifEmpty(map.isEmpty);
+ ifNotEmpty(map.isNotEmpty);
+ ifEmpty(map.keys.isEmpty);
+ ifNotEmpty(map.keys.isNotEmpty);
+ ifEmpty(map.values.isEmpty);
+ ifNotEmpty(map.values.isNotEmpty);
+ // Test key/value iterators match their isEmpty/isNotEmpty.
+ ifNotEmpty(map.keys.iterator.moveNext());
+ ifNotEmpty(map.values.iterator.moveNext());
+ if (length == 0) {
+ for (var k in map.keys) Expect.fail("contains key when iterating: $k");
+ for (var v in map.values) Expect.fail("contains values when iterating: $v");
+ }
+}
+
+
+testIdentityMap(Map map) {
+ Expect.isTrue(map.isEmpty);
+
+ var nan = double.NAN;
+ // TODO(11551): Remove guard when dart2js makes identical(NaN, NaN) true.
+ if (identical(nan, nan)) {
+ map[nan] = 42;
+ testLength(1, map);
+ Expect.isTrue(map.containsKey(nan));
+ Expect.equals(42, map[nan]);
+ map[nan] = 37;
+ testLength(1, map);
+ Expect.equals(37, map[nan]);
+ Expect.equals(37, map.remove(nan));
+ testLength(0, map);
+ }
+
+ Vampire v1 = const Vampire(1);
+ Vampire v2 = const Vampire(2);
+ Expect.isFalse(v1 == v1);
+ Expect.isFalse(v2 == v2);
+ Expect.isTrue(v2 == v1); // Snob!
+
+ map[v1] = 1;
+ map[v2] = 2;
+ testLength(2, map);
+
+ Expect.isTrue(map.containsKey(v1));
+ Expect.isTrue(map.containsKey(v2));
+
+ Expect.equals(1, map[v1]);
+ Expect.equals(2, map[v2]);
+
+ Expect.equals(1, map.remove(v1));
+ testLength(1, map);
+ Expect.isFalse(map.containsKey(v1));
+ Expect.isTrue(map.containsKey(v2));
+
+ Expect.isNull(map.remove(v1));
+ Expect.equals(2, map.remove(v2));
+ testLength(0, map);
+
+ var eq01 = new Equalizer(0);
+ var eq02 = new Equalizer(0);
+ var eq11 = new Equalizer(1);
+ var eq12 = new Equalizer(1);
+ // Sanity.
+ Expect.equals(eq01, eq02);
+ Expect.equals(eq02, eq01);
+ Expect.equals(eq11, eq12);
+ Expect.equals(eq12, eq11);
+ Expect.notEquals(eq01, eq11);
+ Expect.notEquals(eq01, eq12);
+ Expect.notEquals(eq02, eq11);
+ Expect.notEquals(eq02, eq12);
+ Expect.notEquals(eq11, eq01);
+ Expect.notEquals(eq11, eq02);
+ Expect.notEquals(eq12, eq01);
+ Expect.notEquals(eq12, eq02);
+
+ map[eq01] = 0;
+ map[eq02] = 1;
+ map[eq11] = 2;
+ map[eq12] = 3;
+ testLength(4, map);
+
+ Expect.equals(0, map[eq01]);
+ Expect.equals(1, map[eq02]);
+ Expect.equals(2, map[eq11]);
+ Expect.equals(3, map[eq12]);
+
+ Expect.isTrue(map.containsKey(eq01));
+ Expect.isTrue(map.containsKey(eq02));
+ Expect.isTrue(map.containsKey(eq11));
+ Expect.isTrue(map.containsKey(eq12));
+
+ Expect.equals(1, map.remove(eq02));
+ Expect.equals(3, map.remove(eq12));
+ testLength(2, map);
+ Expect.isTrue(map.containsKey(eq01));
+ Expect.isFalse(map.containsKey(eq02));
+ Expect.isTrue(map.containsKey(eq11));
+ Expect.isFalse(map.containsKey(eq12));
+
+ Expect.equals(0, map[eq01]);
+ Expect.equals(null, map[eq02]);
+ Expect.equals(2, map[eq11]);
+ Expect.equals(null, map[eq12]);
+
+ Expect.equals(0, map.remove(eq01));
+ Expect.equals(2, map.remove(eq11));
+ testLength(0, map);
+
+ map[eq01] = 0;
+ map[eq02] = 1;
+ map[eq11] = 2;
+ map[eq12] = 3;
+ testLength(4, map);
+
+ // Transfer to equality-based map will collapse elements.
+ Map eqMap = new HashMap();
+ eqMap.addAll(map);
+ testLength(2, eqMap);
+ Expect.isTrue(eqMap.containsKey(eq01));
+ Expect.isTrue(eqMap.containsKey(eq02));
+ Expect.isTrue(eqMap.containsKey(eq11));
+ Expect.isTrue(eqMap.containsKey(eq12));
+
+ // Changing objects will not affect identity map.
+ map.clear();
+ var m1 = new Mutable(1);
+ var m2 = new Mutable(2);
+ var m3 = new Mutable(3);
+ map[m1] = 1;
+ map[m2] = 2;
+ map[m3] = 3;
+ Expect.equals(3, map.length);
+ Expect.isTrue(map.containsKey(m1));
+ Expect.isTrue(map.containsKey(m2));
+ Expect.isTrue(map.containsKey(m3));
+ Expect.notEquals(m1, m3);
+ m3.id = 1;
+ Expect.equals(m1, m3);
+ // Even if keys are equal, they are still not identical.
+ // Even if hashcode of m3 changed, it can still be found.
+ Expect.equals(1, map[m1]);
+ Expect.equals(3, map[m3]);
+}
+
+/** Class of objects that are equal if they hold the same id. */
+class Equalizer {
+ int id;
+ Equalizer(this.id);
+ int get hashCode => id;
+ bool operator==(Object other) =>
+ other is Equalizer && id == (other as Equalizer).id;
+}
+
+/**
+ * Objects that are not reflexive.
+ *
+ * They think they are better than their equals.
+ */
+class Vampire {
+ final int generation;
+ const Vampire(this.generation);
+
+ int get hashCode => generation;
+
+ // The double-fang operator falsely claims that a vampire is equal to
+ // any of its sire's generation.
+ bool operator==(Object other) =>
+ other is Vampire && generation - 1 == (other as Vampire).generation;
+}
+
+void testCustomMap(Map map) {
+ testLength(0, map);
+ var c11 = const Customer(1, 1);
+ var c12 = const Customer(1, 2);
+ var c21 = const Customer(2, 1);
+ var c22 = const Customer(2, 2);
+ // Sanity.
+ Expect.equals(c11, c12);
+ Expect.notEquals(c11, c21);
+ Expect.notEquals(c11, c22);
+ Expect.equals(c21, c22);
+ Expect.notEquals(c21, c11);
+ Expect.notEquals(c21, c12);
+
+ Expect.isTrue(myEquals(c11, c21));
+ Expect.isFalse(myEquals(c11, c12));
+ Expect.isFalse(myEquals(c11, c22));
+ Expect.isTrue(myEquals(c12, c22));
+ Expect.isFalse(myEquals(c12, c11));
+ Expect.isFalse(myEquals(c12, c21));
+
+ map[c11] = 42;
+ testLength(1, map);
+ Expect.isTrue(map.containsKey(c11));
+ Expect.isTrue(map.containsKey(c21));
+ Expect.isFalse(map.containsKey(c12));
+ Expect.isFalse(map.containsKey(c22));
+ Expect.equals(42, map[c11]);
+ Expect.equals(42, map[c21]);
+
+ map[c21] = 37;
+ testLength(1, map);
+ Expect.isTrue(map.containsKey(c11));
+ Expect.isTrue(map.containsKey(c21));
+ Expect.isFalse(map.containsKey(c12));
+ Expect.isFalse(map.containsKey(c22));
+ Expect.equals(37, map[c11]);
+ Expect.equals(37, map[c21]);
+
+ map[c22] = 42;
+ testLength(2, map);
+ Expect.isTrue(map.containsKey(c11));
+ Expect.isTrue(map.containsKey(c21));
+ Expect.isTrue(map.containsKey(c12));
+ Expect.isTrue(map.containsKey(c22));
+ Expect.equals(37, map[c11]);
+ Expect.equals(37, map[c21]);
+ Expect.equals(42, map[c12]);
+ Expect.equals(42, map[c22]);
+
+ Expect.equals(42, map.remove(c12));
+ testLength(1, map);
+ Expect.isTrue(map.containsKey(c11));
+ Expect.isTrue(map.containsKey(c21));
+ Expect.isFalse(map.containsKey(c12));
+ Expect.isFalse(map.containsKey(c22));
+ Expect.equals(37, map[c11]);
+ Expect.equals(37, map[c21]);
+
+ Expect.equals(37, map.remove(c11));
+ testLength(0, map);
+}
+
+void testUnmodifiableMap(Map map) {
+ Expect.isTrue(map.containsKey(1));
+ testLength(1, map);
+ Expect.equals(1, map.keys.first);
+ Expect.equals(37, map.values.first);
+
+ Expect.throws(map.clear);
+ Expect.throws(() { map.remove(1); });
+ Expect.throws(() { map[2] = 42; });
+ Expect.throws(() { map.addAll({2 : 42}); });
+}
+
+class Customer {
+ final int id;
+ final int secondId;
+ const Customer(this.id, this.secondId);
+ int get hashCode => id;
+ bool operator==(Object other) {
+ if (other is! Customer) return false;
+ Customer otherCustomer = other;
+ return id == otherCustomer.id;
+ }
+}
+
+int myHashCode(Customer c) => c.secondId;
+bool myEquals(Customer a, Customer b) => a.secondId == b.secondId;
+
+void testIterationOrder(Map map) {
+ var order = [0, 6, 4, 2, 7, 9, 7, 1, 2, 5, 3];
+ for (int i = 0; i < order.length; i++) map[order[i]] = i;
+ Expect.listEquals(map.keys.toList(), [0, 6, 4, 2, 7, 9, 1, 5, 3]);
+ Expect.listEquals(map.values.toList(), [0, 1, 2, 8, 6, 5, 7, 9, 10]);
+}
+
+void testOtherKeys(Map<int, int> map) {
+ // Test that non-int keys are allowed in containsKey/remove/lookup.
+ // Custom hash sets and tree sets must be constructed so they don't
+ // use the equality/comparator on incompatible objects.
+
+ // This should not throw in either checked or unchecked mode.
+ map[0] = 0;
+ map[1] = 1;
+ map[2] = 2;
+ Expect.isFalse(map.containsKey("not an int"));
+ Expect.isFalse(map.containsKey(1.5));
+ Expect.isNull(map.remove("not an int"));
+ Expect.isNull(map.remove(1.5));
+ Expect.isNull(map["not an int"]);
+ Expect.isNull(map[1.5]);
+}
+
+class Mutable {
+ int id;
+ Mutable(this.id);
+ int get hashCode => id;
+ bool operator==(other) => other is Mutable && other.id == id;
+}
+
+
+// Slow implementation of Map based on MapBase.
+abstract class MapBaseOperations<K, V> {
+ final List _keys = <K>[];
+ final List _values = <V>[];
+ int _modCount = 0;
+
+ V operator[](Object key) {
+ int index = _keys.indexOf(key);
+ if (index < 0) return null;
+ return _values[index];
+ }
+
+ Iterable<K> get keys => new TestKeyIterable<K>(this);
+
+ void operator[]=(K key, V value) {
+ int index = _keys.indexOf(key);
+ if (index >= 0) {
+ _values[index] = value;
+ } else {
+ _modCount++;
+ _keys.add(key);
+ _values.add(value);
+ }
+ }
+
+ V remove(Object key) {
+ int index = _keys.indexOf(key);
+ if (index >= 0) {
+ var result = _values[index];
+ key = _keys.removeLast();
+ var value = _values.removeLast();
+ if (index != _keys.length) {
+ _keys[index] = key;
+ _values[index] = value;
+ }
+ _modCount++;
+ return result;
+ }
+ return null;
+ }
+
+ void clear() {
+ // Clear cannot be based on remove, since remove won't remove keys that
+ // are not equal to themselves. It will fail the testNaNKeys test.
+ _keys.clear();
+ _values.clear();
+ _modCount++;
+ }
+}
+
+class MapBaseMap<K, V> = MapBase<K, V> with MapBaseOperations<K, V>;
+class MapMixinMap<K, V> = MapBaseOperations<K, V> with MapMixin<K, V>;
+
+class TestKeyIterable<K> extends IterableBase<K> {
+ final _map;
+ TestKeyIterable(this._map);
+ int get length => _map._keys.length;
+ Iterator<K> get iterator => new TestKeyIterator<K>(_map);
+}
+
+class TestKeyIterator<K> implements Iterator<K> {
+ final _map;
+ final int _modCount;
+ int _index = 0;
+ var _current;
+ TestKeyIterator(map) : _map = map, _modCount = map._modCount;
+ bool moveNext() {
+ if (_modCount != _map._modCount) {
+ throw new ConcurrentModificationError(_map);
+ }
+ if (_index == _map._keys.length) {
+ _current = null;
+ return false;
+ }
+ _current = _map._keys[_index++];
+ return true;
+ }
+ K get current => _current;
+}
+
+// Slow implementation of Map based on MapBase.
+class UnmodifiableMapBaseMap<K, V> extends UnmodifiableMapBase<K, V> {
+ final List _keys = <K>[];
+ final List _values = <V>[];
+ UnmodifiableMapBaseMap(List pairs) {
+ for (int i = 0; i < pairs.length; i += 2) {
+ _keys.add(pairs[i]);
+ _values.add(pairs[i + 1]);
+ }
+ }
+
+ int get _modCount => 0;
+
+ V operator[](K key) {
+ int index = _keys.indexOf(key);
+ if (index < 0) return null;
+ return _values[index];
+ }
+
+ Iterable<K> get keys => _keys.skip(0);
+}
+
+abstract class Super implements Comparable {}
+abstract class Interface implements Comparable {}
+class Sub extends Super implements Interface, Comparable {
+ int compareTo(Sub other) => 0;
+ int get hashCode => 0;
+ bool operator==(other) => other is Sub;
+}
+
+expectMap(Map expect, Map actual) {
+ Expect.equals(expect.length, actual.length, "length");
+ for (var key in expect.keys) {
+ Expect.isTrue(actual.containsKey(key), "containsKey $key");
+ Expect.equals(expect[key], actual[key]);
+ }
+}
+
+void testFrom() {
+ // Check contents.
+ for (var map in [{}, {1: 1}, {1: 2, 3: 4, 5: 6, 7: 8}]) {
+ expectMap(map, new Map.from(map));
+ expectMap(map, new HashMap.from(map));
+ expectMap(map, new LinkedHashMap.from(map));
+ expectMap(map, new SplayTreeMap.from(map));
+ }
+ // Test type combinations allowed.
+ Map<int,int> intMap = <int, int>{1: 2, 3: 4};
+ Map<num,num> numMap = <num, num>{1: 2, 3: 4};
+ expectMap(intMap, new Map<int, int>.from(numMap));
+ expectMap(intMap, new Map<num, num>.from(intMap));
+ expectMap(intMap, new HashMap<int, int>.from(numMap));
+ expectMap(intMap, new HashMap<num, num>.from(intMap));
+ expectMap(intMap, new LinkedHashMap<int, int>.from(numMap));
+ expectMap(intMap, new LinkedHashMap<num, num>.from(intMap));
+ expectMap(intMap, new SplayTreeMap<int, int>.from(numMap));
+ expectMap(intMap, new SplayTreeMap<num, num>.from(intMap));
+
+ var sub = new Sub();
+ Map<Super, Super> superMap = <Super, Super>{sub: sub};
+ Map<Interface, Interface> interfaceMap = <Interface, Interface>{sub: sub};
+ expectMap(superMap, new Map<Super, Super>.from(interfaceMap));
+ expectMap(superMap, new Map<Interface, Interface>.from(superMap));
+ expectMap(superMap, new HashMap<Super, Super>.from(interfaceMap));
+ expectMap(superMap, new HashMap<Interface, Interface>.from(superMap));
+ expectMap(superMap, new LinkedHashMap<Super, Super>.from(interfaceMap));
+ expectMap(superMap, new LinkedHashMap<Interface, Interface>.from(superMap));
+ expectMap(superMap, new SplayTreeMap<Super, Super>.from(interfaceMap));
+ expectMap(superMap, new SplayTreeMap<Interface, Interface>.from(superMap));
+}
« no previous file with comments | « test/codegen/corelib/map_remove_test.dart ('k') | test/codegen/corelib/map_to_string_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698