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

Side by Side Diff: service/datastore/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: 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
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 datastore
6
7 import (
8 "encoding/json"
9 "fmt"
10 "testing"
11
12 . "github.com/luci/luci-go/common/testing/assertions"
13 . "github.com/smartystreets/goconvey/convey"
14 )
15
16 func ShouldEqualKey(actual interface{}, expected ...interface{}) string {
17 if len(expected) != 1 {
18 return fmt.Sprintf("Assertion requires 1 expected value, got %d" , len(expected))
19 }
20 if actual.(*Key).Equal(expected[0].(*Key)) {
21 return ""
22 }
23 return fmt.Sprintf("Expected: %q\nActual: %q", actual, expected[0])
24 }
25
26 func TestKeyEncode(t *testing.T) {
27 t.Parallel()
28
29 keys := []*Key{
30 MakeKey("appid", "ns", "kind", 1),
31 MakeKey("appid", "ns", "nerd", "moo"),
32 MakeKey("appid", "ns", "parent", 10, "renerd", "moo"),
33 }
34
35 Convey("Key Round trip", t, func() {
36 for _, k := range keys {
37 k := k
38 Convey(k.String(), func() {
39 enc := k.Encode()
40 dec, err := NewKeyEncoded(enc)
41 So(err, ShouldBeNil)
42 So(dec, ShouldNotBeNil)
43 So(dec, ShouldEqualKey, k)
44
45 dec2, err := NewKeyEncoded(enc)
46 So(err, ShouldBeNil)
47 So(dec2, ShouldEqualKey, dec)
48 So(dec2, ShouldEqualKey, k)
49 })
50
51 Convey(k.String()+" (json)", func() {
52 data, err := k.MarshalJSON()
53 So(err, ShouldBeNil)
54
55 dec := &Key{}
56 So(dec.UnmarshalJSON(data), ShouldBeNil)
57 So(dec, ShouldEqualKey, k)
58 })
59 }
60 })
61
62 Convey("NewKey", t, func() {
63 Convey("single", func() {
64 k := NewKey("appid", "ns", "kind", "", 1, nil)
65 So(k, ShouldEqualKey, keys[0])
66 })
67
68 Convey("empty", func() {
69 So(NewKeyToks("appid", "ns", nil), ShouldBeNil)
70 })
71
72 Convey("nest", func() {
73 k := NewKey("appid", "ns", "renerd", "moo", 0,
74 NewKey("appid", "ns", "parent", "", 10, nil))
75 So(k, ShouldEqualKey, keys[2])
76 })
77 })
78
79 Convey("Key bad encoding", t, func() {
80 Convey("extra junk before", func() {
81 enc := keys[2].Encode()
82 _, err := NewKeyEncoded("/" + enc)
83 So(err, ShouldErrLike, "illegal base64")
84 })
85
86 Convey("extra junk after", func() {
87 enc := keys[2].Encode()
88 _, err := NewKeyEncoded(enc[:len(enc)-1])
89 So(err, ShouldErrLike, "EOF")
90 })
91
92 Convey("json encoding includes quotes", func() {
93 data, err := keys[0].MarshalJSON()
94 So(err, ShouldBeNil)
95
96 dec := &Key{}
97 err = dec.UnmarshalJSON(append(data, '!'))
98 So(err, ShouldErrLike, "bad JSON key")
99 })
100 })
101 }
102
103 func TestKeyValidity(t *testing.T) {
104 //t.Parallel()
105
106 Convey("keys validity", t, func() {
107 Convey("incomplete", func() {
108 So(MakeKey("aid", "ns", "kind", 1).Incomplete(), ShouldB eFalse)
109 So(MakeKey("aid", "ns", "kind", 0).Incomplete(), ShouldB eTrue)
110 })
111
112 Convey("invalid", func() {
113 So(MakeKey("aid", "ns", "hat", "face", "__kind__", 1).Va lid(true, "aid", "ns"), ShouldBeTrue)
114
115 bads := []*Key{
116 nil,
117 NewKeyToks("aid", "ns", []KeyTok{{"Kind", 1, "1" }}),
118 MakeKey("", "ns", "hat", "face"),
119 MakeKey("aid", "ns", "base", 1, "", "id"),
120 MakeKey("aid", "ns", "hat", "face", "__kind__", 1),
121 MakeKey("aid", "ns", "hat", 0, "kind", 1),
122 }
123 for _, k := range bads {
124 s := "<nil>"
125 if k != nil {
126 s = k.String()
127 }
128 Convey(s, func() {
129 So(k.Valid(false, "aid", "ns"), ShouldBe False)
130 })
131 }
132 })
133
134 Convey("partially valid", func() {
135 So(MakeKey("aid", "ns", "kind", "").PartialValid("aid", "ns"), ShouldBeTrue)
136 So(MakeKey("aid", "ns", "kind", "", "child", "").Partial Valid("aid", "ns"), ShouldBeFalse)
137 })
138 })
139 }
140
141 func TestMiscKey(t *testing.T) {
142 t.Parallel()
143
144 Convey("KeyRoot", t, func() {
145 k := MakeKey("appid", "ns", "parent", 10, "renerd", "moo")
146 r := MakeKey("appid", "ns", "parent", 10)
147 So(k.Root(), ShouldEqualKey, r)
148 So((*Key)(nil).Root(), ShouldBeNil)
149 })
150
151 Convey("KeySplit", t, func() {
152 aid, ns, toks := (*Key)(nil).Split()
153 So(aid, ShouldEqual, "")
154 So(ns, ShouldEqual, "")
155 So(toks, ShouldResemble, []KeyTok(nil))
156 })
157
158 Convey("KeysEqual", t, func() {
159 k1 := MakeKey("a", "n", "knd", 1)
160 k2 := MakeKey("a", "n", "knd", 1)
161 So(k1.Equal(k2), ShouldBeTrue)
162 k3 := MakeKey("a", "n", "knd", 2)
163 So(k1.Equal(k3), ShouldBeFalse)
164 })
165
166 Convey("KeyString", t, func() {
167 k1 := MakeKey("a", "n", "knd", 1, "other", "wat")
168 So(k1.String(), ShouldEqual, "a:n:/knd,1/other,\"wat\"")
169 So((*Key)(nil).String(), ShouldEqual, "")
170 })
171
172 Convey("*GenericKey supports json encoding", t, func() {
173 type TestStruct struct {
174 Key *Key
175 }
176 t := &TestStruct{
177 NewKey("aid", "ns", "kind", "id", 0,
178 NewKey("aid", "ns", "parent", "", 1, nil),
179 )}
180 d, err := json.Marshal(t)
181 So(err, ShouldBeNil)
182 t2 := &TestStruct{}
183 err = json.Unmarshal(d, t2)
184 So(err, ShouldBeNil)
185 So(t.Key, ShouldEqualKey, t2.Key)
186 })
187 }
188
189 func shouldBeLess(actual interface{}, expected ...interface{}) string {
190 a, b := actual.(*Key), expected[0].(*Key)
191 if a.Less(b) {
192 return ""
193 }
194 return fmt.Sprintf("Expected %q < %q", a.String(), b.String())
195 }
196
197 func shouldNotBeEqual(actual interface{}, expected ...interface{}) string {
198 a, b := actual.(*Key), expected[0].(*Key)
199 if !a.Equal(b) {
200 return ""
201 }
202 return fmt.Sprintf("Expected %q != %q", a.String(), b.String())
203 }
204
205 func shouldNotBeLess(actual interface{}, expected ...interface{}) string {
206 a, b := actual.(*Key), expected[0].(*Key)
207 if !a.Less(b) {
208 return ""
209 }
210 return fmt.Sprintf("Expected !(%q < %q)", a.String(), b.String())
211 }
212
213 func TestKeySort(t *testing.T) {
214 t.Parallel()
215
216 Convey("KeyTok.Less() works", t, func() {
217 So((KeyTok{"a", 0, "1"}).Less(KeyTok{"b", 0, "2"}), ShouldBeTrue )
218 So((KeyTok{"b", 0, "1"}).Less(KeyTok{"a", 0, "2"}), ShouldBeFals e)
219 So((KeyTok{"kind", 0, "1"}).Less(KeyTok{"kind", 0, "2"}), Should BeTrue)
220 So((KeyTok{"kind", 1, ""}).Less(KeyTok{"kind", 2, ""}), ShouldBe True)
221 So((KeyTok{"kind", 1, ""}).Less(KeyTok{"kind", 0, "1"}), ShouldB eTrue)
222 })
223
224 Convey("Key comparison works", t, func() {
225 So((*Key)(nil).Equal(nil), ShouldBeTrue)
226
227 s := []*Key{
228 nil,
229 MakeKey("A", "", "kind", 1),
230 MakeKey("A", "n", "kind", 1),
231 MakeKey("A", "n", "kind", 1, "something", "else"),
232 MakeKey("A", "n", "kind", "1"),
233 MakeKey("A", "n", "kind", "1", "something", "else"),
234 MakeKey("A", "n", "other", 1, "something", "else"),
235 MakeKey("a", "", "kind", 1),
236 MakeKey("a", "n", "kind", 1),
237 MakeKey("a", "n", "kind", 2),
238 MakeKey("a", "p", "aleph", 1),
239 MakeKey("b", "n", "kind", 2),
240 }
241
242 for i := 1; i < len(s); i++ {
243 So(s[i-1], shouldBeLess, s[i])
244 So(s[i-1], shouldNotBeEqual, s[i])
245 So(s[i], shouldNotBeEqual, s[i-1])
246 So(s[i], shouldNotBeLess, s[i-1])
247 }
248 })
249 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698