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 set_test; | 5 library set_test; |
6 | 6 |
7 | 7 |
8 import 'package:expect/expect.dart'; | 8 import 'package:expect/expect.dart'; |
9 import "dart:collection"; | 9 import "dart:collection"; |
10 | 10 |
11 void testMain(Set create()) { | 11 void testMain(Set create()) { |
| 12 testInts(create); |
| 13 testStrings(create); |
| 14 } |
| 15 |
| 16 void testInts(Set create()) { |
12 Set set = create(); | 17 Set set = create(); |
| 18 |
13 testLength(0, set); | 19 testLength(0, set); |
14 set.add(1); | 20 set.add(1); |
15 testLength(1, set); | 21 testLength(1, set); |
16 Expect.isTrue(set.contains(1)); | 22 Expect.isTrue(set.contains(1)); |
17 | 23 |
18 set.add(1); | 24 set.add(1); |
19 testLength(1, set); | 25 testLength(1, set); |
20 Expect.isTrue(set.contains(1)); | 26 Expect.isTrue(set.contains(1)); |
21 | 27 |
22 set.remove(1); | 28 set.remove(1); |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 set.clear(); | 185 set.clear(); |
180 testLength(0, set); | 186 testLength(0, set); |
181 set.add(11); | 187 set.add(11); |
182 testLength(1, set); | 188 testLength(1, set); |
183 } | 189 } |
184 | 190 |
185 void testLength(int length, Set set) { | 191 void testLength(int length, Set set) { |
186 Expect.equals(length, set.length); | 192 Expect.equals(length, set.length); |
187 (length == 0 ? Expect.isTrue : Expect.isFalse)(set.isEmpty); | 193 (length == 0 ? Expect.isTrue : Expect.isFalse)(set.isEmpty); |
188 (length != 0 ? Expect.isTrue : Expect.isFalse)(set.isNotEmpty); | 194 (length != 0 ? Expect.isTrue : Expect.isFalse)(set.isNotEmpty); |
| 195 if (length == 0) { |
| 196 for (var e in set) { Expect.fail("contains element when iterated: $e"); } |
| 197 } |
| 198 (length == 0 ? Expect.isFalse : Expect.isTrue)(set.iterator.moveNext()); |
189 } | 199 } |
190 | 200 |
| 201 void testStrings(Set create()) { |
| 202 var set = create(); |
| 203 var strings = ["foo", "bar", "baz", "qux", "fisk", "hest", "svin", "pigvar"]; |
| 204 set.addAll(strings); |
| 205 testLength(8, set); |
| 206 set.removeAll(strings.where((x) => x.length == 3)); |
| 207 testLength(4, set); |
| 208 set.add("bar"); |
| 209 set.add("qux"); |
| 210 testLength(6, set); |
| 211 set.addAll(strings); |
| 212 testLength(8, set); |
| 213 set.removeWhere((x) => x.length != 3); |
| 214 testLength(4, set); |
| 215 set.retainWhere((x) => x[1] == "a"); |
| 216 testLength(2, set); |
| 217 Expect.isTrue(set.containsAll(["baz", "bar"])); |
| 218 |
| 219 set = set.union(strings.where((x) => x.length != 3).toSet()); |
| 220 testLength(6, set); |
| 221 set = set.intersection(["qux", "baz", "fisk", "egern"].toSet()); |
| 222 testLength(2, set); |
| 223 Expect.isTrue(set.containsAll(["baz", "fisk"])); |
| 224 } |
| 225 |
| 226 void testTypeAnnotations(Set<int> set) { |
| 227 set.add(0); |
| 228 set.add(999); |
| 229 set.add(0x800000000); |
| 230 set.add(0x20000000000000); |
| 231 Expect.isFalse(set.contains("not an it")); |
| 232 Expect.isFalse(set.remove("not an it")); |
| 233 Expect.isFalse(set.containsAll(["Not an int", "Also no an int"])); |
| 234 |
| 235 testLength(4, set); |
| 236 set.removeAll(["Not an int", 999, "Also no an int"]); |
| 237 testLength(3, set); |
| 238 set.retainAll(["Not an int", 0, "Also no an int"]); |
| 239 testLength(1, set); |
| 240 } |
| 241 |
| 242 void testRetainWhere(Set create([equals, hashCode, validKey])) { |
| 243 // The retainWhere method must not collapse the argument Iterable |
| 244 // in a way that doesn't match the equality of the set. |
| 245 // It must not throw away equal elements that are different in the |
| 246 // equality of the set. |
| 247 // It must not consider objects to be not there if they are equal |
| 248 // in the equality of the set. |
| 249 |
| 250 // If set equality is natural equality, using different but equal objects |
| 251 // must work. Can't use an identity set internally (as was done at some point |
| 252 // during development). |
| 253 Set set = create(); |
| 254 set.addAll([new EO(0), new EO(1), new EO(2)]); |
| 255 Expect.equals(3, set.length); // All different. |
| 256 set.retainAll([new EO(0), new EO(2)]); |
| 257 Expect.equals(2, set.length); |
| 258 Expect.isTrue(set.contains(new EO(0))); |
| 259 Expect.isTrue(set.contains(new EO(2))); |
| 260 |
| 261 // If equality of set is identity, we can't internally use a non-identity |
| 262 // based set because it might throw away equal objects that are not identical. |
| 263 var elems = [new EO(0), new EO(1), new EO(2), new EO(0)]; |
| 264 set = create(identical); |
| 265 set.addAll(elems); |
| 266 Expect.equals(4, set.length); |
| 267 set.retainAll([elems[0], elems[2], elems[3]]); |
| 268 Expect.equals(3, set.length); |
| 269 Expect.isTrue(set.contains(elems[0])); |
| 270 Expect.isTrue(set.contains(elems[2])); |
| 271 Expect.isTrue(set.contains(elems[3])); |
| 272 |
| 273 // If set equality is less precise than equality, we must not use equality |
| 274 // internally to see if the element is there: |
| 275 set = create(customEq(3), customHash(3), validKey); |
| 276 set.addAll([new EO(0), new EO(1), new EO(2)]); |
| 277 Expect.equals(3, set.length); |
| 278 set.retainAll([new EO(3), new EO(5)]); |
| 279 Expect.equals(2, set.length); |
| 280 Expect.isTrue(set.contains(new EO(6))); |
| 281 Expect.isTrue(set.contains(new EO(8))); |
| 282 |
| 283 // It shouldn't matter if the input is a set. |
| 284 set.clear(); |
| 285 set.addAll([new EO(0), new EO(1), new EO(2)]); |
| 286 Expect.equals(3, set.length); |
| 287 set.retainAll(new Set.from([new EO(3), new EO(5)])); |
| 288 Expect.equals(2, set.length); |
| 289 Expect.isTrue(set.contains(new EO(6))); |
| 290 Expect.isTrue(set.contains(new EO(8))); |
| 291 } |
| 292 |
| 293 // Objects that are equal based on data. |
| 294 class EO { |
| 295 final int id; |
| 296 const EO(this.id); |
| 297 int get hashCode => id; |
| 298 bool operator==(Object other) => other is EO && id == (other as EO).id; |
| 299 } |
| 300 |
| 301 // Equality of Id objects based on id modulo value. |
| 302 Function customEq(int mod) => (EO e1, EO e2) => ((e1.id - e2.id) % mod) == 0; |
| 303 Function customHash(int mod) => (EO e) => e.id % mod; |
| 304 bool validKey(Object o) => o is EO; |
| 305 |
| 306 |
191 main() { | 307 main() { |
192 testMain(() => new Set()); | |
193 testMain(() => new HashSet()); | 308 testMain(() => new HashSet()); |
| 309 testMain(() => new LinkedHashSet()); |
| 310 testMain(() => new HashSet(equals: identical)); |
| 311 testMain(() => new LinkedHashSet(equals: identical)); |
| 312 testMain(() => new HashSet(equals: (a, b) => a == b, |
| 313 hashCode: (a) => -a.hashCode, |
| 314 isValidKey: (a) => true)); |
| 315 testMain(() => new LinkedHashSet( |
| 316 equals: (a, b) => a == b, |
| 317 hashCode: (a) => -a.hashCode, |
| 318 isValidKey: (a) => true)); |
| 319 |
| 320 testTypeAnnotations(new HashSet<int>()); |
| 321 testTypeAnnotations(new LinkedHashSet<int>()); |
| 322 testTypeAnnotations(new HashSet<int>(equals: identical)); |
| 323 testTypeAnnotations(new LinkedHashSet<int>(equals: identical)); |
| 324 testTypeAnnotations(new HashSet<int>(equals: (int a, int b) => a == b, |
| 325 hashCode: (int a) => a.hashCode, |
| 326 isValidKey: (a) => a is int)); |
| 327 testTypeAnnotations(new LinkedHashSet<int>(equals: (int a, int b) => a == b, |
| 328 hashCode: (int a) => a.hashCode, |
| 329 isValidKey: (a) => a is int)); |
| 330 |
| 331 testRetainWhere(([equals, hashCode, validKey]) => |
| 332 new HashSet(equals: equals, hashCode: hashCode, isValidKey: validKey)); |
| 333 testRetainWhere(([equals, hashCode, validKey]) => |
| 334 new LinkedHashSet(equals: equals, hashCode: hashCode, |
| 335 isValidKey: validKey)); |
194 } | 336 } |
OLD | NEW |