| 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 |