OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package helper | 5 package rawdatastore |
6 | 6 |
7 import ( | 7 import ( |
8 "encoding/json" | 8 "encoding/json" |
9 "fmt" | 9 "fmt" |
10 "testing" | 10 "testing" |
11 | 11 |
12 "github.com/luci/gae" | |
13 . "github.com/smartystreets/goconvey/convey" | 12 . "github.com/smartystreets/goconvey/convey" |
14 ) | 13 ) |
15 | 14 |
16 func mkKey(aid, ns string, elems ...interface{}) gae.DSKey { | 15 func mkKey(aid, ns string, elems ...interface{}) Key { |
17 if len(elems)%2 != 0 { | 16 if len(elems)%2 != 0 { |
18 panic("odd number of tokens") | 17 panic("odd number of tokens") |
19 } | 18 } |
20 » toks := make([]gae.DSKeyTok, len(elems)/2) | 19 » toks := make([]KeyTok, len(elems)/2) |
21 for i := 0; i < len(elems); i += 2 { | 20 for i := 0; i < len(elems); i += 2 { |
22 toks[i/2].Kind = elems[i].(string) | 21 toks[i/2].Kind = elems[i].(string) |
23 switch x := elems[i+1].(type) { | 22 switch x := elems[i+1].(type) { |
24 case string: | 23 case string: |
25 toks[i/2].StringID = x | 24 toks[i/2].StringID = x |
26 case int: | 25 case int: |
27 toks[i/2].IntID = int64(x) | 26 toks[i/2].IntID = int64(x) |
28 default: | 27 default: |
29 panic("bad token id") | 28 panic("bad token id") |
30 } | 29 } |
31 } | 30 } |
32 » return NewDSKeyToks(aid, ns, toks) | 31 » return NewKeyToks(aid, ns, toks) |
33 } | 32 } |
34 | 33 |
35 func ShouldEqualKey(actual interface{}, expected ...interface{}) string { | 34 func ShouldEqualKey(actual interface{}, expected ...interface{}) string { |
36 if len(expected) != 1 { | 35 if len(expected) != 1 { |
37 return fmt.Sprintf("Assertion requires 1 expected value, got %d"
, len(expected)) | 36 return fmt.Sprintf("Assertion requires 1 expected value, got %d"
, len(expected)) |
38 } | 37 } |
39 » if DSKeysEqual(actual.(gae.DSKey), expected[0].(gae.DSKey)) { | 38 » if KeysEqual(actual.(Key), expected[0].(Key)) { |
40 return "" | 39 return "" |
41 } | 40 } |
42 return fmt.Sprintf("Expected: %q\nActual: %q", actual, expected[0]) | 41 return fmt.Sprintf("Expected: %q\nActual: %q", actual, expected[0]) |
43 } | 42 } |
44 | 43 |
45 func TestKeyEncode(t *testing.T) { | 44 func TestKeyEncode(t *testing.T) { |
46 t.Parallel() | 45 t.Parallel() |
47 | 46 |
48 » keys := []gae.DSKey{ | 47 » keys := []Key{ |
49 mkKey("appid", "ns", "kind", 1), | 48 mkKey("appid", "ns", "kind", 1), |
50 mkKey("appid", "ns", "nerd", "moo"), | 49 mkKey("appid", "ns", "nerd", "moo"), |
51 mkKey("appid", "ns", "parent", 10, "renerd", "moo"), | 50 mkKey("appid", "ns", "parent", 10, "renerd", "moo"), |
52 } | 51 } |
53 | 52 |
54 » Convey("DSKey Round trip", t, func() { | 53 » Convey("Key Round trip", t, func() { |
55 for _, k := range keys { | 54 for _, k := range keys { |
56 k := k | 55 k := k |
57 Convey(k.String(), func() { | 56 Convey(k.String(), func() { |
58 » » » » enc := DSKeyEncode(k) | 57 » » » » enc := KeyEncode(k) |
59 » » » » aid, ns, toks, err := DSKeyToksDecode(enc) | 58 » » » » aid, ns, toks, err := KeyToksDecode(enc) |
60 So(err, ShouldBeNil) | 59 So(err, ShouldBeNil) |
61 » » » » dec := NewDSKeyToks(aid, ns, toks) | 60 » » » » dec := NewKeyToks(aid, ns, toks) |
62 So(dec, ShouldNotBeNil) | 61 So(dec, ShouldNotBeNil) |
63 So(dec, ShouldEqualKey, k) | 62 So(dec, ShouldEqualKey, k) |
64 | 63 |
65 » » » » dec2, err := NewDSKeyFromEncoded(enc) | 64 » » » » dec2, err := NewKeyFromEncoded(enc) |
66 So(err, ShouldBeNil) | 65 So(err, ShouldBeNil) |
67 So(dec2, ShouldEqualKey, dec) | 66 So(dec2, ShouldEqualKey, dec) |
68 So(dec2, ShouldEqualKey, k) | 67 So(dec2, ShouldEqualKey, k) |
69 }) | 68 }) |
70 | 69 |
71 Convey(k.String()+" (json)", func() { | 70 Convey(k.String()+" (json)", func() { |
72 » » » » data, err := DSKeyMarshalJSON(k) | 71 » » » » data, err := KeyMarshalJSON(k) |
73 So(err, ShouldBeNil) | 72 So(err, ShouldBeNil) |
74 | 73 |
75 » » » » aid, ns, toks, err := DSKeyUnmarshalJSON(data) | 74 » » » » aid, ns, toks, err := KeyUnmarshalJSON(data) |
76 So(err, ShouldBeNil) | 75 So(err, ShouldBeNil) |
77 » » » » So(NewDSKeyToks(aid, ns, toks), ShouldEqualKey,
k) | 76 » » » » So(NewKeyToks(aid, ns, toks), ShouldEqualKey, k) |
78 }) | 77 }) |
79 } | 78 } |
80 }) | 79 }) |
81 | 80 |
82 » Convey("NewDSKey", t, func() { | 81 » Convey("NewKey", t, func() { |
83 Convey("single", func() { | 82 Convey("single", func() { |
84 » » » k := NewDSKey("appid", "ns", "kind", "", 1, nil) | 83 » » » k := NewKey("appid", "ns", "kind", "", 1, nil) |
85 So(k, ShouldEqualKey, keys[0]) | 84 So(k, ShouldEqualKey, keys[0]) |
86 }) | 85 }) |
87 | 86 |
88 Convey("nest", func() { | 87 Convey("nest", func() { |
89 » » » k := NewDSKey("appid", "ns", "renerd", "moo", 0, | 88 » » » k := NewKey("appid", "ns", "renerd", "moo", 0, |
90 » » » » NewDSKey("appid", "ns", "parent", "", 10, nil)) | 89 » » » » NewKey("appid", "ns", "parent", "", 10, nil)) |
91 So(k, ShouldEqualKey, keys[2]) | 90 So(k, ShouldEqualKey, keys[2]) |
92 }) | 91 }) |
93 }) | 92 }) |
94 | 93 |
95 » Convey("DSKey bad encoding", t, func() { | 94 » Convey("Key bad encoding", t, func() { |
96 Convey("extra junk before", func() { | 95 Convey("extra junk before", func() { |
97 » » » enc := DSKeyEncode(keys[2]) | 96 » » » enc := KeyEncode(keys[2]) |
98 » » » _, _, _, err := DSKeyToksDecode("/" + enc) | 97 » » » _, _, _, err := KeyToksDecode("/" + enc) |
99 So(err, ShouldErrLike, "illegal base64") | 98 So(err, ShouldErrLike, "illegal base64") |
100 }) | 99 }) |
101 | 100 |
102 Convey("extra junk after", func() { | 101 Convey("extra junk after", func() { |
103 » » » enc := DSKeyEncode(keys[2]) | 102 » » » enc := KeyEncode(keys[2]) |
104 » » » _, _, _, err := DSKeyToksDecode(enc[:len(enc)-1]) | 103 » » » _, _, _, err := KeyToksDecode(enc[:len(enc)-1]) |
105 So(err, ShouldErrLike, "EOF") | 104 So(err, ShouldErrLike, "EOF") |
106 }) | 105 }) |
107 | 106 |
108 Convey("json encoding includes quotes", func() { | 107 Convey("json encoding includes quotes", func() { |
109 » » » data, err := DSKeyMarshalJSON(keys[0]) | 108 » » » data, err := KeyMarshalJSON(keys[0]) |
110 So(err, ShouldBeNil) | 109 So(err, ShouldBeNil) |
111 | 110 |
112 » » » _, _, _, err = DSKeyUnmarshalJSON(append(data, '!')) | 111 » » » _, _, _, err = KeyUnmarshalJSON(append(data, '!')) |
113 So(err, ShouldErrLike, "bad JSON key") | 112 So(err, ShouldErrLike, "bad JSON key") |
114 }) | 113 }) |
115 }) | 114 }) |
116 } | 115 } |
117 | 116 |
118 type dumbKey1 struct{ gae.DSKey } | 117 type dumbKey1 struct{ Key } |
119 | 118 |
120 func (dk dumbKey1) Namespace() string { return "ns" } | 119 func (dk dumbKey1) Namespace() string { return "ns" } |
121 func (dk dumbKey1) Parent() gae.DSKey { return dk.DSKey } | 120 func (dk dumbKey1) Parent() Key { return dk.Key } |
122 func (dk dumbKey1) String() string { return "dumbKey1" } | 121 func (dk dumbKey1) String() string { return "dumbKey1" } |
123 | 122 |
124 type dumbKey2 struct{ gae.DSKey } | 123 type dumbKey2 struct{ Key } |
125 | 124 |
126 /// This is the dumb part... can't have both IDs set. | 125 /// This is the dumb part... can't have both IDs set. |
127 func (dk dumbKey2) IntID() int64 { return 1 } | 126 func (dk dumbKey2) IntID() int64 { return 1 } |
128 func (dk dumbKey2) StringID() string { return "wat" } | 127 func (dk dumbKey2) StringID() string { return "wat" } |
129 | 128 |
130 func (dk dumbKey2) Kind() string { return "kind" } | 129 func (dk dumbKey2) Kind() string { return "kind" } |
131 func (dk dumbKey2) Parent() gae.DSKey { return nil } | 130 func (dk dumbKey2) Parent() Key { return nil } |
132 func (dk dumbKey2) Namespace() string { return "ns" } | 131 func (dk dumbKey2) Namespace() string { return "ns" } |
133 func (dk dumbKey2) AppID() string { return "aid" } | 132 func (dk dumbKey2) AppID() string { return "aid" } |
134 func (dk dumbKey2) String() string { return "dumbKey2" } | 133 func (dk dumbKey2) String() string { return "dumbKey2" } |
135 | 134 |
136 func TestBadKeyEncode(t *testing.T) { | 135 func TestBadKeyEncode(t *testing.T) { |
137 t.Parallel() | 136 t.Parallel() |
138 | 137 |
139 Convey("bad keys", t, func() { | 138 Convey("bad keys", t, func() { |
140 Convey("incomplete", func() { | 139 Convey("incomplete", func() { |
141 » » » So(DSKeyIncomplete(mkKey("aid", "ns", "kind", 1)), Shoul
dBeFalse) | 140 » » » So(KeyIncomplete(mkKey("aid", "ns", "kind", 1)), ShouldB
eFalse) |
142 » » » So(DSKeyIncomplete(mkKey("aid", "ns", "kind", 0)), Shoul
dBeTrue) | 141 » » » So(KeyIncomplete(mkKey("aid", "ns", "kind", 0)), ShouldB
eTrue) |
143 }) | 142 }) |
144 | 143 |
145 Convey("invalid", func() { | 144 Convey("invalid", func() { |
146 » » » So(DSKeyValid(mkKey("aid", "ns", "hat", "face", "__kind_
_", 1), "ns", true), ShouldBeTrue) | 145 » » » So(KeyValid(mkKey("aid", "ns", "hat", "face", "__kind__"
, 1), "ns", true), ShouldBeTrue) |
147 » » » So(DSKeyValid(mkKey("aid", "ns", "hat", "face", "kind",
1), "wat", false), ShouldBeFalse) | 146 » » » So(KeyValid(mkKey("aid", "ns", "hat", "face", "kind", 1)
, "wat", false), ShouldBeFalse) |
148 | 147 |
149 » » » bads := []gae.DSKey{ | 148 » » » bads := []Key{ |
150 nil, | 149 nil, |
151 mkKey("", "ns", "hat", "face"), | 150 mkKey("", "ns", "hat", "face"), |
152 mkKey("aid", "ns", "base", 1, "", "id"), | 151 mkKey("aid", "ns", "base", 1, "", "id"), |
153 mkKey("aid", "ns", "hat", "face", "__kind__", 1)
, | 152 mkKey("aid", "ns", "hat", "face", "__kind__", 1)
, |
154 mkKey("aid", "ns", "hat", 0, "kind", 1), | 153 mkKey("aid", "ns", "hat", 0, "kind", 1), |
155 dumbKey1{mkKey("aid", "badNS", "hat", 1)}, | 154 dumbKey1{mkKey("aid", "badNS", "hat", 1)}, |
156 dumbKey2{}, | 155 dumbKey2{}, |
157 } | 156 } |
158 for _, k := range bads { | 157 for _, k := range bads { |
159 s := "<nil>" | 158 s := "<nil>" |
160 if k != nil { | 159 if k != nil { |
161 s = k.String() | 160 s = k.String() |
162 } | 161 } |
163 Convey(s, func() { | 162 Convey(s, func() { |
164 » » » » » So(DSKeyValid(k, "ns", false), ShouldBeF
alse) | 163 » » » » » So(KeyValid(k, "ns", false), ShouldBeFal
se) |
165 }) | 164 }) |
166 } | 165 } |
167 }) | 166 }) |
168 }) | 167 }) |
169 } | 168 } |
170 | 169 |
171 type keyWrap struct{ gae.DSKey } | 170 type keyWrap struct{ Key } |
172 | 171 |
173 func (k keyWrap) Parent() gae.DSKey { | 172 func (k keyWrap) Parent() Key { |
174 » if k.DSKey.Parent() != nil { | 173 » if k.Key.Parent() != nil { |
175 » » return keyWrap{k.DSKey.Parent()} | 174 » » return keyWrap{k.Key.Parent()} |
176 } | 175 } |
177 return nil | 176 return nil |
178 } | 177 } |
179 | 178 |
180 func TestMiscKey(t *testing.T) { | 179 func TestMiscKey(t *testing.T) { |
181 t.Parallel() | 180 t.Parallel() |
182 | 181 |
183 » Convey("DSKeyRoot", t, func() { | 182 » Convey("KeyRoot", t, func() { |
184 k := mkKey("appid", "ns", "parent", 10, "renerd", "moo") | 183 k := mkKey("appid", "ns", "parent", 10, "renerd", "moo") |
185 r := mkKey("appid", "ns", "parent", 10) | 184 r := mkKey("appid", "ns", "parent", 10) |
186 » » So(DSKeyRoot(k), ShouldEqualKey, r) | 185 » » So(KeyRoot(k), ShouldEqualKey, r) |
187 » » So(DSKeyRoot(nil), ShouldBeNil) | 186 » » So(KeyRoot(nil), ShouldBeNil) |
188 }) | 187 }) |
189 | 188 |
190 » Convey("DSKeySplit", t, func() { | 189 » Convey("KeySplit", t, func() { |
191 » » // keyWrap forces DSKeySplit to not take the GenericDSKey shortc
ut. | 190 » » // keyWrap forces KeySplit to not take the GenericKey shortcut. |
192 k := keyWrap{mkKey("appid", "ns", "parent", 10, "renerd", "moo")
} | 191 k := keyWrap{mkKey("appid", "ns", "parent", 10, "renerd", "moo")
} |
193 » » aid, ns, toks := DSKeySplit(k) | 192 » » aid, ns, toks := KeySplit(k) |
194 So(aid, ShouldEqual, "appid") | 193 So(aid, ShouldEqual, "appid") |
195 So(ns, ShouldEqual, "ns") | 194 So(ns, ShouldEqual, "ns") |
196 » » So(toks, ShouldResemble, []gae.DSKeyTok{ | 195 » » So(toks, ShouldResemble, []KeyTok{ |
197 {Kind: "parent", IntID: 10}, | 196 {Kind: "parent", IntID: 10}, |
198 {Kind: "renerd", StringID: "moo"}, | 197 {Kind: "renerd", StringID: "moo"}, |
199 }) | 198 }) |
200 }) | 199 }) |
201 | 200 |
202 » Convey("DSKeySplit (nil)", t, func() { | 201 » Convey("KeySplit (nil)", t, func() { |
203 » » aid, ns, toks := DSKeySplit(nil) | 202 » » aid, ns, toks := KeySplit(nil) |
204 So(aid, ShouldEqual, "") | 203 So(aid, ShouldEqual, "") |
205 So(ns, ShouldEqual, "") | 204 So(ns, ShouldEqual, "") |
206 » » So(toks, ShouldResemble, []gae.DSKeyTok(nil)) | 205 » » So(toks, ShouldResemble, []KeyTok(nil)) |
207 }) | 206 }) |
208 | 207 |
209 » Convey("DSKeySplit ((*GenericDSKey)(nil))", t, func() { | 208 » Convey("KeySplit ((*GenericKey)(nil))", t, func() { |
210 » » aid, ns, toks := DSKeySplit((*GenericDSKey)(nil)) | 209 » » aid, ns, toks := KeySplit((*GenericKey)(nil)) |
211 So(aid, ShouldEqual, "") | 210 So(aid, ShouldEqual, "") |
212 So(ns, ShouldEqual, "") | 211 So(ns, ShouldEqual, "") |
213 » » So(toks, ShouldResemble, []gae.DSKeyTok(nil)) | 212 » » So(toks, ShouldResemble, []KeyTok(nil)) |
214 }) | 213 }) |
215 | 214 |
216 » Convey("DSKeysEqual", t, func() { | 215 » Convey("KeysEqual", t, func() { |
217 k1 := mkKey("a", "n", "knd", 1) | 216 k1 := mkKey("a", "n", "knd", 1) |
218 k2 := mkKey("a", "n", "knd", 1) | 217 k2 := mkKey("a", "n", "knd", 1) |
219 » » So(DSKeysEqual(k1, k2), ShouldBeTrue) | 218 » » So(KeysEqual(k1, k2), ShouldBeTrue) |
220 k3 := mkKey("a", "n", "knd", 2) | 219 k3 := mkKey("a", "n", "knd", 2) |
221 » » So(DSKeysEqual(k1, k3), ShouldBeFalse) | 220 » » So(KeysEqual(k1, k3), ShouldBeFalse) |
222 }) | 221 }) |
223 | 222 |
224 » Convey("DSKeyString", t, func() { | 223 » Convey("KeyString", t, func() { |
225 k1 := mkKey("a", "n", "knd", 1, "other", "wat") | 224 k1 := mkKey("a", "n", "knd", 1, "other", "wat") |
226 » » So(DSKeyString(k1), ShouldEqual, "/knd,1/other,wat") | 225 » » So(KeyString(k1), ShouldEqual, "/knd,1/other,wat") |
227 » » So(DSKeyString(nil), ShouldEqual, "") | 226 » » So(KeyString(nil), ShouldEqual, "") |
228 }) | 227 }) |
229 | 228 |
230 » Convey("*GenericDSKey supports json encoding", t, func() { | 229 » Convey("*GenericKey supports json encoding", t, func() { |
231 type TestStruct struct { | 230 type TestStruct struct { |
232 » » » Key *GenericDSKey | 231 » » » Key *GenericKey |
233 } | 232 } |
234 t := &TestStruct{ | 233 t := &TestStruct{ |
235 » » » NewDSKey("aid", "ns", "kind", "id", 0, | 234 » » » NewKey("aid", "ns", "kind", "id", 0, |
236 » » » » NewDSKey("aid", "ns", "parent", "", 1, nil), | 235 » » » » NewKey("aid", "ns", "parent", "", 1, nil), |
237 )} | 236 )} |
238 d, err := json.Marshal(t) | 237 d, err := json.Marshal(t) |
239 So(err, ShouldBeNil) | 238 So(err, ShouldBeNil) |
240 t2 := &TestStruct{} | 239 t2 := &TestStruct{} |
241 err = json.Unmarshal(d, t2) | 240 err = json.Unmarshal(d, t2) |
242 So(err, ShouldBeNil) | 241 So(err, ShouldBeNil) |
243 So(t, ShouldResemble, t2) | 242 So(t, ShouldResemble, t2) |
244 }) | 243 }) |
245 } | 244 } |
OLD | NEW |