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

Side by Side Diff: impl/memory/raw_datastore_test.go

Issue 1270063002: Rename rawdatastore -> datastore (Closed) Base URL: https://github.com/luci/gae.git@master
Patch Set: and a bit more 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 | « impl/memory/raw_datastore_query.go ('k') | impl/memory/taskqueue_data.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 memory 5 package memory
6 6
7 import ( 7 import (
8 "fmt" 8 "fmt"
9 "math" 9 "math"
10 "testing" 10 "testing"
11 11
12 » rdsS "github.com/luci/gae/service/rawdatastore" 12 » dsS "github.com/luci/gae/service/datastore"
13 . "github.com/smartystreets/goconvey/convey" 13 . "github.com/smartystreets/goconvey/convey"
14 "golang.org/x/net/context" 14 "golang.org/x/net/context"
15 ) 15 )
16 16
17 func TestDatastoreKinder(t *testing.T) { 17 func TestDatastoreKinder(t *testing.T) {
18 t.Parallel() 18 t.Parallel()
19 19
20 Convey("Datastore keys", t, func() { 20 Convey("Datastore keys", t, func() {
21 c := Use(context.Background()) 21 c := Use(context.Background())
22 » » rds := rdsS.Get(c) 22 » » ds := dsS.Get(c)
23 » » So(rds, ShouldNotBeNil) 23 » » So(ds, ShouldNotBeNil)
24 24
25 Convey("implements DSNewKeyer", func() { 25 Convey("implements DSNewKeyer", func() {
26 Convey("NewKey", func() { 26 Convey("NewKey", func() {
27 » » » » key := rds.NewKey("nerd", "stringID", 0, nil) 27 » » » » key := ds.NewKey("nerd", "stringID", 0, nil)
28 So(key, ShouldNotBeNil) 28 So(key, ShouldNotBeNil)
29 So(key.Kind(), ShouldEqual, "nerd") 29 So(key.Kind(), ShouldEqual, "nerd")
30 So(key.StringID(), ShouldEqual, "stringID") 30 So(key.StringID(), ShouldEqual, "stringID")
31 So(key.IntID(), ShouldEqual, 0) 31 So(key.IntID(), ShouldEqual, 0)
32 So(key.Parent(), ShouldBeNil) 32 So(key.Parent(), ShouldBeNil)
33 So(key.AppID(), ShouldEqual, "dev~app") 33 So(key.AppID(), ShouldEqual, "dev~app")
34 So(key.Namespace(), ShouldEqual, "") 34 So(key.Namespace(), ShouldEqual, "")
35 So(key.String(), ShouldEqual, "/nerd,stringID") 35 So(key.String(), ShouldEqual, "/nerd,stringID")
36 » » » » So(rdsS.KeyIncomplete(key), ShouldBeFalse) 36 » » » » So(dsS.KeyIncomplete(key), ShouldBeFalse)
37 » » » » So(rdsS.KeyValid(key, false, "dev~app", ""), Sho uldBeTrue) 37 » » » » So(dsS.KeyValid(key, false, "dev~app", ""), Shou ldBeTrue)
38 }) 38 })
39 }) 39 })
40 40
41 }) 41 })
42 } 42 }
43 43
44 func testGetMeta(c context.Context, k rdsS.Key) int64 { 44 func testGetMeta(c context.Context, k dsS.Key) int64 {
45 » rds := rdsS.Get(c) 45 » ds := dsS.Get(c)
46 retval := int64(0) 46 retval := int64(0)
47 » err := rds.GetMulti([]rdsS.Key{rds.NewKey("__entity_group__", "", 1, rds S.KeyRoot(k))}, func(val rdsS.PropertyMap, err error) { 47 » err := ds.GetMulti([]dsS.Key{ds.NewKey("__entity_group__", "", 1, dsS.Ke yRoot(k))}, func(val dsS.PropertyMap, err error) {
48 if err != nil { 48 if err != nil {
49 panic(err) 49 panic(err)
50 } 50 }
51 retval = val["__version__"][0].Value().(int64) 51 retval = val["__version__"][0].Value().(int64)
52 }) 52 })
53 if err != nil { 53 if err != nil {
54 panic(err) 54 panic(err)
55 } 55 }
56 return retval 56 return retval
57 } 57 }
58 58
59 var pls = rdsS.GetPLS 59 var pls = dsS.GetPLS
60 60
61 func TestDatastoreSingleReadWriter(t *testing.T) { 61 func TestDatastoreSingleReadWriter(t *testing.T) {
62 t.Parallel() 62 t.Parallel()
63 63
64 » getOnePM := func(rds rdsS.Interface, key rdsS.Key) (pmap rdsS.PropertyMa p, err error) { 64 » getOnePM := func(ds dsS.Interface, key dsS.Key) (pmap dsS.PropertyMap, e rr error) {
65 » » blankErr := rds.GetMulti([]rdsS.Key{key}, func(itmPmap rdsS.Prop ertyMap, itmErr error) { 65 » » blankErr := ds.GetMulti([]dsS.Key{key}, func(itmPmap dsS.Propert yMap, itmErr error) {
66 pmap = itmPmap 66 pmap = itmPmap
67 err = itmErr 67 err = itmErr
68 }) 68 })
69 So(blankErr, ShouldBeNil) 69 So(blankErr, ShouldBeNil)
70 return 70 return
71 } 71 }
72 72
73 » delOneErr := func(rds rdsS.Interface, key rdsS.Key) (err error) { 73 » delOneErr := func(ds dsS.Interface, key dsS.Key) (err error) {
74 » » blankErr := rds.DeleteMulti([]rdsS.Key{key}, func(itmErr error) { 74 » » blankErr := ds.DeleteMulti([]dsS.Key{key}, func(itmErr error) {
75 err = itmErr 75 err = itmErr
76 }) 76 })
77 So(blankErr, ShouldBeNil) 77 So(blankErr, ShouldBeNil)
78 return 78 return
79 } 79 }
80 80
81 » delOne := func(rds rdsS.Interface, key rdsS.Key) { 81 » delOne := func(ds dsS.Interface, key dsS.Key) {
82 » » So(delOneErr(rds, key), ShouldBeNil) 82 » » So(delOneErr(ds, key), ShouldBeNil)
83 } 83 }
84 84
85 » getOne := func(rds rdsS.Interface, key rdsS.Key, dst interface{}) { 85 » getOne := func(ds dsS.Interface, key dsS.Key, dst interface{}) {
86 » » pm, err := getOnePM(rds, key) 86 » » pm, err := getOnePM(ds, key)
87 So(err, ShouldBeNil) 87 So(err, ShouldBeNil)
88 So(pls(dst).Load(pm), ShouldBeNil) 88 So(pls(dst).Load(pm), ShouldBeNil)
89 } 89 }
90 90
91 » putOneErr := func(rds rdsS.Interface, key rdsS.Key, val interface{}) (re tKey rdsS.Key, err error) { 91 » putOneErr := func(ds dsS.Interface, key dsS.Key, val interface{}) (retKe y dsS.Key, err error) {
92 » » blankErr := rds.PutMulti([]rdsS.Key{key}, []rdsS.PropertyLoadSav er{pls(val)}, func(itmKey rdsS.Key, itmErr error) { 92 » » blankErr := ds.PutMulti([]dsS.Key{key}, []dsS.PropertyLoadSaver{ pls(val)}, func(itmKey dsS.Key, itmErr error) {
93 err = itmErr 93 err = itmErr
94 retKey = itmKey 94 retKey = itmKey
95 }) 95 })
96 So(blankErr, ShouldBeNil) 96 So(blankErr, ShouldBeNil)
97 return 97 return
98 } 98 }
99 99
100 » putOne := func(rds rdsS.Interface, key rdsS.Key, val interface{}) (retKe y rdsS.Key) { 100 » putOne := func(ds dsS.Interface, key dsS.Key, val interface{}) (retKey d sS.Key) {
101 » » key, err := putOneErr(rds, key, val) 101 » » key, err := putOneErr(ds, key, val)
102 So(err, ShouldBeNil) 102 So(err, ShouldBeNil)
103 return key 103 return key
104 } 104 }
105 105
106 Convey("Datastore single reads and writes", t, func() { 106 Convey("Datastore single reads and writes", t, func() {
107 c := Use(context.Background()) 107 c := Use(context.Background())
108 » » rds := rdsS.Get(c) 108 » » ds := dsS.Get(c)
109 » » So(rds, ShouldNotBeNil) 109 » » So(ds, ShouldNotBeNil)
110 110
111 Convey("implements DSSingleReadWriter", func() { 111 Convey("implements DSSingleReadWriter", func() {
112 type Foo struct { 112 type Foo struct {
113 Val int 113 Val int
114 } 114 }
115 115
116 Convey("getting objects that DNE is an error", func() { 116 Convey("getting objects that DNE is an error", func() {
117 » » » » _, err := getOnePM(rds, rds.NewKey("Foo", "", 1, nil)) 117 » » » » _, err := getOnePM(ds, ds.NewKey("Foo", "", 1, n il))
118 » » » » So(err, ShouldEqual, rdsS.ErrNoSuchEntity) 118 » » » » So(err, ShouldEqual, dsS.ErrNoSuchEntity)
119 }) 119 })
120 120
121 Convey("Can Put stuff", func() { 121 Convey("Can Put stuff", func() {
122 // with an incomplete key! 122 // with an incomplete key!
123 » » » » k := rds.NewKey("Foo", "", 0, nil) 123 » » » » k := ds.NewKey("Foo", "", 0, nil)
124 f := &Foo{Val: 10} 124 f := &Foo{Val: 10}
125 » » » » k = putOne(rds, k, f) 125 » » » » k = putOne(ds, k, f)
126 So(k.String(), ShouldEqual, "/Foo,1") 126 So(k.String(), ShouldEqual, "/Foo,1")
127 127
128 Convey("and Get it back", func() { 128 Convey("and Get it back", func() {
129 newFoo := &Foo{} 129 newFoo := &Foo{}
130 » » » » » getOne(rds, k, newFoo) 130 » » » » » getOne(ds, k, newFoo)
131 So(newFoo, ShouldResemble, f) 131 So(newFoo, ShouldResemble, f)
132 132
133 Convey("and we can Delete it", func() { 133 Convey("and we can Delete it", func() {
134 » » » » » » delOne(rds, k) 134 » » » » » » delOne(ds, k)
135 » » » » » » _, err := getOnePM(rds, k) 135 » » » » » » _, err := getOnePM(ds, k)
136 » » » » » » So(err, ShouldEqual, rdsS.ErrNoS uchEntity) 136 » » » » » » So(err, ShouldEqual, dsS.ErrNoSu chEntity)
137 }) 137 })
138 }) 138 })
139 Convey("Deleteing with a bogus key is bad", func () { 139 Convey("Deleteing with a bogus key is bad", func () {
140 » » » » » So(delOneErr(rds, rds.NewKey("Foo", "wat ", 100, nil)), ShouldEqual, rdsS.ErrInvalidKey) 140 » » » » » So(delOneErr(ds, ds.NewKey("Foo", "wat", 100, nil)), ShouldEqual, dsS.ErrInvalidKey)
141 }) 141 })
142 Convey("Deleteing a DNE entity is fine", func() { 142 Convey("Deleteing a DNE entity is fine", func() {
143 » » » » » delOne(rds, rds.NewKey("Foo", "wat", 0, nil)) 143 » » » » » delOne(ds, ds.NewKey("Foo", "wat", 0, ni l))
144 }) 144 })
145 145
146 Convey("with multiple puts", func() { 146 Convey("with multiple puts", func() {
147 So(testGetMeta(c, k), ShouldEqual, 1) 147 So(testGetMeta(c, k), ShouldEqual, 1)
148 148
149 » » » » » keys := []rdsS.Key{} 149 » » » » » keys := []dsS.Key{}
150 » » » » » vals := []rdsS.PropertyLoadSaver{} 150 » » » » » vals := []dsS.PropertyLoadSaver{}
151 151
152 pkey := k 152 pkey := k
153 for i := 0; i < 10; i++ { 153 for i := 0; i < 10; i++ {
154 » » » » » » keys = append(keys, rds.NewKey(" Foo", "", 0, pkey)) 154 » » » » » » keys = append(keys, ds.NewKey("F oo", "", 0, pkey))
155 vals = append(vals, pls(&Foo{Val : 10})) 155 vals = append(vals, pls(&Foo{Val : 10}))
156 } 156 }
157 i := 0 157 i := 0
158 » » » » » err := rds.PutMulti(keys, vals, func(k r dsS.Key, err error) { 158 » » » » » err := ds.PutMulti(keys, vals, func(k ds S.Key, err error) {
159 So(err, ShouldBeNil) 159 So(err, ShouldBeNil)
160 keys[i] = k 160 keys[i] = k
161 i++ 161 i++
162 }) 162 })
163 So(err, ShouldBeNil) 163 So(err, ShouldBeNil)
164 So(testGetMeta(c, k), ShouldEqual, 11) 164 So(testGetMeta(c, k), ShouldEqual, 11)
165 165
166 Convey("ensure that group versions persi st across deletes", func() { 166 Convey("ensure that group versions persi st across deletes", func() {
167 keys = append(keys, pkey) 167 keys = append(keys, pkey)
168 » » » » » » err := rds.DeleteMulti(keys, fun c(err error) { 168 » » » » » » err := ds.DeleteMulti(keys, func (err error) {
169 So(err, ShouldBeNil) 169 So(err, ShouldBeNil)
170 }) 170 })
171 So(err, ShouldBeNil) 171 So(err, ShouldBeNil)
172 172
173 // TODO(riannucci): replace with a Count query instead of this cast 173 // TODO(riannucci): replace with a Count query instead of this cast
174 /* 174 /*
175 » » » » » » » ents := rds.(*dsImpl).da ta.store.GetCollection("ents:") 175 » » » » » » » ents := ds.(*dsImpl).dat a.store.GetCollection("ents:")
176 num, _ := ents.GetTotals () 176 num, _ := ents.GetTotals ()
177 // /__entity_root_ids__, Foo 177 // /__entity_root_ids__, Foo
178 // /Foo,1/__entity_group __,1 178 // /Foo,1/__entity_group __,1
179 // /Foo,1/__entity_group _ids__,1 179 // /Foo,1/__entity_group _ids__,1
180 So(num, ShouldEqual, 3) 180 So(num, ShouldEqual, 3)
181 */ 181 */
182 182
183 So(testGetMeta(c, k), ShouldEqua l, 22) 183 So(testGetMeta(c, k), ShouldEqua l, 22)
184 184
185 » » » » » » putOne(rds, k, f) 185 » » » » » » putOne(ds, k, f)
186 So(testGetMeta(c, k), ShouldEqua l, 23) 186 So(testGetMeta(c, k), ShouldEqua l, 23)
187 }) 187 })
188 188
189 Convey("can Get", func() { 189 Convey("can Get", func() {
190 » » » » » » vals := []rdsS.PropertyMap{} 190 » » » » » » vals := []dsS.PropertyMap{}
191 » » » » » » err := rds.GetMulti(keys, func(p m rdsS.PropertyMap, err error) { 191 » » » » » » err := ds.GetMulti(keys, func(pm dsS.PropertyMap, err error) {
192 So(err, ShouldBeNil) 192 So(err, ShouldBeNil)
193 vals = append(vals, pm) 193 vals = append(vals, pm)
194 }) 194 })
195 So(err, ShouldBeNil) 195 So(err, ShouldBeNil)
196 196
197 for _, val := range vals { 197 for _, val := range vals {
198 » » » » » » » So(val, ShouldResemble, rdsS.PropertyMap{"Val": {rdsS.MkProperty(10)}}) 198 » » » » » » » So(val, ShouldResemble, dsS.PropertyMap{"Val": {dsS.MkProperty(10)}})
199 } 199 }
200 }) 200 })
201 }) 201 })
202 }) 202 })
203 }) 203 })
204 204
205 Convey("implements DSTransactioner", func() { 205 Convey("implements DSTransactioner", func() {
206 type Foo struct { 206 type Foo struct {
207 Val int 207 Val int
208 } 208 }
209 Convey("Put", func() { 209 Convey("Put", func() {
210 f := &Foo{Val: 10} 210 f := &Foo{Val: 10}
211 » » » » origKey := rds.NewKey("Foo", "", 0, nil) 211 » » » » origKey := ds.NewKey("Foo", "", 0, nil)
212 » » » » k := putOne(rds, origKey, f) 212 » » » » k := putOne(ds, origKey, f)
213 So(k.String(), ShouldEqual, "/Foo,1") 213 So(k.String(), ShouldEqual, "/Foo,1")
214 214
215 Convey("can Put new entity groups", func() { 215 Convey("can Put new entity groups", func() {
216 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 216 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
217 » » » » » » rds := rdsS.Get(c) 217 » » » » » » ds := dsS.Get(c)
218 218
219 f1 := &Foo{Val: 100} 219 f1 := &Foo{Val: 100}
220 » » » » » » k := putOne(rds, origKey, f1) 220 » » » » » » k := putOne(ds, origKey, f1)
221 So(k.String(), ShouldEqual, "/Fo o,2") 221 So(k.String(), ShouldEqual, "/Fo o,2")
222 222
223 f2 := &Foo{Val: 200} 223 f2 := &Foo{Val: 200}
224 » » » » » » k = putOne(rds, origKey, f2) 224 » » » » » » k = putOne(ds, origKey, f2)
225 So(k.String(), ShouldEqual, "/Fo o,3") 225 So(k.String(), ShouldEqual, "/Fo o,3")
226 226
227 return nil 227 return nil
228 » » » » » }, &rdsS.TransactionOptions{XG: true}) 228 » » » » » }, &dsS.TransactionOptions{XG: true})
229 So(err, ShouldBeNil) 229 So(err, ShouldBeNil)
230 230
231 f := &Foo{} 231 f := &Foo{}
232 » » » » » getOne(rds, rds.NewKey("Foo", "", 2, nil ), f) 232 » » » » » getOne(ds, ds.NewKey("Foo", "", 2, nil), f)
233 So(f.Val, ShouldEqual, 100) 233 So(f.Val, ShouldEqual, 100)
234 234
235 » » » » » getOne(rds, rds.NewKey("Foo", "", 3, nil ), f) 235 » » » » » getOne(ds, ds.NewKey("Foo", "", 3, nil), f)
236 So(f.Val, ShouldEqual, 200) 236 So(f.Val, ShouldEqual, 200)
237 }) 237 })
238 238
239 Convey("can Put new entities in a current group" , func() { 239 Convey("can Put new entities in a current group" , func() {
240 par := k 240 par := k
241 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 241 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
242 » » » » » » rds := rdsS.Get(c) 242 » » » » » » ds := dsS.Get(c)
243 » » » » » » So(rds, ShouldNotBeNil) 243 » » » » » » So(ds, ShouldNotBeNil)
244 244
245 f1 := &Foo{Val: 100} 245 f1 := &Foo{Val: 100}
246 » » » » » » k := putOne(rds, rds.NewKey("Foo ", "", 0, par), f1) 246 » » » » » » k := putOne(ds, ds.NewKey("Foo", "", 0, par), f1)
247 So(k.String(), ShouldEqual, "/Fo o,1/Foo,1") 247 So(k.String(), ShouldEqual, "/Fo o,1/Foo,1")
248 248
249 f2 := &Foo{Val: 200} 249 f2 := &Foo{Val: 200}
250 » » » » » » k = putOne(rds, rds.NewKey("Foo" , "", 0, par), f2) 250 » » » » » » k = putOne(ds, ds.NewKey("Foo", "", 0, par), f2)
251 So(k.String(), ShouldEqual, "/Fo o,1/Foo,2") 251 So(k.String(), ShouldEqual, "/Fo o,1/Foo,2")
252 252
253 return nil 253 return nil
254 }, nil) 254 }, nil)
255 So(err, ShouldBeNil) 255 So(err, ShouldBeNil)
256 256
257 f := &Foo{} 257 f := &Foo{}
258 » » » » » getOne(rds, rds.NewKey("Foo", "", 1, k), f) 258 » » » » » getOne(ds, ds.NewKey("Foo", "", 1, k), f )
259 So(f.Val, ShouldEqual, 100) 259 So(f.Val, ShouldEqual, 100)
260 260
261 » » » » » getOne(rds, rds.NewKey("Foo", "", 2, k), f) 261 » » » » » getOne(ds, ds.NewKey("Foo", "", 2, k), f )
262 So(f.Val, ShouldEqual, 200) 262 So(f.Val, ShouldEqual, 200)
263 }) 263 })
264 264
265 Convey("Deletes work too", func() { 265 Convey("Deletes work too", func() {
266 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 266 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
267 » » » » » » rds := rdsS.Get(c) 267 » » » » » » ds := dsS.Get(c)
268 » » » » » » So(rds, ShouldNotBeNil) 268 » » » » » » So(ds, ShouldNotBeNil)
269 » » » » » » delOne(rds, k) 269 » » » » » » delOne(ds, k)
270 return nil 270 return nil
271 }, nil) 271 }, nil)
272 So(err, ShouldBeNil) 272 So(err, ShouldBeNil)
273 » » » » » _, err = getOnePM(rds, k) 273 » » » » » _, err = getOnePM(ds, k)
274 » » » » » So(err, ShouldEqual, rdsS.ErrNoSuchEntit y) 274 » » » » » So(err, ShouldEqual, dsS.ErrNoSuchEntity )
275 }) 275 })
276 276
277 Convey("A Get counts against your group count", func() { 277 Convey("A Get counts against your group count", func() {
278 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 278 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
279 » » » » » » rds := rdsS.Get(c) 279 » » » » » » ds := dsS.Get(c)
280 280
281 » » » » » » _, err := getOnePM(rds, rds.NewK ey("Foo", "", 20, nil)) 281 » » » » » » _, err := getOnePM(ds, ds.NewKey ("Foo", "", 20, nil))
282 » » » » » » So(err, ShouldEqual, rdsS.ErrNoS uchEntity) 282 » » » » » » So(err, ShouldEqual, dsS.ErrNoSu chEntity)
283 283
284 » » » » » » err = rds.GetMulti([]rdsS.Key{k} , func(_ rdsS.PropertyMap, err error) { 284 » » » » » » err = ds.GetMulti([]dsS.Key{k}, func(_ dsS.PropertyMap, err error) {
285 So(err, ShouldBeNil) 285 So(err, ShouldBeNil)
286 }) 286 })
287 So(err.Error(), ShouldContainSub string, "cross-group") 287 So(err.Error(), ShouldContainSub string, "cross-group")
288 return nil 288 return nil
289 }, nil) 289 }, nil)
290 So(err, ShouldBeNil) 290 So(err, ShouldBeNil)
291 }) 291 })
292 292
293 Convey("Get takes a snapshot", func() { 293 Convey("Get takes a snapshot", func() {
294 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 294 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
295 » » » » » » txnDS := rdsS.Get(c) 295 » » » » » » txnDS := dsS.Get(c)
296 So(txnDS, ShouldNotBeNil) 296 So(txnDS, ShouldNotBeNil)
297 297
298 getOne(txnDS, k, f) 298 getOne(txnDS, k, f)
299 So(f.Val, ShouldEqual, 10) 299 So(f.Val, ShouldEqual, 10)
300 300
301 // Don't ever do this in a real program unless you want to guarantee 301 // Don't ever do this in a real program unless you want to guarantee
302 // a failed transaction :) 302 // a failed transaction :)
303 f.Val = 11 303 f.Val = 11
304 » » » » » » putOne(rds, k, f) 304 » » » » » » putOne(ds, k, f)
305 305
306 getOne(txnDS, k, f) 306 getOne(txnDS, k, f)
307 So(f.Val, ShouldEqual, 10) 307 So(f.Val, ShouldEqual, 10)
308 308
309 return nil 309 return nil
310 }, nil) 310 }, nil)
311 So(err, ShouldBeNil) 311 So(err, ShouldBeNil)
312 312
313 f := &Foo{} 313 f := &Foo{}
314 » » » » » getOne(rds, k, f) 314 » » » » » getOne(ds, k, f)
315 So(f.Val, ShouldEqual, 11) 315 So(f.Val, ShouldEqual, 11)
316 }) 316 })
317 317
318 Convey("and snapshots are consistent even after Puts", func() { 318 Convey("and snapshots are consistent even after Puts", func() {
319 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 319 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
320 » » » » » » txnDS := rdsS.Get(c) 320 » » » » » » txnDS := dsS.Get(c)
321 So(txnDS, ShouldNotBeNil) 321 So(txnDS, ShouldNotBeNil)
322 322
323 f := &Foo{} 323 f := &Foo{}
324 getOne(txnDS, k, f) 324 getOne(txnDS, k, f)
325 So(f.Val, ShouldEqual, 10) 325 So(f.Val, ShouldEqual, 10)
326 326
327 // Don't ever do this in a real program unless you want to guarantee 327 // Don't ever do this in a real program unless you want to guarantee
328 // a failed transaction :) 328 // a failed transaction :)
329 f.Val = 11 329 f.Val = 11
330 » » » » » » putOne(rds, k, f) 330 » » » » » » putOne(ds, k, f)
331 331
332 getOne(txnDS, k, f) 332 getOne(txnDS, k, f)
333 So(f.Val, ShouldEqual, 10) 333 So(f.Val, ShouldEqual, 10)
334 334
335 f.Val = 20 335 f.Val = 20
336 putOne(txnDS, k, f) 336 putOne(txnDS, k, f)
337 337
338 getOne(txnDS, k, f) 338 getOne(txnDS, k, f)
339 So(f.Val, ShouldEqual, 10) // st ill gets 10 339 So(f.Val, ShouldEqual, 10) // st ill gets 10
340 340
341 return nil 341 return nil
342 }, nil) 342 }, nil)
343 So(err.Error(), ShouldContainSubstring, "concurrent") 343 So(err.Error(), ShouldContainSubstring, "concurrent")
344 344
345 f := &Foo{} 345 f := &Foo{}
346 » » » » » getOne(rds, k, f) 346 » » » » » getOne(ds, k, f)
347 So(f.Val, ShouldEqual, 11) 347 So(f.Val, ShouldEqual, 11)
348 }) 348 })
349 349
350 Convey("Reusing a transaction context is bad new s", func() { 350 Convey("Reusing a transaction context is bad new s", func() {
351 » » » » » k := rds.NewKey("Foo", "", 1, nil) 351 » » » » » k := ds.NewKey("Foo", "", 1, nil)
352 » » » » » txnDS := rdsS.Interface(nil) 352 » » » » » txnDS := dsS.Interface(nil)
353 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 353 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
354 » » » » » » txnDS = rdsS.Get(c) 354 » » » » » » txnDS = dsS.Get(c)
355 getOnePM(txnDS, k) 355 getOnePM(txnDS, k)
356 return nil 356 return nil
357 }, nil) 357 }, nil)
358 So(err, ShouldBeNil) 358 So(err, ShouldBeNil)
359 » » » » » err = txnDS.GetMulti([]rdsS.Key{k}, func (_ rdsS.PropertyMap, err error) { 359 » » » » » err = txnDS.GetMulti([]dsS.Key{k}, func( _ dsS.PropertyMap, err error) {
360 So(err, ShouldBeNil) 360 So(err, ShouldBeNil)
361 }) 361 })
362 So(err.Error(), ShouldContainSubstring, "expired") 362 So(err.Error(), ShouldContainSubstring, "expired")
363 }) 363 })
364 364
365 Convey("Nested transactions are rejected", func( ) { 365 Convey("Nested transactions are rejected", func( ) {
366 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 366 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
367 » » » » » » err := rdsS.Get(c).RunInTransact ion(func(c context.Context) error { 367 » » » » » » err := dsS.Get(c).RunInTransacti on(func(c context.Context) error {
368 panic("noooo") 368 panic("noooo")
369 }, nil) 369 }, nil)
370 So(err.Error(), ShouldContainSub string, "nested transactions") 370 So(err.Error(), ShouldContainSub string, "nested transactions")
371 return nil 371 return nil
372 }, nil) 372 }, nil)
373 So(err, ShouldBeNil) 373 So(err, ShouldBeNil)
374 }) 374 })
375 375
376 Convey("Concurrent transactions only accept one set of changes", func() { 376 Convey("Concurrent transactions only accept one set of changes", func() {
377 // Note: I think this implementation is actually /slightly/ wrong. 377 // Note: I think this implementation is actually /slightly/ wrong.
378 // Accorting to my read of the docs for appengine, when you open a 378 // Accorting to my read of the docs for appengine, when you open a
379 // transaction it actually (essentially) holds a reference to the 379 // transaction it actually (essentially) holds a reference to the
380 // entire datastore. Our implementation takes a snapshot of the 380 // entire datastore. Our implementation takes a snapshot of the
381 // entity group as soon as something obs erves/affects it. 381 // entity group as soon as something obs erves/affects it.
382 // 382 //
383 // That said... I'm not sure if there's really a semantic difference. 383 // That said... I'm not sure if there's really a semantic difference.
384 » » » » » err := rds.RunInTransaction(func(c conte xt.Context) error { 384 » » » » » err := ds.RunInTransaction(func(c contex t.Context) error {
385 » » » » » » txnDS := rdsS.Get(c) 385 » » » » » » txnDS := dsS.Get(c)
386 f := &Foo{Val: 21} 386 f := &Foo{Val: 21}
387 putOne(txnDS, k, f) 387 putOne(txnDS, k, f)
388 388
389 » » » » » » err := rds.RunInTransaction(func (c context.Context) error { 389 » » » » » » err := ds.RunInTransaction(func( c context.Context) error {
390 » » » » » » » txnDS := rdsS.Get(c) 390 » » » » » » » txnDS := dsS.Get(c)
391 f := &Foo{Val: 27} 391 f := &Foo{Val: 27}
392 putOne(txnDS, k, f) 392 putOne(txnDS, k, f)
393 return nil 393 return nil
394 }, nil) 394 }, nil)
395 So(err, ShouldBeNil) 395 So(err, ShouldBeNil)
396 396
397 return nil 397 return nil
398 }, nil) 398 }, nil)
399 So(err.Error(), ShouldContainSubstring, "concurrent") 399 So(err.Error(), ShouldContainSubstring, "concurrent")
400 400
401 f := &Foo{} 401 f := &Foo{}
402 » » » » » getOne(rds, k, f) 402 » » » » » getOne(ds, k, f)
403 So(f.Val, ShouldEqual, 27) 403 So(f.Val, ShouldEqual, 27)
404 }) 404 })
405 405
406 Convey("XG", func() { 406 Convey("XG", func() {
407 Convey("Modifying two groups with XG=fal se is invalid", func() { 407 Convey("Modifying two groups with XG=fal se is invalid", func() {
408 » » » » » » err := rds.RunInTransaction(func (c context.Context) error { 408 » » » » » » err := ds.RunInTransaction(func( c context.Context) error {
409 » » » » » » » rds := rdsS.Get(c) 409 » » » » » » » ds := dsS.Get(c)
410 f := &Foo{Val: 200} 410 f := &Foo{Val: 200}
411 » » » » » » » putOne(rds, k, f) 411 » » » » » » » putOne(ds, k, f)
412 412
413 » » » » » » » _, err := putOneErr(rds, rds.NewKey("Foo", "", 2, nil), f) 413 » » » » » » » _, err := putOneErr(ds, ds.NewKey("Foo", "", 2, nil), f)
414 So(err.Error(), ShouldCo ntainSubstring, "cross-group") 414 So(err.Error(), ShouldCo ntainSubstring, "cross-group")
415 return err 415 return err
416 }, nil) 416 }, nil)
417 So(err.Error(), ShouldContainSub string, "cross-group") 417 So(err.Error(), ShouldContainSub string, "cross-group")
418 }) 418 })
419 419
420 Convey("Modifying >25 groups with XG=tru e is invald", func() { 420 Convey("Modifying >25 groups with XG=tru e is invald", func() {
421 » » » » » » err := rds.RunInTransaction(func (c context.Context) error { 421 » » » » » » err := ds.RunInTransaction(func( c context.Context) error {
422 » » » » » » » rds := rdsS.Get(c) 422 » » » » » » » ds := dsS.Get(c)
423 for i := int64(1); i < 2 6; i++ { 423 for i := int64(1); i < 2 6; i++ {
424 » » » » » » » » k := rds.NewKey( "Foo", "", i, nil) 424 » » » » » » » » k := ds.NewKey(" Foo", "", i, nil)
425 f := &Foo{Val: 2 00} 425 f := &Foo{Val: 2 00}
426 » » » » » » » » putOne(rds, k, f ) 426 » » » » » » » » putOne(ds, k, f)
427 } 427 }
428 f := &Foo{Val: 200} 428 f := &Foo{Val: 200}
429 » » » » » » » _, err := putOneErr(rds, rds.NewKey("Foo", "", 27, nil), f) 429 » » » » » » » _, err := putOneErr(ds, ds.NewKey("Foo", "", 27, nil), f)
430 So(err.Error(), ShouldCo ntainSubstring, "too many entity groups") 430 So(err.Error(), ShouldCo ntainSubstring, "too many entity groups")
431 return err 431 return err
432 » » » » » » }, &rdsS.TransactionOptions{XG: true}) 432 » » » » » » }, &dsS.TransactionOptions{XG: t rue})
433 So(err.Error(), ShouldContainSub string, "too many entity groups") 433 So(err.Error(), ShouldContainSub string, "too many entity groups")
434 }) 434 })
435 }) 435 })
436 436
437 Convey("Errors and panics", func() { 437 Convey("Errors and panics", func() {
438 Convey("returning an error aborts", func () { 438 Convey("returning an error aborts", func () {
439 » » » » » » err := rds.RunInTransaction(func (c context.Context) error { 439 » » » » » » err := ds.RunInTransaction(func( c context.Context) error {
440 » » » » » » » rds := rdsS.Get(c) 440 » » » » » » » ds := dsS.Get(c)
441 f := &Foo{Val: 200} 441 f := &Foo{Val: 200}
442 » » » » » » » putOne(rds, k, f) 442 » » » » » » » putOne(ds, k, f)
443 443
444 return fmt.Errorf("thing y") 444 return fmt.Errorf("thing y")
445 }, nil) 445 }, nil)
446 So(err.Error(), ShouldEqual, "th ingy") 446 So(err.Error(), ShouldEqual, "th ingy")
447 447
448 f := &Foo{} 448 f := &Foo{}
449 » » » » » » getOne(rds, k, f) 449 » » » » » » getOne(ds, k, f)
450 So(f.Val, ShouldEqual, 10) 450 So(f.Val, ShouldEqual, 10)
451 }) 451 })
452 452
453 Convey("panicing aborts", func() { 453 Convey("panicing aborts", func() {
454 So(func() { 454 So(func() {
455 » » » » » » » rds.RunInTransaction(fun c(c context.Context) error { 455 » » » » » » » ds.RunInTransaction(func (c context.Context) error {
456 » » » » » » » » rds := rdsS.Get( c) 456 » » » » » » » » ds := dsS.Get(c)
457 f := &Foo{Val: 2 00} 457 f := &Foo{Val: 2 00}
458 » » » » » » » » putOne(rds, k, f ) 458 » » » » » » » » putOne(ds, k, f)
459 panic("wheeeeee" ) 459 panic("wheeeeee" )
460 }, nil) 460 }, nil)
461 }, ShouldPanic) 461 }, ShouldPanic)
462 462
463 f := &Foo{} 463 f := &Foo{}
464 » » » » » » getOne(rds, k, f) 464 » » » » » » getOne(ds, k, f)
465 So(f.Val, ShouldEqual, 10) 465 So(f.Val, ShouldEqual, 10)
466 }) 466 })
467 }) 467 })
468 }) 468 })
469 }) 469 })
470 470
471 }) 471 })
472 } 472 }
473 473
474 const MaxUint = ^uint(0) 474 const MaxUint = ^uint(0)
475 const MaxInt = int(MaxUint >> 1) 475 const MaxInt = int(MaxUint >> 1)
476 const IntIs32Bits = int64(MaxInt) < math.MaxInt64 476 const IntIs32Bits = int64(MaxInt) < math.MaxInt64
477 477
478 func TestDatastoreQueryer(t *testing.T) { 478 func TestDatastoreQueryer(t *testing.T) {
479 Convey("Datastore Query suport", t, func() { 479 Convey("Datastore Query suport", t, func() {
480 c := Use(context.Background()) 480 c := Use(context.Background())
481 » » rds := rdsS.Get(c) 481 » » ds := dsS.Get(c)
482 » » So(rds, ShouldNotBeNil) 482 » » So(ds, ShouldNotBeNil)
483 483
484 Convey("can create good queries", func() { 484 Convey("can create good queries", func() {
485 » » » q := rds.NewQuery("Foo").KeysOnly().Limit(10).Offset(39) 485 » » » q := ds.NewQuery("Foo").KeysOnly().Limit(10).Offset(39)
486 q = q.Start(queryCursor("kosmik")).End(queryCursor("krab s")) 486 q = q.Start(queryCursor("kosmik")).End(queryCursor("krab s"))
487 So(q, ShouldNotBeNil) 487 So(q, ShouldNotBeNil)
488 So(q.(*queryImpl).err, ShouldBeNil) 488 So(q.(*queryImpl).err, ShouldBeNil)
489 qi := q.(*queryImpl).checkCorrectness("", false) 489 qi := q.(*queryImpl).checkCorrectness("", false)
490 So(qi.err, ShouldBeNil) 490 So(qi.err, ShouldBeNil)
491 }) 491 })
492 492
493 Convey("normalize ensures orders make sense", func() { 493 Convey("normalize ensures orders make sense", func() {
494 » » » q := rds.NewQuery("Cool") 494 » » » q := ds.NewQuery("Cool")
495 q = q.Filter("cat =", 19).Filter("bob =", 10).Order("bob ").Order("bob") 495 q = q.Filter("cat =", 19).Filter("bob =", 10).Order("bob ").Order("bob")
496 496
497 Convey("removes dups and equality orders", func() { 497 Convey("removes dups and equality orders", func() {
498 q = q.Order("wat") 498 q = q.Order("wat")
499 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false) 499 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false)
500 So(qi.err, ShouldBeNil) 500 So(qi.err, ShouldBeNil)
501 So(qi.order, ShouldResemble, []queryOrder{{"wat" , qASC}}) 501 So(qi.order, ShouldResemble, []queryOrder{{"wat" , qASC}})
502 }) 502 })
503 503
504 Convey("keeps inequality orders", func() { 504 Convey("keeps inequality orders", func() {
505 q = q.Order("wat") 505 q = q.Order("wat")
506 q := q.Filter("bob >", 10).Filter("wat <", 29) 506 q := q.Filter("bob >", 10).Filter("wat <", 29)
507 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false) 507 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false)
508 So(qi.order, ShouldResemble, []queryOrder{{"bob" , qASC}, {"wat", qASC}}) 508 So(qi.order, ShouldResemble, []queryOrder{{"bob" , qASC}, {"wat", qASC}})
509 So(qi.err.Error(), ShouldContainSubstring, "Only one inequality") 509 So(qi.err.Error(), ShouldContainSubstring, "Only one inequality")
510 }) 510 })
511 511
512 Convey("if we equality-filter on __key__, order is ditch ed", func() { 512 Convey("if we equality-filter on __key__, order is ditch ed", func() {
513 q = q.Order("wat") 513 q = q.Order("wat")
514 » » » » q := q.Filter("__key__ =", rds.NewKey("Foo", "wa t", 0, nil)) 514 » » » » q := q.Filter("__key__ =", ds.NewKey("Foo", "wat ", 0, nil))
515 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false) 515 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false)
516 So(qi.order, ShouldResemble, []queryOrder(nil)) 516 So(qi.order, ShouldResemble, []queryOrder(nil))
517 So(qi.err, ShouldBeNil) 517 So(qi.err, ShouldBeNil)
518 }) 518 })
519 519
520 Convey("if we order by key and something else, key domin ates", func() { 520 Convey("if we order by key and something else, key domin ates", func() {
521 q := q.Order("__key__").Order("wat") 521 q := q.Order("__key__").Order("wat")
522 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false) 522 qi := q.(*queryImpl).normalize().checkCorrectnes s("", false)
523 So(qi.order, ShouldResemble, []queryOrder{{"__ke y__", qASC}}) 523 So(qi.order, ShouldResemble, []queryOrder{{"__ke y__", qASC}})
524 So(qi.err, ShouldBeNil) 524 So(qi.err, ShouldBeNil)
525 }) 525 })
526 }) 526 })
527 527
528 Convey("can create bad queries", func() { 528 Convey("can create bad queries", func() {
529 » » » q := rds.NewQuery("Foo") 529 » » » q := ds.NewQuery("Foo")
530 530
531 Convey("bad filter ops", func() { 531 Convey("bad filter ops", func() {
532 q := q.Filter("Bob !", "value") 532 q := q.Filter("Bob !", "value")
533 So(q.(*queryImpl).err.Error(), ShouldContainSubs tring, "invalid operator \"!\"") 533 So(q.(*queryImpl).err.Error(), ShouldContainSubs tring, "invalid operator \"!\"")
534 }) 534 })
535 Convey("bad filter", func() { 535 Convey("bad filter", func() {
536 q := q.Filter("Bob", "value") 536 q := q.Filter("Bob", "value")
537 So(q.(*queryImpl).err.Error(), ShouldContainSubs tring, "invalid filter") 537 So(q.(*queryImpl).err.Error(), ShouldContainSubs tring, "invalid filter")
538 }) 538 })
539 Convey("bad order", func() { 539 Convey("bad order", func() {
(...skipping 20 matching lines...) Expand all
560 if !IntIs32Bits { 560 if !IntIs32Bits {
561 q := q.Offset(MaxInt) 561 q := q.Offset(MaxInt)
562 So(q.(*queryImpl).err.Error(), ShouldCon tainSubstring, "query offset overflow") 562 So(q.(*queryImpl).err.Error(), ShouldCon tainSubstring, "query offset overflow")
563 } 563 }
564 }) 564 })
565 Convey("Bad cursors", func() { 565 Convey("Bad cursors", func() {
566 q := q.Start(queryCursor("")).End(queryCursor("" )) 566 q := q.Start(queryCursor("")).End(queryCursor("" ))
567 So(q.(*queryImpl).err.Error(), ShouldContainSubs tring, "invalid cursor") 567 So(q.(*queryImpl).err.Error(), ShouldContainSubs tring, "invalid cursor")
568 }) 568 })
569 Convey("Bad ancestors", func() { 569 Convey("Bad ancestors", func() {
570 » » » » q := q.Ancestor(rds.NewKey("Goop", "wat", 10, ni l)) 570 » » » » q := q.Ancestor(ds.NewKey("Goop", "wat", 10, nil ))
571 So(q, ShouldNotBeNil) 571 So(q, ShouldNotBeNil)
572 qi := q.(*queryImpl).checkCorrectness("", false) 572 qi := q.(*queryImpl).checkCorrectness("", false)
573 » » » » So(qi.err, ShouldEqual, rdsS.ErrInvalidKey) 573 » » » » So(qi.err, ShouldEqual, dsS.ErrInvalidKey)
574 }) 574 })
575 Convey("nil ancestors", func() { 575 Convey("nil ancestors", func() {
576 qi := q.Ancestor(nil).(*queryImpl).checkCorrectn ess("", false) 576 qi := q.Ancestor(nil).(*queryImpl).checkCorrectn ess("", false)
577 So(qi.err.Error(), ShouldContainSubstring, "nil query ancestor") 577 So(qi.err.Error(), ShouldContainSubstring, "nil query ancestor")
578 }) 578 })
579 Convey("Bad key filters", func() { 579 Convey("Bad key filters", func() {
580 » » » » q := q.Filter("__key__ =", rds.NewKey("Goop", "w at", 10, nil)) 580 » » » » q := q.Filter("__key__ =", ds.NewKey("Goop", "wa t", 10, nil))
581 qi := q.(*queryImpl).checkCorrectness("", false) 581 qi := q.(*queryImpl).checkCorrectness("", false)
582 » » » » So(qi.err, ShouldEqual, rdsS.ErrInvalidKey) 582 » » » » So(qi.err, ShouldEqual, dsS.ErrInvalidKey)
583 }) 583 })
584 Convey("non-ancestor queries in a transaction", func() { 584 Convey("non-ancestor queries in a transaction", func() {
585 qi := q.(*queryImpl).checkCorrectness("", true) 585 qi := q.(*queryImpl).checkCorrectness("", true)
586 So(qi.err.Error(), ShouldContainSubstring, "Only ancestor queries") 586 So(qi.err.Error(), ShouldContainSubstring, "Only ancestor queries")
587 }) 587 })
588 Convey("absurd numbers of filters are prohibited", func( ) { 588 Convey("absurd numbers of filters are prohibited", func( ) {
589 » » » » q := q.Ancestor(rds.NewKey("thing", "wat", 0, ni l)) 589 » » » » q := q.Ancestor(ds.NewKey("thing", "wat", 0, nil ))
590 for i := 0; i < 100; i++ { 590 for i := 0; i < 100; i++ {
591 q = q.Filter("something =", 10) 591 q = q.Filter("something =", 10)
592 } 592 }
593 qi := q.(*queryImpl).checkCorrectness("", false) 593 qi := q.(*queryImpl).checkCorrectness("", false)
594 So(qi.err.Error(), ShouldContainSubstring, "quer y is too large") 594 So(qi.err.Error(), ShouldContainSubstring, "quer y is too large")
595 }) 595 })
596 Convey("filters for __key__ that aren't keys", func() { 596 Convey("filters for __key__ that aren't keys", func() {
597 q := q.Filter("__key__ = ", 10) 597 q := q.Filter("__key__ = ", 10)
598 qi := q.(*queryImpl).checkCorrectness("", false) 598 qi := q.(*queryImpl).checkCorrectness("", false)
599 So(qi.err.Error(), ShouldContainSubstring, "must be a Key") 599 So(qi.err.Error(), ShouldContainSubstring, "must be a Key")
600 }) 600 })
601 Convey("multiple inequalities", func() { 601 Convey("multiple inequalities", func() {
602 q := q.Filter("bob > ", 19).Filter("charlie < ", 20) 602 q := q.Filter("bob > ", 19).Filter("charlie < ", 20)
603 qi := q.(*queryImpl).checkCorrectness("", false) 603 qi := q.(*queryImpl).checkCorrectness("", false)
604 So(qi.err.Error(), ShouldContainSubstring, "one inequality filter") 604 So(qi.err.Error(), ShouldContainSubstring, "one inequality filter")
605 }) 605 })
606 Convey("bad sort orders", func() { 606 Convey("bad sort orders", func() {
607 q := q.Filter("bob > ", 19).Order("-charlie") 607 q := q.Filter("bob > ", 19).Order("-charlie")
608 qi := q.(*queryImpl).checkCorrectness("", false) 608 qi := q.(*queryImpl).checkCorrectness("", false)
609 So(qi.err.Error(), ShouldContainSubstring, "firs t sort property") 609 So(qi.err.Error(), ShouldContainSubstring, "firs t sort property")
610 }) 610 })
611 Convey("kindless with non-__key__ filters", func() { 611 Convey("kindless with non-__key__ filters", func() {
612 » » » » q := rds.NewQuery("").Filter("face <", 25.3) 612 » » » » q := ds.NewQuery("").Filter("face <", 25.3)
613 qi := q.(*queryImpl).checkCorrectness("", false) 613 qi := q.(*queryImpl).checkCorrectness("", false)
614 So(qi.err.Error(), ShouldContainSubstring, "kind is required for non-__key__") 614 So(qi.err.Error(), ShouldContainSubstring, "kind is required for non-__key__")
615 }) 615 })
616 Convey("kindless with non-__key__ orders", func() { 616 Convey("kindless with non-__key__ orders", func() {
617 » » » » q := rds.NewQuery("").Order("face") 617 » » » » q := ds.NewQuery("").Order("face")
618 qi := q.(*queryImpl).checkCorrectness("", false) 618 qi := q.(*queryImpl).checkCorrectness("", false)
619 So(qi.err.Error(), ShouldContainSubstring, "kind is required for all orders") 619 So(qi.err.Error(), ShouldContainSubstring, "kind is required for all orders")
620 }) 620 })
621 Convey("kindless with decending-__key__ orders", func() { 621 Convey("kindless with decending-__key__ orders", func() {
622 » » » » q := rds.NewQuery("").Order("-__key__") 622 » » » » q := ds.NewQuery("").Order("-__key__")
623 qi := q.(*queryImpl).checkCorrectness("", false) 623 qi := q.(*queryImpl).checkCorrectness("", false)
624 So(qi.err.Error(), ShouldContainSubstring, "kind is required for all orders") 624 So(qi.err.Error(), ShouldContainSubstring, "kind is required for all orders")
625 }) 625 })
626 }) 626 })
627 627
628 }) 628 })
629 } 629 }
OLDNEW
« no previous file with comments | « impl/memory/raw_datastore_query.go ('k') | impl/memory/taskqueue_data.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698