OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 // Tests of hash set behavior, with focus in iteration and concurrent | 5 // Tests of hash set behavior, with focus in iteration and concurrent |
6 // modification errors. | 6 // modification errors. |
7 | 7 |
8 library hash_map2_test; | 8 library hash_map2_test; |
9 import "package:expect/expect.dart"; | 9 import "package:expect/expect.dart"; |
10 import 'dart:collection'; | 10 import 'dart:collection'; |
11 | 11 |
12 testSet(Set newSet(), Set newSetFrom(Set from)) { | 12 testSet(Set newSet(), Set newSetFrom(Iterable from)) { |
13 | 13 |
14 Set gen(int from, int to) => | 14 Set gen(int from, int to) => |
15 new Set.from(new Iterable.generate(to - from, (n) => n + from)); | 15 new Set.from(new Iterable.generate(to - from, (n) => n + from)); |
16 | 16 |
17 bool odd(int n) => (n & 1) == 1; | 17 bool odd(int n) => (n & 1) == 1; |
18 bool even(int n) => (n & 1) == 0; | 18 bool even(int n) => (n & 1) == 0; |
19 | 19 |
20 { // Test growing to largish capacity. | 20 { // Test growing to largish capacity. |
21 Set set = newSet(); | 21 Set set = newSet(); |
22 | 22 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 Expect.isFalse(set.contains(2)); | 213 Expect.isFalse(set.contains(2)); |
214 Expect.isTrue(set.contains(3)); | 214 Expect.isTrue(set.contains(3)); |
215 set.retainWhere((each) => each == 3); | 215 set.retainWhere((each) => each == 3); |
216 Expect.equals(1, set.length); | 216 Expect.equals(1, set.length); |
217 Expect.isFalse(set.contains(1)); | 217 Expect.isFalse(set.contains(1)); |
218 Expect.isFalse(set.contains(2)); | 218 Expect.isFalse(set.contains(2)); |
219 Expect.isTrue(set.contains(3)); | 219 Expect.isTrue(set.contains(3)); |
220 } | 220 } |
221 } | 221 } |
222 | 222 |
223 void main() { | 223 |
224 testSet(() => new HashSet(), (m) => new HashSet.from(m)); | 224 void testIdentitySet(Set create()) { |
225 testSet(() => new LinkedHashSet(), (m) => new LinkedHashSet.from(m)); | 225 Set set = create(); |
| 226 set.add(1); |
| 227 set.add(2); |
| 228 set.add(1); // Integers are identical if equal. |
| 229 Expect.equals(2, set.length); |
| 230 var complex = 4; |
| 231 complex = set.length == 2 ? complex ~/ 4 : 87; // Avoid compile-time constant
. |
| 232 Expect.isTrue(set.contains(complex)); // 1 is in set, even if computed. |
| 233 set.clear(); |
| 234 |
| 235 // All compile time constants are identical to themselves. |
| 236 var constants = [double.INFINITY, |
| 237 double.NAN, -0.0, /// 01: ok |
| 238 0.0, 42, "", null, false, true, #bif, testIdentitySet]; |
| 239 set.addAll(constants); |
| 240 Expect.equals(constants.length, set.length); |
| 241 for (var c in constants) { |
| 242 Expect.isTrue(set.contains(c), "constant: $c"); |
| 243 } |
| 244 Expect.isTrue(set.containsAll(constants), "constants: $set"); |
| 245 set.clear(); |
| 246 |
| 247 var m1 = new Mutable(1); |
| 248 var m2 = new Mutable(2); |
| 249 var m3 = new Mutable(3); |
| 250 var m4 = new Mutable(2); // Equal to m2, but not identical. |
| 251 set.addAll([m1, m2, m3, m4]); |
| 252 Expect.equals(4, set.length); |
| 253 Expect.equals(3, m3.hashCode); |
| 254 m3.id = 1; |
| 255 Expect.equals(1, m3.hashCode); |
| 256 // Changing hashCode doesn't affect lookup. |
| 257 Expect.isTrue(set.contains(m3)); |
| 258 Expect.isTrue(set.contains(m1)); |
| 259 set.remove(m3); |
| 260 Expect.isFalse(set.contains(m3)); |
| 261 Expect.isTrue(set.contains(m1)); |
226 } | 262 } |
227 | 263 |
228 | 264 |
| 265 void main() { |
| 266 testSet(() => new Set(), (m) => new Set.from(m)); |
| 267 testSet(() => new HashSet(), (m) => new HashSet.from(m)); |
| 268 testSet(() => new LinkedHashSet(), (m) => new LinkedHashSet.from(m)); |
| 269 testIdentitySet(() => new Set.identity()); |
| 270 testIdentitySet(() => new HashSet.identity()); |
| 271 testIdentitySet(() => new LinkedHashSet.identity()); |
| 272 testIdentitySet(() => new HashSet(equals: (x, y) => identical(x, y), |
| 273 hashCode: (x) => identityHashCode(x))); |
| 274 testIdentitySet( |
| 275 () => new LinkedHashSet(equals: (x, y) => identical(x, y), |
| 276 hashCode: (x) => identityHashCode(x))); |
| 277 } |
| 278 |
| 279 |
229 class BadHashCode { | 280 class BadHashCode { |
230 static int idCounter = 0; | 281 static int idCounter = 0; |
231 final int id; | 282 final int id; |
232 BadHashCode() : id = idCounter++; | 283 BadHashCode() : id = idCounter++; |
233 int get hashCode => 42; | 284 int get hashCode => 42; |
234 // operator == is identity. | 285 // operator == is identity. |
235 // Can't make a bad compareTo that isn't invalid. | 286 // Can't make a bad compareTo that isn't invalid. |
236 int compareTo(BadHashCode other) => id - other.id; | 287 int compareTo(BadHashCode other) => id - other.id; |
237 } | 288 } |
| 289 |
| 290 class Mutable { |
| 291 int id; |
| 292 Mutable(this.id); |
| 293 int get hashCode => id; |
| 294 bool operator==(other) => other is Mutable && id == other.id; |
| 295 } |
OLD | NEW |