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

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

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

Powered by Google App Engine
This is Rietveld 408576698