-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathnode_test.go
157 lines (125 loc) · 3.4 KB
/
node_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package trie
import (
"bytes"
"runtime"
"testing"
"unsafe"
)
var emptyTrie *Node
var foodTrie = node("food", nil, edges{
node("foodie", 2, edges{
node("foodies", 3, nil),
}),
node("foods", 4, nil),
node("foodz", 5, nil),
})
var footTrie = node("foot", nil, edges{
node("footie", 2, edges{
node("footies", 3, nil),
}),
node("foots", 4, nil),
node("footz", 5, nil),
})
func TestSizeOfNode(t *testing.T) {
if size := unsafe.Sizeof(Node{}); size != 64 {
t.Errorf("expected Node to be 64 bytes, got %d", size)
}
}
func TestNodeGet(t *testing.T) {
testGet := func(n *Node, key string) interface{} {
a := n.Get([]byte(key))
b := n.GetString(key)
if a != b {
t.Errorf("Get does not agree with GetString")
}
return a
}
if testGet(foodTrie, "foo") != nil {
t.Errorf(`"foo" should not have been found`)
}
if testGet(foodTrie, "foods") != 4 {
t.Errorf(`"foods" should have been 4`)
}
}
func TestNodePut(t *testing.T) {
testPut := func(n *Node, key string, val interface{}) *Node {
a := n.Put([]byte(key), val)
b := n.PutString(key, val)
if !Equal(a, b) {
t.Errorf("Put does not agree with PutString for %q with trie: %#v", key, n)
}
return a
}
if testPut(emptyTrie, "foodie", 2) == nil {
t.Errorf("expected Put to return a new Node")
}
if testPut(foodTrie, "foodie", 2) != foodTrie {
t.Errorf("expected Put to do nothing")
}
if testPut(foodTrie, "foodies", 2) == foodTrie {
t.Errorf("expected Put to replace a Node")
}
if testPut(footTrie, "food", 2) == footTrie {
t.Errorf("expected Put to replace a Node")
}
if testPut(foodTrie, "foodly", 2) == foodTrie {
t.Errorf("expected Put to return a new Node")
}
n := testPut(emptyTrie, "foo bar", []byte("12345"))
m := testPut(n, "foo baz", []byte("2"))
if !m.key.EqualToString("foo ba") {
t.Errorf(`expected "foo ba", got %q`, m.key)
}
if len(m.edges) != 2 {
t.Errorf("expected 2 edges, got %d", len(m.edges))
}
if e := m.edges[0]; e != n {
t.Errorf("expected first node to be reused")
}
}
func TestNodeDelete(t *testing.T) {
testDelete := func(n *Node, key string) *Node {
a := n.Delete([]byte(key))
b := n.DeleteString(key)
if !Equal(a, b) {
t.Errorf("Delete does not agree with DeleteString for %q with trie: %#v", key, n)
}
return a
}
if testDelete(emptyTrie, "food") != nil {
t.Errorf("expected Delete to return nil")
}
if testDelete(foodTrie, "foo") != foodTrie {
t.Errorf("expected Delete to do nothing")
}
if testDelete(foodTrie, "foodsies") != foodTrie {
t.Errorf("expected Delete to do nothing")
}
if testDelete(foodTrie, "foodie") == foodTrie {
t.Errorf("expected Delete to return a new Node")
}
if testDelete(foodTrie, "foodies") == foodTrie {
t.Errorf("expected Delete to return a new Node")
}
n := node("foo bar", []byte("12345"), nil)
m := n.PutString("foo baz", []byte("2")).DeleteString("foo bar")
if res := m.GetString("foo bar"); res != nil {
t.Errorf(`expected nil, got %q`, res)
}
if res := m.GetString("foo baz").([]byte); !bytes.Equal(res, []byte("2")) {
t.Errorf(`expected "2", got %q`, res)
}
}
func assertExactNode(t *testing.T, expected, actual *Node) {
if actual != expected {
_, file, line, _ := runtime.Caller(1)
t.Errorf("expected %q (%p), got %q (%p) at %s:%d", expected.key, expected, actual.key, actual, file, line)
}
}
func node(key string, val interface{}, es edges) *Node {
return &Node{
key: Key(key),
value: val,
edges: es,
}
}