Chromium Code Reviews

Side by Side Diff: packages/quiver/test/collection/multimap_test.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
(Empty)
1 // Copyright 2013 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (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
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 library quiver.collection.multimap_test;
16
17 import 'package:quiver/collection.dart';
18 import 'package:test/test.dart';
19
20 void main() {
21 group('Multimap', () {
22 test('should be a list-backed multimap', () {
23 var map = new Multimap();
24 expect(map is ListMultimap, true);
25 });
26 });
27
28 group('Multimap asMap() view', () {
29 var mmap;
30 var map;
31 setUp(() {
32 mmap = new Multimap()
33 ..add('k1', 'v1')
34 ..add('k1', 'v2')
35 ..add('k2', 'v3');
36 map = mmap.asMap();
37 });
38
39 test('operator[]= should throw UnsupportedError', () {
40 expect(() => map['k1'] = [1, 2, 3], throwsUnsupportedError);
41 });
42
43 test('containsKey() should return false for missing key', () {
44 expect(map.containsKey('k3'), isFalse);
45 });
46
47 test('containsKey() should return true for key in map', () {
48 expect(map.containsKey('k1'), isTrue);
49 });
50
51 test('containsValue() should return false for missing value', () {
52 expect(map.containsValue('k3'), isFalse);
53 });
54
55 test('containsValue() should return true for value in map', () {
56 expect(map.containsValue('v1'), isTrue);
57 });
58
59 test('forEach should iterate over all key-value pairs', () {
60 var results = [];
61 map.forEach((k, v) => results.add(new Pair(k, v)));
62 expect(results, unorderedEquals([
63 new Pair('k1', ['v1', 'v2']),
64 new Pair('k2', ['v3'])
65 ]));
66 });
67
68 test('isEmpty should return whether the map contains key-value pairs', () {
69 expect(map.isEmpty, isFalse);
70 expect(map.isNotEmpty, isTrue);
71 expect(new Multimap().asMap().isEmpty, isTrue);
72 expect(new Multimap().asMap().isNotEmpty, isFalse);
73 });
74
75 test('length should return the number of key-value pairs', () {
76 expect(new Multimap().asMap().length, equals(0));
77 expect(map.length, equals(2));
78 });
79
80 test('addAll(Map m) should throw UnsupportedError', () {
81 expect(() => map.addAll({'k1': [1, 2, 3]}), throwsUnsupportedError);
82 });
83
84 test('putIfAbsent() should throw UnsupportedError', () {
85 var map = new Multimap().asMap();
86 expect(() => map.putIfAbsent('k1', () => [1]), throwsUnsupportedError);
87 });
88 });
89
90 group('ListMultimap', () {
91 test('should initialize empty', () {
92 var map = new ListMultimap();
93 expect(map.isEmpty, true);
94 expect(map.isNotEmpty, false);
95 });
96
97 test('should not be empty after adding', () {
98 var map = new ListMultimap<String, String>()..add('k', 'v');
99 expect(map.isEmpty, false);
100 expect(map.isNotEmpty, true);
101 });
102
103 test('should return the number of keys as length', () {
104 var map = new ListMultimap<String, String>();
105 expect(map.length, 0);
106 map
107 ..add('k1', 'v1')
108 ..add('k1', 'v2')
109 ..add('k2', 'v3');
110 expect(map.length, 2);
111 });
112
113 test('should return an empty iterable for unmapped keys', () {
114 var map = new ListMultimap<String, String>();
115 expect(map['k1'], []);
116 });
117
118 test('should support adding values for unmapped keys', () {
119 var map = new ListMultimap<String, String>()..['k1'].add('v1');
120 expect(map['k1'], ['v1']);
121 });
122
123 test('should support adding multiple values for unmapped keys', () {
124 var map = new ListMultimap<String, String>()..['k1'].addAll(['v1', 'v2']);
125 expect(map['k1'], ['v1', 'v2']);
126 });
127
128 test('should support inserting values for unmapped keys', () {
129 var map = new ListMultimap<String, String>()..['k1'].insert(0, 'v1');
130 expect(map['k1'], ['v1']);
131 });
132
133 test('should support inserting multiple values for unmapped keys', () {
134 var map = new ListMultimap<String, String>()
135 ..['k1'].insertAll(0, ['v1', 'v2']);
136 expect(map['k1'], ['v1', 'v2']);
137 });
138
139 test('should support inserting multiple values for unmapped keys', () {
140 var map = new ListMultimap<String, String>()..['k1'].length = 2;
141 expect(map['k1'], [null, null]);
142 });
143
144 test('should return unmapped iterables that stay in sync on add', () {
145 var map = new ListMultimap<String, String>();
146 List values1 = map['k1'];
147 List values2 = map['k1'];
148 values1.add('v1');
149 expect(map['k1'], ['v1']);
150 expect(values2, ['v1']);
151 });
152
153 test('should return unmapped iterables that stay in sync on addAll', () {
154 var map = new ListMultimap<String, String>();
155 List values1 = map['k1'];
156 List values2 = map['k1'];
157 values1.addAll(['v1', 'v2']);
158 expect(map['k1'], ['v1', 'v2']);
159 expect(values2, ['v1', 'v2']);
160 });
161
162 test('should support adding duplicate values for a key', () {
163 var map = new ListMultimap<String, String>()
164 ..add('k', 'v1')
165 ..add('k', 'v1');
166 expect(map['k'], ['v1', 'v1']);
167 });
168
169 test('should support adding multiple keys', () {
170 var map = new ListMultimap<String, String>()
171 ..add('k1', 'v1')
172 ..add('k1', 'v2')
173 ..add('k2', 'v3');
174 expect(map['k1'], ['v1', 'v2']);
175 expect(map['k2'], ['v3']);
176 });
177
178 test('should support adding multiple values at once', () {
179 var map = new ListMultimap<String, String>()
180 ..addValues('k1', ['v1', 'v2']);
181 expect(map['k1'], ['v1', 'v2']);
182 });
183
184 test('should support adding multiple values at once for existing keys', () {
185 var map = new ListMultimap<String, String>()
186 ..add('k1', 'v1')
187 ..addValues('k1', ['v1', 'v2']);
188 expect(map['k1'], ['v1', 'v1', 'v2']);
189 });
190
191 test('should support adding from another multimap', () {
192 var from = new ListMultimap<String, String>()
193 ..addValues('k1', ['v1', 'v2'])
194 ..add('k2', 'v3');
195 var map = new ListMultimap<String, String>()..addAll(from);
196 expect(map['k1'], ['v1', 'v2']);
197 expect(map['k2'], ['v3']);
198 });
199
200 test('should support adding from another multimap with existing keys', () {
201 var from = new ListMultimap<String, String>()
202 ..addValues('k1', ['v1', 'v2'])
203 ..add('k2', 'v3');
204 var map = new ListMultimap<String, String>()
205 ..add('k1', 'v0')
206 ..add('k2', 'v3')
207 ..addAll(from);
208 expect(map['k1'], ['v0', 'v1', 'v2']);
209 expect(map['k2'], ['v3', 'v3']);
210 });
211
212 test('should return its keys', () {
213 var map = new ListMultimap<String, String>()
214 ..add('k1', 'v1')
215 ..add('k1', 'v2')
216 ..add('k2', 'v3');
217 expect(map.keys, unorderedEquals(['k1', 'k2']));
218 });
219
220 test('should return its values', () {
221 var map = new ListMultimap<String, String>()
222 ..add('k1', 'v1')
223 ..add('k1', 'v2')
224 ..add('k2', 'v3');
225 expect(map.values, unorderedEquals(['v1', 'v2', 'v3']));
226 });
227
228 test('should support duplicate values', () {
229 var map = new ListMultimap<String, String>()
230 ..add('k1', 'v1')
231 ..add('k1', 'v2')
232 ..add('k2', 'v1');
233 expect(map.values, unorderedEquals(['v1', 'v2', 'v1']));
234 });
235
236 test('should return an ordered list of values', () {
237 var map = new ListMultimap<String, String>()
238 ..add('k', 'v1')
239 ..add('k', 'v2');
240 expect(map['k'], ['v1', 'v2']);
241 });
242
243 test('should reflect changes to underlying list', () {
244 var map = new ListMultimap<String, String>()
245 ..add('k', 'v1')
246 ..add('k', 'v2');
247 map['k'].add('v3');
248 map['k'].remove('v2');
249 expect(map['k'], ['v1', 'v3']);
250 });
251
252 test('should return whether it contains a key', () {
253 var map = new ListMultimap<String, String>()
254 ..add('k', 'v1')
255 ..add('k', 'v2');
256 expect(map.containsKey('j'), false);
257 expect(map.containsKey('k'), true);
258 });
259
260 test('should return whether it contains a value', () {
261 var map = new ListMultimap<String, String>()
262 ..add('k', 'v1')
263 ..add('k', 'v2');
264 expect(map.containsValue('v0'), false);
265 expect(map.containsValue('v1'), true);
266 });
267
268 test('should remove specified key-value associations', () {
269 var map = new ListMultimap<String, String>()
270 ..add('k1', 'v1')
271 ..add('k1', 'v2')
272 ..add('k2', 'v3');
273 expect(map.remove('k1', 'v0'), false);
274 expect(map.remove('k1', 'v1'), true);
275 expect(map['k1'], ['v2']);
276 expect(map.containsKey('k2'), true);
277 });
278
279 test('should remove a key when all associated values are removed', () {
280 var map = new ListMultimap<String, String>()
281 ..add('k1', 'v1')
282 ..remove('k1', 'v1');
283 expect(map.containsKey('k1'), false);
284 });
285
286 test('should remove a key when all associated values are removed '
287 'via the underlying iterable.remove', () {
288 var map = new ListMultimap<String, String>()..add('k1', 'v1');
289 map['k1'].remove('v1');
290 expect(map.containsKey('k1'), false);
291 });
292
293 test('should remove a key when all associated values are removed '
294 'via the underlying iterable.removeAt', () {
295 var map = new ListMultimap<String, String>()..add('k1', 'v1');
296 map['k1'].removeAt(0);
297 expect(map.containsKey('k1'), false);
298 });
299
300 test('should remove a key when all associated values are removed '
301 'via the underlying iterable.removeAt', () {
302 var map = new ListMultimap<String, String>()..add('k1', 'v1');
303 map['k1'].removeLast();
304 expect(map.containsKey('k1'), false);
305 });
306
307 test('should remove a key when all associated values are removed '
308 'via the underlying iterable.removeRange', () {
309 var map = new ListMultimap<String, String>()..add('k1', 'v1');
310 map['k1'].removeRange(0, 1);
311 expect(map.containsKey('k1'), false);
312 });
313
314 test('should remove a key when all associated values are removed '
315 'via the underlying iterable.removeWhere', () {
316 var map = new ListMultimap<String, String>()..add('k1', 'v1');
317 map['k1'].removeWhere((_) => true);
318 expect(map.containsKey('k1'), false);
319 });
320
321 test('should remove a key when all associated values are removed '
322 'via the underlying iterable.replaceRange', () {
323 var map = new ListMultimap<String, String>()..add('k1', 'v1');
324 map['k1'].replaceRange(0, 1, []);
325 expect(map.containsKey('k1'), false);
326 });
327
328 test('should remove a key when all associated values are removed '
329 'via the underlying iterable.retainWhere', () {
330 var map = new ListMultimap<String, String>()..add('k1', 'v1');
331 map['k1'].retainWhere((_) => false);
332 expect(map.containsKey('k1'), false);
333 });
334
335 test('should remove a key when all associated values are removed '
336 'via the underlying iterable.clear', () {
337 var map = new ListMultimap<String, String>()
338 ..add('k1', 'v1')
339 ..add('k1', 'v2');
340 map['k1'].clear();
341 expect(map.containsKey('k1'), false);
342 });
343
344 test('should remove all values for a key', () {
345 var map = new ListMultimap<String, String>()
346 ..add('k1', 'v1')
347 ..add('k1', 'v2')
348 ..add('k2', 'v3');
349 expect(map.removeAll('k1'), ['v1', 'v2']);
350 expect(map.containsKey('k1'), false);
351 expect(map.containsKey('k2'), true);
352 });
353
354 test('should clear underlying iterable on remove', () {
355 var map = new ListMultimap<String, String>()..add('k1', 'v1');
356 List values = map['k1'];
357 expect(map.removeAll('k1'), ['v1']);
358 expect(values, []);
359 });
360
361 test('should return an empty iterable on removeAll of unmapped key', () {
362 var map = new ListMultimap<String, String>();
363 var removed = map.removeAll('k1');
364 expect(removed, []);
365 });
366
367 test('should be uncoupled from the iterable returned by removeAll', () {
368 var map = new ListMultimap<String, String>()..add('k1', 'v1');
369 var removed = map.removeAll('k1');
370 removed.add('v2');
371 map.add('k1', 'v3');
372 expect(removed, ['v1', 'v2']);
373 expect(map['k1'], ['v3']);
374 });
375
376 test('should clear the map', () {
377 var map = new ListMultimap<String, String>()
378 ..add('k1', 'v1')
379 ..add('k1', 'v2')
380 ..add('k2', 'v3')
381 ..clear();
382 expect(map.isEmpty, true);
383 expect(map.containsKey('k1'), false);
384 expect(map.containsKey('k2'), false);
385 });
386
387 test('should clear underlying iterables on clear', () {
388 var map = new ListMultimap<String, String>()..add('k1', 'v1');
389 List values = map['k1'];
390 map.clear();
391 expect(values, []);
392 });
393
394 test('should not add mappings on lookup of unmapped keys', () {
395 var map = new ListMultimap<String, String>()..['k1'];
396 expect(map.containsKey('k1'), false);
397 });
398
399 test('should not remove mappings on clearing mapped values', () {
400 var map = new ListMultimap<String, String>()
401 ..add('k1', 'v1')
402 ..['v1'].clear();
403 expect(map.containsKey('k1'), true);
404 });
405
406 test('should return a map view', () {
407 var mmap = new ListMultimap<String, String>()
408 ..add('k1', 'v1')
409 ..add('k1', 'v2')
410 ..add('k2', 'v3');
411 Map map = mmap.asMap();
412 expect(map.keys, unorderedEquals(['k1', 'k2']));
413 expect(map.values, hasLength(2));
414 expect(map.values, anyElement(unorderedEquals(['v1', 'v2'])));
415 expect(map.values, anyElement(unorderedEquals(['v3'])));
416 expect(map['k1'], ['v1', 'v2']);
417 expect(map['k2'], ['v3']);
418 });
419
420 test('should return an empty iterable on map view unmapped key', () {
421 Map map = new ListMultimap<String, String>().asMap();
422 expect(map['k1'], []);
423 });
424
425 test('should allow addition via unmapped key lookup on map view', () {
426 var mmap = new ListMultimap<String, String>();
427 Map map = mmap.asMap();
428 map['k1'].add('v1');
429 map['k2'].addAll(['v1', 'v2']);
430 expect(mmap['k1'], ['v1']);
431 expect(mmap['k2'], ['v1', 'v2']);
432 });
433
434 test('should reflect additions to iterables returned by map view', () {
435 var mmap = new ListMultimap<String, String>()
436 ..add('k1', 'v1')
437 ..add('k1', 'v2');
438 Map map = mmap.asMap();
439 map['k1'].add('v3');
440 expect(mmap['k1'], ['v1', 'v2', 'v3']);
441 });
442
443 test('should reflect removals of keys in returned map view', () {
444 var mmap = new ListMultimap<String, String>()
445 ..add('k1', 'v1')
446 ..add('k1', 'v2');
447 Map map = mmap.asMap();
448 map.remove('k1');
449 expect(mmap.containsKey('k1'), false);
450 });
451
452 test('should reflect clearing of returned map view', () {
453 var mmap = new ListMultimap<String, String>()
454 ..add('k1', 'v1')
455 ..add('k1', 'v2')
456 ..add('k2', 'v3');
457 Map map = mmap.asMap();
458 map.clear();
459 expect(mmap.isEmpty, true);
460 });
461
462 test('should support iteration over all {key, value} pairs', () {
463 Set s = new Set();
464 new ListMultimap<String, String>()
465 ..add('k1', 'v1')
466 ..add('k1', 'v2')
467 ..add('k2', 'v3')
468 ..forEach((k, v) => s.add(new Pair(k, v)));
469 expect(s, unorderedEquals(
470 [new Pair('k1', 'v1'), new Pair('k1', 'v2'), new Pair('k2', 'v3')]));
471 });
472
473 test('should support iteration over all {key, Iterable<value>} pairs', () {
474 Map map = new Map();
475 var mmap = new ListMultimap<String, String>()
476 ..add('k1', 'v1')
477 ..add('k1', 'v2')
478 ..add('k2', 'v3')
479 ..forEachKey((k, v) => map[k] = v);
480 expect(map.length, mmap.length);
481 expect(map['k1'], ['v1', 'v2']);
482 expect(map['k2'], ['v3']);
483 });
484
485 test(
486 'should support operations on empty map views without breaking delegate synchronization',
487 () {
488 var mmap = new ListMultimap<String, String>();
489 List x = mmap['k1'];
490 List y = mmap['k1'];
491 List z = mmap['k1'];
492 List w = mmap['k1'];
493 mmap['k1'].add('v1');
494 expect(mmap['k1'], ['v1']);
495 x.add('v2');
496 expect(mmap['k1'], ['v1', 'v2']);
497 y.addAll(['v3', 'v4']);
498 expect(mmap['k1'], ['v1', 'v2', 'v3', 'v4']);
499 z.insert(0, 'v0');
500 expect(mmap['k1'], ['v0', 'v1', 'v2', 'v3', 'v4']);
501 w.insertAll(5, ['v5', 'v6']);
502 expect(mmap['k1'], ['v0', 'v1', 'v2', 'v3', 'v4', 'v5', 'v6']);
503 });
504 });
505
506 group('SetMultimap', () {
507 test('should initialize empty', () {
508 var map = new SetMultimap<String, String>();
509 expect(map.isEmpty, true);
510 expect(map.isNotEmpty, false);
511 });
512
513 test('should not be empty after adding', () {
514 var map = new SetMultimap<String, String>()..add('k', 'v');
515 expect(map.isEmpty, false);
516 expect(map.isNotEmpty, true);
517 });
518
519 test('should return the number of keys as length', () {
520 var map = new SetMultimap<String, String>();
521 expect(map.length, 0);
522 map
523 ..add('k1', 'v1')
524 ..add('k1', 'v2')
525 ..add('k2', 'v3');
526 expect(map.length, 2);
527 });
528
529 test('should return an empty iterable for unmapped keys', () {
530 var map = new SetMultimap<String, String>();
531 expect(map['k1'], []);
532 });
533
534 test('should support adding values for unmapped keys', () {
535 var map = new SetMultimap<String, String>()..['k1'].add('v1');
536 expect(map['k1'], ['v1']);
537 });
538
539 test('should support adding multiple values for unmapped keys', () {
540 var map = new SetMultimap<String, String>()..['k1'].addAll(['v1', 'v2']);
541 expect(map['k1'], unorderedEquals(['v1', 'v2']));
542 });
543
544 test('should return unmapped iterables that stay in sync on add', () {
545 var map = new SetMultimap<String, String>();
546 Set values1 = map['k1'];
547 Set values2 = map['k1'];
548 values1.add('v1');
549 expect(map['k1'], ['v1']);
550 expect(values2, ['v1']);
551 });
552
553 test('should return unmapped iterables that stay in sync on addAll', () {
554 var map = new SetMultimap<String, String>();
555 Set values1 = map['k1'];
556 Set values2 = map['k1'];
557 values1.addAll(['v1', 'v2']);
558 expect(map['k1'], unorderedEquals(['v1', 'v2']));
559 expect(values2, unorderedEquals(['v1', 'v2']));
560 });
561
562 test('should not support adding duplicate values for a key', () {
563 var map = new SetMultimap<String, String>()
564 ..add('k', 'v1')
565 ..add('k', 'v1');
566 expect(map['k'], ['v1']);
567 });
568
569 test('should support adding multiple keys', () {
570 var map = new SetMultimap<String, String>()
571 ..add('k1', 'v1')
572 ..add('k1', 'v2')
573 ..add('k2', 'v3');
574 expect(map['k1'], unorderedEquals(['v1', 'v2']));
575 expect(map['k2'], ['v3']);
576 });
577
578 test('should support adding multiple values at once', () {
579 var map = new SetMultimap<String, String>()
580 ..addValues('k1', ['v1', 'v2']);
581 expect(map['k1'], ['v1', 'v2']);
582 });
583
584 test('should support adding multiple values at once for existing keys', () {
585 var map = new SetMultimap<String, String>()
586 ..add('k1', 'v0')
587 ..addValues('k1', ['v1', 'v2']);
588 expect(map['k1'], unorderedEquals(['v0', 'v1', 'v2']));
589 });
590
591 test('should support adding multiple values for existing (key,value)', () {
592 var map = new SetMultimap<String, String>()
593 ..add('k1', 'v1')
594 ..addValues('k1', ['v1', 'v2']);
595 expect(map['k1'], unorderedEquals(['v1', 'v2']));
596 });
597
598 test('should support adding from another multimap', () {
599 var from = new SetMultimap<String, String>()
600 ..addValues('k1', ['v1', 'v2'])
601 ..add('k2', 'v3');
602 var map = new SetMultimap<String, String>()..addAll(from);
603 expect(map['k1'], unorderedEquals(['v1', 'v2']));
604 expect(map['k2'], ['v3']);
605 });
606
607 test('should support adding from another multimap with existing keys', () {
608 var from = new SetMultimap<String, String>()
609 ..addValues('k1', ['v1', 'v2'])
610 ..add('k2', 'v3');
611 var map = new SetMultimap<String, String>()
612 ..add('k1', 'v0')
613 ..add('k2', 'v3')
614 ..addAll(from);
615 expect(map['k1'], unorderedEquals(['v0', 'v1', 'v2']));
616 expect(map['k2'], ['v3']);
617 });
618
619 test('should return its keys', () {
620 var map = new SetMultimap<String, String>()
621 ..add('k1', 'v1')
622 ..add('k1', 'v2')
623 ..add('k2', 'v3');
624 expect(map.keys, unorderedEquals(['k1', 'k2']));
625 });
626
627 test('should return its values', () {
628 var map = new SetMultimap<String, String>()
629 ..add('k1', 'v1')
630 ..add('k1', 'v2')
631 ..add('k2', 'v3');
632 expect(map.values, unorderedEquals(['v1', 'v2', 'v3']));
633 });
634
635 test('should support duplicate values', () {
636 var map = new SetMultimap<String, String>()
637 ..add('k1', 'v1')
638 ..add('k1', 'v2')
639 ..add('k2', 'v1');
640 expect(map.values, unorderedEquals(['v1', 'v2', 'v1']));
641 });
642
643 test('should return an ordered list of values', () {
644 var map = new SetMultimap<String, String>()
645 ..add('k', 'v1')
646 ..add('k', 'v2');
647 expect(map['k'], unorderedEquals(['v1', 'v2']));
648 });
649
650 test('should reflect changes to underlying set', () {
651 var map = new SetMultimap<String, String>()
652 ..add('k', 'v1')
653 ..add('k', 'v2');
654 map['k'].add('v3');
655 map['k'].remove('v2');
656 expect(map['k'], unorderedEquals(['v1', 'v3']));
657 });
658
659 test('should return whether it contains a key', () {
660 var map = new SetMultimap<String, String>()
661 ..add('k', 'v1')
662 ..add('k', 'v2');
663 expect(map.containsKey('j'), false);
664 expect(map.containsKey('k'), true);
665 });
666
667 test('should return whether it contains a value', () {
668 var map = new SetMultimap<String, String>()
669 ..add('k', 'v1')
670 ..add('k', 'v2');
671 expect(map.containsValue('v0'), false);
672 expect(map.containsValue('v1'), true);
673 });
674
675 test('should remove specified key-value associations', () {
676 var map = new SetMultimap<String, String>()
677 ..add('k1', 'v1')
678 ..add('k1', 'v2')
679 ..add('k2', 'v3');
680 expect(map.remove('k1', 'v0'), false);
681 expect(map.remove('k1', 'v1'), true);
682 expect(map['k1'], ['v2']);
683 expect(map.containsKey('k2'), true);
684 });
685
686 test('should remove a key when all associated values are removed', () {
687 var map = new SetMultimap<String, String>()
688 ..add('k1', 'v1')
689 ..remove('k1', 'v1');
690 expect(map.containsKey('k1'), false);
691 });
692
693 test('should remove a key when all associated values are removed '
694 'via the underlying iterable.remove', () {
695 var map = new SetMultimap<String, String>()..add('k1', 'v1');
696 map['k1'].remove('v1');
697 expect(map.containsKey('k1'), false);
698 });
699
700 test('should remove a key when all associated values are removed '
701 'via the underlying iterable.removeAll', () {
702 var map = new SetMultimap<String, String>()
703 ..add('k1', 'v1')
704 ..add('k1', 'v2');
705 map['k1'].removeAll(['v1', 'v2']);
706 expect(map.containsKey('k1'), false);
707 });
708
709 test('should remove a key when all associated values are removed '
710 'via the underlying iterable.removeWhere', () {
711 var map = new SetMultimap<String, String>()..add('k1', 'v1');
712 map['k1'].removeWhere((_) => true);
713 expect(map.containsKey('k1'), false);
714 });
715
716 test('should remove a key when all associated values are removed '
717 'via the underlying iterable.retainAll', () {
718 var map = new SetMultimap<String, String>()..add('k1', 'v1');
719 map['k1'].retainAll([]);
720 expect(map.containsKey('k1'), false);
721 });
722
723 test('should remove a key when all associated values are removed '
724 'via the underlying iterable.retainWhere', () {
725 var map = new SetMultimap<String, String>()..add('k1', 'v1');
726 map['k1'].retainWhere((_) => false);
727 expect(map.containsKey('k1'), false);
728 });
729
730 test('should remove a key when all associated values are removed '
731 'via the underlying iterable.clear', () {
732 var map = new SetMultimap<String, String>()..add('k1', 'v1');
733 map['k1'].clear();
734 expect(map.containsKey('k1'), false);
735 });
736
737 test('should remove all values for a key', () {
738 var map = new SetMultimap<String, String>()
739 ..add('k1', 'v1')
740 ..add('k1', 'v2')
741 ..add('k2', 'v3');
742 expect(map.removeAll('k1'), unorderedEquals(['v1', 'v2']));
743 expect(map.containsKey('k1'), false);
744 expect(map.containsKey('k2'), true);
745 });
746
747 test('should clear underlying iterable on remove', () {
748 var map = new SetMultimap<String, String>()..add('k1', 'v1');
749 Set values = map['k1'];
750 expect(map.removeAll('k1'), ['v1']);
751 expect(values, []);
752 });
753
754 test('should return an empty iterable on removeAll of unmapped key', () {
755 var map = new SetMultimap<String, String>();
756 var removed = map.removeAll('k1');
757 expect(removed, []);
758 });
759
760 test('should be uncoupled from the iterable returned by removeAll', () {
761 var map = new SetMultimap<String, String>()..add('k1', 'v1');
762 var removed = map.removeAll('k1');
763 removed.add('v2');
764 map.add('k1', 'v3');
765 expect(removed, unorderedEquals(['v1', 'v2']));
766 expect(map['k1'], ['v3']);
767 });
768
769 test('should clear the map', () {
770 var map = new SetMultimap<String, String>()
771 ..add('k1', 'v1')
772 ..add('k1', 'v2')
773 ..add('k2', 'v3')
774 ..clear();
775 expect(map.isEmpty, true);
776 expect(map.containsKey('k1'), false);
777 expect(map.containsKey('k2'), false);
778 });
779
780 test('should clear underlying iterables on clear', () {
781 var map = new SetMultimap<String, String>()..add('k1', 'v1');
782 Set values = map['k1'];
783 map.clear();
784 expect(values, []);
785 });
786
787 test('should not add mappings on lookup of unmapped keys', () {
788 var map = new SetMultimap<String, String>()..['k1'];
789 expect(map.containsKey('k1'), false);
790 });
791
792 test('should not remove mappings on clearing mapped values', () {
793 var map = new SetMultimap<String, String>()
794 ..add('k1', 'v1')
795 ..['v1'].clear();
796 expect(map.containsKey('k1'), true);
797 });
798
799 test('should return a map view', () {
800 var mmap = new SetMultimap<String, String>()
801 ..add('k1', 'v1')
802 ..add('k1', 'v2')
803 ..add('k2', 'v3');
804 Map map = mmap.asMap();
805 expect(map.keys, unorderedEquals(['k1', 'k2']));
806 expect(map['k1'], ['v1', 'v2']);
807 expect(map['k2'], ['v3']);
808 });
809
810 test('should return an empty iterable on map view unmapped key', () {
811 Map map = new SetMultimap<String, String>().asMap();
812 expect(map['k1'], []);
813 });
814
815 test('should allow addition via unmapped key lookup on map view', () {
816 var mmap = new SetMultimap<String, String>();
817 Map map = mmap.asMap();
818 map['k1'].add('v1');
819 map['k2'].addAll(['v1', 'v2']);
820 expect(mmap['k1'], ['v1']);
821 expect(mmap['k2'], unorderedEquals(['v1', 'v2']));
822 });
823
824 test('should reflect additions to iterables returned by map view', () {
825 var mmap = new SetMultimap<String, String>()
826 ..add('k1', 'v1')
827 ..add('k1', 'v2');
828 Map map = mmap.asMap();
829 map['k1'].add('v3');
830 expect(mmap['k1'], unorderedEquals(['v1', 'v2', 'v3']));
831 });
832
833 test('should reflect additions to iterables returned by map view', () {
834 var mmap = new SetMultimap<String, String>()
835 ..add('k1', 'v1')
836 ..add('k1', 'v2');
837 Map map = mmap.asMap();
838 map['k1'].add('v3');
839 expect(mmap['k1'], unorderedEquals(['v1', 'v2', 'v3']));
840 });
841
842 test('should reflect removals of keys in returned map view', () {
843 var mmap = new SetMultimap<String, String>()
844 ..add('k1', 'v1')
845 ..add('k1', 'v2');
846 Map map = mmap.asMap();
847 map.remove('k1');
848 expect(mmap.containsKey('k1'), false);
849 });
850
851 test('should reflect clearing of returned map view', () {
852 var mmap = new SetMultimap<String, String>()
853 ..add('k1', 'v1')
854 ..add('k1', 'v2')
855 ..add('k2', 'v3');
856 Map map = mmap.asMap();
857 map.clear();
858 expect(mmap.isEmpty, true);
859 });
860
861 test('should support iteration over all {key, value} pairs', () {
862 Set s = new Set();
863 new SetMultimap<String, String>()
864 ..add('k1', 'v1')
865 ..add('k1', 'v2')
866 ..add('k2', 'v3')
867 ..forEach((k, v) => s.add(new Pair(k, v)));
868 expect(s, unorderedEquals(
869 [new Pair('k1', 'v1'), new Pair('k1', 'v2'), new Pair('k2', 'v3')]));
870 });
871
872 test('should support iteration over all {key, Iterable<value>} pairs', () {
873 Map map = new Map();
874 var mmap = new SetMultimap<String, String>()
875 ..add('k1', 'v1')
876 ..add('k1', 'v2')
877 ..add('k2', 'v3')
878 ..forEachKey((k, v) => map[k] = v);
879 expect(map.length, mmap.length);
880 expect(map['k1'], unorderedEquals(['v1', 'v2']));
881 expect(map['k2'], unorderedEquals(['v3']));
882 });
883
884 test('should support operations on empty map views without breaking '
885 'delegate synchronization', () {
886 var mmap = new SetMultimap<String, String>();
887 Set x = mmap['k1'];
888 Set y = mmap['k1'];
889 mmap['k1'].add('v0');
890 x.add('v1');
891 y.addAll(['v2', 'v3']);
892 expect(mmap['k1'], unorderedEquals(['v0', 'v1', 'v2', 'v3']));
893 });
894 });
895 }
896
897 class Pair {
898 final x;
899 final y;
900 Pair(this.x, this.y);
901 bool operator ==(Pair other) {
902 if (x != other.x) return false;
903 return equals(y).matches(other.y, {});
904 }
905 String toString() => "($x, $y)";
906 }
OLDNEW
« no previous file with comments | « packages/quiver/test/collection/lru_map_test.dart ('k') | packages/quiver/test/collection/treeset_test.dart » ('j') | no next file with comments »

Powered by Google App Engine