Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(381)

Side by Side Diff: tests/corelib_strong/hash_set_test.dart

Issue 3004073002: Remove corelib/corelib_strong and migrate last two remaining tests. (Closed)
Patch Set: Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4 //
5 // VMOptions=
6
7 // Tests of hash set behavior, with focus in iteration and concurrent
8 // modification errors.
9
10 library hash_map2_test;
11
12 import "package:expect/expect.dart";
13 import 'dart:collection';
14 import 'dart:math' as math;
15
16 testSet(Set newSet(), Set newSetFrom(Iterable from)) {
17 Set gen(int from, int to) =>
18 new Set.from(new Iterable.generate(to - from, (n) => n + from));
19
20 bool odd(int n) => (n & 1) == 1;
21 bool even(int n) => (n & 1) == 0;
22
23 {
24 // Test growing to largish capacity.
25 Set set = newSet();
26
27 for (int i = 0; i < 256; i++) {
28 set.add(i);
29 }
30
31 set.addAll(gen(256, 512));
32 set.addAll(newSetFrom(gen(512, 1000)));
33 Expect.equals(1000, set.length);
34
35 // Remove half.
36 for (int i = 0; i < 1000; i += 2) set.remove(i);
37 Expect.equals(500, set.length);
38 Expect.isFalse(set.any(even));
39 Expect.isTrue(set.every(odd));
40
41 // Re-add all.
42 set.addAll(gen(0, 1000));
43 Expect.equals(1000, set.length);
44 }
45
46 {
47 // Test having many deleted elements.
48 Set set = newSet();
49 set.add(0);
50 for (int i = 0; i < 1000; i++) {
51 set.add(i + 1);
52 set.remove(i);
53 Expect.equals(1, set.length);
54 }
55 }
56
57 {
58 // Test having many elements with same hashCode
59 Set set = newSet();
60 for (int i = 0; i < 1000; i++) {
61 set.add(new BadHashCode());
62 }
63 Expect.equals(1000, set.length);
64 }
65
66 {
67 // Check concurrent modification
68 Set set = newSet()..add(0)..add(1);
69
70 {
71 // Test adding before a moveNext.
72 Iterator iter = set.iterator;
73 iter.moveNext();
74 set.add(1); // Updating existing key isn't a modification.
75 iter.moveNext();
76 set.add(2);
77 Expect.throws(iter.moveNext, (e) => e is Error);
78 }
79
80 {
81 // Test adding after last element.
82 Iterator iter = set.iterator;
83 Expect.equals(3, set.length);
84 iter.moveNext();
85 iter.moveNext();
86 iter.moveNext();
87 set.add(3);
88 Expect.throws(iter.moveNext, (e) => e is Error);
89 }
90
91 {
92 // Test removing during iteration.
93 Iterator iter = set.iterator;
94 iter.moveNext();
95 set.remove(1000); // Not a modification if it's not there.
96 iter.moveNext();
97 int n = iter.current;
98 set.remove(n);
99 // Removing doesn't change current.
100 Expect.equals(n, iter.current);
101 Expect.throws(iter.moveNext, (e) => e is Error);
102 }
103
104 {
105 // Test removing after last element.
106 Iterator iter = set.iterator;
107 Expect.equals(3, set.length);
108 iter.moveNext();
109 iter.moveNext();
110 iter.moveNext();
111 int n = iter.current;
112 set.remove(n);
113 // Removing doesn't change current.
114 Expect.equals(n, iter.current);
115 Expect.throws(iter.moveNext, (e) => e is Error);
116 }
117
118 {
119 // Test that updating value doesn't cause error.
120 Iterator iter = set.iterator;
121 Expect.equals(2, set.length);
122 iter.moveNext();
123 int n = iter.current;
124 set.add(n);
125 iter.moveNext();
126 Expect.isTrue(set.contains(iter.current));
127 }
128
129 {
130 // Check adding many existing values isn't considered modification.
131 Set set2 = newSet();
132 for (var value in set) {
133 set2.add(value);
134 }
135 Iterator iter = set.iterator;
136 set.addAll(set2);
137 // Shouldn't throw.
138 iter.moveNext();
139 }
140 }
141
142 {
143 // Check that updating existing elements is not a modification.
144 // This must be the case even if the underlying data structure is
145 // nearly full.
146 for (int i = 1; i < 128; i++) {
147 // Create maps of different sizes, some of which should be
148 // at a limit of the underlying data structure.
149 Set set = newSetFrom(gen(0, i));
150 Iterator iter = set.iterator;
151 for (int j = 0; j < i; j++) {
152 set.add(j);
153 }
154 iter.moveNext(); // Should not throw.
155
156 for (int j = 1; j < i; j++) {
157 set.remove(j);
158 }
159 iter = set.iterator;
160 set.add(0);
161 iter.moveNext(); // Should not throw.
162 }
163 }
164
165 {
166 // Check that null can be in the set.
167 Set set = newSet();
168 set.add(null);
169 Expect.equals(1, set.length);
170 Expect.isTrue(set.contains(null));
171 Expect.isNull(set.first);
172 Expect.isNull(set.last);
173 set.add(null);
174 Expect.equals(1, set.length);
175 Expect.isTrue(set.contains(null));
176 set.remove(null);
177 Expect.isTrue(set.isEmpty);
178 Expect.isFalse(set.contains(null));
179
180 // Created using Set.from.
181 set = newSetFrom([null]);
182 Expect.equals(1, set.length);
183 Expect.isTrue(set.contains(null));
184 Expect.isNull(set.first);
185 Expect.isNull(set.last);
186 set.add(null);
187 Expect.equals(1, set.length);
188 Expect.isTrue(set.contains(null));
189 set.remove(null);
190 Expect.isTrue(set.isEmpty);
191 Expect.isFalse(set.contains(null));
192
193 // Set that grows with null in it.
194 set = newSetFrom([1, 2, 3, null, 4, 5, 6]);
195 Expect.equals(7, set.length);
196 for (int i = 7; i < 128; i++) {
197 set.add(i);
198 }
199 Expect.equals(128, set.length);
200 Expect.isTrue(set.contains(null));
201 set.add(null);
202 Expect.equals(128, set.length);
203 Expect.isTrue(set.contains(null));
204 set.remove(null);
205 Expect.equals(127, set.length);
206 Expect.isFalse(set.contains(null));
207 }
208
209 {
210 // Check that addAll and clear works.
211 Set set = newSet();
212 set.addAll([]);
213 Expect.isTrue(set.isEmpty);
214 set.addAll([1, 3, 2]);
215 Expect.equals(3, set.length);
216 Expect.isTrue(set.contains(1));
217 Expect.isTrue(set.contains(3));
218 Expect.isTrue(set.contains(2));
219 Expect.isFalse(set.contains(4));
220 set.clear();
221 Expect.isTrue(set.isEmpty);
222 }
223
224 {
225 // Check that removeWhere and retainWhere work.
226 Set set = newSetFrom([1, 2, 3]);
227 set.removeWhere((each) => each == 2);
228 Expect.equals(2, set.length);
229 Expect.isTrue(set.contains(1));
230 Expect.isFalse(set.contains(2));
231 Expect.isTrue(set.contains(3));
232 set.retainWhere((each) => each == 3);
233 Expect.equals(1, set.length);
234 Expect.isFalse(set.contains(1));
235 Expect.isFalse(set.contains(2));
236 Expect.isTrue(set.contains(3));
237 }
238
239 {
240 // Test lookup
241 Set set = newSet();
242 var m1a = new Mutable(1);
243 var m1b = new Mutable(1);
244 var m2a = new Mutable(2);
245 var m2b = new Mutable(2);
246 Expect.isNull(set.lookup(m1a));
247 Expect.isNull(set.lookup(m1b));
248 set.add(m1a);
249 Expect.identical(m1a, set.lookup(m1a));
250 Expect.identical(m1a, set.lookup(m1b));
251
252 Expect.isNull(set.lookup(m2a));
253 Expect.isNull(set.lookup(m2b));
254 set.add(m2a);
255 Expect.identical(m2a, set.lookup(m2a));
256 Expect.identical(m2a, set.lookup(m2b));
257
258 set.add(m2b); // Adding doesn't change element.
259 Expect.identical(m2a, set.lookup(m2a));
260 Expect.identical(m2a, set.lookup(m2b));
261
262 set.remove(m1a);
263 set.add(m1b);
264 Expect.identical(m1b, set.lookup(m1a));
265 Expect.identical(m1b, set.lookup(m1b));
266
267 set.add(1);
268 Expect.identical(1, set.lookup(1.0));
269 set.add(-0.0);
270 Expect.identical(-0.0, set.lookup(0.0));
271 }
272
273 {
274 // Test special hash codes
275 Set set = newSet();
276 List keys = [];
277 // Powers of two
278 for (int i = 63; i >= 2; --i) {
279 keys.add(new Mutable(math.pow(2, i)));
280 }
281 for (var key in keys) {
282 Expect.isTrue(set.add(key));
283 }
284 for (var key in keys) {
285 Expect.isTrue(set.contains(key));
286 }
287 }
288 }
289
290 void testIdentitySet(Set create()) {
291 Set set = create();
292 set.add(1);
293 set.add(2);
294 set.add(1); // Integers are identical if equal.
295 Expect.equals(2, set.length);
296 var complex = 4;
297 complex = set.length == 2 ? complex ~/ 4 : 87; // Avoid compile-time constant.
298 Expect.isTrue(set.contains(complex)); // 1 is in set, even if computed.
299 set.clear();
300
301 // All compile time constants are identical to themselves.
302 var constants = [
303 double.INFINITY,
304 double.NAN, -0.0, //# 01: ok
305 0.0, 42, "", null, false, true, #bif, testIdentitySet
306 ];
307 set.addAll(constants);
308 Expect.equals(constants.length, set.length);
309 for (var c in constants) {
310 Expect.isTrue(set.contains(c), "constant: $c");
311 }
312 Expect.isTrue(set.containsAll(constants), "constants: $set");
313 set.clear();
314
315 var m1 = new Mutable(1);
316 var m2 = new Mutable(2);
317 var m3 = new Mutable(3);
318 var m4 = new Mutable(2); // Equal to m2, but not identical.
319 set.addAll([m1, m2, m3, m4]);
320 Expect.equals(4, set.length);
321 Expect.equals(3, m3.hashCode);
322 m3.id = 1;
323 Expect.equals(1, m3.hashCode);
324 // Changing hashCode doesn't affect lookup.
325 Expect.isTrue(set.contains(m3));
326 Expect.isTrue(set.contains(m1));
327 set.remove(m3);
328 Expect.isFalse(set.contains(m3));
329 Expect.isTrue(set.contains(m1));
330
331 Expect.identical(m1, set.lookup(m1));
332 Expect.identical(null, set.lookup(m3));
333 }
334
335 void main() {
336 testSet(() => new Set(), (m) => new Set.from(m));
337 testSet(() => new HashSet(), (m) => new HashSet.from(m));
338 testSet(() => new LinkedHashSet(), (m) => new LinkedHashSet.from(m));
339 testIdentitySet(() => new Set.identity());
340 testIdentitySet(() => new HashSet.identity());
341 testIdentitySet(() => new LinkedHashSet.identity());
342 testIdentitySet(() => new HashSet(
343 equals: (x, y) => identical(x, y), hashCode: (x) => identityHashCode(x)));
344 testIdentitySet(() => new LinkedHashSet(
345 equals: (x, y) => identical(x, y), hashCode: (x) => identityHashCode(x)));
346 }
347
348 class BadHashCode {
349 static int idCounter = 0;
350 final int id;
351 BadHashCode() : id = idCounter++;
352 int get hashCode => 42;
353 // operator == is identity.
354 // Can't make a bad compareTo that isn't invalid.
355 int compareTo(BadHashCode other) => id - other.id;
356 }
357
358 class Mutable {
359 int id;
360 Mutable(this.id);
361 int get hashCode => id;
362 bool operator ==(other) => other is Mutable && id == other.id;
363 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698