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 library map_test; | 5 library map_test; |
| 6 |
6 import "package:expect/expect.dart"; | 7 import "package:expect/expect.dart"; |
7 import 'dart:collection'; | 8 import 'dart:collection'; |
8 import 'dart:convert' show JSON; | 9 import 'dart:convert' show JSON; |
9 | 10 |
10 Map newJsonMap() | 11 Map newJsonMap() => JSON.decode('{}'); |
11 => JSON.decode('{}'); | 12 Map newJsonMapCustomReviver() => |
12 Map newJsonMapCustomReviver() | 13 JSON.decode('{}', reviver: (key, value) => value); |
13 => JSON.decode('{}', reviver: (key, value) => value); | |
14 | 14 |
15 void main() { | 15 void main() { |
16 test(new HashMap()); | 16 test(new HashMap()); |
17 test(new LinkedHashMap()); | 17 test(new LinkedHashMap()); |
18 test(new SplayTreeMap()); | 18 test(new SplayTreeMap()); |
19 test(new SplayTreeMap(Comparable.compare)); | 19 test(new SplayTreeMap(Comparable.compare)); |
20 test(new MapView(new HashMap())); | 20 test(new MapView(new HashMap())); |
21 test(new MapView(new SplayTreeMap())); | 21 test(new MapView(new SplayTreeMap())); |
22 test(new MapBaseMap()); | 22 test(new MapBaseMap()); |
23 test(new MapMixinMap()); | 23 test(new MapMixinMap()); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 testNaNKeys(new MapBaseMap<num, String>()); | 65 testNaNKeys(new MapBaseMap<num, String>()); |
66 testNaNKeys(new MapMixinMap<num, String>()); | 66 testNaNKeys(new MapMixinMap<num, String>()); |
67 testNaNKeys(newJsonMap()); | 67 testNaNKeys(newJsonMap()); |
68 testNaNKeys(newJsonMapCustomReviver()); | 68 testNaNKeys(newJsonMapCustomReviver()); |
69 // Identity maps fail the NaN-keys tests because the test assumes that | 69 // Identity maps fail the NaN-keys tests because the test assumes that |
70 // NaN is not equal to NaN. | 70 // NaN is not equal to NaN. |
71 | 71 |
72 testIdentityMap(new Map.identity()); | 72 testIdentityMap(new Map.identity()); |
73 testIdentityMap(new HashMap.identity()); | 73 testIdentityMap(new HashMap.identity()); |
74 testIdentityMap(new LinkedHashMap.identity()); | 74 testIdentityMap(new LinkedHashMap.identity()); |
75 testIdentityMap(new HashMap(equals: identical, | 75 testIdentityMap(new HashMap(equals: identical, hashCode: identityHashCode)); |
76 hashCode: identityHashCode)); | 76 testIdentityMap( |
77 testIdentityMap(new LinkedHashMap(equals: identical, | 77 new LinkedHashMap(equals: identical, hashCode: identityHashCode)); |
78 hashCode: identityHashCode)); | 78 testIdentityMap(new HashMap( |
79 testIdentityMap(new HashMap(equals: (x, y) => identical(x, y), | 79 equals: (x, y) => identical(x, y), hashCode: (x) => identityHashCode(x))); |
80 hashCode: (x) => identityHashCode(x))); | 80 testIdentityMap(new LinkedHashMap( |
81 testIdentityMap(new LinkedHashMap(equals: (x, y) => identical(x, y), | 81 equals: (x, y) => identical(x, y), hashCode: (x) => identityHashCode(x))); |
82 hashCode: (x) => identityHashCode(x))); | |
83 | 82 |
84 testCustomMap(new HashMap(equals: myEquals, hashCode: myHashCode, | 83 testCustomMap(new HashMap( |
85 isValidKey: (v) => v is Customer)); | 84 equals: myEquals, |
86 testCustomMap(new LinkedHashMap(equals: myEquals, hashCode: myHashCode, | 85 hashCode: myHashCode, |
87 isValidKey: (v) => v is Customer)); | 86 isValidKey: (v) => v is Customer)); |
88 testCustomMap(new HashMap<Customer,dynamic>(equals: myEquals, | 87 testCustomMap(new LinkedHashMap( |
89 hashCode: myHashCode)); | 88 equals: myEquals, |
| 89 hashCode: myHashCode, |
| 90 isValidKey: (v) => v is Customer)); |
| 91 testCustomMap( |
| 92 new HashMap<Customer, dynamic>(equals: myEquals, hashCode: myHashCode)); |
90 | 93 |
91 testCustomMap(new LinkedHashMap<Customer,dynamic>(equals: myEquals, | 94 testCustomMap(new LinkedHashMap<Customer, dynamic>( |
92 hashCode: myHashCode)); | 95 equals: myEquals, hashCode: myHashCode)); |
93 | 96 |
94 testIterationOrder(new LinkedHashMap()); | 97 testIterationOrder(new LinkedHashMap()); |
95 testIterationOrder(new LinkedHashMap.identity()); | 98 testIterationOrder(new LinkedHashMap.identity()); |
96 testIterationOrder(newJsonMap()); | 99 testIterationOrder(newJsonMap()); |
97 testIterationOrder(newJsonMapCustomReviver()); | 100 testIterationOrder(newJsonMapCustomReviver()); |
98 | 101 |
99 testOtherKeys(new SplayTreeMap<int, int>()); | 102 testOtherKeys(new SplayTreeMap<int, int>()); |
100 testOtherKeys(new SplayTreeMap<int, int>((int a, int b) => a - b, | 103 testOtherKeys( |
101 (v) => v is int)); | 104 new SplayTreeMap<int, int>((int a, int b) => a - b, (v) => v is int)); |
102 testOtherKeys(new SplayTreeMap((int a, int b) => a - b, | 105 testOtherKeys(new SplayTreeMap((int a, int b) => a - b, (v) => v is int)); |
103 (v) => v is int)); | |
104 testOtherKeys(new HashMap<int, int>()); | 106 testOtherKeys(new HashMap<int, int>()); |
105 testOtherKeys(new HashMap<int, int>.identity()); | 107 testOtherKeys(new HashMap<int, int>.identity()); |
106 testOtherKeys(new HashMap<int, int>(hashCode: (v) => v.hashCode, | 108 testOtherKeys(new HashMap<int, int>( |
107 isValidKey: (v) => v is int)); | 109 hashCode: (v) => v.hashCode, isValidKey: (v) => v is int)); |
108 testOtherKeys(new HashMap(equals: (int x, int y) => x == y, | 110 testOtherKeys(new HashMap( |
109 hashCode: (int v) => v.hashCode, | 111 equals: (int x, int y) => x == y, |
110 isValidKey: (v) => v is int)); | 112 hashCode: (int v) => v.hashCode, |
| 113 isValidKey: (v) => v is int)); |
111 testOtherKeys(new LinkedHashMap<int, int>()); | 114 testOtherKeys(new LinkedHashMap<int, int>()); |
112 testOtherKeys(new LinkedHashMap<int, int>.identity()); | 115 testOtherKeys(new LinkedHashMap<int, int>.identity()); |
113 testOtherKeys(new LinkedHashMap<int, int>(hashCode: (v) => v.hashCode, | 116 testOtherKeys(new LinkedHashMap<int, int>( |
114 isValidKey: (v) => v is int)); | 117 hashCode: (v) => v.hashCode, isValidKey: (v) => v is int)); |
115 testOtherKeys(new LinkedHashMap(equals: (int x, int y) => x == y, | 118 testOtherKeys(new LinkedHashMap( |
116 hashCode: (int v) => v.hashCode, | 119 equals: (int x, int y) => x == y, |
117 isValidKey: (v) => v is int)); | 120 hashCode: (int v) => v.hashCode, |
| 121 isValidKey: (v) => v is int)); |
118 testOtherKeys(new MapBaseMap<int, int>()); | 122 testOtherKeys(new MapBaseMap<int, int>()); |
119 testOtherKeys(new MapMixinMap<int, int>()); | 123 testOtherKeys(new MapMixinMap<int, int>()); |
120 testOtherKeys(newJsonMap()); | 124 testOtherKeys(newJsonMap()); |
121 testOtherKeys(newJsonMapCustomReviver()); | 125 testOtherKeys(newJsonMapCustomReviver()); |
122 | 126 |
123 testUnmodifiableMap(const {1 : 37}); | 127 testUnmodifiableMap(const {1: 37}); |
124 testUnmodifiableMap(new UnmodifiableMapView({1 : 37})); | 128 testUnmodifiableMap(new UnmodifiableMapView({1: 37})); |
125 testUnmodifiableMap(new UnmodifiableMapBaseMap([1, 37])); | 129 testUnmodifiableMap(new UnmodifiableMapBaseMap([1, 37])); |
126 | 130 |
127 testFrom(); | 131 testFrom(); |
128 } | 132 } |
129 | 133 |
130 | |
131 void test(Map map) { | 134 void test(Map map) { |
132 testDeletedElement(map); | 135 testDeletedElement(map); |
133 testMap(map, 1, 2, 3, 4, 5, 6, 7, 8); | 136 testMap(map, 1, 2, 3, 4, 5, 6, 7, 8); |
134 map.clear(); | 137 map.clear(); |
135 testMap(map, "value1", "value2", "value3", "value4", "value5", | 138 testMap(map, "value1", "value2", "value3", "value4", "value5", "value6", |
136 "value6", "value7", "value8"); | 139 "value7", "value8"); |
137 } | 140 } |
138 | 141 |
139 void testLinkedHashMap() { | 142 void testLinkedHashMap() { |
140 LinkedHashMap map = new LinkedHashMap(); | 143 LinkedHashMap map = new LinkedHashMap(); |
141 Expect.equals(false, map.containsKey(1)); | 144 Expect.equals(false, map.containsKey(1)); |
142 map[1] = 1; | 145 map[1] = 1; |
143 map[1] = 2; | 146 map[1] = 2; |
144 testLength(1, map); | 147 testLength(1, map); |
145 } | 148 } |
146 | 149 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 testLength(2, map); | 246 testLength(2, map); |
244 | 247 |
245 Expect.equals(true, map.containsKey(key1)); | 248 Expect.equals(true, map.containsKey(key1)); |
246 Expect.equals(true, map.containsValue(value1)); | 249 Expect.equals(true, map.containsValue(value1)); |
247 | 250 |
248 // Test Map.forEach. | 251 // Test Map.forEach. |
249 Map otherMap = new Map(); | 252 Map otherMap = new Map(); |
250 void testForEachMap(key, value) { | 253 void testForEachMap(key, value) { |
251 otherMap[key] = value; | 254 otherMap[key] = value; |
252 } | 255 } |
| 256 |
253 map.forEach(testForEachMap); | 257 map.forEach(testForEachMap); |
254 Expect.equals(true, otherMap.containsKey(key1)); | 258 Expect.equals(true, otherMap.containsKey(key1)); |
255 Expect.equals(true, otherMap.containsKey(key2)); | 259 Expect.equals(true, otherMap.containsKey(key2)); |
256 Expect.equals(true, otherMap.containsValue(value1)); | 260 Expect.equals(true, otherMap.containsValue(value1)); |
257 Expect.equals(true, otherMap.containsValue(value2)); | 261 Expect.equals(true, otherMap.containsValue(value2)); |
258 Expect.equals(2, otherMap.length); | 262 Expect.equals(2, otherMap.length); |
259 | 263 |
260 otherMap.clear(); | 264 otherMap.clear(); |
261 Expect.equals(0, otherMap.length); | 265 Expect.equals(0, otherMap.length); |
262 | 266 |
263 // Test Collection.keys. | 267 // Test Collection.keys. |
264 void testForEachCollection(value) { | 268 void testForEachCollection(value) { |
265 otherMap[value] = value; | 269 otherMap[value] = value; |
266 } | 270 } |
| 271 |
267 Iterable keys = map.keys; | 272 Iterable keys = map.keys; |
268 keys.forEach(testForEachCollection); | 273 keys.forEach(testForEachCollection); |
269 Expect.equals(true, otherMap.containsKey(key1)); | 274 Expect.equals(true, otherMap.containsKey(key1)); |
270 Expect.equals(true, otherMap.containsKey(key2)); | 275 Expect.equals(true, otherMap.containsKey(key2)); |
271 Expect.equals(true, otherMap.containsValue(key1)); | 276 Expect.equals(true, otherMap.containsValue(key1)); |
272 Expect.equals(true, otherMap.containsValue(key2)); | 277 Expect.equals(true, otherMap.containsValue(key2)); |
273 Expect.equals(true, !otherMap.containsKey(value1)); | 278 Expect.equals(true, !otherMap.containsKey(value1)); |
274 Expect.equals(true, !otherMap.containsKey(value2)); | 279 Expect.equals(true, !otherMap.containsKey(value2)); |
275 Expect.equals(true, !otherMap.containsValue(value1)); | 280 Expect.equals(true, !otherMap.containsValue(value1)); |
276 Expect.equals(true, !otherMap.containsValue(value2)); | 281 Expect.equals(true, !otherMap.containsValue(value2)); |
(...skipping 15 matching lines...) Expand all Loading... |
292 Expect.equals(2, otherMap.length); | 297 Expect.equals(2, otherMap.length); |
293 otherMap.clear(); | 298 otherMap.clear(); |
294 Expect.equals(0, otherMap.length); | 299 Expect.equals(0, otherMap.length); |
295 | 300 |
296 // Test Map.putIfAbsent. | 301 // Test Map.putIfAbsent. |
297 map.clear(); | 302 map.clear(); |
298 Expect.equals(false, map.containsKey(key1)); | 303 Expect.equals(false, map.containsKey(key1)); |
299 map.putIfAbsent(key1, () => 10); | 304 map.putIfAbsent(key1, () => 10); |
300 Expect.equals(true, map.containsKey(key1)); | 305 Expect.equals(true, map.containsKey(key1)); |
301 Expect.equals(10, map[key1]); | 306 Expect.equals(10, map[key1]); |
302 Expect.equals(10, | 307 Expect.equals(10, map.putIfAbsent(key1, () => 11)); |
303 map.putIfAbsent(key1, () => 11)); | |
304 | 308 |
305 // Test Map.addAll. | 309 // Test Map.addAll. |
306 map.clear(); | 310 map.clear(); |
307 otherMap.clear(); | 311 otherMap.clear(); |
308 otherMap[99] = 1; | 312 otherMap[99] = 1; |
309 otherMap[50] = 50; | 313 otherMap[50] = 50; |
310 otherMap[1] = 99; | 314 otherMap[1] = 99; |
311 map.addAll(otherMap); | 315 map.addAll(otherMap); |
312 Expect.equals(3, map.length); | 316 Expect.equals(3, map.length); |
313 Expect.equals(1, map[99]); | 317 Expect.equals(1, map[99]); |
(...skipping 29 matching lines...) Expand all Loading... |
343 for (int i = 0; i < 100; i++) { | 347 for (int i = 0; i < 100; i++) { |
344 map[1] = 2; | 348 map[1] = 2; |
345 testLength(1, map); | 349 testLength(1, map); |
346 map.remove(1); | 350 map.remove(1); |
347 testLength(0, map); | 351 testLength(0, map); |
348 } | 352 } |
349 testLength(0, map); | 353 testLength(0, map); |
350 } | 354 } |
351 | 355 |
352 void testMapLiteral() { | 356 void testMapLiteral() { |
353 Map m = {"a": 1, "b" : 2, "c": 3 }; | 357 Map m = {"a": 1, "b": 2, "c": 3}; |
354 Expect.equals(3, m.length); | 358 Expect.equals(3, m.length); |
355 int sum = 0; | 359 int sum = 0; |
356 m.forEach((a, b) { | 360 m.forEach((a, b) { |
357 sum += b; | 361 sum += b; |
358 }); | 362 }); |
359 Expect.equals(6, sum); | 363 Expect.equals(6, sum); |
360 | 364 |
361 List values = m.keys.toList(); | 365 List values = m.keys.toList(); |
362 Expect.equals(3, values.length); | 366 Expect.equals(3, values.length); |
363 String first = values[0]; | 367 String first = values[0]; |
364 String second = values[1]; | 368 String second = values[1]; |
365 String third = values[2]; | 369 String third = values[2]; |
366 String all = "${first}${second}${third}"; | 370 String all = "${first}${second}${third}"; |
367 Expect.equals(3, all.length); | 371 Expect.equals(3, all.length); |
368 Expect.equals(true, all.contains("a", 0)); | 372 Expect.equals(true, all.contains("a", 0)); |
369 Expect.equals(true, all.contains("b", 0)); | 373 Expect.equals(true, all.contains("b", 0)); |
370 Expect.equals(true, all.contains("c", 0)); | 374 Expect.equals(true, all.contains("c", 0)); |
371 } | 375 } |
372 | 376 |
373 void testNullValue() { | 377 void testNullValue() { |
374 Map m = {"a": 1, "b" : null, "c": 3 }; | 378 Map m = {"a": 1, "b": null, "c": 3}; |
375 | 379 |
376 Expect.equals(null, m["b"]); | 380 Expect.equals(null, m["b"]); |
377 Expect.equals(true, m.containsKey("b")); | 381 Expect.equals(true, m.containsKey("b")); |
378 Expect.equals(3, m.length); | 382 Expect.equals(3, m.length); |
379 | 383 |
380 m["a"] = null; | 384 m["a"] = null; |
381 m["c"] = null; | 385 m["c"] = null; |
382 Expect.equals(null, m["a"]); | 386 Expect.equals(null, m["a"]); |
383 Expect.equals(true, m.containsKey("a")); | 387 Expect.equals(true, m.containsKey("a")); |
384 Expect.equals(null, m["c"]); | 388 Expect.equals(null, m["c"]); |
(...skipping 22 matching lines...) Expand all Loading... |
407 | 411 |
408 // Ensure that "containsKey", "containsValue" and "remove" | 412 // Ensure that "containsKey", "containsValue" and "remove" |
409 // accepts any object. | 413 // accepts any object. |
410 for (var object in [true, null, new Object()]) { | 414 for (var object in [true, null, new Object()]) { |
411 Expect.isFalse(map.containsKey(object)); | 415 Expect.isFalse(map.containsKey(object)); |
412 Expect.isFalse(map.containsValue(object)); | 416 Expect.isFalse(map.containsValue(object)); |
413 Expect.isNull(map.remove(object)); | 417 Expect.isNull(map.remove(object)); |
414 Expect.isNull(map[object]); | 418 Expect.isNull(map[object]); |
415 } | 419 } |
416 } | 420 } |
| 421 |
417 testMap(new HashMap<int, String>()); | 422 testMap(new HashMap<int, String>()); |
418 testMap(new LinkedHashMap<int, String>()); | 423 testMap(new LinkedHashMap<int, String>()); |
419 testMap(new SplayTreeMap<int, String>()); | 424 testMap(new SplayTreeMap<int, String>()); |
420 testMap(new SplayTreeMap<int, String>(Comparable.compare)); | 425 testMap(new SplayTreeMap<int, String>(Comparable.compare)); |
421 testMap(new SplayTreeMap<int, String>((int a, int b) => a.compareTo(b))); | 426 testMap(new SplayTreeMap<int, String>((int a, int b) => a.compareTo(b))); |
422 testMap(new HashMap<num, String>()); | 427 testMap(new HashMap<num, String>()); |
423 testMap(new LinkedHashMap<num, String>()); | 428 testMap(new LinkedHashMap<num, String>()); |
424 testMap(new SplayTreeMap<num, String>()); | 429 testMap(new SplayTreeMap<num, String>()); |
425 testMap(new SplayTreeMap<num, String>(Comparable.compare)); | 430 testMap(new SplayTreeMap<num, String>(Comparable.compare)); |
426 testMap(new SplayTreeMap<num, String>((num a, num b) => a.compareTo(b))); | 431 testMap(new SplayTreeMap<num, String>((num a, num b) => a.compareTo(b))); |
427 } | 432 } |
428 | 433 |
429 void testWeirdStringKeys(Map map) { | 434 void testWeirdStringKeys(Map map) { |
430 // Test weird keys. | 435 // Test weird keys. |
431 var weirdKeys = const [ | 436 var weirdKeys = const [ |
432 'hasOwnProperty', | 437 'hasOwnProperty', |
433 'constructor', | 438 'constructor', |
434 'toLocaleString', | 439 'toLocaleString', |
435 'propertyIsEnumerable', | 440 'propertyIsEnumerable', |
436 '__defineGetter__', | 441 '__defineGetter__', |
437 '__defineSetter__', | 442 '__defineSetter__', |
438 '__lookupGetter__', | 443 '__lookupGetter__', |
439 '__lookupSetter__', | 444 '__lookupSetter__', |
440 'isPrototypeOf', | 445 'isPrototypeOf', |
441 'toString', | 446 'toString', |
442 'valueOf', | 447 'valueOf', |
443 '__proto__', | 448 '__proto__', |
444 '__count__', | 449 '__count__', |
445 '__parent__', | 450 '__parent__', |
446 '']; | 451 '' |
| 452 ]; |
447 Expect.isTrue(map.isEmpty); | 453 Expect.isTrue(map.isEmpty); |
448 for (var key in weirdKeys) { | 454 for (var key in weirdKeys) { |
449 Expect.isFalse(map.containsKey(key)); | 455 Expect.isFalse(map.containsKey(key)); |
450 Expect.equals(null, map[key]); | 456 Expect.equals(null, map[key]); |
451 var value = 'value:$key'; | 457 var value = 'value:$key'; |
452 map[key] = value; | 458 map[key] = value; |
453 Expect.isTrue(map.containsKey(key)); | 459 Expect.isTrue(map.containsKey(key)); |
454 Expect.equals(value, map[key]); | 460 Expect.equals(value, map[key]); |
455 Expect.equals(value, map.remove(key)); | 461 Expect.equals(value, map.remove(key)); |
456 Expect.isFalse(map.containsKey(key)); | 462 Expect.isFalse(map.containsKey(key)); |
457 Expect.equals(null, map[key]); | 463 Expect.equals(null, map[key]); |
458 } | 464 } |
459 Expect.isTrue(map.isEmpty); | 465 Expect.isTrue(map.isEmpty); |
460 | |
461 } | 466 } |
462 | 467 |
463 void testNumericKeys(Map map) { | 468 void testNumericKeys(Map map) { |
464 var numericKeys = const [ | 469 var numericKeys = const [ |
465 double.INFINITY, | 470 double.INFINITY, |
466 double.NEGATIVE_INFINITY, | 471 double.NEGATIVE_INFINITY, |
467 0, | 472 0, |
468 0.0, | 473 0.0, |
469 -0.0 ]; | 474 -0.0 |
| 475 ]; |
470 | 476 |
471 Expect.isTrue(map.isEmpty); | 477 Expect.isTrue(map.isEmpty); |
472 for (var key in numericKeys) { | 478 for (var key in numericKeys) { |
473 Expect.isFalse(map.containsKey(key)); | 479 Expect.isFalse(map.containsKey(key)); |
474 Expect.equals(null, map[key]); | 480 Expect.equals(null, map[key]); |
475 var value = 'value:$key'; | 481 var value = 'value:$key'; |
476 map[key] = value; | 482 map[key] = value; |
477 Expect.isTrue(map.containsKey(key)); | 483 Expect.isTrue(map.containsKey(key)); |
478 Expect.equals(value, map[key]); | 484 Expect.equals(value, map[key]); |
479 Expect.equals(value, map.remove(key)); | 485 Expect.equals(value, map.remove(key)); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 ifNotEmpty(map.values.isNotEmpty); | 534 ifNotEmpty(map.values.isNotEmpty); |
529 // Test key/value iterators match their isEmpty/isNotEmpty. | 535 // Test key/value iterators match their isEmpty/isNotEmpty. |
530 ifNotEmpty(map.keys.iterator.moveNext()); | 536 ifNotEmpty(map.keys.iterator.moveNext()); |
531 ifNotEmpty(map.values.iterator.moveNext()); | 537 ifNotEmpty(map.values.iterator.moveNext()); |
532 if (length == 0) { | 538 if (length == 0) { |
533 for (var k in map.keys) Expect.fail("contains key when iterating: $k"); | 539 for (var k in map.keys) Expect.fail("contains key when iterating: $k"); |
534 for (var v in map.values) Expect.fail("contains values when iterating: $v"); | 540 for (var v in map.values) Expect.fail("contains values when iterating: $v"); |
535 } | 541 } |
536 } | 542 } |
537 | 543 |
538 | |
539 testIdentityMap(Map map) { | 544 testIdentityMap(Map map) { |
540 Expect.isTrue(map.isEmpty); | 545 Expect.isTrue(map.isEmpty); |
541 | 546 |
542 var nan = double.NAN; | 547 var nan = double.NAN; |
543 // TODO(11551): Remove guard when dart2js makes identical(NaN, NaN) true. | 548 // TODO(11551): Remove guard when dart2js makes identical(NaN, NaN) true. |
544 if (identical(nan, nan)) { | 549 if (identical(nan, nan)) { |
545 map[nan] = 42; | 550 map[nan] = 42; |
546 testLength(1, map); | 551 testLength(1, map); |
547 Expect.isTrue(map.containsKey(nan)); | 552 Expect.isTrue(map.containsKey(nan)); |
548 Expect.equals(42, map[nan]); | 553 Expect.equals(42, map[nan]); |
549 map[nan] = 37; | 554 map[nan] = 37; |
550 testLength(1, map); | 555 testLength(1, map); |
551 Expect.equals(37, map[nan]); | 556 Expect.equals(37, map[nan]); |
552 Expect.equals(37, map.remove(nan)); | 557 Expect.equals(37, map.remove(nan)); |
553 testLength(0, map); | 558 testLength(0, map); |
554 } | 559 } |
555 | 560 |
556 Vampire v1 = const Vampire(1); | 561 Vampire v1 = const Vampire(1); |
557 Vampire v2 = const Vampire(2); | 562 Vampire v2 = const Vampire(2); |
558 Expect.isFalse(v1 == v1); | 563 Expect.isFalse(v1 == v1); |
559 Expect.isFalse(v2 == v2); | 564 Expect.isFalse(v2 == v2); |
560 Expect.isTrue(v2 == v1); // Snob! | 565 Expect.isTrue(v2 == v1); // Snob! |
561 | 566 |
562 map[v1] = 1; | 567 map[v1] = 1; |
563 map[v2] = 2; | 568 map[v2] = 2; |
564 testLength(2, map); | 569 testLength(2, map); |
565 | 570 |
566 Expect.isTrue(map.containsKey(v1)); | 571 Expect.isTrue(map.containsKey(v1)); |
567 Expect.isTrue(map.containsKey(v2)); | 572 Expect.isTrue(map.containsKey(v2)); |
568 | 573 |
569 Expect.equals(1, map[v1]); | 574 Expect.equals(1, map[v1]); |
570 Expect.equals(2, map[v2]); | 575 Expect.equals(2, map[v2]); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 // Even if hashcode of m3 changed, it can still be found. | 668 // Even if hashcode of m3 changed, it can still be found. |
664 Expect.equals(1, map[m1]); | 669 Expect.equals(1, map[m1]); |
665 Expect.equals(3, map[m3]); | 670 Expect.equals(3, map[m3]); |
666 } | 671 } |
667 | 672 |
668 /** Class of objects that are equal if they hold the same id. */ | 673 /** Class of objects that are equal if they hold the same id. */ |
669 class Equalizer { | 674 class Equalizer { |
670 int id; | 675 int id; |
671 Equalizer(this.id); | 676 Equalizer(this.id); |
672 int get hashCode => id; | 677 int get hashCode => id; |
673 bool operator==(Object other) => | 678 bool operator ==(Object other) => |
674 other is Equalizer && id == (other as Equalizer).id; | 679 other is Equalizer && id == (other as Equalizer).id; |
675 } | 680 } |
676 | 681 |
677 /** | 682 /** |
678 * Objects that are not reflexive. | 683 * Objects that are not reflexive. |
679 * | 684 * |
680 * They think they are better than their equals. | 685 * They think they are better than their equals. |
681 */ | 686 */ |
682 class Vampire { | 687 class Vampire { |
683 final int generation; | 688 final int generation; |
684 const Vampire(this.generation); | 689 const Vampire(this.generation); |
685 | 690 |
686 int get hashCode => generation; | 691 int get hashCode => generation; |
687 | 692 |
688 // The double-fang operator falsely claims that a vampire is equal to | 693 // The double-fang operator falsely claims that a vampire is equal to |
689 // any of its sire's generation. | 694 // any of its sire's generation. |
690 bool operator==(Object other) => | 695 bool operator ==(Object other) => |
691 other is Vampire && generation - 1 == (other as Vampire).generation; | 696 other is Vampire && generation - 1 == (other as Vampire).generation; |
692 } | 697 } |
693 | 698 |
694 void testCustomMap(Map map) { | 699 void testCustomMap(Map map) { |
695 testLength(0, map); | 700 testLength(0, map); |
696 var c11 = const Customer(1, 1); | 701 var c11 = const Customer(1, 1); |
697 var c12 = const Customer(1, 2); | 702 var c12 = const Customer(1, 2); |
698 var c21 = const Customer(2, 1); | 703 var c21 = const Customer(2, 1); |
699 var c22 = const Customer(2, 2); | 704 var c22 = const Customer(2, 2); |
700 // Sanity. | 705 // Sanity. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 testLength(0, map); | 759 testLength(0, map); |
755 } | 760 } |
756 | 761 |
757 void testUnmodifiableMap(Map map) { | 762 void testUnmodifiableMap(Map map) { |
758 Expect.isTrue(map.containsKey(1)); | 763 Expect.isTrue(map.containsKey(1)); |
759 testLength(1, map); | 764 testLength(1, map); |
760 Expect.equals(1, map.keys.first); | 765 Expect.equals(1, map.keys.first); |
761 Expect.equals(37, map.values.first); | 766 Expect.equals(37, map.values.first); |
762 | 767 |
763 Expect.throws(map.clear); | 768 Expect.throws(map.clear); |
764 Expect.throws(() { map.remove(1); }); | 769 Expect.throws(() { |
765 Expect.throws(() { map[2] = 42; }); | 770 map.remove(1); |
766 Expect.throws(() { map.addAll({2 : 42}); }); | 771 }); |
| 772 Expect.throws(() { |
| 773 map[2] = 42; |
| 774 }); |
| 775 Expect.throws(() { |
| 776 map.addAll({2: 42}); |
| 777 }); |
767 } | 778 } |
768 | 779 |
769 class Customer { | 780 class Customer { |
770 final int id; | 781 final int id; |
771 final int secondId; | 782 final int secondId; |
772 const Customer(this.id, this.secondId); | 783 const Customer(this.id, this.secondId); |
773 int get hashCode => id; | 784 int get hashCode => id; |
774 bool operator==(Object other) { | 785 bool operator ==(Object other) { |
775 if (other is! Customer) return false; | 786 if (other is! Customer) return false; |
776 Customer otherCustomer = other; | 787 Customer otherCustomer = other; |
777 return id == otherCustomer.id; | 788 return id == otherCustomer.id; |
778 } | 789 } |
779 } | 790 } |
780 | 791 |
781 int myHashCode(Customer c) => c.secondId; | 792 int myHashCode(Customer c) => c.secondId; |
782 bool myEquals(Customer a, Customer b) => a.secondId == b.secondId; | 793 bool myEquals(Customer a, Customer b) => a.secondId == b.secondId; |
783 | 794 |
784 void testIterationOrder(Map map) { | 795 void testIterationOrder(Map map) { |
(...skipping 17 matching lines...) Expand all Loading... |
802 Expect.isNull(map.remove("not an int")); | 813 Expect.isNull(map.remove("not an int")); |
803 Expect.isNull(map.remove(1.5)); | 814 Expect.isNull(map.remove(1.5)); |
804 Expect.isNull(map["not an int"]); | 815 Expect.isNull(map["not an int"]); |
805 Expect.isNull(map[1.5]); | 816 Expect.isNull(map[1.5]); |
806 } | 817 } |
807 | 818 |
808 class Mutable { | 819 class Mutable { |
809 int id; | 820 int id; |
810 Mutable(this.id); | 821 Mutable(this.id); |
811 int get hashCode => id; | 822 int get hashCode => id; |
812 bool operator==(other) => other is Mutable && other.id == id; | 823 bool operator ==(other) => other is Mutable && other.id == id; |
813 } | 824 } |
814 | 825 |
815 | |
816 // Slow implementation of Map based on MapBase. | 826 // Slow implementation of Map based on MapBase. |
817 abstract class MapBaseOperations<K, V> { | 827 abstract class MapBaseOperations<K, V> { |
818 final List _keys = <K>[]; | 828 final List _keys = <K>[]; |
819 final List _values = <V>[]; | 829 final List _values = <V>[]; |
820 int _modCount = 0; | 830 int _modCount = 0; |
821 | 831 |
822 V operator[](Object key) { | 832 V operator [](Object key) { |
823 int index = _keys.indexOf(key); | 833 int index = _keys.indexOf(key); |
824 if (index < 0) return null; | 834 if (index < 0) return null; |
825 return _values[index]; | 835 return _values[index]; |
826 } | 836 } |
827 | 837 |
828 Iterable<K> get keys => new TestKeyIterable<K>(this); | 838 Iterable<K> get keys => new TestKeyIterable<K>(this); |
829 | 839 |
830 void operator[]=(K key, V value) { | 840 void operator []=(K key, V value) { |
831 int index = _keys.indexOf(key); | 841 int index = _keys.indexOf(key); |
832 if (index >= 0) { | 842 if (index >= 0) { |
833 _values[index] = value; | 843 _values[index] = value; |
834 } else { | 844 } else { |
835 _modCount++; | 845 _modCount++; |
836 _keys.add(key); | 846 _keys.add(key); |
837 _values.add(value); | 847 _values.add(value); |
838 } | 848 } |
839 } | 849 } |
840 | 850 |
(...skipping 30 matching lines...) Expand all Loading... |
871 TestKeyIterable(this._map); | 881 TestKeyIterable(this._map); |
872 int get length => _map._keys.length; | 882 int get length => _map._keys.length; |
873 Iterator<K> get iterator => new TestKeyIterator<K>(_map); | 883 Iterator<K> get iterator => new TestKeyIterator<K>(_map); |
874 } | 884 } |
875 | 885 |
876 class TestKeyIterator<K> implements Iterator<K> { | 886 class TestKeyIterator<K> implements Iterator<K> { |
877 final _map; | 887 final _map; |
878 final int _modCount; | 888 final int _modCount; |
879 int _index = 0; | 889 int _index = 0; |
880 var _current; | 890 var _current; |
881 TestKeyIterator(map) : _map = map, _modCount = map._modCount; | 891 TestKeyIterator(map) |
| 892 : _map = map, |
| 893 _modCount = map._modCount; |
882 bool moveNext() { | 894 bool moveNext() { |
883 if (_modCount != _map._modCount) { | 895 if (_modCount != _map._modCount) { |
884 throw new ConcurrentModificationError(_map); | 896 throw new ConcurrentModificationError(_map); |
885 } | 897 } |
886 if (_index == _map._keys.length) { | 898 if (_index == _map._keys.length) { |
887 _current = null; | 899 _current = null; |
888 return false; | 900 return false; |
889 } | 901 } |
890 _current = _map._keys[_index++]; | 902 _current = _map._keys[_index++]; |
891 return true; | 903 return true; |
892 } | 904 } |
| 905 |
893 K get current => _current; | 906 K get current => _current; |
894 } | 907 } |
895 | 908 |
896 // Slow implementation of Map based on MapBase. | 909 // Slow implementation of Map based on MapBase. |
897 class UnmodifiableMapBaseMap<K, V> extends UnmodifiableMapBase<K, V> { | 910 class UnmodifiableMapBaseMap<K, V> extends UnmodifiableMapBase<K, V> { |
898 final List _keys = <K>[]; | 911 final List _keys = <K>[]; |
899 final List _values = <V>[]; | 912 final List _values = <V>[]; |
900 UnmodifiableMapBaseMap(List pairs) { | 913 UnmodifiableMapBaseMap(List pairs) { |
901 for (int i = 0; i < pairs.length; i += 2) { | 914 for (int i = 0; i < pairs.length; i += 2) { |
902 _keys.add(pairs[i]); | 915 _keys.add(pairs[i]); |
903 _values.add(pairs[i + 1]); | 916 _values.add(pairs[i + 1]); |
904 } | 917 } |
905 } | 918 } |
906 | 919 |
907 int get _modCount => 0; | 920 int get _modCount => 0; |
908 | 921 |
909 V operator[](K key) { | 922 V operator [](K key) { |
910 int index = _keys.indexOf(key); | 923 int index = _keys.indexOf(key); |
911 if (index < 0) return null; | 924 if (index < 0) return null; |
912 return _values[index]; | 925 return _values[index]; |
913 } | 926 } |
914 | 927 |
915 Iterable<K> get keys => _keys.skip(0); | 928 Iterable<K> get keys => _keys.skip(0); |
916 } | 929 } |
917 | 930 |
918 abstract class Super implements Comparable {} | 931 abstract class Super implements Comparable {} |
| 932 |
919 abstract class Interface implements Comparable {} | 933 abstract class Interface implements Comparable {} |
| 934 |
920 class Sub extends Super implements Interface, Comparable { | 935 class Sub extends Super implements Interface, Comparable { |
921 int compareTo(Sub other) => 0; | 936 int compareTo(Sub other) => 0; |
922 int get hashCode => 0; | 937 int get hashCode => 0; |
923 bool operator==(other) => other is Sub; | 938 bool operator ==(other) => other is Sub; |
924 } | 939 } |
925 | 940 |
926 expectMap(Map expect, Map actual) { | 941 expectMap(Map expect, Map actual) { |
927 Expect.equals(expect.length, actual.length, "length"); | 942 Expect.equals(expect.length, actual.length, "length"); |
928 for (var key in expect.keys) { | 943 for (var key in expect.keys) { |
929 Expect.isTrue(actual.containsKey(key), "containsKey $key"); | 944 Expect.isTrue(actual.containsKey(key), "containsKey $key"); |
930 Expect.equals(expect[key], actual[key]); | 945 Expect.equals(expect[key], actual[key]); |
931 } | 946 } |
932 } | 947 } |
933 | 948 |
934 void testFrom() { | 949 void testFrom() { |
935 // Check contents. | 950 // Check contents. |
936 for (var map in [{}, {1: 1}, {1: 2, 3: 4, 5: 6, 7: 8}]) { | 951 for (var map in [ |
| 952 {}, |
| 953 {1: 1}, |
| 954 {1: 2, 3: 4, 5: 6, 7: 8} |
| 955 ]) { |
937 expectMap(map, new Map.from(map)); | 956 expectMap(map, new Map.from(map)); |
938 expectMap(map, new HashMap.from(map)); | 957 expectMap(map, new HashMap.from(map)); |
939 expectMap(map, new LinkedHashMap.from(map)); | 958 expectMap(map, new LinkedHashMap.from(map)); |
940 expectMap(map, new SplayTreeMap.from(map)); | 959 expectMap(map, new SplayTreeMap.from(map)); |
941 } | 960 } |
942 // Test type combinations allowed. | 961 // Test type combinations allowed. |
943 Map<int,int> intMap = <int, int>{1: 2, 3: 4}; | 962 Map<int, int> intMap = <int, int>{1: 2, 3: 4}; |
944 Map<num,num> numMap = <num, num>{1: 2, 3: 4}; | 963 Map<num, num> numMap = <num, num>{1: 2, 3: 4}; |
945 expectMap(intMap, new Map<int, int>.from(numMap)); | 964 expectMap(intMap, new Map<int, int>.from(numMap)); |
946 expectMap(intMap, new Map<num, num>.from(intMap)); | 965 expectMap(intMap, new Map<num, num>.from(intMap)); |
947 expectMap(intMap, new HashMap<int, int>.from(numMap)); | 966 expectMap(intMap, new HashMap<int, int>.from(numMap)); |
948 expectMap(intMap, new HashMap<num, num>.from(intMap)); | 967 expectMap(intMap, new HashMap<num, num>.from(intMap)); |
949 expectMap(intMap, new LinkedHashMap<int, int>.from(numMap)); | 968 expectMap(intMap, new LinkedHashMap<int, int>.from(numMap)); |
950 expectMap(intMap, new LinkedHashMap<num, num>.from(intMap)); | 969 expectMap(intMap, new LinkedHashMap<num, num>.from(intMap)); |
951 expectMap(intMap, new SplayTreeMap<int, int>.from(numMap)); | 970 expectMap(intMap, new SplayTreeMap<int, int>.from(numMap)); |
952 expectMap(intMap, new SplayTreeMap<num, num>.from(intMap)); | 971 expectMap(intMap, new SplayTreeMap<num, num>.from(intMap)); |
953 | 972 |
954 var sub = new Sub(); | 973 var sub = new Sub(); |
955 Map<Super, Super> superMap = <Super, Super>{sub: sub}; | 974 Map<Super, Super> superMap = <Super, Super>{sub: sub}; |
956 Map<Interface, Interface> interfaceMap = <Interface, Interface>{sub: sub}; | 975 Map<Interface, Interface> interfaceMap = <Interface, Interface>{sub: sub}; |
957 expectMap(superMap, new Map<Super, Super>.from(interfaceMap)); | 976 expectMap(superMap, new Map<Super, Super>.from(interfaceMap)); |
958 expectMap(superMap, new Map<Interface, Interface>.from(superMap)); | 977 expectMap(superMap, new Map<Interface, Interface>.from(superMap)); |
959 expectMap(superMap, new HashMap<Super, Super>.from(interfaceMap)); | 978 expectMap(superMap, new HashMap<Super, Super>.from(interfaceMap)); |
960 expectMap(superMap, new HashMap<Interface, Interface>.from(superMap)); | 979 expectMap(superMap, new HashMap<Interface, Interface>.from(superMap)); |
961 expectMap(superMap, new LinkedHashMap<Super, Super>.from(interfaceMap)); | 980 expectMap(superMap, new LinkedHashMap<Super, Super>.from(interfaceMap)); |
962 expectMap(superMap, new LinkedHashMap<Interface, Interface>.from(superMap)); | 981 expectMap(superMap, new LinkedHashMap<Interface, Interface>.from(superMap)); |
963 expectMap(superMap, new SplayTreeMap<Super, Super>.from(interfaceMap)); | 982 expectMap(superMap, new SplayTreeMap<Super, Super>.from(interfaceMap)); |
964 expectMap(superMap, new SplayTreeMap<Interface, Interface>.from(superMap)); | 983 expectMap(superMap, new SplayTreeMap<Interface, Interface>.from(superMap)); |
965 } | 984 } |
OLD | NEW |