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

Side by Side Diff: packages/quiver/test/collection/treeset_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. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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.treeset_test;
16
17 import 'package:quiver/collection.dart';
18 import 'package:test/test.dart';
19
20 main() {
21 group("TreeSet", () {
22 group("when empty", () {
23 TreeSet<num> tree;
24 setUp(() {
25 tree = new TreeSet<num>();
26 });
27 test("should actually be empty", () => expect(tree, isEmpty));
28 test("should not contain an element",
29 () => expect(tree.lookup(0), isNull));
30 test("has no element when iterating forward", () {
31 var i = tree.iterator;
32 expect(i.moveNext(), isFalse, reason: "moveNext reports an element");
33 expect(i.current, isNull, reason: "current returns an element");
34 });
35 test("has no element when iterating backward", () {
36 var i = tree.iterator;
37 expect(i.movePrevious(), isFalse,
38 reason: "movePrevious reports an element");
39 expect(i.current, isNull, reason: "current returns an element");
40 });
41 });
42
43 group("with [10, 20, 15]", () {
44 AvlTreeSet<num> tree;
45 setUp(() {
46 tree = new TreeSet<num>()..addAll([10, 20, 15]);
47 });
48 test("lookup succeeds for inserted elements", () {
49 expect(tree.lookup(10), equals(10), reason: "missing 10");
50 expect(tree.lookup(15), equals(15), reason: "missing 15");
51 expect(tree.lookup(20), equals(20), reason: "missing 20");
52 });
53 test("order is correct", () {
54 AvlNode ten = tree.getNode(10);
55 AvlNode twenty = tree.getNode(20);
56 AvlNode fifteen = tree.getNode(15);
57 expect(ten.predecessor, isNull, reason: "10 is the smalled element");
58 expect(ten.successor, equals(fifteen), reason: "15 should follow 10");
59 expect(ten.successor.successor, equals(twenty),
60 reason: "20 should follow 10");
61
62 expect(twenty.successor, isNull, reason: "20 is the largest element");
63 expect(twenty.predecessor, equals(fifteen), reason: "15 is before 20");
64 expect(twenty.predecessor.predecessor, equals(ten),
65 reason: "10 is before 15");
66 });
67 });
68
69 group("with repeated elements", () {
70 TreeSet<num> tree;
71 setUp(() {
72 tree = new TreeSet<num>()..addAll([10, 20, 15, 21, 30, 20]);
73 });
74
75 test("only contains subset", () {
76 var it = tree.iterator;
77 var testList = new List.from([10, 15, 20, 21, 30]);
78 while (it.moveNext()) {
79 expect(it.current, equals(testList.removeAt(0)));
80 }
81 expect(testList.length, equals(0), reason: "valid subset seen in tree");
82 });
83 });
84
85 group("iteration", () {
86 TreeSet<num> tree;
87 setUp(() {
88 tree = new TreeSet<num>()..addAll([10, 20, 15, 21, 30]);
89 });
90
91 test("works bidirectionally", () {
92 var it = tree.iterator;
93 while (it.moveNext());
94 expect(it.movePrevious(), isTrue,
95 reason: "we can backup after walking the entire list");
96 expect(it.current, equals(30),
97 reason: "the last element is what we expect");
98 while (it.movePrevious());
99 expect(it.moveNext(), isTrue,
100 reason: "we can move next after walking to the front of the set");
101 expect(it.current, equals(10),
102 reason: "the first element is what we expect");
103 });
104
105 group("from", () {
106 test("non-inserted midpoint works forward", () {
107 var it = tree.fromIterator(19);
108 expect(it.current, isNull, reason: "iteration starts with null");
109 expect(it.moveNext(), isTrue, reason: "moveNext() from spot works");
110 expect(it.current, equals(20));
111 });
112
113 test("non-inserted midpoint works for movePrevious()", () {
114 var it = tree.fromIterator(19);
115 expect(it.current, isNull, reason: "iteration starts with null");
116 expect(it.movePrevious(), isTrue,
117 reason: "movePrevious() from spot works");
118 expect(it.current, equals(15));
119 });
120
121 test("non-inserted midpoint works reversed", () {
122 var it = tree.fromIterator(19, reversed: true);
123 expect(it.current, isNull, reason: "iteration starts with null");
124 expect(it.moveNext(), isTrue, reason: "moveNext() from spot works");
125 expect(it.current, equals(15));
126 });
127
128 test("non-inserted midpoint works reversed, movePrevious()", () {
129 var it = tree.fromIterator(19, reversed: true);
130 expect(it.current, isNull, reason: "iteration starts with null");
131 expect(it.movePrevious(), isTrue,
132 reason: "movePrevious() from spot works");
133 expect(it.current, equals(20));
134 });
135
136 test("inserted midpoint works forward", () {
137 var it = tree.fromIterator(20);
138 expect(it.current, isNull, reason: "iteration starts with null");
139 expect(it.moveNext(), isTrue, reason: "moveNext() from spot works");
140 expect(it.current, equals(20));
141 });
142
143 test("inserted midpoint works reversed", () {
144 var it = tree.fromIterator(20, reversed: true);
145 expect(it.current, isNull, reason: "iteration starts with null");
146 expect(it.moveNext(), isTrue, reason: "moveNext() from spot works");
147 expect(it.current, equals(20));
148 });
149
150 test("after the set", () {
151 var it = tree.fromIterator(100);
152 expect(it.current, isNull);
153 expect(it.moveNext(), isFalse, reason: "not following items");
154 expect(it.movePrevious(), isTrue, reason: "backwards movement valid");
155 expect(it.current, equals(30));
156 });
157
158 test("before the set", () {
159 var it = tree.fromIterator(0);
160 expect(it.current, isNull);
161 expect(it.movePrevious(), isFalse, reason: "not previous items");
162 expect(it.moveNext(), isTrue, reason: "forwards movement valid");
163 expect(it.current, equals(10));
164 });
165
166 test("inserted midpoint, non-inclusive, works forward", () {
167 var it = tree.fromIterator(20, inclusive: false);
168 expect(it.current, isNull, reason: "iteration starts with null");
169 expect(it.moveNext(), isTrue, reason: "moveNext() from spot works");
170 expect(it.current, equals(21));
171 });
172
173 test("inserted endpoint, non-inclusive, works forward", () {
174 var it = tree.fromIterator(30, inclusive: false);
175 expect(it.current, isNull, reason: "iteration starts with null");
176 expect(it.moveNext(), isFalse, reason: "moveNext() from spot works");
177
178 it = tree.fromIterator(10, inclusive: false);
179 expect(it.current, isNull, reason: "iteration starts with null");
180 expect(it.moveNext(), isTrue, reason: "moveNext() from spot works");
181 expect(it.current, equals(15),
182 reason: "non-inclusive start should be 15");
183 });
184
185 test("inserted endpoint, non-inclusive, works backward", () {
186 var it = tree.fromIterator(10, inclusive: false);
187 expect(it.current, isNull, reason: "iteration starts with null");
188 expect(it.movePrevious(), isFalse,
189 reason: "movePrevious() from spot is null");
190
191 it = tree.fromIterator(30, inclusive: false);
192 expect(it.current, isNull, reason: "iteration starts with null");
193 expect(
194 it.movePrevious(), isTrue, reason: "moveNext() from spot works");
195 expect(it.current, equals(21));
196 });
197
198 test("inserted midpoint, non-inclusive, reversed, works forward", () {
199 var it = tree.fromIterator(20, inclusive: false, reversed: true);
200 expect(it.current, isNull, reason: "iteration starts with null");
201 expect(it.moveNext(), isTrue, reason: "moveNext() from spot works");
202 expect(it.current, equals(15));
203 });
204
205 test("inserted endpoint, non-inclusive, reversed, works forward", () {
206 var it = tree.fromIterator(30, inclusive: false, reversed: true);
207 expect(it.current, isNull, reason: "iteration starts with null");
208 expect(it.moveNext(), isTrue, reason: "moveNext() from spot works");
209 expect(it.current, equals(21));
210
211 it = tree.fromIterator(10, inclusive: false, reversed: true);
212 expect(it.current, isNull, reason: "iteration starts with null");
213 expect(it.moveNext(), isFalse, reason: "moveNext() works");
214 });
215
216 test("inserted endpoint, non-inclusive, reversed, works backward", () {
217 var it = tree.fromIterator(10, inclusive: false, reversed: true);
218 expect(it.current, isNull, reason: "iteration starts with null");
219 expect(
220 it.movePrevious(), isTrue, reason: "moveNext() from spot works");
221 expect(it.current, equals(15));
222
223 it = tree.fromIterator(30, inclusive: false, reversed: true);
224 expect(it.current, isNull, reason: "iteration starts with null");
225 expect(
226 it.movePrevious(), isFalse, reason: "moveNext() from spot works");
227 });
228 });
229
230 group("fails", () {
231 var it;
232 setUp(() => it = tree.iterator);
233
234 test("after tree is cleared", () {
235 tree.clear();
236 var error;
237 try {
238 it.moveNext();
239 } catch (e) {
240 error = e;
241 }
242 expect(error, isConcurrentModificationError);
243 });
244
245 test("after inserting an element", () {
246 tree.add(101);
247 var error;
248 try {
249 it.moveNext();
250 } catch (e) {
251 error = e;
252 }
253 expect(error, isConcurrentModificationError);
254 });
255
256 test("after removing an element", () {
257 tree.remove(10);
258 var error;
259 try {
260 it.moveNext();
261 } catch (e) {
262 error = e;
263 }
264 expect(error, isConcurrentModificationError);
265 });
266 });
267
268 group("still works", () {
269 var it;
270 setUp(() => it = tree.iterator);
271
272 test("when removing non-existing element", () {
273 tree.remove(42);
274 var error;
275 try {
276 it.moveNext();
277 } catch (e) {
278 error = e;
279 }
280 expect(error, isNull, reason: "set was not modified");
281 });
282 test("when adding an already existing element", () {
283 tree.add(10);
284 var error;
285 try {
286 it.moveNext();
287 } catch (e) {
288 error = e;
289 }
290 expect(error, isNull, reason: "set was not modified");
291 });
292 });
293 });
294
295 group("set math", () {
296 /// NOTE: set math with sorted sets should have a performance benifit,
297 /// we do not check the performance, only that the resulting math
298 /// is equivilant to non-sorted sets.
299
300 TreeSet<num> tree;
301 List<num> expectedUnion;
302 List<num> expectedIntersection;
303 List<num> expectedDifference;
304 Set<num> nonSortedTestSet;
305 TreeSet<num> sortedTestSet;
306
307 setUp(() {
308 tree = new TreeSet()..addAll([10, 20, 15, 21, 30, 20]);
309 expectedUnion = [10, 15, 18, 20, 21, 22, 30];
310 expectedIntersection = [10, 15];
311 expectedDifference = [20, 21, 30];
312 nonSortedTestSet = new Set.from([10, 18, 22, 15]);
313 sortedTestSet = new TreeSet()..addAll(nonSortedTestSet);
314 });
315
316 test("union with non sorted set", () =>
317 expect(tree.union(nonSortedTestSet).toList(), equals(expectedUnion)));
318 test("union with sorted set", () =>
319 expect(tree.union(sortedTestSet).toList(), equals(expectedUnion)));
320 test("intersection with non sorted set", () => expect(
321 tree.intersection(nonSortedTestSet).toList(),
322 equals(expectedIntersection)));
323 test("intersection with sorted set", () => expect(
324 tree.intersection(sortedTestSet).toList(),
325 equals(expectedIntersection)));
326 test("difference with non sorted set", () => expect(
327 tree.difference(nonSortedTestSet).toList(),
328 equals(expectedDifference)));
329 test("difference with sorted set", () => expect(
330 tree.difference(sortedTestSet).toList(), equals(expectedDifference)));
331 });
332
333 group("AVL implementaiton", () {
334 /// NOTE: This is implementation specific testing for coverage.
335 /// Users do not have access to [AvlNode] or [AvlTreeSet]
336 test("RightLeftRotation", () {
337 AvlTreeSet<num> tree = new TreeSet<num>();
338 tree.add(10);
339 tree.add(20);
340 tree.add(15);
341
342 AvlNode ten = tree.getNode(10);
343 AvlNode twenty = tree.getNode(20);
344 AvlNode fifteen = tree.getNode(15);
345
346 expect(ten.parent, equals(fifteen));
347 expect(ten.left, equals(null));
348 expect(ten.right, equals(null));
349 expect(ten.balance, equals(0));
350
351 expect(twenty.parent, equals(fifteen));
352 expect(twenty.left, equals(null));
353 expect(twenty.right, equals(null));
354 expect(twenty.balance, equals(0));
355
356 expect(fifteen.parent, equals(null));
357 expect(fifteen.left, equals(ten));
358 expect(fifteen.right, equals(twenty));
359 expect(fifteen.balance, equals(0));
360 });
361 test("LeftRightRotation", () {
362 AvlTreeSet<num> tree = new TreeSet<num>();
363 tree.add(30);
364 tree.add(10);
365 tree.add(20);
366
367 AvlNode thirty = tree.getNode(30);
368 AvlNode ten = tree.getNode(10);
369 AvlNode twenty = tree.getNode(20);
370
371 expect(thirty.parent, equals(twenty));
372 expect(thirty.left, equals(null));
373 expect(thirty.right, equals(null));
374 expect(thirty.balance, equals(0));
375
376 expect(ten.parent, equals(twenty));
377 expect(ten.left, equals(null));
378 expect(ten.right, equals(null));
379 expect(ten.balance, equals(0));
380
381 expect(twenty.parent, equals(null));
382 expect(twenty.left, equals(ten));
383 expect(twenty.right, equals(thirty));
384 expect(twenty.balance, equals(0));
385 });
386
387 test("AVL-LeftRotation", () {
388 AvlTreeSet<num> tree = new TreeSet<num>();
389 tree.add(1);
390 tree.add(2);
391 tree.add(3);
392
393 AvlNode one = tree.getNode(1);
394 AvlNode two = tree.getNode(2);
395 AvlNode three = tree.getNode(3);
396
397 expect(one.parent, equals(two));
398 expect(one.left, equals(null));
399 expect(one.right, equals(null));
400 expect(one.balance, equals(0));
401
402 expect(three.parent, equals(two));
403 expect(three.left, equals(null));
404 expect(three.right, equals(null));
405 expect(three.balance, equals(0));
406
407 expect(two.parent, equals(null));
408 expect(two.left, equals(one));
409 expect(two.right, equals(three));
410 expect(two.balance, equals(0));
411 });
412
413 test("AVL-RightRotation", () {
414 AvlTreeSet<num> tree = new TreeSet<num>();
415 tree.add(3);
416 tree.add(2);
417 tree.add(1);
418
419 AvlNode one = tree.getNode(1);
420 AvlNode two = tree.getNode(2);
421 AvlNode three = tree.getNode(3);
422
423 expect(one.parent, equals(two));
424 expect(one.left, equals(null));
425 expect(one.right, equals(null));
426 expect(one.balance, equals(0));
427
428 expect(three.parent, equals(two));
429 expect(three.left, equals(null));
430 expect(three.right, equals(null));
431 expect(three.balance, equals(0));
432
433 expect(two.parent, equals(null));
434 expect(two.left, equals(one));
435 expect(two.right, equals(three));
436 expect(two.balance, equals(0));
437 });
438 });
439
440 group("nearest search", () {
441 TreeSet<num> tree;
442 setUp(() {
443 tree = new TreeSet<num>(comparator: (num left, num right) {
444 return left - right;
445 })..addAll([300, 200, 100]);
446 });
447
448 test("NEAREST is sane", () {
449 var val = tree.nearest(199);
450 expect(val, equals(200), reason: "199 is closer to 200");
451 val = tree.nearest(201);
452 expect(val, equals(200), reason: "201 is 200");
453 val = tree.nearest(150);
454 expect(val, equals(100), reason: "150 defaults to lower 100");
455 });
456
457 test("LESS_THAN is sane", () {
458 var val = tree.nearest(199, nearestOption: TreeSearch.LESS_THAN);
459 expect(val, equals(100), reason: "199 rounds down to 100");
460 });
461
462 test("GREATER_THAN is sane", () {
463 var val = tree.nearest(101, nearestOption: TreeSearch.GREATER_THAN);
464 expect(val, equals(200), reason: "101 rounds up to 200");
465 });
466 });
467 });
468 }
OLDNEW
« no previous file with comments | « packages/quiver/test/collection/multimap_test.dart ('k') | packages/quiver/test/core/all_tests.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698