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

Side by Side Diff: service/datastore/dskey/key_test.go

Issue 1292913002: Split off serialization and key functions to their own packages. (Closed) Base URL: https://github.com/luci/gae.git@make_queries_better
Patch Set: rebase Created 5 years, 4 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
« no previous file with comments | « service/datastore/dskey/key.go ('k') | service/datastore/generic_key.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 datastore 5 package dskey
6 6
7 import ( 7 import (
8 "encoding/json" 8 "encoding/json"
9 "fmt" 9 "fmt"
10 "testing" 10 "testing"
11 11
12 ds "github.com/luci/gae/service/datastore"
13 . "github.com/luci/luci-go/common/testing/assertions"
12 . "github.com/smartystreets/goconvey/convey" 14 . "github.com/smartystreets/goconvey/convey"
13 ) 15 )
14 16
15 func mkKey(aid, ns string, elems ...interface{}) Key { 17 func mkKey(aid, ns string, elems ...interface{}) ds.Key {
16 if len(elems)%2 != 0 { 18 if len(elems)%2 != 0 {
17 panic("odd number of tokens") 19 panic("odd number of tokens")
18 } 20 }
19 » toks := make([]KeyTok, len(elems)/2) 21 » toks := make([]ds.KeyTok, len(elems)/2)
20 for i := 0; i < len(elems); i += 2 { 22 for i := 0; i < len(elems); i += 2 {
21 toks[i/2].Kind = elems[i].(string) 23 toks[i/2].Kind = elems[i].(string)
22 switch x := elems[i+1].(type) { 24 switch x := elems[i+1].(type) {
23 case string: 25 case string:
24 toks[i/2].StringID = x 26 toks[i/2].StringID = x
25 case int: 27 case int:
26 toks[i/2].IntID = int64(x) 28 toks[i/2].IntID = int64(x)
27 default: 29 default:
28 panic("bad token id") 30 panic("bad token id")
29 } 31 }
30 } 32 }
31 » return NewKeyToks(aid, ns, toks) 33 » return NewToks(aid, ns, toks)
32 } 34 }
33 35
34 func ShouldEqualKey(actual interface{}, expected ...interface{}) string { 36 func ShouldEqualKey(actual interface{}, expected ...interface{}) string {
35 if len(expected) != 1 { 37 if len(expected) != 1 {
36 return fmt.Sprintf("Assertion requires 1 expected value, got %d" , len(expected)) 38 return fmt.Sprintf("Assertion requires 1 expected value, got %d" , len(expected))
37 } 39 }
38 » if KeysEqual(actual.(Key), expected[0].(Key)) { 40 » if Equal(actual.(ds.Key), expected[0].(ds.Key)) {
39 return "" 41 return ""
40 } 42 }
41 return fmt.Sprintf("Expected: %q\nActual: %q", actual, expected[0]) 43 return fmt.Sprintf("Expected: %q\nActual: %q", actual, expected[0])
42 } 44 }
43 45
44 func TestKeyEncode(t *testing.T) { 46 func TestKeyEncode(t *testing.T) {
45 t.Parallel() 47 t.Parallel()
46 48
47 » keys := []Key{ 49 » keys := []ds.Key{
48 mkKey("appid", "ns", "kind", 1), 50 mkKey("appid", "ns", "kind", 1),
49 mkKey("appid", "ns", "nerd", "moo"), 51 mkKey("appid", "ns", "nerd", "moo"),
50 mkKey("appid", "ns", "parent", 10, "renerd", "moo"), 52 mkKey("appid", "ns", "parent", 10, "renerd", "moo"),
51 } 53 }
52 54
53 Convey("Key Round trip", t, func() { 55 Convey("Key Round trip", t, func() {
54 for _, k := range keys { 56 for _, k := range keys {
55 k := k 57 k := k
56 Convey(k.String(), func() { 58 Convey(k.String(), func() {
57 » » » » enc := KeyEncode(k) 59 » » » » enc := Encode(k)
58 » » » » aid, ns, toks, err := KeyToksDecode(enc) 60 » » » » aid, ns, toks, err := ToksDecode(enc)
59 So(err, ShouldBeNil) 61 So(err, ShouldBeNil)
60 » » » » dec := NewKeyToks(aid, ns, toks) 62 » » » » dec := NewToks(aid, ns, toks)
61 So(dec, ShouldNotBeNil) 63 So(dec, ShouldNotBeNil)
62 So(dec, ShouldEqualKey, k) 64 So(dec, ShouldEqualKey, k)
63 65
64 » » » » dec2, err := NewKeyFromEncoded(enc) 66 » » » » dec2, err := NewFromEncoded(enc)
65 So(err, ShouldBeNil) 67 So(err, ShouldBeNil)
66 So(dec2, ShouldEqualKey, dec) 68 So(dec2, ShouldEqualKey, dec)
67 So(dec2, ShouldEqualKey, k) 69 So(dec2, ShouldEqualKey, k)
68 }) 70 })
69 71
70 Convey(k.String()+" (json)", func() { 72 Convey(k.String()+" (json)", func() {
71 » » » » data, err := KeyMarshalJSON(k) 73 » » » » data, err := MarshalJSON(k)
72 So(err, ShouldBeNil) 74 So(err, ShouldBeNil)
73 75
74 » » » » aid, ns, toks, err := KeyUnmarshalJSON(data) 76 » » » » aid, ns, toks, err := UnmarshalJSON(data)
75 So(err, ShouldBeNil) 77 So(err, ShouldBeNil)
76 » » » » So(NewKeyToks(aid, ns, toks), ShouldEqualKey, k) 78 » » » » So(NewToks(aid, ns, toks), ShouldEqualKey, k)
77 }) 79 })
78 } 80 }
79 }) 81 })
80 82
81 Convey("NewKey", t, func() { 83 Convey("NewKey", t, func() {
82 Convey("single", func() { 84 Convey("single", func() {
83 » » » k := NewKey("appid", "ns", "kind", "", 1, nil) 85 » » » k := New("appid", "ns", "kind", "", 1, nil)
84 So(k, ShouldEqualKey, keys[0]) 86 So(k, ShouldEqualKey, keys[0])
85 }) 87 })
86 88
87 Convey("nest", func() { 89 Convey("nest", func() {
88 » » » k := NewKey("appid", "ns", "renerd", "moo", 0, 90 » » » k := New("appid", "ns", "renerd", "moo", 0,
89 » » » » NewKey("appid", "ns", "parent", "", 10, nil)) 91 » » » » New("appid", "ns", "parent", "", 10, nil))
90 So(k, ShouldEqualKey, keys[2]) 92 So(k, ShouldEqualKey, keys[2])
91 }) 93 })
92 }) 94 })
93 95
94 Convey("Key bad encoding", t, func() { 96 Convey("Key bad encoding", t, func() {
95 Convey("extra junk before", func() { 97 Convey("extra junk before", func() {
96 » » » enc := KeyEncode(keys[2]) 98 » » » enc := Encode(keys[2])
97 » » » _, _, _, err := KeyToksDecode("/" + enc) 99 » » » _, _, _, err := ToksDecode("/" + enc)
98 So(err, ShouldErrLike, "illegal base64") 100 So(err, ShouldErrLike, "illegal base64")
99 }) 101 })
100 102
101 Convey("extra junk after", func() { 103 Convey("extra junk after", func() {
102 » » » enc := KeyEncode(keys[2]) 104 » » » enc := Encode(keys[2])
103 » » » _, _, _, err := KeyToksDecode(enc[:len(enc)-1]) 105 » » » _, _, _, err := ToksDecode(enc[:len(enc)-1])
104 So(err, ShouldErrLike, "EOF") 106 So(err, ShouldErrLike, "EOF")
105 }) 107 })
106 108
107 Convey("json encoding includes quotes", func() { 109 Convey("json encoding includes quotes", func() {
108 » » » data, err := KeyMarshalJSON(keys[0]) 110 » » » data, err := MarshalJSON(keys[0])
109 So(err, ShouldBeNil) 111 So(err, ShouldBeNil)
110 112
111 » » » _, _, _, err = KeyUnmarshalJSON(append(data, '!')) 113 » » » _, _, _, err = UnmarshalJSON(append(data, '!'))
112 So(err, ShouldErrLike, "bad JSON key") 114 So(err, ShouldErrLike, "bad JSON key")
113 }) 115 })
114 }) 116 })
115 } 117 }
116 118
117 type dumbKey1 struct{ Key } 119 type dumbKey1 struct{ ds.Key }
118 120
119 func (dk dumbKey1) Namespace() string { return "ns" } 121 func (dk dumbKey1) Namespace() string { return "ns" }
120 func (dk dumbKey1) Parent() Key { return dk.Key } 122 func (dk dumbKey1) Parent() ds.Key { return dk.Key }
121 func (dk dumbKey1) String() string { return "dumbKey1" } 123 func (dk dumbKey1) String() string { return "dumbKey1" }
122 124
123 type dumbKey2 struct{ Key } 125 type dumbKey2 struct{ ds.Key }
124 126
125 /// This is the dumb part... can't have both IDs set. 127 /// This is the dumb part... can't have both IDs set.
126 func (dk dumbKey2) IntID() int64 { return 1 } 128 func (dk dumbKey2) IntID() int64 { return 1 }
127 func (dk dumbKey2) StringID() string { return "wat" } 129 func (dk dumbKey2) StringID() string { return "wat" }
128 130
129 func (dk dumbKey2) Kind() string { return "kind" } 131 func (dk dumbKey2) Kind() string { return "kind" }
130 func (dk dumbKey2) Parent() Key { return nil } 132 func (dk dumbKey2) Parent() ds.Key { return nil }
131 func (dk dumbKey2) Namespace() string { return "ns" } 133 func (dk dumbKey2) Namespace() string { return "ns" }
132 func (dk dumbKey2) AppID() string { return "aid" } 134 func (dk dumbKey2) AppID() string { return "aid" }
133 func (dk dumbKey2) String() string { return "dumbKey2" } 135 func (dk dumbKey2) String() string { return "dumbKey2" }
136 func (dk dumbKey2) Valid(allowSpecial bool, aid, ns string) bool {
137 return Valid(dk, allowSpecial, aid, ns)
138 }
134 139
135 func TestBadKeyEncode(t *testing.T) { 140 func TestKeyValidity(t *testing.T) {
136 » t.Parallel() 141 » //t.Parallel()
137 142
138 » Convey("bad keys", t, func() { 143 » Convey("keys validity", t, func() {
139 Convey("incomplete", func() { 144 Convey("incomplete", func() {
140 » » » So(KeyIncomplete(mkKey("aid", "ns", "kind", 1)), ShouldB eFalse) 145 » » » So(Incomplete(mkKey("aid", "ns", "kind", 1)), ShouldBeFa lse)
141 » » » So(KeyIncomplete(mkKey("aid", "ns", "kind", 0)), ShouldB eTrue) 146 » » » So(Incomplete(mkKey("aid", "ns", "kind", 0)), ShouldBeTr ue)
142 }) 147 })
143 148
144 Convey("invalid", func() { 149 Convey("invalid", func() {
145 » » » So(KeyValid(mkKey("aid", "ns", "hat", "face", "__kind__" , 1), true, "aid", "ns"), ShouldBeTrue) 150 » » » So(mkKey("aid", "ns", "hat", "face", "__kind__", 1).Vali d(true, "aid", "ns"), ShouldBeTrue)
146 151
147 » » » bads := []Key{ 152 » » » bads := []ds.Key{
148 nil, 153 nil,
149 mkKey("", "ns", "hat", "face"), 154 mkKey("", "ns", "hat", "face"),
150 mkKey("aid", "ns", "base", 1, "", "id"), 155 mkKey("aid", "ns", "base", 1, "", "id"),
151 mkKey("aid", "ns", "hat", "face", "__kind__", 1) , 156 mkKey("aid", "ns", "hat", "face", "__kind__", 1) ,
152 mkKey("aid", "ns", "hat", 0, "kind", 1), 157 mkKey("aid", "ns", "hat", 0, "kind", 1),
153 dumbKey1{mkKey("aid", "badNS", "hat", 1)}, 158 dumbKey1{mkKey("aid", "badNS", "hat", 1)},
154 dumbKey2{}, 159 dumbKey2{},
155 } 160 }
156 for _, k := range bads { 161 for _, k := range bads {
157 s := "<nil>" 162 s := "<nil>"
158 if k != nil { 163 if k != nil {
159 s = k.String() 164 s = k.String()
160 } 165 }
161 Convey(s, func() { 166 Convey(s, func() {
162 » » » » » So(KeyValid(k, false, "aid", "ns"), Shou ldBeFalse) 167 » » » » » if k != nil {
168 » » » » » » So(k.Valid(false, "aid", "ns"), ShouldBeFalse)
169 » » » » » } else {
170 » » » » » » So(Valid(k, false, "aid", "ns"), ShouldBeFalse)
171 » » » » » }
163 }) 172 })
164 } 173 }
165 }) 174 })
175
176 Convey("partially valid", func() {
177 So(mkKey("aid", "ns", "kind", "").PartialValid("aid", "n s"), ShouldBeTrue)
178 So(mkKey("aid", "ns", "kind", "", "child", "").PartialVa lid("aid", "ns"), ShouldBeFalse)
179 })
166 }) 180 })
167 } 181 }
168 182
169 type keyWrap struct{ Key } 183 type keyWrap struct{ ds.Key }
170 184
171 func (k keyWrap) Parent() Key { 185 func (k keyWrap) Parent() ds.Key {
172 if k.Key.Parent() != nil { 186 if k.Key.Parent() != nil {
173 return keyWrap{k.Key.Parent()} 187 return keyWrap{k.Key.Parent()}
174 } 188 }
175 return nil 189 return nil
176 } 190 }
177 191
178 func TestMiscKey(t *testing.T) { 192 func TestMiscKey(t *testing.T) {
179 t.Parallel() 193 t.Parallel()
180 194
181 Convey("KeyRoot", t, func() { 195 Convey("KeyRoot", t, func() {
182 k := mkKey("appid", "ns", "parent", 10, "renerd", "moo") 196 k := mkKey("appid", "ns", "parent", 10, "renerd", "moo")
183 r := mkKey("appid", "ns", "parent", 10) 197 r := mkKey("appid", "ns", "parent", 10)
184 » » So(KeyRoot(k), ShouldEqualKey, r) 198 » » So(Root(k), ShouldEqualKey, r)
185 » » So(KeyRoot(nil), ShouldBeNil) 199 » » So(Root(nil), ShouldBeNil)
186 }) 200 })
187 201
188 Convey("KeySplit", t, func() { 202 Convey("KeySplit", t, func() {
189 // keyWrap forces KeySplit to not take the GenericKey shortcut. 203 // keyWrap forces KeySplit to not take the GenericKey shortcut.
190 k := keyWrap{mkKey("appid", "ns", "parent", 10, "renerd", "moo") } 204 k := keyWrap{mkKey("appid", "ns", "parent", 10, "renerd", "moo") }
191 » » aid, ns, toks := KeySplit(k) 205 » » aid, ns, toks := Split(k)
192 So(aid, ShouldEqual, "appid") 206 So(aid, ShouldEqual, "appid")
193 So(ns, ShouldEqual, "ns") 207 So(ns, ShouldEqual, "ns")
194 » » So(toks, ShouldResemble, []KeyTok{ 208 » » So(toks, ShouldResemble, []ds.KeyTok{
195 {Kind: "parent", IntID: 10}, 209 {Kind: "parent", IntID: 10},
196 {Kind: "renerd", StringID: "moo"}, 210 {Kind: "renerd", StringID: "moo"},
197 }) 211 })
198 }) 212 })
199 213
200 Convey("KeySplit (nil)", t, func() { 214 Convey("KeySplit (nil)", t, func() {
201 » » aid, ns, toks := KeySplit(nil) 215 » » aid, ns, toks := Split(nil)
202 So(aid, ShouldEqual, "") 216 So(aid, ShouldEqual, "")
203 So(ns, ShouldEqual, "") 217 So(ns, ShouldEqual, "")
204 » » So(toks, ShouldResemble, []KeyTok(nil)) 218 » » So(toks, ShouldResemble, []ds.KeyTok(nil))
205 }) 219 })
206 220
207 Convey("KeySplit ((*GenericKey)(nil))", t, func() { 221 Convey("KeySplit ((*GenericKey)(nil))", t, func() {
208 » » aid, ns, toks := KeySplit((*GenericKey)(nil)) 222 » » aid, ns, toks := Split((*Generic)(nil))
209 So(aid, ShouldEqual, "") 223 So(aid, ShouldEqual, "")
210 So(ns, ShouldEqual, "") 224 So(ns, ShouldEqual, "")
211 » » So(toks, ShouldResemble, []KeyTok(nil)) 225 » » So(toks, ShouldResemble, []ds.KeyTok(nil))
212 }) 226 })
213 227
214 Convey("KeysEqual", t, func() { 228 Convey("KeysEqual", t, func() {
215 k1 := mkKey("a", "n", "knd", 1) 229 k1 := mkKey("a", "n", "knd", 1)
216 k2 := mkKey("a", "n", "knd", 1) 230 k2 := mkKey("a", "n", "knd", 1)
217 » » So(KeysEqual(k1, k2), ShouldBeTrue) 231 » » So(Equal(k1, k2), ShouldBeTrue)
218 k3 := mkKey("a", "n", "knd", 2) 232 k3 := mkKey("a", "n", "knd", 2)
219 » » So(KeysEqual(k1, k3), ShouldBeFalse) 233 » » So(Equal(k1, k3), ShouldBeFalse)
220 }) 234 })
221 235
222 Convey("KeyString", t, func() { 236 Convey("KeyString", t, func() {
223 k1 := mkKey("a", "n", "knd", 1, "other", "wat") 237 k1 := mkKey("a", "n", "knd", 1, "other", "wat")
224 » » So(KeyString(k1), ShouldEqual, "/knd,1/other,wat") 238 » » So(String(k1), ShouldEqual, "/knd,1/other,wat")
225 » » So(KeyString(nil), ShouldEqual, "") 239 » » So(String(nil), ShouldEqual, "")
226 }) 240 })
227 241
228 Convey("*GenericKey supports json encoding", t, func() { 242 Convey("*GenericKey supports json encoding", t, func() {
229 type TestStruct struct { 243 type TestStruct struct {
230 » » » Key *GenericKey 244 » » » Key *Generic
231 } 245 }
232 t := &TestStruct{ 246 t := &TestStruct{
233 » » » NewKey("aid", "ns", "kind", "id", 0, 247 » » » New("aid", "ns", "kind", "id", 0,
234 » » » » NewKey("aid", "ns", "parent", "", 1, nil), 248 » » » » New("aid", "ns", "parent", "", 1, nil),
235 )} 249 )}
236 d, err := json.Marshal(t) 250 d, err := json.Marshal(t)
237 So(err, ShouldBeNil) 251 So(err, ShouldBeNil)
238 t2 := &TestStruct{} 252 t2 := &TestStruct{}
239 err = json.Unmarshal(d, t2) 253 err = json.Unmarshal(d, t2)
240 So(err, ShouldBeNil) 254 So(err, ShouldBeNil)
241 So(t, ShouldResemble, t2) 255 So(t, ShouldResemble, t2)
242 }) 256 })
243 } 257 }
OLDNEW
« no previous file with comments | « service/datastore/dskey/key.go ('k') | service/datastore/generic_key.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698