OLD | NEW |
1 // Copyright 2013 Google Inc. All Rights Reserved. | 1 // Copyright 2013 Google Inc. All Rights Reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 library quiver.collection.multimap_test; | 15 library quiver.collection.multimap_test; |
16 | 16 |
17 import 'package:quiver/collection.dart'; | 17 import 'package:quiver/collection.dart'; |
18 import 'package:test/test.dart'; | 18 import 'package:test/test.dart'; |
19 | 19 |
20 void main() { | 20 void main() { |
21 group('Multimap', () { | 21 group('Multimap', () { |
22 test('should be a list-backed multimap', () { | 22 test('should be a list-backed multimap', () { |
23 var map = new Multimap(); | 23 var map = new Multimap(); |
24 expect(map is ListMultimap, true); | 24 expect(map is ListMultimap, true); |
25 }); | 25 }); |
26 }); | 26 }); |
27 | 27 |
| 28 group('Multimap.fromIterable', () { |
| 29 test('should default to the identity for key and value', () { |
| 30 var map = new Multimap<int, int>.fromIterable([1, 2, 1]); |
| 31 expect(map.asMap(), { |
| 32 1: [1, 1], |
| 33 2: [2], |
| 34 }); |
| 35 }); |
| 36 |
| 37 test('should allow setting value', () { |
| 38 var i = 0; |
| 39 var map = new Multimap<int, String>.fromIterable([1, 2, 1], |
| 40 value: (x) => '$x:${i++}'); |
| 41 expect(map.asMap(), { |
| 42 1: ['1:0', '1:2'], |
| 43 2: ['2:1'], |
| 44 }); |
| 45 }); |
| 46 |
| 47 test('should allow setting key', () { |
| 48 var map = |
| 49 new Multimap<String, int>.fromIterable([1, 2, 1], key: (x) => '($x)'); |
| 50 expect(map.asMap(), { |
| 51 '(1)': [1, 1], |
| 52 '(2)': [2], |
| 53 }); |
| 54 }); |
| 55 |
| 56 test('should allow setting both key and value', () { |
| 57 var i = 0; |
| 58 var map = new Multimap<int, String>.fromIterable([1, 2, 1], |
| 59 key: (x) => -x, value: (x) => '$x:${i++}'); |
| 60 expect(map.asMap(), { |
| 61 -1: ['1:0', '1:2'], |
| 62 -2: ['2:1'], |
| 63 }); |
| 64 }); |
| 65 }); |
| 66 |
28 group('Multimap asMap() view', () { | 67 group('Multimap asMap() view', () { |
29 var mmap; | 68 var mmap; |
30 var map; | 69 var map; |
31 setUp(() { | 70 setUp(() { |
32 mmap = new Multimap() | 71 mmap = new Multimap()..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); |
33 ..add('k1', 'v1') | |
34 ..add('k1', 'v2') | |
35 ..add('k2', 'v3'); | |
36 map = mmap.asMap(); | 72 map = mmap.asMap(); |
37 }); | 73 }); |
38 | 74 |
39 test('operator[]= should throw UnsupportedError', () { | 75 test('operator[]= should throw UnsupportedError', () { |
40 expect(() => map['k1'] = [1, 2, 3], throwsUnsupportedError); | 76 expect(() => map['k1'] = [1, 2, 3], throwsUnsupportedError); |
41 }); | 77 }); |
42 | 78 |
43 test('containsKey() should return false for missing key', () { | 79 test('containsKey() should return false for missing key', () { |
44 expect(map.containsKey('k3'), isFalse); | 80 expect(map.containsKey('k3'), isFalse); |
45 }); | 81 }); |
46 | 82 |
47 test('containsKey() should return true for key in map', () { | 83 test('containsKey() should return true for key in map', () { |
48 expect(map.containsKey('k1'), isTrue); | 84 expect(map.containsKey('k1'), isTrue); |
49 }); | 85 }); |
50 | 86 |
51 test('containsValue() should return false for missing value', () { | 87 test('containsValue() should return false for missing value', () { |
52 expect(map.containsValue('k3'), isFalse); | 88 expect(map.containsValue('k3'), isFalse); |
53 }); | 89 }); |
54 | 90 |
55 test('containsValue() should return true for value in map', () { | 91 test('containsValue() should return true for value in map', () { |
56 expect(map.containsValue('v1'), isTrue); | 92 expect(map.containsValue('v1'), isTrue); |
57 }); | 93 }); |
58 | 94 |
59 test('forEach should iterate over all key-value pairs', () { | 95 test('forEach should iterate over all key-value pairs', () { |
60 var results = []; | 96 var results = []; |
61 map.forEach((k, v) => results.add(new Pair(k, v))); | 97 map.forEach((k, v) => results.add(new Pair(k, v))); |
62 expect(results, unorderedEquals([ | 98 expect( |
63 new Pair('k1', ['v1', 'v2']), | 99 results, |
64 new Pair('k2', ['v3']) | 100 unorderedEquals([ |
65 ])); | 101 new Pair('k1', ['v1', 'v2']), |
| 102 new Pair('k2', ['v3']) |
| 103 ])); |
66 }); | 104 }); |
67 | 105 |
68 test('isEmpty should return whether the map contains key-value pairs', () { | 106 test('isEmpty should return whether the map contains key-value pairs', () { |
69 expect(map.isEmpty, isFalse); | 107 expect(map.isEmpty, isFalse); |
70 expect(map.isNotEmpty, isTrue); | 108 expect(map.isNotEmpty, isTrue); |
71 expect(new Multimap().asMap().isEmpty, isTrue); | 109 expect(new Multimap().asMap().isEmpty, isTrue); |
72 expect(new Multimap().asMap().isNotEmpty, isFalse); | 110 expect(new Multimap().asMap().isNotEmpty, isFalse); |
73 }); | 111 }); |
74 | 112 |
75 test('length should return the number of key-value pairs', () { | 113 test('length should return the number of key-value pairs', () { |
76 expect(new Multimap().asMap().length, equals(0)); | 114 expect(new Multimap().asMap().length, equals(0)); |
77 expect(map.length, equals(2)); | 115 expect(map.length, equals(2)); |
78 }); | 116 }); |
79 | 117 |
80 test('addAll(Map m) should throw UnsupportedError', () { | 118 test('addAll(Map m) should throw UnsupportedError', () { |
81 expect(() => map.addAll({'k1': [1, 2, 3]}), throwsUnsupportedError); | 119 expect( |
| 120 () => map.addAll({ |
| 121 'k1': [1, 2, 3] |
| 122 }), |
| 123 throwsUnsupportedError); |
82 }); | 124 }); |
83 | 125 |
84 test('putIfAbsent() should throw UnsupportedError', () { | 126 test('putIfAbsent() should throw UnsupportedError', () { |
85 var map = new Multimap().asMap(); | 127 var map = new Multimap().asMap(); |
86 expect(() => map.putIfAbsent('k1', () => [1]), throwsUnsupportedError); | 128 expect(() => map.putIfAbsent('k1', () => [1]), throwsUnsupportedError); |
87 }); | 129 }); |
88 }); | 130 }); |
89 | 131 |
90 group('ListMultimap', () { | 132 group('ListMultimap', () { |
91 test('should initialize empty', () { | 133 test('should initialize empty', () { |
92 var map = new ListMultimap(); | 134 var map = new ListMultimap(); |
93 expect(map.isEmpty, true); | 135 expect(map.isEmpty, true); |
94 expect(map.isNotEmpty, false); | 136 expect(map.isNotEmpty, false); |
95 }); | 137 }); |
96 | 138 |
97 test('should not be empty after adding', () { | 139 test('should not be empty after adding', () { |
98 var map = new ListMultimap<String, String>()..add('k', 'v'); | 140 var map = new ListMultimap<String, String>()..add('k', 'v'); |
99 expect(map.isEmpty, false); | 141 expect(map.isEmpty, false); |
100 expect(map.isNotEmpty, true); | 142 expect(map.isNotEmpty, true); |
101 }); | 143 }); |
102 | 144 |
103 test('should return the number of keys as length', () { | 145 test('should return the number of keys as length', () { |
104 var map = new ListMultimap<String, String>(); | 146 var map = new ListMultimap<String, String>(); |
105 expect(map.length, 0); | 147 expect(map.length, 0); |
106 map | 148 map..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); |
107 ..add('k1', 'v1') | |
108 ..add('k1', 'v2') | |
109 ..add('k2', 'v3'); | |
110 expect(map.length, 2); | 149 expect(map.length, 2); |
111 }); | 150 }); |
112 | 151 |
113 test('should return an empty iterable for unmapped keys', () { | 152 test('should return an empty iterable for unmapped keys', () { |
114 var map = new ListMultimap<String, String>(); | 153 var map = new ListMultimap<String, String>(); |
115 expect(map['k1'], []); | 154 expect(map['k1'], []); |
116 }); | 155 }); |
117 | 156 |
118 test('should support adding values for unmapped keys', () { | 157 test('should support adding values for unmapped keys', () { |
119 var map = new ListMultimap<String, String>()..['k1'].add('v1'); | 158 var map = new ListMultimap<String, String>()..['k1'].add('v1'); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 expect(values2, ['v1', 'v2']); | 198 expect(values2, ['v1', 'v2']); |
160 }); | 199 }); |
161 | 200 |
162 test('should support adding duplicate values for a key', () { | 201 test('should support adding duplicate values for a key', () { |
163 var map = new ListMultimap<String, String>() | 202 var map = new ListMultimap<String, String>() |
164 ..add('k', 'v1') | 203 ..add('k', 'v1') |
165 ..add('k', 'v1'); | 204 ..add('k', 'v1'); |
166 expect(map['k'], ['v1', 'v1']); | 205 expect(map['k'], ['v1', 'v1']); |
167 }); | 206 }); |
168 | 207 |
| 208 test( |
| 209 'should support adding duplicate values for a key when initialized ' |
| 210 'from an iterable', () { |
| 211 var map = new ListMultimap<String, String>.fromIterable(['k', 'k'], |
| 212 value: (x) => 'v1'); |
| 213 expect(map['k'], ['v1', 'v1']); |
| 214 }); |
| 215 |
169 test('should support adding multiple keys', () { | 216 test('should support adding multiple keys', () { |
170 var map = new ListMultimap<String, String>() | 217 var map = new ListMultimap<String, String>() |
171 ..add('k1', 'v1') | 218 ..add('k1', 'v1') |
172 ..add('k1', 'v2') | 219 ..add('k1', 'v2') |
173 ..add('k2', 'v3'); | 220 ..add('k2', 'v3'); |
174 expect(map['k1'], ['v1', 'v2']); | 221 expect(map['k1'], ['v1', 'v2']); |
175 expect(map['k2'], ['v3']); | 222 expect(map['k2'], ['v3']); |
176 }); | 223 }); |
177 | 224 |
178 test('should support adding multiple values at once', () { | 225 test('should support adding multiple values at once', () { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 expect(map.containsKey('k2'), true); | 323 expect(map.containsKey('k2'), true); |
277 }); | 324 }); |
278 | 325 |
279 test('should remove a key when all associated values are removed', () { | 326 test('should remove a key when all associated values are removed', () { |
280 var map = new ListMultimap<String, String>() | 327 var map = new ListMultimap<String, String>() |
281 ..add('k1', 'v1') | 328 ..add('k1', 'v1') |
282 ..remove('k1', 'v1'); | 329 ..remove('k1', 'v1'); |
283 expect(map.containsKey('k1'), false); | 330 expect(map.containsKey('k1'), false); |
284 }); | 331 }); |
285 | 332 |
286 test('should remove a key when all associated values are removed ' | 333 test( |
| 334 'should remove a key when all associated values are removed ' |
287 'via the underlying iterable.remove', () { | 335 'via the underlying iterable.remove', () { |
288 var map = new ListMultimap<String, String>()..add('k1', 'v1'); | 336 var map = new ListMultimap<String, String>()..add('k1', 'v1'); |
289 map['k1'].remove('v1'); | 337 map['k1'].remove('v1'); |
290 expect(map.containsKey('k1'), false); | 338 expect(map.containsKey('k1'), false); |
291 }); | 339 }); |
292 | 340 |
293 test('should remove a key when all associated values are removed ' | 341 test( |
| 342 'should remove a key when all associated values are removed ' |
294 'via the underlying iterable.removeAt', () { | 343 'via the underlying iterable.removeAt', () { |
295 var map = new ListMultimap<String, String>()..add('k1', 'v1'); | 344 var map = new ListMultimap<String, String>()..add('k1', 'v1'); |
296 map['k1'].removeAt(0); | 345 map['k1'].removeAt(0); |
297 expect(map.containsKey('k1'), false); | 346 expect(map.containsKey('k1'), false); |
298 }); | 347 }); |
299 | 348 |
300 test('should remove a key when all associated values are removed ' | 349 test( |
| 350 'should remove a key when all associated values are removed ' |
301 'via the underlying iterable.removeAt', () { | 351 'via the underlying iterable.removeAt', () { |
302 var map = new ListMultimap<String, String>()..add('k1', 'v1'); | 352 var map = new ListMultimap<String, String>()..add('k1', 'v1'); |
303 map['k1'].removeLast(); | 353 map['k1'].removeLast(); |
304 expect(map.containsKey('k1'), false); | 354 expect(map.containsKey('k1'), false); |
305 }); | 355 }); |
306 | 356 |
307 test('should remove a key when all associated values are removed ' | 357 test( |
| 358 'should remove a key when all associated values are removed ' |
308 'via the underlying iterable.removeRange', () { | 359 'via the underlying iterable.removeRange', () { |
309 var map = new ListMultimap<String, String>()..add('k1', 'v1'); | 360 var map = new ListMultimap<String, String>()..add('k1', 'v1'); |
310 map['k1'].removeRange(0, 1); | 361 map['k1'].removeRange(0, 1); |
311 expect(map.containsKey('k1'), false); | 362 expect(map.containsKey('k1'), false); |
312 }); | 363 }); |
313 | 364 |
314 test('should remove a key when all associated values are removed ' | 365 test( |
| 366 'should remove a key when all associated values are removed ' |
315 'via the underlying iterable.removeWhere', () { | 367 'via the underlying iterable.removeWhere', () { |
316 var map = new ListMultimap<String, String>()..add('k1', 'v1'); | 368 var map = new ListMultimap<String, String>()..add('k1', 'v1'); |
317 map['k1'].removeWhere((_) => true); | 369 map['k1'].removeWhere((_) => true); |
318 expect(map.containsKey('k1'), false); | 370 expect(map.containsKey('k1'), false); |
319 }); | 371 }); |
320 | 372 |
321 test('should remove a key when all associated values are removed ' | 373 test( |
| 374 'should remove a key when all associated values are removed ' |
322 'via the underlying iterable.replaceRange', () { | 375 'via the underlying iterable.replaceRange', () { |
323 var map = new ListMultimap<String, String>()..add('k1', 'v1'); | 376 var map = new ListMultimap<String, String>()..add('k1', 'v1'); |
324 map['k1'].replaceRange(0, 1, []); | 377 map['k1'].replaceRange(0, 1, []); |
325 expect(map.containsKey('k1'), false); | 378 expect(map.containsKey('k1'), false); |
326 }); | 379 }); |
327 | 380 |
328 test('should remove a key when all associated values are removed ' | 381 test( |
| 382 'should remove a key when all associated values are removed ' |
329 'via the underlying iterable.retainWhere', () { | 383 'via the underlying iterable.retainWhere', () { |
330 var map = new ListMultimap<String, String>()..add('k1', 'v1'); | 384 var map = new ListMultimap<String, String>()..add('k1', 'v1'); |
331 map['k1'].retainWhere((_) => false); | 385 map['k1'].retainWhere((_) => false); |
332 expect(map.containsKey('k1'), false); | 386 expect(map.containsKey('k1'), false); |
333 }); | 387 }); |
334 | 388 |
335 test('should remove a key when all associated values are removed ' | 389 test( |
| 390 'should remove a key when all associated values are removed ' |
336 'via the underlying iterable.clear', () { | 391 'via the underlying iterable.clear', () { |
337 var map = new ListMultimap<String, String>() | 392 var map = new ListMultimap<String, String>() |
338 ..add('k1', 'v1') | 393 ..add('k1', 'v1') |
339 ..add('k1', 'v2'); | 394 ..add('k1', 'v2'); |
340 map['k1'].clear(); | 395 map['k1'].clear(); |
341 expect(map.containsKey('k1'), false); | 396 expect(map.containsKey('k1'), false); |
342 }); | 397 }); |
343 | 398 |
344 test('should remove all values for a key', () { | 399 test('should remove all values for a key', () { |
345 var map = new ListMultimap<String, String>() | 400 var map = new ListMultimap<String, String>() |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 expect(mmap.isEmpty, true); | 514 expect(mmap.isEmpty, true); |
460 }); | 515 }); |
461 | 516 |
462 test('should support iteration over all {key, value} pairs', () { | 517 test('should support iteration over all {key, value} pairs', () { |
463 Set s = new Set(); | 518 Set s = new Set(); |
464 new ListMultimap<String, String>() | 519 new ListMultimap<String, String>() |
465 ..add('k1', 'v1') | 520 ..add('k1', 'v1') |
466 ..add('k1', 'v2') | 521 ..add('k1', 'v2') |
467 ..add('k2', 'v3') | 522 ..add('k2', 'v3') |
468 ..forEach((k, v) => s.add(new Pair(k, v))); | 523 ..forEach((k, v) => s.add(new Pair(k, v))); |
469 expect(s, unorderedEquals( | 524 expect( |
470 [new Pair('k1', 'v1'), new Pair('k1', 'v2'), new Pair('k2', 'v3')])); | 525 s, |
| 526 unorderedEquals([ |
| 527 new Pair('k1', 'v1'), |
| 528 new Pair('k1', 'v2'), |
| 529 new Pair('k2', 'v3') |
| 530 ])); |
471 }); | 531 }); |
472 | 532 |
473 test('should support iteration over all {key, Iterable<value>} pairs', () { | 533 test('should support iteration over all {key, Iterable<value>} pairs', () { |
474 Map map = new Map(); | 534 Map map = new Map(); |
475 var mmap = new ListMultimap<String, String>() | 535 var mmap = new ListMultimap<String, String>() |
476 ..add('k1', 'v1') | 536 ..add('k1', 'v1') |
477 ..add('k1', 'v2') | 537 ..add('k1', 'v2') |
478 ..add('k2', 'v3') | 538 ..add('k2', 'v3') |
479 ..forEachKey((k, v) => map[k] = v); | 539 ..forEachKey((k, v) => map[k] = v); |
480 expect(map.length, mmap.length); | 540 expect(map.length, mmap.length); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 | 572 |
513 test('should not be empty after adding', () { | 573 test('should not be empty after adding', () { |
514 var map = new SetMultimap<String, String>()..add('k', 'v'); | 574 var map = new SetMultimap<String, String>()..add('k', 'v'); |
515 expect(map.isEmpty, false); | 575 expect(map.isEmpty, false); |
516 expect(map.isNotEmpty, true); | 576 expect(map.isNotEmpty, true); |
517 }); | 577 }); |
518 | 578 |
519 test('should return the number of keys as length', () { | 579 test('should return the number of keys as length', () { |
520 var map = new SetMultimap<String, String>(); | 580 var map = new SetMultimap<String, String>(); |
521 expect(map.length, 0); | 581 expect(map.length, 0); |
522 map | 582 map..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); |
523 ..add('k1', 'v1') | |
524 ..add('k1', 'v2') | |
525 ..add('k2', 'v3'); | |
526 expect(map.length, 2); | 583 expect(map.length, 2); |
527 }); | 584 }); |
528 | 585 |
529 test('should return an empty iterable for unmapped keys', () { | 586 test('should return an empty iterable for unmapped keys', () { |
530 var map = new SetMultimap<String, String>(); | 587 var map = new SetMultimap<String, String>(); |
531 expect(map['k1'], []); | 588 expect(map['k1'], []); |
532 }); | 589 }); |
533 | 590 |
534 test('should support adding values for unmapped keys', () { | 591 test('should support adding values for unmapped keys', () { |
535 var map = new SetMultimap<String, String>()..['k1'].add('v1'); | 592 var map = new SetMultimap<String, String>()..['k1'].add('v1'); |
(...skipping 23 matching lines...) Expand all Loading... |
559 expect(values2, unorderedEquals(['v1', 'v2'])); | 616 expect(values2, unorderedEquals(['v1', 'v2'])); |
560 }); | 617 }); |
561 | 618 |
562 test('should not support adding duplicate values for a key', () { | 619 test('should not support adding duplicate values for a key', () { |
563 var map = new SetMultimap<String, String>() | 620 var map = new SetMultimap<String, String>() |
564 ..add('k', 'v1') | 621 ..add('k', 'v1') |
565 ..add('k', 'v1'); | 622 ..add('k', 'v1'); |
566 expect(map['k'], ['v1']); | 623 expect(map['k'], ['v1']); |
567 }); | 624 }); |
568 | 625 |
| 626 test( |
| 627 'should not support adding duplicate values for a key when ' |
| 628 'initialized from an iterable', () { |
| 629 var map = new SetMultimap<String, String>.fromIterable(['k', 'k'], |
| 630 value: (x) => 'v1'); |
| 631 expect(map['k'], ['v1']); |
| 632 }); |
| 633 |
569 test('should support adding multiple keys', () { | 634 test('should support adding multiple keys', () { |
570 var map = new SetMultimap<String, String>() | 635 var map = new SetMultimap<String, String>() |
571 ..add('k1', 'v1') | 636 ..add('k1', 'v1') |
572 ..add('k1', 'v2') | 637 ..add('k1', 'v2') |
573 ..add('k2', 'v3'); | 638 ..add('k2', 'v3'); |
574 expect(map['k1'], unorderedEquals(['v1', 'v2'])); | 639 expect(map['k1'], unorderedEquals(['v1', 'v2'])); |
575 expect(map['k2'], ['v3']); | 640 expect(map['k2'], ['v3']); |
576 }); | 641 }); |
577 | 642 |
578 test('should support adding multiple values at once', () { | 643 test('should support adding multiple values at once', () { |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 expect(map.containsKey('k2'), true); | 748 expect(map.containsKey('k2'), true); |
684 }); | 749 }); |
685 | 750 |
686 test('should remove a key when all associated values are removed', () { | 751 test('should remove a key when all associated values are removed', () { |
687 var map = new SetMultimap<String, String>() | 752 var map = new SetMultimap<String, String>() |
688 ..add('k1', 'v1') | 753 ..add('k1', 'v1') |
689 ..remove('k1', 'v1'); | 754 ..remove('k1', 'v1'); |
690 expect(map.containsKey('k1'), false); | 755 expect(map.containsKey('k1'), false); |
691 }); | 756 }); |
692 | 757 |
693 test('should remove a key when all associated values are removed ' | 758 test( |
| 759 'should remove a key when all associated values are removed ' |
694 'via the underlying iterable.remove', () { | 760 'via the underlying iterable.remove', () { |
695 var map = new SetMultimap<String, String>()..add('k1', 'v1'); | 761 var map = new SetMultimap<String, String>()..add('k1', 'v1'); |
696 map['k1'].remove('v1'); | 762 map['k1'].remove('v1'); |
697 expect(map.containsKey('k1'), false); | 763 expect(map.containsKey('k1'), false); |
698 }); | 764 }); |
699 | 765 |
700 test('should remove a key when all associated values are removed ' | 766 test( |
| 767 'should remove a key when all associated values are removed ' |
701 'via the underlying iterable.removeAll', () { | 768 'via the underlying iterable.removeAll', () { |
702 var map = new SetMultimap<String, String>() | 769 var map = new SetMultimap<String, String>() |
703 ..add('k1', 'v1') | 770 ..add('k1', 'v1') |
704 ..add('k1', 'v2'); | 771 ..add('k1', 'v2'); |
705 map['k1'].removeAll(['v1', 'v2']); | 772 map['k1'].removeAll(['v1', 'v2']); |
706 expect(map.containsKey('k1'), false); | 773 expect(map.containsKey('k1'), false); |
707 }); | 774 }); |
708 | 775 |
709 test('should remove a key when all associated values are removed ' | 776 test( |
| 777 'should remove a key when all associated values are removed ' |
710 'via the underlying iterable.removeWhere', () { | 778 'via the underlying iterable.removeWhere', () { |
711 var map = new SetMultimap<String, String>()..add('k1', 'v1'); | 779 var map = new SetMultimap<String, String>()..add('k1', 'v1'); |
712 map['k1'].removeWhere((_) => true); | 780 map['k1'].removeWhere((_) => true); |
713 expect(map.containsKey('k1'), false); | 781 expect(map.containsKey('k1'), false); |
714 }); | 782 }); |
715 | 783 |
716 test('should remove a key when all associated values are removed ' | 784 test( |
| 785 'should remove a key when all associated values are removed ' |
717 'via the underlying iterable.retainAll', () { | 786 'via the underlying iterable.retainAll', () { |
718 var map = new SetMultimap<String, String>()..add('k1', 'v1'); | 787 var map = new SetMultimap<String, String>()..add('k1', 'v1'); |
719 map['k1'].retainAll([]); | 788 map['k1'].retainAll([]); |
720 expect(map.containsKey('k1'), false); | 789 expect(map.containsKey('k1'), false); |
721 }); | 790 }); |
722 | 791 |
723 test('should remove a key when all associated values are removed ' | 792 test( |
| 793 'should remove a key when all associated values are removed ' |
724 'via the underlying iterable.retainWhere', () { | 794 'via the underlying iterable.retainWhere', () { |
725 var map = new SetMultimap<String, String>()..add('k1', 'v1'); | 795 var map = new SetMultimap<String, String>()..add('k1', 'v1'); |
726 map['k1'].retainWhere((_) => false); | 796 map['k1'].retainWhere((_) => false); |
727 expect(map.containsKey('k1'), false); | 797 expect(map.containsKey('k1'), false); |
728 }); | 798 }); |
729 | 799 |
730 test('should remove a key when all associated values are removed ' | 800 test( |
| 801 'should remove a key when all associated values are removed ' |
731 'via the underlying iterable.clear', () { | 802 'via the underlying iterable.clear', () { |
732 var map = new SetMultimap<String, String>()..add('k1', 'v1'); | 803 var map = new SetMultimap<String, String>()..add('k1', 'v1'); |
733 map['k1'].clear(); | 804 map['k1'].clear(); |
734 expect(map.containsKey('k1'), false); | 805 expect(map.containsKey('k1'), false); |
735 }); | 806 }); |
736 | 807 |
737 test('should remove all values for a key', () { | 808 test('should remove all values for a key', () { |
738 var map = new SetMultimap<String, String>() | 809 var map = new SetMultimap<String, String>() |
739 ..add('k1', 'v1') | 810 ..add('k1', 'v1') |
740 ..add('k1', 'v2') | 811 ..add('k1', 'v2') |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 expect(mmap.isEmpty, true); | 929 expect(mmap.isEmpty, true); |
859 }); | 930 }); |
860 | 931 |
861 test('should support iteration over all {key, value} pairs', () { | 932 test('should support iteration over all {key, value} pairs', () { |
862 Set s = new Set(); | 933 Set s = new Set(); |
863 new SetMultimap<String, String>() | 934 new SetMultimap<String, String>() |
864 ..add('k1', 'v1') | 935 ..add('k1', 'v1') |
865 ..add('k1', 'v2') | 936 ..add('k1', 'v2') |
866 ..add('k2', 'v3') | 937 ..add('k2', 'v3') |
867 ..forEach((k, v) => s.add(new Pair(k, v))); | 938 ..forEach((k, v) => s.add(new Pair(k, v))); |
868 expect(s, unorderedEquals( | 939 expect( |
869 [new Pair('k1', 'v1'), new Pair('k1', 'v2'), new Pair('k2', 'v3')])); | 940 s, |
| 941 unorderedEquals([ |
| 942 new Pair('k1', 'v1'), |
| 943 new Pair('k1', 'v2'), |
| 944 new Pair('k2', 'v3') |
| 945 ])); |
870 }); | 946 }); |
871 | 947 |
872 test('should support iteration over all {key, Iterable<value>} pairs', () { | 948 test('should support iteration over all {key, Iterable<value>} pairs', () { |
873 Map map = new Map(); | 949 Map map = new Map(); |
874 var mmap = new SetMultimap<String, String>() | 950 var mmap = new SetMultimap<String, String>() |
875 ..add('k1', 'v1') | 951 ..add('k1', 'v1') |
876 ..add('k1', 'v2') | 952 ..add('k1', 'v2') |
877 ..add('k2', 'v3') | 953 ..add('k2', 'v3') |
878 ..forEachKey((k, v) => map[k] = v); | 954 ..forEachKey((k, v) => map[k] = v); |
879 expect(map.length, mmap.length); | 955 expect(map.length, mmap.length); |
880 expect(map['k1'], unorderedEquals(['v1', 'v2'])); | 956 expect(map['k1'], unorderedEquals(['v1', 'v2'])); |
881 expect(map['k2'], unorderedEquals(['v3'])); | 957 expect(map['k2'], unorderedEquals(['v3'])); |
882 }); | 958 }); |
883 | 959 |
884 test('should support operations on empty map views without breaking ' | 960 test( |
885 'delegate synchronization', () { | 961 'should support operations on empty map views without breaking ' |
| 962 'delegate synchronization', () { |
886 var mmap = new SetMultimap<String, String>(); | 963 var mmap = new SetMultimap<String, String>(); |
887 Set x = mmap['k1']; | 964 Set x = mmap['k1']; |
888 Set y = mmap['k1']; | 965 Set y = mmap['k1']; |
889 mmap['k1'].add('v0'); | 966 mmap['k1'].add('v0'); |
890 x.add('v1'); | 967 x.add('v1'); |
891 y.addAll(['v2', 'v3']); | 968 y.addAll(['v2', 'v3']); |
892 expect(mmap['k1'], unorderedEquals(['v0', 'v1', 'v2', 'v3'])); | 969 expect(mmap['k1'], unorderedEquals(['v0', 'v1', 'v2', 'v3'])); |
893 }); | 970 }); |
894 }); | 971 }); |
895 } | 972 } |
896 | 973 |
897 class Pair { | 974 class Pair { |
898 final x; | 975 final x; |
899 final y; | 976 final y; |
900 Pair(this.x, this.y); | 977 Pair(this.x, this.y); |
901 bool operator ==(Pair other) { | 978 bool operator ==(other) { |
902 if (x != other.x) return false; | 979 if (x != other.x) return false; |
903 return equals(y).matches(other.y, {}); | 980 return equals(y).matches(other.y, {}); |
904 } | 981 } |
| 982 |
905 String toString() => "($x, $y)"; | 983 String toString() => "($x, $y)"; |
906 } | 984 } |
OLD | NEW |