1
2
3
4
5
6
7
8 package trie
9
10 import (
11 "reflect"
12 "strconv"
13 "testing"
14 )
15
16 func TestScope(t *testing.T) {
17 def := Scope{}
18 s0, s1 := newScope(), newScope()
19 if s0 == def || s1 == def {
20 t.Error("newScope() should never be == to the default scope")
21 }
22 if s0 == s1 {
23 t.Errorf("newScope() %q and %q should not be ==", s0, s1)
24 }
25 if s0.id == 0 {
26 t.Error("s0.id is 0")
27 }
28 if s1.id == 0 {
29 t.Error("s1.id is 0")
30 }
31 got := s0.String()
32 if _, err := strconv.Atoi(got); err != nil {
33 t.Errorf("scope{%s}.String() is not an int: got %s with error %s", s0, got, err)
34 }
35 }
36
37 func TestCollision(t *testing.T) {
38 var x interface{} = 1
39 var y interface{} = 2
40
41 if v := TakeLhs(x, y); v != x {
42 t.Errorf("TakeLhs(%s, %s) got %s. want %s", x, y, v, x)
43 }
44 if v := TakeRhs(x, y); v != y {
45 t.Errorf("TakeRhs(%s, %s) got %s. want %s", x, y, v, y)
46 }
47 }
48
49 func TestDefault(t *testing.T) {
50 def := Map{}
51
52 if def.Size() != 0 {
53 t.Errorf("default node has non-0 size %d", def.Size())
54 }
55 if want, got := (Scope{}), def.Scope(); got != want {
56 t.Errorf("default is in a non default scope (%s) from b (%s)", got, want)
57 }
58 if v, ok := def.Lookup(123); !(v == nil && !ok) {
59 t.Errorf("Scope{}.Lookup() = (%s, %v) not (nil, false)", v, ok)
60 }
61 if !def.Range(func(k uint64, v interface{}) bool {
62 t.Errorf("Scope{}.Range() called it callback on %d:%s", k, v)
63 return true
64 }) {
65 t.Error("Scope{}.Range() always iterates through all elements")
66 }
67
68 if got, want := def.String(), "{}"; got != want {
69 t.Errorf("Scope{}.String() got %s. want %s", got, want)
70 }
71
72 b := NewBuilder()
73 if def == b.Empty() {
74 t.Error("Scope{} == to an empty node from a builder")
75 }
76 if b.Clone(def) != b.Empty() {
77 t.Error("b.Clone(Scope{}) should equal b.Empty()")
78 }
79 if !def.DeepEqual(b.Empty()) {
80 t.Error("Scope{}.DeepEqual(b.Empty()) should hold")
81 }
82 }
83
84 func TestBuilders(t *testing.T) {
85 b0, b1 := NewBuilder(), NewBuilder()
86 if b0.Scope() == b1.Scope() {
87 t.Errorf("builders have the same scope %s", b0.Scope())
88 }
89
90 if b0.Empty() == b1.Empty() {
91 t.Errorf("empty nodes from different scopes are disequal")
92 }
93 if !b0.Empty().DeepEqual(b1.Empty()) {
94 t.Errorf("empty nodes from different scopes are not DeepEqual")
95 }
96
97 clone := b1.Clone(b0.Empty())
98 if clone != b1.Empty() {
99 t.Errorf("Clone() empty nodes %v != %v", clone, b1.Empty())
100 }
101 }
102
103 func TestEmpty(t *testing.T) {
104 b := NewBuilder()
105 e := b.Empty()
106 if e.Size() != 0 {
107 t.Errorf("empty nodes has non-0 size %d", e.Size())
108 }
109 if e.Scope() != b.Scope() {
110 t.Errorf("b.Empty() is in a different scope (%s) from b (%s)", e.Scope(), b.Scope())
111 }
112 if v, ok := e.Lookup(123); !(v == nil && !ok) {
113 t.Errorf("empty.Lookup() = (%s, %v) not (nil, false)", v, ok)
114 }
115 if l := e.n.find(123); l != nil {
116 t.Errorf("empty.find(123) got %v. want nil", l)
117 }
118 e.Range(func(k uint64, v interface{}) bool {
119 t.Errorf("empty.Range() called it callback on %d:%s", k, v)
120 return true
121 })
122
123 want := "{}"
124 if got := e.String(); got != want {
125 t.Errorf("empty.String(123) got %s. want %s", got, want)
126 }
127 }
128
129 func TestCreate(t *testing.T) {
130
131 b := NewBuilder()
132 for _, c := range []struct {
133 m map[uint64]interface{}
134 want string
135 }{
136 {
137 map[uint64]interface{}{},
138 "{}",
139 },
140 {
141 map[uint64]interface{}{1: "a"},
142 "{1: a}",
143 },
144 {
145 map[uint64]interface{}{2: "b", 1: "a"},
146 "{1: a, 2: b}",
147 },
148 {
149 map[uint64]interface{}{1: "x", 4: "y", 5: "z"},
150 "{1: x, 4: y, 5: z}",
151 },
152 } {
153 m := b.Create(c.m)
154 if got := m.String(); got != c.want {
155 t.Errorf("Create(%v) got %q. want %q ", c.m, got, c.want)
156 }
157 }
158 }
159
160 func TestElems(t *testing.T) {
161 b := NewBuilder()
162 for _, orig := range []map[uint64]interface{}{
163 {},
164 {1: "a"},
165 {1: "a", 2: "b"},
166 {1: "x", 4: "y", 5: "z"},
167 {1: "x", 4: "y", 5: "z", 123: "abc"},
168 } {
169 m := b.Create(orig)
170 if elems := Elems(m); !reflect.DeepEqual(orig, elems) {
171 t.Errorf("Elems(%v) got %q. want %q ", m, elems, orig)
172 }
173 }
174 }
175
176 func TestRange(t *testing.T) {
177 b := NewBuilder()
178 m := b.Create(map[uint64]interface{}{1: "x", 3: "y", 5: "z", 6: "stop", 8: "a"})
179
180 calls := 0
181 cb := func(k uint64, v interface{}) bool {
182 t.Logf("visiting (%d, %v)", k, v)
183 calls++
184 return k%2 != 0
185 }
186
187 all := m.Range(cb)
188 if all {
189 t.Error("expected to stop early")
190 }
191 want := 4
192 if calls != want {
193 t.Errorf("# of callbacks (%d) was expected to equal %d (1 + # of evens)",
194 calls, want)
195 }
196 }
197
198 func TestDeepEqual(t *testing.T) {
199 for _, m := range []map[uint64]interface{}{
200 {},
201 {1: "x"},
202 {1: "x", 2: "y"},
203 } {
204 l := NewBuilder().Create(m)
205 r := NewBuilder().Create(m)
206 if !l.DeepEqual(r) {
207 t.Errorf("Expect %v to be DeepEqual() to %v", l, r)
208 }
209 }
210 }
211
212 func TestNotDeepEqual(t *testing.T) {
213 for _, c := range []struct {
214 left map[uint64]interface{}
215 right map[uint64]interface{}
216 }{
217 {
218 map[uint64]interface{}{1: "x"},
219 map[uint64]interface{}{},
220 },
221 {
222 map[uint64]interface{}{},
223 map[uint64]interface{}{1: "y"},
224 },
225 {
226 map[uint64]interface{}{1: "x"},
227 map[uint64]interface{}{1: "y"},
228 },
229 {
230 map[uint64]interface{}{1: "x"},
231 map[uint64]interface{}{1: "x", 2: "Y"},
232 },
233 {
234 map[uint64]interface{}{1: "x", 2: "Y"},
235 map[uint64]interface{}{1: "x"},
236 },
237 {
238 map[uint64]interface{}{1: "x", 2: "y"},
239 map[uint64]interface{}{1: "x", 2: "Y"},
240 },
241 } {
242 l := NewBuilder().Create(c.left)
243 r := NewBuilder().Create(c.right)
244 if l.DeepEqual(r) {
245 t.Errorf("Expect %v to be !DeepEqual() to %v", l, r)
246 }
247 }
248 }
249
250 func TestMerge(t *testing.T) {
251 b := NewBuilder()
252 for _, c := range []struct {
253 left map[uint64]interface{}
254 right map[uint64]interface{}
255 want string
256 }{
257 {
258 map[uint64]interface{}{},
259 map[uint64]interface{}{},
260 "{}",
261 },
262 {
263 map[uint64]interface{}{},
264 map[uint64]interface{}{1: "a"},
265 "{1: a}",
266 },
267 {
268 map[uint64]interface{}{1: "a"},
269 map[uint64]interface{}{},
270 "{1: a}",
271 },
272 {
273 map[uint64]interface{}{1: "a", 2: "b"},
274 map[uint64]interface{}{},
275 "{1: a, 2: b}",
276 },
277 {
278 map[uint64]interface{}{1: "x"},
279 map[uint64]interface{}{1: "y"},
280 "{1: x}",
281 },
282 {
283 map[uint64]interface{}{1: "x"},
284 map[uint64]interface{}{2: "y"},
285 "{1: x, 2: y}",
286 },
287 {
288 map[uint64]interface{}{4: "y", 5: "z"},
289 map[uint64]interface{}{1: "x"},
290 "{1: x, 4: y, 5: z}",
291 },
292 {
293 map[uint64]interface{}{1: "x", 5: "z"},
294 map[uint64]interface{}{4: "y"},
295 "{1: x, 4: y, 5: z}",
296 },
297 {
298 map[uint64]interface{}{1: "x", 4: "y"},
299 map[uint64]interface{}{5: "z"},
300 "{1: x, 4: y, 5: z}",
301 },
302 {
303 map[uint64]interface{}{1: "a", 4: "c"},
304 map[uint64]interface{}{2: "b", 5: "d"},
305 "{1: a, 2: b, 4: c, 5: d}",
306 },
307 {
308 map[uint64]interface{}{1: "a", 4: "c"},
309 map[uint64]interface{}{2: "b", 5 + 8: "d"},
310 "{1: a, 2: b, 4: c, 13: d}",
311 },
312 {
313 map[uint64]interface{}{2: "b", 5 + 8: "d"},
314 map[uint64]interface{}{1: "a", 4: "c"},
315 "{1: a, 2: b, 4: c, 13: d}",
316 },
317 {
318 map[uint64]interface{}{1: "a", 4: "c"},
319 map[uint64]interface{}{2: "b", 5 + 8: "d"},
320 "{1: a, 2: b, 4: c, 13: d}",
321 },
322 {
323 map[uint64]interface{}{2: "b", 5 + 8: "d"},
324 map[uint64]interface{}{1: "a", 4: "c"},
325 "{1: a, 2: b, 4: c, 13: d}",
326 },
327 {
328 map[uint64]interface{}{2: "b", 5 + 8: "d"},
329 map[uint64]interface{}{2: "", 3: "a"},
330 "{2: b, 3: a, 13: d}",
331 },
332
333 {
334
335 left: map[uint64]interface{}{1: "a", 2 + 1: "b"},
336 right: map[uint64]interface{}{4 + 1: "c", 4 + 2: "d"},
337
338 want: "{1: a, 3: b, 5: c, 6: d}",
339 },
340 {
341
342 left: map[uint64]interface{}{8 + 2 + 1: "a", 16 + 4: "b"},
343 right: map[uint64]interface{}{16 + 8 + 2 + 1: "c", 16 + 8 + 4 + 2 + 1: "d"},
344
345
346 want: "{11: a, 20: b, 27: c, 31: d}",
347 },
348 {
349
350
351 left: map[uint64]interface{}{4 + 2: "b", 4 + 2 + 1: "c"},
352 right: map[uint64]interface{}{4: "a", 4 + 2 + 1: "dropped"},
353 want: "{4: a, 6: b, 7: c}",
354 },
355 } {
356 l, r := b.Create(c.left), b.Create(c.right)
357 m := b.Merge(l, r)
358 if got := m.String(); got != c.want {
359 t.Errorf("Merge(%s, %s) got %q. want %q ", l, r, got, c.want)
360 }
361 }
362 }
363
364 func TestIntersect(t *testing.T) {
365
366 b := NewBuilder()
367 for _, c := range []struct {
368 left map[uint64]interface{}
369 right map[uint64]interface{}
370 want string
371 }{
372 {
373 left: map[uint64]interface{}{10: "a", 39: "b"},
374 right: map[uint64]interface{}{10: "A", 39: "B", 75: "C"},
375 want: "{10: a, 39: b}",
376 },
377 {
378 left: map[uint64]interface{}{10: "a", 39: "b"},
379 right: map[uint64]interface{}{},
380 want: "{}",
381 },
382 {
383 left: map[uint64]interface{}{},
384 right: map[uint64]interface{}{10: "A", 39: "B", 75: "C"},
385 want: "{}",
386 },
387 {
388 left: map[uint64]interface{}{4: 1, 6: 3, 10: 8, 15: "on left"},
389 right: map[uint64]interface{}{0: 8, 7: 6, 11: 0, 15: "on right"},
390 want: "{15: on left}",
391 },
392 {
393 left: map[uint64]interface{}{0: "on left", 1: 2, 2: 3, 3: 1, 7: 3},
394 right: map[uint64]interface{}{0: "on right", 5: 1, 6: 8},
395 want: "{0: on left}",
396 },
397 {
398 left: map[uint64]interface{}{1: "a", 2: "b", 3: "c"},
399 right: map[uint64]interface{}{0: "A", 1: "B", 2: "C"},
400 want: "{1: a, 2: b}",
401 },
402 {
403 left: map[uint64]interface{}{1: "a", 2: "b", 3: "c"},
404 right: map[uint64]interface{}{0: "A", 1: "B", 2: "C"},
405 want: "{1: a, 2: b}",
406 },
407 {
408
409 left: map[uint64]interface{}{0b001: 1, 0b011: 3},
410 right: map[uint64]interface{}{0b100: 4, 0b111: 7},
411 want: "{}",
412 },
413 {
414
415 left: map[uint64]interface{}{0b010: 2, 0b101: 5},
416 right: map[uint64]interface{}{0b000: 0, 0b001: 1},
417 want: "{}",
418 },
419
420 {
421
422 left: map[uint64]interface{}{
423 0b11101: "29",
424 0b11110: "30",
425 },
426 right: map[uint64]interface{}{
427 0b11110: "30 on right",
428 0b11111: "31",
429 },
430 want: "{30: 30}",
431 },
432 {
433
434 left: map[uint64]interface{}{0b000: 0, 0b001: 1},
435 right: map[uint64]interface{}{0b010: 2, 0b101: 5},
436 want: "{}",
437 },
438 {
439
440 left: map[uint64]interface{}{0b100: 1, 0b110: 3},
441 right: map[uint64]interface{}{0b000: 8, 0b111: 6},
442 want: "{}",
443 },
444 } {
445 l, r := b.Create(c.left), b.Create(c.right)
446 m := b.Intersect(l, r)
447 if got := m.String(); got != c.want {
448 t.Errorf("Intersect(%s, %s) got %q. want %q ", l, r, got, c.want)
449 }
450 }
451 }
452
453 func TestIntersectWith(t *testing.T) {
454 b := NewBuilder()
455 l := b.Create(map[uint64]interface{}{10: 2.0, 39: 32.0})
456 r := b.Create(map[uint64]interface{}{10: 6.0, 39: 10.0, 75: 1.0})
457
458 prodIfDifferent := func(x interface{}, y interface{}) interface{} {
459 if x, ok := x.(float64); ok {
460 if y, ok := y.(float64); ok {
461 if x == y {
462 return x
463 }
464 return x * y
465 }
466 }
467 return x
468 }
469
470 m := b.IntersectWith(prodIfDifferent, l, r)
471
472 want := "{10: %!s(float64=12), 39: %!s(float64=320)}"
473 if got := m.String(); got != want {
474 t.Errorf("IntersectWith(min, %s, %s) got %q. want %q ", l, r, got, want)
475 }
476 }
477
478 func TestRemove(t *testing.T) {
479
480 b := NewBuilder()
481 for _, c := range []struct {
482 m map[uint64]interface{}
483 key uint64
484 want string
485 }{
486 {map[uint64]interface{}{}, 10, "{}"},
487 {map[uint64]interface{}{10: "a"}, 10, "{}"},
488 {map[uint64]interface{}{39: "b"}, 10, "{39: b}"},
489
490
491 {map[uint64]interface{}{10: "a", 39: "b"}, 128, "{10: a, 39: b}"},
492
493 {map[uint64]interface{}{10: "a", 39: "b"}, 16, "{10: a, 39: b}"},
494
495 {map[uint64]interface{}{10: "a", 39: "b"}, 10, "{39: b}"},
496
497 {map[uint64]interface{}{10: "a", 39: "b"}, 39, "{10: a}"},
498
499 {map[uint64]interface{}{10: "a", 39: "b", 128: "c"}, 39, "{10: a, 128: c}"},
500 } {
501 pre := b.Create(c.m)
502 post := b.Remove(pre, c.key)
503 if got := post.String(); got != c.want {
504 t.Errorf("Remove(%s, %d) got %q. want %q ", pre, c.key, got, c.want)
505 }
506 }
507 }
508
509 func TestRescope(t *testing.T) {
510 b := NewBuilder()
511 l := b.Create(map[uint64]interface{}{10: "a", 39: "b"})
512 r := b.Create(map[uint64]interface{}{10: "A", 39: "B", 75: "C"})
513
514 b.Rescope()
515
516 m := b.Intersect(l, r)
517 if got, want := m.String(), "{10: a, 39: b}"; got != want {
518 t.Errorf("Intersect(%s, %s) got %q. want %q", l, r, got, want)
519 }
520 if m.Scope() == l.Scope() {
521 t.Errorf("m.Scope() = %v should not equal l.Scope() = %v", m.Scope(), l.Scope())
522 }
523 if m.Scope() == r.Scope() {
524 t.Errorf("m.Scope() = %v should not equal r.Scope() = %v", m.Scope(), r.Scope())
525 }
526 }
527
528 func TestSharing(t *testing.T) {
529 b := NewBuilder()
530 l := b.Create(map[uint64]interface{}{0: "a", 1: "b"})
531 r := b.Create(map[uint64]interface{}{1: "B", 2: "C"})
532
533 rleftold := r.n.(*branch).left
534
535 m := b.Merge(l, r)
536 if mleft := m.n.(*branch).left; mleft != l.n {
537 t.Errorf("unexpected value for left branch of %v. want %v got %v", m, l, mleft)
538 }
539
540 if rleftnow := r.n.(*branch).left; rleftnow != rleftold {
541 t.Errorf("r.n.(*branch).left was modified by the Merge operation. was %v now %v", rleftold, rleftnow)
542 }
543 }
544
View as plain text