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

Side by Side Diff: service/rawdatastore/datastore_key_test.go

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

Powered by Google App Engine
This is Rietveld 408576698