| OLD | NEW |
| 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 // adapted from github.com/golang/appengine/datastore | 5 // adapted from github.com/golang/appengine/datastore |
| 6 | 6 |
| 7 package datastore | 7 package datastore |
| 8 | 8 |
| 9 import ( | 9 import ( |
| 10 "fmt" | 10 "fmt" |
| 11 "testing" | 11 "testing" |
| 12 | 12 |
| 13 "github.com/luci/gae/service/info" | 13 "github.com/luci/gae/service/info" |
| 14 "github.com/luci/luci-go/common/errors" | 14 "github.com/luci/luci-go/common/errors" |
| 15 . "github.com/luci/luci-go/common/testing/assertions" |
| 15 . "github.com/smartystreets/goconvey/convey" | 16 . "github.com/smartystreets/goconvey/convey" |
| 16 "golang.org/x/net/context" | 17 "golang.org/x/net/context" |
| 17 ) | 18 ) |
| 18 | 19 |
| 19 func fakeDatastoreFactory(c context.Context) RawInterface { | 20 func fakeDatastoreFactory(c context.Context) RawInterface { |
| 20 i := info.Get(c) | 21 i := info.Get(c) |
| 21 return &fakeDatastore{ | 22 return &fakeDatastore{ |
| 22 aid: i.FullyQualifiedAppID(), | 23 aid: i.FullyQualifiedAppID(), |
| 23 ns: i.GetNamespace(), | 24 ns: i.GetNamespace(), |
| 24 } | 25 } |
| 25 } | 26 } |
| 26 | 27 |
| 27 type fakeQuery struct { | |
| 28 Query | |
| 29 | |
| 30 limit int | |
| 31 | |
| 32 err error | |
| 33 errSingle error | |
| 34 errSingleIdx int | |
| 35 } | |
| 36 | |
| 37 func (q *fakeQuery) KeysOnly() Query { | |
| 38 return q | |
| 39 } | |
| 40 | |
| 41 func (q *fakeQuery) Limit(i int) Query { | |
| 42 q.limit = i | |
| 43 return q | |
| 44 } | |
| 45 | |
| 46 func (q *fakeQuery) FailAll() Query { | |
| 47 q.err = errors.New("Query fail all") | |
| 48 return q | |
| 49 } | |
| 50 | |
| 51 func (q *fakeQuery) Fail(i int) Query { | |
| 52 q.errSingleIdx = i | |
| 53 q.errSingle = errors.New("Query fail") | |
| 54 return q | |
| 55 } | |
| 56 | |
| 57 type fakeDatastore struct { | 28 type fakeDatastore struct { |
| 58 RawInterface | 29 RawInterface |
| 59 aid string | 30 aid string |
| 60 ns string | 31 ns string |
| 61 } | 32 } |
| 62 | 33 |
| 63 func (f *fakeDatastore) NewKey(kind, stringID string, intID int64, parent Key) K
ey { | 34 func (f *fakeDatastore) mkKey(elems ...interface{}) *Key { |
| 64 » id := interface{}(stringID) | 35 » return MakeKey(f.aid, f.ns, elems...) |
| 65 » if stringID == "" { | |
| 66 » » id = intID | |
| 67 » } | |
| 68 » return mkKey(f.aid, f.ns, kind, id, parent) | |
| 69 } | 36 } |
| 70 | 37 |
| 71 func (f *fakeDatastore) NewQuery(string) Query { | 38 func (f *fakeDatastore) Run(fq *FinalizedQuery, cb RawRunCB) error { |
| 72 » return &fakeQuery{} | 39 » lim, _ := fq.Limit() |
| 73 } | |
| 74 | 40 |
| 75 func (f *fakeDatastore) Run(q Query, cb RawRunCB) error { | 41 » for i := int32(0); i < lim; i++ { |
| 76 » rq := q.(*fakeQuery) | 42 » » if v, ok := fq.eqFilts["$err_single"]; ok { |
| 77 » if rq.err != nil { | 43 » » » idx := fq.eqFilts["$err_single_idx"][0].Value().(int64) |
| 78 » » return rq.err | 44 » » » if idx == int64(i) { |
| 79 » } | 45 » » » » return errors.New(v[0].Value().(string)) |
| 80 » for i := 0; i < rq.limit; i++ { | |
| 81 » » if rq.errSingle != nil && i == rq.errSingleIdx { | |
| 82 » » » return rq.errSingle | |
| 83 » » } else { | |
| 84 » » » k := f.NewKey("Kind", "", int64(i+1), nil) | |
| 85 » » » if i == 10 { | |
| 86 » » » » k = f.NewKey("Kind", "eleven", 0, nil) | |
| 87 } | 46 } |
| 88 » » » pm := PropertyMap{"Value": {MkProperty(i)}} | 47 » » } |
| 89 » » » if !cb(k, pm, nil) { | 48 » » k := f.mkKey("Kind", i+1) |
| 90 » » » » break | 49 » » if i == 10 { |
| 91 » » » } | 50 » » » k = f.mkKey("Kind", "eleven") |
| 51 » » } |
| 52 » » pm := PropertyMap{"Value": {MkProperty(i)}} |
| 53 » » if !cb(k, pm, nil) { |
| 54 » » » break |
| 92 } | 55 } |
| 93 } | 56 } |
| 94 return nil | 57 return nil |
| 95 } | 58 } |
| 96 | 59 |
| 97 func (f *fakeDatastore) PutMulti(keys []Key, vals []PropertyMap, cb PutMultiCB)
error { | 60 func (f *fakeDatastore) PutMulti(keys []*Key, vals []PropertyMap, cb PutMultiCB)
error { |
| 98 » if keys[0].Kind() == "FailAll" { | 61 » if keys[0].Last().Kind == "FailAll" { |
| 99 return errors.New("PutMulti fail all") | 62 return errors.New("PutMulti fail all") |
| 100 } | 63 } |
| 101 assertExtra := false | 64 assertExtra := false |
| 102 if _, err := vals[0].GetMeta("assertExtra"); err == nil { | 65 if _, err := vals[0].GetMeta("assertExtra"); err == nil { |
| 103 assertExtra = true | 66 assertExtra = true |
| 104 } | 67 } |
| 105 for i, k := range keys { | 68 for i, k := range keys { |
| 106 err := error(nil) | 69 err := error(nil) |
| 107 » » if k.Kind() == "Fail" { | 70 » » if k.Last().Kind == "Fail" { |
| 108 err = errors.New("PutMulti fail") | 71 err = errors.New("PutMulti fail") |
| 109 } else { | 72 } else { |
| 110 So(vals[i]["Value"], ShouldResemble, []Property{MkProper
ty(i)}) | 73 So(vals[i]["Value"], ShouldResemble, []Property{MkProper
ty(i)}) |
| 111 if assertExtra { | 74 if assertExtra { |
| 112 So(vals[i]["Extra"], ShouldResemble, []Property{
MkProperty("whoa")}) | 75 So(vals[i]["Extra"], ShouldResemble, []Property{
MkProperty("whoa")}) |
| 113 } | 76 } |
| 114 if k.Incomplete() { | 77 if k.Incomplete() { |
| 115 » » » » k = mkKey(k.AppID(), k.Namespace(), k.Kind(), in
t64(i+1), k.Parent()) | 78 » » » » k = NewKey(k.AppID(), k.Namespace(), k.Last().Ki
nd, "", int64(i+1), k.Parent()) |
| 116 } | 79 } |
| 117 } | 80 } |
| 118 cb(k, err) | 81 cb(k, err) |
| 119 } | 82 } |
| 120 return nil | 83 return nil |
| 121 } | 84 } |
| 122 | 85 |
| 123 func (f *fakeDatastore) GetMulti(keys []Key, _meta MultiMetaGetter, cb GetMultiC
B) error { | 86 func (f *fakeDatastore) GetMulti(keys []*Key, _meta MultiMetaGetter, cb GetMulti
CB) error { |
| 124 » if keys[0].Kind() == "FailAll" { | 87 » if keys[0].Last().Kind == "FailAll" { |
| 125 return errors.New("GetMulti fail all") | 88 return errors.New("GetMulti fail all") |
| 126 } | 89 } |
| 127 for i, k := range keys { | 90 for i, k := range keys { |
| 128 » » if k.Kind() == "Fail" { | 91 » » if k.Last().Kind == "Fail" { |
| 129 cb(nil, errors.New("GetMulti fail")) | 92 cb(nil, errors.New("GetMulti fail")) |
| 130 } else { | 93 } else { |
| 131 cb(PropertyMap{"Value": {MkProperty(i + 1)}}, nil) | 94 cb(PropertyMap{"Value": {MkProperty(i + 1)}}, nil) |
| 132 } | 95 } |
| 133 } | 96 } |
| 134 return nil | 97 return nil |
| 135 } | 98 } |
| 136 | 99 |
| 137 func (f *fakeDatastore) DeleteMulti(keys []Key, cb DeleteMultiCB) error { | 100 func (f *fakeDatastore) DeleteMulti(keys []*Key, cb DeleteMultiCB) error { |
| 138 » if keys[0].Kind() == "FailAll" { | 101 » if keys[0].Last().Kind == "FailAll" { |
| 139 return errors.New("DeleteMulti fail all") | 102 return errors.New("DeleteMulti fail all") |
| 140 } | 103 } |
| 141 for _, k := range keys { | 104 for _, k := range keys { |
| 142 » » if k.Kind() == "Fail" { | 105 » » if k.Last().Kind == "Fail" { |
| 143 cb(errors.New("DeleteMulti fail")) | 106 cb(errors.New("DeleteMulti fail")) |
| 144 } else { | 107 } else { |
| 145 cb(nil) | 108 cb(nil) |
| 146 } | 109 } |
| 147 } | 110 } |
| 148 return nil | 111 return nil |
| 149 } | 112 } |
| 150 | 113 |
| 151 type badStruct struct { | 114 type badStruct struct { |
| 152 ID int64 `gae:"$id"` | 115 ID int64 `gae:"$id"` |
| 153 Compy complex64 // bad type | 116 Compy complex64 // bad type |
| 154 } | 117 } |
| 155 | 118 |
| 156 type CommonStruct struct { | 119 type CommonStruct struct { |
| 157 ID int64 `gae:"$id"` | 120 ID int64 `gae:"$id"` |
| 158 » Parent Key `gae:"$parent"` | 121 » Parent *Key `gae:"$parent"` |
| 159 | 122 |
| 160 Value int64 | 123 Value int64 |
| 161 } | 124 } |
| 162 | 125 |
| 163 type permaBad struct { | 126 type permaBad struct { |
| 164 PropertyLoadSaver | 127 PropertyLoadSaver |
| 165 } | 128 } |
| 166 | 129 |
| 167 func (f *permaBad) Load(pm PropertyMap) error { | 130 func (f *permaBad) Load(pm PropertyMap) error { |
| 168 return errors.New("permaBad") | 131 return errors.New("permaBad") |
| (...skipping 28 matching lines...) Expand all Loading... |
| 197 func (f *FakePLS) Save(withMeta bool) (PropertyMap, error) { | 160 func (f *FakePLS) Save(withMeta bool) (PropertyMap, error) { |
| 198 if f.failSave { | 161 if f.failSave { |
| 199 return nil, errors.New("FakePLS.Save") | 162 return nil, errors.New("FakePLS.Save") |
| 200 } | 163 } |
| 201 ret := PropertyMap{ | 164 ret := PropertyMap{ |
| 202 "Value": {MkProperty(f.Value)}, | 165 "Value": {MkProperty(f.Value)}, |
| 203 "Extra": {MkProperty("whoa")}, | 166 "Extra": {MkProperty("whoa")}, |
| 204 } | 167 } |
| 205 if withMeta { | 168 if withMeta { |
| 206 id, _ := f.GetMeta("id") | 169 id, _ := f.GetMeta("id") |
| 207 » » ret.SetMeta("id", id) | 170 » » So(ret.SetMeta("id", id), ShouldBeNil) |
| 208 if f.Kind == "" { | 171 if f.Kind == "" { |
| 209 » » » ret.SetMeta("kind", "FakePLS") | 172 » » » So(ret.SetMeta("kind", "FakePLS"), ShouldBeNil) |
| 210 } else { | 173 } else { |
| 211 » » » ret.SetMeta("kind", f.Kind) | 174 » » » So(ret.SetMeta("kind", f.Kind), ShouldBeNil) |
| 212 } | 175 } |
| 213 » » ret.SetMeta("assertExtra", true) | 176 » » So(ret.SetMeta("assertExtra", true), ShouldBeNil) |
| 214 } | 177 } |
| 215 return ret, nil | 178 return ret, nil |
| 216 } | 179 } |
| 217 | 180 |
| 218 func (f *FakePLS) GetMetaDefault(key string, dflt interface{}) interface{} { | 181 func (f *FakePLS) GetMetaDefault(key string, dflt interface{}) interface{} { |
| 219 return GetMetaDefaultImpl(f.GetMeta, key, dflt) | 182 return GetMetaDefaultImpl(f.GetMeta, key, dflt) |
| 220 } | 183 } |
| 221 | 184 |
| 222 func (f *FakePLS) GetMeta(key string) (interface{}, error) { | 185 func (f *FakePLS) GetMeta(key string) (interface{}, error) { |
| 223 if f.failGetMeta { | 186 if f.failGetMeta { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 } | 229 } |
| 267 | 230 |
| 268 func TestKeyForObj(t *testing.T) { | 231 func TestKeyForObj(t *testing.T) { |
| 269 t.Parallel() | 232 t.Parallel() |
| 270 | 233 |
| 271 Convey("Test interface.KeyForObj", t, func() { | 234 Convey("Test interface.KeyForObj", t, func() { |
| 272 c := info.Set(context.Background(), fakeInfo{}) | 235 c := info.Set(context.Background(), fakeInfo{}) |
| 273 c = SetRawFactory(c, fakeDatastoreFactory) | 236 c = SetRawFactory(c, fakeDatastoreFactory) |
| 274 ds := Get(c) | 237 ds := Get(c) |
| 275 | 238 |
| 276 » » k := ds.NewKey("Hello", "world", 0, nil) | 239 » » k := ds.MakeKey("Hello", "world") |
| 277 | 240 |
| 278 Convey("good", func() { | 241 Convey("good", func() { |
| 279 Convey("struct containing $key", func() { | 242 Convey("struct containing $key", func() { |
| 280 type keyStruct struct { | 243 type keyStruct struct { |
| 281 » » » » » Key Key `gae:"$key"` | 244 » » » » » Key *Key `gae:"$key"` |
| 282 } | 245 } |
| 283 | 246 |
| 284 ks := &keyStruct{k} | 247 ks := &keyStruct{k} |
| 285 So(ds.KeyForObj(ks), ShouldEqual, k) | 248 So(ds.KeyForObj(ks), ShouldEqual, k) |
| 286 }) | 249 }) |
| 287 | 250 |
| 288 Convey("struct containing default $id and $kind", func()
{ | 251 Convey("struct containing default $id and $kind", func()
{ |
| 289 type idStruct struct { | 252 type idStruct struct { |
| 290 id string `gae:"$id,wut"` | 253 id string `gae:"$id,wut"` |
| 291 knd string `gae:"$kind,SuperKind"` | 254 knd string `gae:"$kind,SuperKind"` |
| 292 } | 255 } |
| 293 | 256 |
| 294 » » » » So(ds.KeyForObj(&idStruct{}).String(), ShouldEqu
al, `/SuperKind,wut`) | 257 » » » » So(ds.KeyForObj(&idStruct{}).String(), ShouldEqu
al, `s~aid:ns:/SuperKind,"wut"`) |
| 295 }) | 258 }) |
| 296 | 259 |
| 297 Convey("struct containing $id and $parent", func() { | 260 Convey("struct containing $id and $parent", func() { |
| 298 » » » » So(ds.KeyForObj(&CommonStruct{ID: 4}).String(),
ShouldEqual, `/CommonStruct,4`) | 261 » » » » So(ds.KeyForObj(&CommonStruct{ID: 4}).String(),
ShouldEqual, `s~aid:ns:/CommonStruct,4`) |
| 299 | 262 |
| 300 » » » » So(ds.KeyForObj(&CommonStruct{ID: 4, Parent: k})
.String(), ShouldEqual, `/Hello,world/CommonStruct,4`) | 263 » » » » So(ds.KeyForObj(&CommonStruct{ID: 4, Parent: k})
.String(), ShouldEqual, `s~aid:ns:/Hello,"world"/CommonStruct,4`) |
| 301 }) | 264 }) |
| 302 | 265 |
| 303 Convey("a propmap with $key", func() { | 266 Convey("a propmap with $key", func() { |
| 304 pm := PropertyMap{} | 267 pm := PropertyMap{} |
| 305 » » » » pm.SetMeta("key", k) | 268 » » » » So(pm.SetMeta("key", k), ShouldBeNil) |
| 306 » » » » So(ds.KeyForObj(pm).String(), ShouldEqual, `/Hel
lo,world`) | 269 » » » » So(ds.KeyForObj(pm).String(), ShouldEqual, `s~ai
d:ns:/Hello,"world"`) |
| 307 }) | 270 }) |
| 308 | 271 |
| 309 Convey("a propmap with $id, $kind, $parent", func() { | 272 Convey("a propmap with $id, $kind, $parent", func() { |
| 310 pm := PropertyMap{} | 273 pm := PropertyMap{} |
| 311 » » » » pm.SetMeta("id", 100) | 274 » » » » So(pm.SetMeta("id", 100), ShouldBeNil) |
| 312 » » » » pm.SetMeta("kind", "Sup") | 275 » » » » So(pm.SetMeta("kind", "Sup"), ShouldBeNil) |
| 313 » » » » So(ds.KeyForObj(pm).String(), ShouldEqual, `/Sup
,100`) | 276 » » » » So(ds.KeyForObj(pm).String(), ShouldEqual, `s~ai
d:ns:/Sup,100`) |
| 314 | 277 |
| 315 » » » » pm.SetMeta("parent", k) | 278 » » » » So(pm.SetMeta("parent", k), ShouldBeNil) |
| 316 » » » » So(ds.KeyForObj(pm).String(), ShouldEqual, `/Hel
lo,world/Sup,100`) | 279 » » » » So(ds.KeyForObj(pm).String(), ShouldEqual, `s~ai
d:ns:/Hello,"world"/Sup,100`) |
| 317 }) | 280 }) |
| 318 | 281 |
| 319 Convey("a pls with $id, $parent", func() { | 282 Convey("a pls with $id, $parent", func() { |
| 320 pls := GetPLS(&CommonStruct{ID: 1}) | 283 pls := GetPLS(&CommonStruct{ID: 1}) |
| 321 » » » » So(ds.KeyForObj(pls).String(), ShouldEqual, `/Co
mmonStruct,1`) | 284 » » » » So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a
id:ns:/CommonStruct,1`) |
| 322 | 285 |
| 323 » » » » pls.SetMeta("parent", k) | 286 » » » » So(pls.SetMeta("parent", k), ShouldBeNil) |
| 324 » » » » So(ds.KeyForObj(pls).String(), ShouldEqual, `/He
llo,world/CommonStruct,1`) | 287 » » » » So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a
id:ns:/Hello,"world"/CommonStruct,1`) |
| 325 }) | 288 }) |
| 326 | 289 |
| 327 }) | 290 }) |
| 328 | 291 |
| 329 Convey("bad", func() { | 292 Convey("bad", func() { |
| 330 Convey("a propmap without $kind", func() { | 293 Convey("a propmap without $kind", func() { |
| 331 pm := PropertyMap{} | 294 pm := PropertyMap{} |
| 332 » » » » pm.SetMeta("id", 100) | 295 » » » » So(pm.SetMeta("id", 100), ShouldBeNil) |
| 333 So(func() { ds.KeyForObj(pm) }, ShouldPanic) | 296 So(func() { ds.KeyForObj(pm) }, ShouldPanic) |
| 334 }) | 297 }) |
| 335 }) | 298 }) |
| 336 }) | 299 }) |
| 337 } | 300 } |
| 338 | 301 |
| 339 func TestPut(t *testing.T) { | 302 func TestPut(t *testing.T) { |
| 340 t.Parallel() | 303 t.Parallel() |
| 341 | 304 |
| 342 Convey("Test Put/PutMulti", t, func() { | 305 Convey("Test Put/PutMulti", t, func() { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 for i, fpls := range fplss { | 405 for i, fpls := range fplss { |
| 443 expect := int64(i + 1) | 406 expect := int64(i + 1) |
| 444 if i == 4 { | 407 if i == 4 { |
| 445 expect = 200 | 408 expect = 200 |
| 446 } | 409 } |
| 447 So(fpls.IntID, ShouldEqual, expect) | 410 So(fpls.IntID, ShouldEqual, expect) |
| 448 } | 411 } |
| 449 | 412 |
| 450 pm := PropertyMap{"Value": {MkProperty(0)}, "$ki
nd": {MkPropertyNI("Pmap")}} | 413 pm := PropertyMap{"Value": {MkProperty(0)}, "$ki
nd": {MkPropertyNI("Pmap")}} |
| 451 So(ds.Put(pm), ShouldBeNil) | 414 So(ds.Put(pm), ShouldBeNil) |
| 452 » » » » So(ds.KeyForObj(pm).IntID(), ShouldEqual, 1) | 415 » » » » So(ds.KeyForObj(pm).Last().IntID, ShouldEqual, 1
) |
| 453 }) | 416 }) |
| 454 | 417 |
| 455 Convey("[]P (map)", func() { | 418 Convey("[]P (map)", func() { |
| 456 pms := make([]PropertyMap, 7) | 419 pms := make([]PropertyMap, 7) |
| 457 for i := range pms { | 420 for i := range pms { |
| 458 pms[i] = PropertyMap{ | 421 pms[i] = PropertyMap{ |
| 459 "$kind": {MkProperty("Pmap")}, | 422 "$kind": {MkProperty("Pmap")}, |
| 460 "Value": {MkProperty(i)}, | 423 "Value": {MkProperty(i)}, |
| 461 } | 424 } |
| 462 if i == 4 { | 425 if i == 4 { |
| 463 » » » » » » pms[i].SetMeta("id", int64(200)) | 426 » » » » » » So(pms[i].SetMeta("id", int64(20
0)), ShouldBeNil) |
| 464 } | 427 } |
| 465 } | 428 } |
| 466 So(ds.PutMulti(pms), ShouldBeNil) | 429 So(ds.PutMulti(pms), ShouldBeNil) |
| 467 for i, pm := range pms { | 430 for i, pm := range pms { |
| 468 expect := int64(i + 1) | 431 expect := int64(i + 1) |
| 469 if i == 4 { | 432 if i == 4 { |
| 470 expect = 200 | 433 expect = 200 |
| 471 } | 434 } |
| 472 » » » » » So(ds.KeyForObj(pm).String(), ShouldEqua
l, fmt.Sprintf("/Pmap,%d", expect)) | 435 » » » » » So(ds.KeyForObj(pm).String(), ShouldEqua
l, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect)) |
| 473 } | 436 } |
| 474 }) | 437 }) |
| 475 | 438 |
| 476 Convey("[]*P", func() { | 439 Convey("[]*P", func() { |
| 477 fplss := make([]*FakePLS, 7) | 440 fplss := make([]*FakePLS, 7) |
| 478 for i := range fplss { | 441 for i := range fplss { |
| 479 fplss[i] = &FakePLS{Value: int64(i)} | 442 fplss[i] = &FakePLS{Value: int64(i)} |
| 480 if i == 4 { | 443 if i == 4 { |
| 481 fplss[i].IntID = int64(200) | 444 fplss[i].IntID = int64(200) |
| 482 } | 445 } |
| 483 } | 446 } |
| 484 So(ds.PutMulti(fplss), ShouldBeNil) | 447 So(ds.PutMulti(fplss), ShouldBeNil) |
| 485 for i, fpls := range fplss { | 448 for i, fpls := range fplss { |
| 486 expect := int64(i + 1) | 449 expect := int64(i + 1) |
| 487 if i == 4 { | 450 if i == 4 { |
| 488 expect = 200 | 451 expect = 200 |
| 489 } | 452 } |
| 490 So(fpls.IntID, ShouldEqual, expect) | 453 So(fpls.IntID, ShouldEqual, expect) |
| 491 } | 454 } |
| 492 }) | 455 }) |
| 493 | 456 |
| 494 Convey("[]*P (map)", func() { | 457 Convey("[]*P (map)", func() { |
| 495 pms := make([]*PropertyMap, 7) | 458 pms := make([]*PropertyMap, 7) |
| 496 for i := range pms { | 459 for i := range pms { |
| 497 pms[i] = &PropertyMap{ | 460 pms[i] = &PropertyMap{ |
| 498 "$kind": {MkProperty("Pmap")}, | 461 "$kind": {MkProperty("Pmap")}, |
| 499 "Value": {MkProperty(i)}, | 462 "Value": {MkProperty(i)}, |
| 500 } | 463 } |
| 501 if i == 4 { | 464 if i == 4 { |
| 502 » » » » » » pms[i].SetMeta("id", int64(200)) | 465 » » » » » » So(pms[i].SetMeta("id", int64(20
0)), ShouldBeNil) |
| 503 } | 466 } |
| 504 } | 467 } |
| 505 So(ds.PutMulti(pms), ShouldBeNil) | 468 So(ds.PutMulti(pms), ShouldBeNil) |
| 506 for i, pm := range pms { | 469 for i, pm := range pms { |
| 507 expect := int64(i + 1) | 470 expect := int64(i + 1) |
| 508 if i == 4 { | 471 if i == 4 { |
| 509 expect = 200 | 472 expect = 200 |
| 510 } | 473 } |
| 511 » » » » » So(ds.KeyForObj(*pm).String(), ShouldEqu
al, fmt.Sprintf("/Pmap,%d", expect)) | 474 » » » » » So(ds.KeyForObj(*pm).String(), ShouldEqu
al, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect)) |
| 512 } | 475 } |
| 513 }) | 476 }) |
| 514 | 477 |
| 515 Convey("[]I", func() { | 478 Convey("[]I", func() { |
| 516 ifs := []interface{}{ | 479 ifs := []interface{}{ |
| 517 &CommonStruct{Value: 0}, | 480 &CommonStruct{Value: 0}, |
| 518 &FakePLS{Value: 1}, | 481 &FakePLS{Value: 1}, |
| 519 PropertyMap{"Value": {MkProperty(2)}, "$
kind": {MkPropertyNI("Pmap")}}, | 482 PropertyMap{"Value": {MkProperty(2)}, "$
kind": {MkPropertyNI("Pmap")}}, |
| 520 &PropertyMap{"Value": {MkProperty(3)}, "
$kind": {MkPropertyNI("Pmap")}}, | 483 &PropertyMap{"Value": {MkProperty(3)}, "
$kind": {MkPropertyNI("Pmap")}}, |
| 521 } | 484 } |
| 522 So(ds.PutMulti(ifs), ShouldBeNil) | 485 So(ds.PutMulti(ifs), ShouldBeNil) |
| 523 for i := range ifs { | 486 for i := range ifs { |
| 524 switch i { | 487 switch i { |
| 525 case 0: | 488 case 0: |
| 526 So(ifs[i].(*CommonStruct).ID, Sh
ouldEqual, 1) | 489 So(ifs[i].(*CommonStruct).ID, Sh
ouldEqual, 1) |
| 527 case 1: | 490 case 1: |
| 528 fpls := ifs[i].(*FakePLS) | 491 fpls := ifs[i].(*FakePLS) |
| 529 So(fpls.IntID, ShouldEqual, 2) | 492 So(fpls.IntID, ShouldEqual, 2) |
| 530 case 2: | 493 case 2: |
| 531 » » » » » » So(ds.KeyForObj(ifs[i].(Property
Map)).String(), ShouldEqual, "/Pmap,3") | 494 » » » » » » So(ds.KeyForObj(ifs[i].(Property
Map)).String(), ShouldEqual, "s~aid:ns:/Pmap,3") |
| 532 case 3: | 495 case 3: |
| 533 » » » » » » So(ds.KeyForObj(*ifs[i].(*Proper
tyMap)).String(), ShouldEqual, "/Pmap,4") | 496 » » » » » » So(ds.KeyForObj(*ifs[i].(*Proper
tyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,4") |
| 534 } | 497 } |
| 535 } | 498 } |
| 536 }) | 499 }) |
| 537 | 500 |
| 538 }) | 501 }) |
| 539 | 502 |
| 540 }) | 503 }) |
| 541 } | 504 } |
| 542 | 505 |
| 543 func TestDelete(t *testing.T) { | 506 func TestDelete(t *testing.T) { |
| 544 t.Parallel() | 507 t.Parallel() |
| 545 | 508 |
| 546 Convey("Test Delete/DeleteMulti", t, func() { | 509 Convey("Test Delete/DeleteMulti", t, func() { |
| 547 c := info.Set(context.Background(), fakeInfo{}) | 510 c := info.Set(context.Background(), fakeInfo{}) |
| 548 c = SetRawFactory(c, fakeDatastoreFactory) | 511 c = SetRawFactory(c, fakeDatastoreFactory) |
| 549 ds := Get(c) | 512 ds := Get(c) |
| 550 So(ds, ShouldNotBeNil) | 513 So(ds, ShouldNotBeNil) |
| 551 | 514 |
| 552 Convey("bad", func() { | 515 Convey("bad", func() { |
| 553 Convey("get single error for RPC failure", func() { | 516 Convey("get single error for RPC failure", func() { |
| 554 » » » » keys := []Key{ | 517 » » » » keys := []*Key{ |
| 555 » » » » » mkKey("s~aid", "ns", "FailAll", 1, nil), | 518 » » » » » MakeKey("s~aid", "ns", "FailAll", 1), |
| 556 » » » » » mkKey("s~aid", "ns", "Ok", 1, nil), | 519 » » » » » MakeKey("s~aid", "ns", "Ok", 1), |
| 557 } | 520 } |
| 558 So(ds.DeleteMulti(keys).Error(), ShouldEqual, "D
eleteMulti fail all") | 521 So(ds.DeleteMulti(keys).Error(), ShouldEqual, "D
eleteMulti fail all") |
| 559 }) | 522 }) |
| 560 | 523 |
| 561 Convey("get multi error for individual failure", func()
{ | 524 Convey("get multi error for individual failure", func()
{ |
| 562 » » » » keys := []Key{ | 525 » » » » keys := []*Key{ |
| 563 » » » » » ds.NewKey("Ok", "", 1, nil), | 526 » » » » » ds.MakeKey("Ok", 1), |
| 564 » » » » » ds.NewKey("Fail", "", 2, nil), | 527 » » » » » ds.MakeKey("Fail", 2), |
| 565 } | 528 } |
| 566 So(ds.DeleteMulti(keys).Error(), ShouldEqual, "D
eleteMulti fail") | 529 So(ds.DeleteMulti(keys).Error(), ShouldEqual, "D
eleteMulti fail") |
| 567 }) | 530 }) |
| 568 | 531 |
| 569 Convey("get single error when deleting a single", func()
{ | 532 Convey("get single error when deleting a single", func()
{ |
| 570 » » » » k := ds.NewKey("Fail", "", 1, nil) | 533 » » » » k := ds.MakeKey("Fail", 1) |
| 571 So(ds.Delete(k).Error(), ShouldEqual, "DeleteMul
ti fail") | 534 So(ds.Delete(k).Error(), ShouldEqual, "DeleteMul
ti fail") |
| 572 }) | 535 }) |
| 573 }) | 536 }) |
| 574 | 537 |
| 575 }) | 538 }) |
| 576 } | 539 } |
| 577 | 540 |
| 578 func TestGet(t *testing.T) { | 541 func TestGet(t *testing.T) { |
| 579 t.Parallel() | 542 t.Parallel() |
| 580 | 543 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 | 584 |
| 622 Convey("ok", func() { | 585 Convey("ok", func() { |
| 623 Convey("Get", func() { | 586 Convey("Get", func() { |
| 624 cs := &CommonStruct{ID: 1} | 587 cs := &CommonStruct{ID: 1} |
| 625 So(ds.Get(cs), ShouldBeNil) | 588 So(ds.Get(cs), ShouldBeNil) |
| 626 So(cs.Value, ShouldEqual, 1) | 589 So(cs.Value, ShouldEqual, 1) |
| 627 }) | 590 }) |
| 628 | 591 |
| 629 Convey("Raw access too", func() { | 592 Convey("Raw access too", func() { |
| 630 rds := ds.Raw() | 593 rds := ds.Raw() |
| 631 » » » » keys := []Key{rds.NewKey("Kind", "", 1, nil)} | 594 » » » » keys := []*Key{ds.MakeKey("Kind", 1)} |
| 632 So(rds.GetMulti(keys, nil, func(pm PropertyMap,
err error) { | 595 So(rds.GetMulti(keys, nil, func(pm PropertyMap,
err error) { |
| 633 So(err, ShouldBeNil) | 596 So(err, ShouldBeNil) |
| 634 So(pm["Value"][0].Value(), ShouldEqual,
1) | 597 So(pm["Value"][0].Value(), ShouldEqual,
1) |
| 635 }), ShouldBeNil) | 598 }), ShouldBeNil) |
| 636 }) | 599 }) |
| 637 }) | 600 }) |
| 638 | 601 |
| 639 }) | 602 }) |
| 640 } | 603 } |
| 641 | 604 |
| 642 func TestGetAll(t *testing.T) { | 605 func TestGetAll(t *testing.T) { |
| 643 t.Parallel() | 606 t.Parallel() |
| 644 | 607 |
| 645 Convey("Test GetAll", t, func() { | 608 Convey("Test GetAll", t, func() { |
| 646 c := info.Set(context.Background(), fakeInfo{}) | 609 c := info.Set(context.Background(), fakeInfo{}) |
| 647 c = SetRawFactory(c, fakeDatastoreFactory) | 610 c = SetRawFactory(c, fakeDatastoreFactory) |
| 648 ds := Get(c) | 611 ds := Get(c) |
| 649 So(ds, ShouldNotBeNil) | 612 So(ds, ShouldNotBeNil) |
| 650 | 613 |
| 651 » » q := ds.NewQuery("").Limit(5) | 614 » » q := NewQuery("").Limit(5) |
| 652 | 615 |
| 653 Convey("bad", func() { | 616 Convey("bad", func() { |
| 654 Convey("nil target", func() { | 617 Convey("nil target", func() { |
| 655 So(ds.GetAll(q, (*[]PropertyMap)(nil)).Error(),
ShouldContainSubstring, "dst: <nil>") | 618 So(ds.GetAll(q, (*[]PropertyMap)(nil)).Error(),
ShouldContainSubstring, "dst: <nil>") |
| 656 }) | 619 }) |
| 657 | 620 |
| 658 Convey("bad type", func() { | 621 Convey("bad type", func() { |
| 659 output := 100 | 622 output := 100 |
| 660 So(ds.GetAll(q, &output).Error(), ShouldContainS
ubstring, "invalid GetAll input type") | 623 So(ds.GetAll(q, &output).Error(), ShouldContainS
ubstring, "invalid GetAll input type") |
| 661 }) | 624 }) |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 } | 665 } |
| 703 }) | 666 }) |
| 704 | 667 |
| 705 Convey("*[]P (map)", func() { | 668 Convey("*[]P (map)", func() { |
| 706 output := []PropertyMap(nil) | 669 output := []PropertyMap(nil) |
| 707 So(ds.GetAll(q, &output), ShouldBeNil) | 670 So(ds.GetAll(q, &output), ShouldBeNil) |
| 708 So(len(output), ShouldEqual, 5) | 671 So(len(output), ShouldEqual, 5) |
| 709 for i, o := range output { | 672 for i, o := range output { |
| 710 k, err := o.GetMeta("key") | 673 k, err := o.GetMeta("key") |
| 711 So(err, ShouldBeNil) | 674 So(err, ShouldBeNil) |
| 712 » » » » » So(k.(Key).IntID(), ShouldEqual, i+1) | 675 » » » » » So(k.(*Key).Last().IntID, ShouldEqual, i
+1) |
| 713 So(o["Value"][0].Value().(int64), Should
Equal, i) | 676 So(o["Value"][0].Value().(int64), Should
Equal, i) |
| 714 } | 677 } |
| 715 }) | 678 }) |
| 716 | 679 |
| 717 Convey("*[]*P", func() { | 680 Convey("*[]*P", func() { |
| 718 output := []*FakePLS(nil) | 681 output := []*FakePLS(nil) |
| 719 So(ds.GetAll(q, &output), ShouldBeNil) | 682 So(ds.GetAll(q, &output), ShouldBeNil) |
| 720 So(len(output), ShouldEqual, 5) | 683 So(len(output), ShouldEqual, 5) |
| 721 for i, o := range output { | 684 for i, o := range output { |
| 722 So(o.gotLoaded, ShouldBeTrue) | 685 So(o.gotLoaded, ShouldBeTrue) |
| 723 So(o.IntID, ShouldEqual, i+1) | 686 So(o.IntID, ShouldEqual, i+1) |
| 724 So(o.Value, ShouldEqual, i) | 687 So(o.Value, ShouldEqual, i) |
| 725 } | 688 } |
| 726 }) | 689 }) |
| 727 | 690 |
| 728 Convey("*[]*P (map)", func() { | 691 Convey("*[]*P (map)", func() { |
| 729 output := []*PropertyMap(nil) | 692 output := []*PropertyMap(nil) |
| 730 So(ds.GetAll(q, &output), ShouldBeNil) | 693 So(ds.GetAll(q, &output), ShouldBeNil) |
| 731 So(len(output), ShouldEqual, 5) | 694 So(len(output), ShouldEqual, 5) |
| 732 for i, op := range output { | 695 for i, op := range output { |
| 733 o := *op | 696 o := *op |
| 734 k, err := o.GetMeta("key") | 697 k, err := o.GetMeta("key") |
| 735 So(err, ShouldBeNil) | 698 So(err, ShouldBeNil) |
| 736 » » » » » So(k.(Key).IntID(), ShouldEqual, i+1) | 699 » » » » » So(k.(*Key).Last().IntID, ShouldEqual, i
+1) |
| 737 So(o["Value"][0].Value().(int64), Should
Equal, i) | 700 So(o["Value"][0].Value().(int64), Should
Equal, i) |
| 738 } | 701 } |
| 739 }) | 702 }) |
| 740 | 703 |
| 741 » » » Convey("*[]Key", func() { | 704 » » » Convey("*[]*Key", func() { |
| 742 » » » » output := []Key(nil) | 705 » » » » output := []*Key(nil) |
| 743 So(ds.GetAll(q, &output), ShouldBeNil) | 706 So(ds.GetAll(q, &output), ShouldBeNil) |
| 744 So(len(output), ShouldEqual, 5) | 707 So(len(output), ShouldEqual, 5) |
| 745 for i, k := range output { | 708 for i, k := range output { |
| 746 » » » » » So(k.IntID(), ShouldEqual, i+1) | 709 » » » » » So(k.Last().IntID, ShouldEqual, i+1) |
| 747 } | 710 } |
| 748 }) | 711 }) |
| 749 | 712 |
| 750 }) | 713 }) |
| 751 }) | 714 }) |
| 752 } | 715 } |
| 753 | 716 |
| 754 func TestRun(t *testing.T) { | 717 func TestRun(t *testing.T) { |
| 755 t.Parallel() | 718 t.Parallel() |
| 756 | 719 |
| 757 Convey("Test Run", t, func() { | 720 Convey("Test Run", t, func() { |
| 758 c := info.Set(context.Background(), fakeInfo{}) | 721 c := info.Set(context.Background(), fakeInfo{}) |
| 759 c = SetRawFactory(c, fakeDatastoreFactory) | 722 c = SetRawFactory(c, fakeDatastoreFactory) |
| 760 ds := Get(c) | 723 ds := Get(c) |
| 761 So(ds, ShouldNotBeNil) | 724 So(ds, ShouldNotBeNil) |
| 762 | 725 |
| 763 » » q := ds.NewQuery("").Limit(5) | 726 » » q := NewQuery("kind").Limit(5) |
| 764 | 727 |
| 765 Convey("bad", func() { | 728 Convey("bad", func() { |
| 766 assertBadTypePanics := func(cb interface{}) { | 729 assertBadTypePanics := func(cb interface{}) { |
| 767 defer func() { | 730 defer func() { |
| 768 err, _ := recover().(error) | 731 err, _ := recover().(error) |
| 769 So(err, ShouldNotBeNil) | 732 So(err, ShouldNotBeNil) |
| 770 So(err.Error(), ShouldContainSubstring, | 733 So(err.Error(), ShouldContainSubstring, |
| 771 "cb does not match the required
callback signature") | 734 "cb does not match the required
callback signature") |
| 772 }() | 735 }() |
| 773 » » » » ds.Run(q, cb) | 736 » » » » So(ds.Run(q, cb), ShouldBeNil) |
| 774 } | 737 } |
| 775 | 738 |
| 776 Convey("not a function", func() { | 739 Convey("not a function", func() { |
| 777 assertBadTypePanics("I am a potato") | 740 assertBadTypePanics("I am a potato") |
| 778 }) | 741 }) |
| 779 | 742 |
| 780 Convey("bad proto type", func() { | 743 Convey("bad proto type", func() { |
| 781 assertBadTypePanics(func(v int, _ CursorCB) bool
{ | 744 assertBadTypePanics(func(v int, _ CursorCB) bool
{ |
| 782 panic("never here!") | 745 panic("never here!") |
| 783 }) | 746 }) |
| (...skipping 11 matching lines...) Expand all Loading... |
| 795 }) | 758 }) |
| 796 }) | 759 }) |
| 797 | 760 |
| 798 Convey("bad 2nd arg", func() { | 761 Convey("bad 2nd arg", func() { |
| 799 assertBadTypePanics(func(v CommonStruct, _ Curso
r) bool { | 762 assertBadTypePanics(func(v CommonStruct, _ Curso
r) bool { |
| 800 panic("never here!") | 763 panic("never here!") |
| 801 }) | 764 }) |
| 802 }) | 765 }) |
| 803 | 766 |
| 804 Convey("early abort on error", func() { | 767 Convey("early abort on error", func() { |
| 805 » » » » rq := q.(*fakeQuery).Fail(3) | 768 » » » » q = q.Eq("$err_single", "Query fail").Eq("$err_s
ingle_idx", 3) |
| 806 i := 0 | 769 i := 0 |
| 807 » » » » So(ds.Run(rq, func(c CommonStruct, _ CursorCB) b
ool { | 770 » » » » So(ds.Run(q, func(c CommonStruct, _ CursorCB) bo
ol { |
| 808 i++ | 771 i++ |
| 809 return true | 772 return true |
| 810 » » » » }).Error(), ShouldEqual, "Query fail") | 773 » » » » }), ShouldErrLike, "Query fail") |
| 811 So(i, ShouldEqual, 3) | 774 So(i, ShouldEqual, 3) |
| 812 }) | 775 }) |
| 813 | 776 |
| 814 Convey("return error on serialization failure", func() { | 777 Convey("return error on serialization failure", func() { |
| 815 So(ds.Run(q, func(_ permaBad, _ CursorCB) bool { | 778 So(ds.Run(q, func(_ permaBad, _ CursorCB) bool { |
| 816 panic("never here") | 779 panic("never here") |
| 817 }).Error(), ShouldEqual, "permaBad") | 780 }).Error(), ShouldEqual, "permaBad") |
| 818 }) | 781 }) |
| 819 }) | 782 }) |
| 820 | 783 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 842 i++ | 805 i++ |
| 843 return true | 806 return true |
| 844 }), ShouldBeNil) | 807 }), ShouldBeNil) |
| 845 }) | 808 }) |
| 846 | 809 |
| 847 Convey("*P (map)", func() { | 810 Convey("*P (map)", func() { |
| 848 i := 0 | 811 i := 0 |
| 849 So(ds.Run(q, func(pm *PropertyMap, _ CursorCB) b
ool { | 812 So(ds.Run(q, func(pm *PropertyMap, _ CursorCB) b
ool { |
| 850 k, err := pm.GetMeta("key") | 813 k, err := pm.GetMeta("key") |
| 851 So(err, ShouldBeNil) | 814 So(err, ShouldBeNil) |
| 852 » » » » » So(k.(Key).IntID(), ShouldEqual, i+1) | 815 » » » » » So(k.(*Key).Last().IntID, ShouldEqual, i
+1) |
| 853 So((*pm)["Value"][0].Value(), ShouldEqua
l, i) | 816 So((*pm)["Value"][0].Value(), ShouldEqua
l, i) |
| 854 i++ | 817 i++ |
| 855 return true | 818 return true |
| 856 }), ShouldBeNil) | 819 }), ShouldBeNil) |
| 857 }) | 820 }) |
| 858 | 821 |
| 859 Convey("S", func() { | 822 Convey("S", func() { |
| 860 i := 0 | 823 i := 0 |
| 861 So(ds.Run(q, func(cs CommonStruct, _ CursorCB) b
ool { | 824 So(ds.Run(q, func(cs CommonStruct, _ CursorCB) b
ool { |
| 862 So(cs.ID, ShouldEqual, i+1) | 825 So(cs.ID, ShouldEqual, i+1) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 875 i++ | 838 i++ |
| 876 return true | 839 return true |
| 877 }), ShouldBeNil) | 840 }), ShouldBeNil) |
| 878 }) | 841 }) |
| 879 | 842 |
| 880 Convey("P (map)", func() { | 843 Convey("P (map)", func() { |
| 881 i := 0 | 844 i := 0 |
| 882 So(ds.Run(q, func(pm PropertyMap, _ CursorCB) bo
ol { | 845 So(ds.Run(q, func(pm PropertyMap, _ CursorCB) bo
ol { |
| 883 k, err := pm.GetMeta("key") | 846 k, err := pm.GetMeta("key") |
| 884 So(err, ShouldBeNil) | 847 So(err, ShouldBeNil) |
| 885 » » » » » So(k.(Key).IntID(), ShouldEqual, i+1) | 848 » » » » » So(k.(*Key).Last().IntID, ShouldEqual, i
+1) |
| 886 So(pm["Value"][0].Value(), ShouldEqual,
i) | 849 So(pm["Value"][0].Value(), ShouldEqual,
i) |
| 887 i++ | 850 i++ |
| 888 return true | 851 return true |
| 889 }), ShouldBeNil) | 852 }), ShouldBeNil) |
| 890 }) | 853 }) |
| 891 | 854 |
| 892 Convey("Key", func() { | 855 Convey("Key", func() { |
| 893 i := 0 | 856 i := 0 |
| 894 » » » » So(ds.Run(q, func(k Key, _ CursorCB) bool { | 857 » » » » So(ds.Run(q, func(k *Key, _ CursorCB) bool { |
| 895 » » » » » So(k.IntID(), ShouldEqual, i+1) | 858 » » » » » So(k.Last().IntID, ShouldEqual, i+1) |
| 896 i++ | 859 i++ |
| 897 return true | 860 return true |
| 898 }), ShouldBeNil) | 861 }), ShouldBeNil) |
| 899 }) | 862 }) |
| 900 | 863 |
| 901 }) | 864 }) |
| 902 }) | 865 }) |
| 903 } | 866 } |
| OLD | NEW |