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

Side by Side Diff: service/datastore/datastore_test.go

Issue 2011773002: datastore: variadic Get, Put, Exists, Delete. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/gae@master
Patch Set: s/chn/chan/ Created 4 years, 6 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/datastore.go ('k') | service/datastore/interface.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 // 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 "bytes" 10 "bytes"
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 if err := cb(k, pm, cursCB); err != nil { 63 if err := cb(k, pm, cursCB); err != nil {
64 if err == Stop { 64 if err == Stop {
65 err = nil 65 err = nil
66 } 66 }
67 return err 67 return err
68 } 68 }
69 } 69 }
70 return nil 70 return nil
71 } 71 }
72 72
73 var (
74 errFail = errors.New("Individual element fail")
75 errFailAll = errors.New("Operation fail")
76 )
77
73 func (f *fakeDatastore) PutMulti(keys []*Key, vals []PropertyMap, cb PutMultiCB) error { 78 func (f *fakeDatastore) PutMulti(keys []*Key, vals []PropertyMap, cb PutMultiCB) error {
74 if keys[0].Kind() == "FailAll" { 79 if keys[0].Kind() == "FailAll" {
75 » » return errors.New("PutMulti fail all") 80 » » return errFailAll
76 } 81 }
77 _, assertExtra := vals[0].GetMeta("assertExtra") 82 _, assertExtra := vals[0].GetMeta("assertExtra")
78 for i, k := range keys { 83 for i, k := range keys {
79 err := error(nil) 84 err := error(nil)
80 if k.Kind() == "Fail" { 85 if k.Kind() == "Fail" {
81 » » » err = errors.New("PutMulti fail") 86 » » » err = errFail
82 } else { 87 } else {
83 So(vals[i]["Value"], ShouldResemble, []Property{MkProper ty(i)}) 88 So(vals[i]["Value"], ShouldResemble, []Property{MkProper ty(i)})
84 if assertExtra { 89 if assertExtra {
85 So(vals[i]["Extra"], ShouldResemble, []Property{ MkProperty("whoa")}) 90 So(vals[i]["Extra"], ShouldResemble, []Property{ MkProperty("whoa")})
86 } 91 }
87 if k.Incomplete() { 92 if k.Incomplete() {
88 k = NewKey(k.AppID(), k.Namespace(), k.Kind(), " ", int64(i+1), k.Parent()) 93 k = NewKey(k.AppID(), k.Namespace(), k.Kind(), " ", int64(i+1), k.Parent())
89 } 94 }
90 } 95 }
91 cb(k, err) 96 cb(k, err)
92 } 97 }
93 return nil 98 return nil
94 } 99 }
95 100
101 const noSuchEntityID = 0xdead
102
96 func (f *fakeDatastore) GetMulti(keys []*Key, _meta MultiMetaGetter, cb GetMulti CB) error { 103 func (f *fakeDatastore) GetMulti(keys []*Key, _meta MultiMetaGetter, cb GetMulti CB) error {
97 if keys[0].Kind() == "FailAll" { 104 if keys[0].Kind() == "FailAll" {
98 » » return errors.New("GetMulti fail all") 105 » » return errFailAll
99 } 106 }
100 for i, k := range keys { 107 for i, k := range keys {
101 if k.Kind() == "Fail" { 108 if k.Kind() == "Fail" {
102 » » » cb(nil, errors.New("GetMulti fail")) 109 » » » cb(nil, errFail)
103 » » } else if k.Kind() == "DNE" { 110 » » } else if k.Kind() == "DNE" || k.IntID() == noSuchEntityID {
104 cb(nil, ErrNoSuchEntity) 111 cb(nil, ErrNoSuchEntity)
105 } else { 112 } else {
106 cb(PropertyMap{"Value": {MkProperty(i + 1)}}, nil) 113 cb(PropertyMap{"Value": {MkProperty(i + 1)}}, nil)
107 } 114 }
108 } 115 }
109 return nil 116 return nil
110 } 117 }
111 118
112 func (f *fakeDatastore) DeleteMulti(keys []*Key, cb DeleteMultiCB) error { 119 func (f *fakeDatastore) DeleteMulti(keys []*Key, cb DeleteMultiCB) error {
113 if keys[0].Kind() == "FailAll" { 120 if keys[0].Kind() == "FailAll" {
114 » » return errors.New("DeleteMulti fail all") 121 » » return errFailAll
115 } 122 }
116 for _, k := range keys { 123 for _, k := range keys {
117 if k.Kind() == "Fail" { 124 if k.Kind() == "Fail" {
118 » » » cb(errors.New("DeleteMulti fail")) 125 » » » cb(errFail)
126 » » } else if k.Kind() == "DNE" || k.IntID() == noSuchEntityID {
127 » » » cb(ErrNoSuchEntity)
119 } else { 128 } else {
120 cb(nil) 129 cb(nil)
121 } 130 }
122 } 131 }
123 return nil 132 return nil
124 } 133 }
125 134
126 type badStruct struct { 135 type badStruct struct {
127 ID int64 `gae:"$id"` 136 ID int64 `gae:"$id"`
128 Compy complex64 // bad type 137 Compy complex64 // bad type
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 return false 253 return false
245 } 254 }
246 255
247 func (f *FakePLS) Problem() error { 256 func (f *FakePLS) Problem() error {
248 if f.failProblem { 257 if f.failProblem {
249 return errors.New("FakePLS.Problem") 258 return errors.New("FakePLS.Problem")
250 } 259 }
251 return nil 260 return nil
252 } 261 }
253 262
263 // plsChan to test channel PLS types.
264 type plsChan chan Property
265
266 var _ PropertyLoadSaver = plsChan(nil)
267
268 func (c plsChan) Load(pm PropertyMap) error { return nil }
269 func (c plsChan) Save(withMeta bool) (PropertyMap, error) { return nil, nil }
270 func (c plsChan) SetMeta(key string, val interface{}) bool { return false }
271 func (c plsChan) Problem() error { return nil }
272
273 func (c plsChan) GetMeta(key string) (interface{}, bool) {
274 switch key {
275 case "kind":
276 return "plsChan", true
277 case "id":
278 return "whyDoIExist", true
279 }
280 return nil, false
281 }
282
283 func (c plsChan) GetAllMeta() PropertyMap {
284 return PropertyMap{
285 "kind": []Property{MkProperty("plsChan")},
286 "id": []Property{MkProperty("whyDoIExist")},
287 }
288 }
289
254 type MGSWithNoKind struct { 290 type MGSWithNoKind struct {
255 S string 291 S string
256 } 292 }
257 293
258 func (s *MGSWithNoKind) GetMeta(key string) (interface{}, bool) { 294 func (s *MGSWithNoKind) GetMeta(key string) (interface{}, bool) {
259 return nil, false 295 return nil, false
260 } 296 }
261 297
262 func (s *MGSWithNoKind) GetAllMeta() PropertyMap { 298 func (s *MGSWithNoKind) GetAllMeta() PropertyMap {
263 » return PropertyMap{} 299 » return PropertyMap{"$kind": []Property{MkProperty("ohai")}}
264 } 300 }
265 301
266 func (s *MGSWithNoKind) SetMeta(key string, val interface{}) bool { 302 func (s *MGSWithNoKind) SetMeta(key string, val interface{}) bool {
267 return false 303 return false
268 } 304 }
269 305
270 var _ MetaGetterSetter = (*MGSWithNoKind)(nil) 306 var _ MetaGetterSetter = (*MGSWithNoKind)(nil)
271 307
272 func TestKeyForObj(t *testing.T) { 308 func TestKeyForObj(t *testing.T) {
273 t.Parallel() 309 t.Parallel()
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 So(ds.KeyForObj(pm).String(), ShouldEqual, `s~ai d:ns:/Hello,"world"/Sup,100`) 356 So(ds.KeyForObj(pm).String(), ShouldEqual, `s~ai d:ns:/Hello,"world"/Sup,100`)
321 }) 357 })
322 358
323 Convey("a pls with $id, $parent", func() { 359 Convey("a pls with $id, $parent", func() {
324 pls := GetPLS(&CommonStruct{ID: 1}) 360 pls := GetPLS(&CommonStruct{ID: 1})
325 So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a id:ns:/CommonStruct,1`) 361 So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a id:ns:/CommonStruct,1`)
326 362
327 So(pls.SetMeta("parent", k), ShouldBeTrue) 363 So(pls.SetMeta("parent", k), ShouldBeTrue)
328 So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a id:ns:/Hello,"world"/CommonStruct,1`) 364 So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a id:ns:/Hello,"world"/CommonStruct,1`)
329 }) 365 })
330
331 Convey("can see if things exist", func() {
332 e, err := ds.Exists(k)
333 So(err, ShouldBeNil)
334 So(e, ShouldBeTrue)
335
336 bl, err := ds.ExistsMulti([]*Key{k, ds.MakeKey(" hello", "other")})
337 So(err, ShouldBeNil)
338 So(bl, ShouldResemble, BoolList{true, true})
339 So(bl.All(), ShouldBeTrue)
340 So(bl.Any(), ShouldBeTrue)
341
342 bl, err = ds.ExistsMulti([]*Key{k, ds.MakeKey("D NE", "other")})
343 So(err, ShouldBeNil)
344 So(bl, ShouldResemble, BoolList{true, false})
345 So(bl.All(), ShouldBeFalse)
346 So(bl.Any(), ShouldBeTrue)
347
348 e, err = ds.Exists(ds.MakeKey("DNE", "nope"))
349 So(err, ShouldBeNil)
350 So(e, ShouldBeFalse)
351
352 bl, err = ds.ExistsMulti([]*Key{ds.MakeKey("DNE" , "nope"), ds.MakeKey("DNE", "other")})
353 So(err, ShouldBeNil)
354 So(bl, ShouldResemble, BoolList{false, false})
355 So(bl.All(), ShouldBeFalse)
356 So(bl.Any(), ShouldBeFalse)
357
358 _, err = ds.Exists(ds.MakeKey("Fail", "boom"))
359 So(err, ShouldErrLike, "GetMulti fail")
360 })
361
362 }) 366 })
363 367
364 Convey("bad", func() { 368 Convey("bad", func() {
365 Convey("a propmap without $kind", func() { 369 Convey("a propmap without $kind", func() {
366 pm := PropertyMap{} 370 pm := PropertyMap{}
367 So(pm.SetMeta("id", 100), ShouldBeTrue) 371 So(pm.SetMeta("id", 100), ShouldBeTrue)
368 So(func() { ds.KeyForObj(pm) }, ShouldPanic) 372 So(func() { ds.KeyForObj(pm) }, ShouldPanic)
369 }) 373 })
370 374
371 Convey("a bad object", func() { 375 Convey("a bad object", func() {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 var broken permaBad 416 var broken permaBad
413 417
414 So(func() { PopulateKey(&broken, k) }, ShouldPanic) 418 So(func() { PopulateKey(&broken, k) }, ShouldPanic)
415 }) 419 })
416 }) 420 })
417 } 421 }
418 422
419 func TestPut(t *testing.T) { 423 func TestPut(t *testing.T) {
420 t.Parallel() 424 t.Parallel()
421 425
422 » Convey("Test Put/PutMulti", t, func() { 426 » Convey("A testing environment", t, func() {
423 c := info.Set(context.Background(), fakeInfo{}) 427 c := info.Set(context.Background(), fakeInfo{})
424 c = SetRawFactory(c, fakeDatastoreFactory) 428 c = SetRawFactory(c, fakeDatastoreFactory)
425 ds := Get(c) 429 ds := Get(c)
426 430
427 » » Convey("bad", func() { 431 » » Convey("Testing Put", func() {
428 » » » Convey("static can't serialize", func() { 432 » » » Convey("bad", func() {
429 » » » » bss := []badStruct{{}, {}} 433 » » » » Convey("static can't serialize", func() {
430 » » » » So(func() { ds.PutMulti(bss) }, ShouldPanicLike, 434 » » » » » bss := []badStruct{{}, {}}
431 » » » » » `field "Compy" has invalid type`) 435 » » » » » So(func() { ds.Put(bss) }, ShouldPanicLi ke,
432 » » » }) 436 » » » » » » `field "Compy" has invalid type` )
433 437 » » » » })
434 » » » Convey("static ptr can't serialize", func() { 438
435 » » » » bss := []*badStruct{{}, {}} 439 » » » » Convey("static ptr can't serialize", func() {
436 » » » » So(func() { ds.PutMulti(bss) }, ShouldPanicLike, 440 » » » » » bss := []*badStruct{{}, {}}
437 » » » » » `field "Compy" has invalid type: complex 64`) 441 » » » » » So(func() { ds.Put(bss) }, ShouldPanicLi ke,
438 » » » }) 442 » » » » » » `field "Compy" has invalid type: complex64`)
439 443 » » » » })
440 » » » Convey("static bad type (non-slice)", func() { 444
441 » » » » So(func() { ds.PutMulti(100) }, ShouldPanicLike, 445 » » » » Convey("static bad type", func() {
442 » » » » » "invalid argument type: expected slice, got int") 446 » » » » » So(func() { ds.Put(100) }, ShouldPanicLi ke,
443 » » » }) 447 » » » » » » "invalid input type (int): not a PLS or pointer-to-struct")
444 448 » » » » })
445 » » » Convey("static bad type (slice of bad type)", func() { 449
446 » » » » So(func() { ds.PutMulti([]int{}) }, ShouldPanicL ike, 450 » » » » Convey("static bad type (slice of bad type)", fu nc() {
447 » » » » » "invalid argument type: []int") 451 » » » » » So(func() { ds.Put([]int{}) }, ShouldPan icLike,
448 » » » }) 452 » » » » » » "invalid input type ([]int): not a PLS or pointer-to-struct")
449 453 » » » » })
450 » » » Convey("dynamic can't serialize", func() { 454
451 » » » » fplss := []FakePLS{{failSave: true}, {}} 455 » » » » Convey("dynamic can't serialize", func() {
452 » » » » So(ds.PutMulti(fplss), ShouldErrLike, "FakePLS.S ave") 456 » » » » » fplss := []FakePLS{{failSave: true}, {}}
453 » » » }) 457 » » » » » So(ds.Put(fplss), ShouldErrLike, "FakePL S.Save")
454 458 » » » » })
455 » » » Convey("can't get keys", func() { 459
456 » » » » fplss := []FakePLS{{failGetMeta: true}, {}} 460 » » » » Convey("can't get keys", func() {
457 » » » » So(ds.PutMulti(fplss), ShouldErrLike, "unable to extract $kind") 461 » » » » » fplss := []FakePLS{{failGetMeta: true}, {}}
458 » » » }) 462 » » » » » So(ds.Put(fplss), ShouldErrLike, "unable to extract $kind")
459 463 » » » » })
460 » » » Convey("get single error for RPC failure", func() { 464
461 » » » » fplss := []FakePLS{{Kind: "FailAll"}, {}} 465 » » » » Convey("get single error for RPC failure", func( ) {
462 » » » » So(ds.PutMulti(fplss), ShouldErrLike, "PutMulti fail all") 466 » » » » » fplss := []FakePLS{{Kind: "FailAll"}, {} }
463 » » » }) 467 » » » » » So(ds.Put(fplss), ShouldEqual, errFailAl l)
464 468 » » » » })
465 » » » Convey("get multi error for individual failures", func() { 469
466 » » » » fplss := []FakePLS{{}, {Kind: "Fail"}} 470 » » » » Convey("get multi error for individual failures" , func() {
467 » » » » So(ds.PutMulti(fplss), ShouldResemble, errors.Mu ltiError{nil, errors.New("PutMulti fail")}) 471 » » » » » fplss := []FakePLS{{}, {Kind: "Fail"}}
468 » » » }) 472 » » » » » So(ds.Put(fplss), ShouldResemble, errors .MultiError{nil, errFail})
469 473 » » » » })
470 » » » Convey("put with non-modifyable type is an error", func( ) { 474
475 » » » » Convey("put with non-modifyable type is an error ", func() {
476 » » » » » cs := CommonStruct{}
477 » » » » » So(func() { ds.Put(cs) }, ShouldPanicLik e,
478 » » » » » » "invalid input type (datastore.C ommonStruct): not a pointer")
479 » » » » })
480
481 » » » » Convey("get with *Key is an error", func() {
482 » » » » » So(func() { ds.Get(&Key{}) }, ShouldPani cLike,
483 » » » » » » "invalid input type (*datastore. Key): not user datatype")
484 » » » » })
485
486 » » » » Convey("struct with no $kind is an error", func( ) {
487 » » » » » s := MGSWithNoKind{}
488 » » » » » So(ds.Put(&s), ShouldErrLike, "unable to extract $kind")
489 » » » » })
490
491 » » » » Convey("struct with invalid but non-nil key is a n error", func() {
492 » » » » » type BadParent struct {
493 » » » » » » ID int64 `gae:"$id"`
494 » » » » » » Parent *Key `gae:"$parent"`
495 » » » » » }
496 » » » » » // having an Incomplete parent makes an invalid key
497 » » » » » bp := &BadParent{ID: 1, Parent: ds.MakeK ey("Something", 0)}
498 » » » » » So(ds.Put(bp), ShouldErrLike, ErrInvalid Key)
499 » » » » })
500
501 » » » » Convey("vararg with errors", func() {
502 » » » » » successSlice := []CommonStruct{{Value: 0 }, {Value: 1}}
503 » » » » » failSlice := []FakePLS{{Kind: "Fail"}, { Value: 3}}
504 » » » » » emptySlice := []CommonStruct(nil)
505 » » » » » cs0 := CommonStruct{Value: 4}
506 » » » » » cs1 := FakePLS{Kind: "Fail", Value: 5}
507 » » » » » fpls := FakePLS{StringID: "ohai", Value: 6}
508
509 » » » » » err := ds.Put(successSlice, failSlice, e mptySlice, &cs0, &cs1, &fpls)
510 » » » » » So(err, ShouldResemble, errors.MultiErro r{
511 » » » » » » nil, errors.MultiError{errFail, nil}, nil, nil, errFail, nil})
512 » » » » » So(successSlice[0].ID, ShouldEqual, 1)
513 » » » » » So(successSlice[1].ID, ShouldEqual, 2)
514 » » » » » So(cs0.ID, ShouldEqual, 5)
515 » » » » })
516 » » » })
517
518 » » » Convey("ok", func() {
519 » » » » Convey("[]S", func() {
520 » » » » » css := make([]CommonStruct, 7)
521 » » » » » for i := range css {
522 » » » » » » if i == 4 {
523 » » » » » » » css[i].ID = 200
524 » » » » » » }
525 » » » » » » css[i].Value = int64(i)
526 » » » » » }
527 » » » » » So(ds.Put(css), ShouldBeNil)
528 » » » » » for i, cs := range css {
529 » » » » » » expect := int64(i + 1)
530 » » » » » » if i == 4 {
531 » » » » » » » expect = 200
532 » » » » » » }
533 » » » » » » So(cs.ID, ShouldEqual, expect)
534 » » » » » }
535 » » » » })
536
537 » » » » Convey("[]*S", func() {
538 » » » » » css := make([]*CommonStruct, 7)
539 » » » » » for i := range css {
540 » » » » » » css[i] = &CommonStruct{Value: in t64(i)}
541 » » » » » » if i == 4 {
542 » » » » » » » css[i].ID = 200
543 » » » » » » }
544 » » » » » }
545 » » » » » So(ds.Put(css), ShouldBeNil)
546 » » » » » for i, cs := range css {
547 » » » » » » expect := int64(i + 1)
548 » » » » » » if i == 4 {
549 » » » » » » » expect = 200
550 » » » » » » }
551 » » » » » » So(cs.ID, ShouldEqual, expect)
552 » » » » » }
553
554 » » » » » s := &CommonStruct{}
555 » » » » » So(ds.Put(s), ShouldBeNil)
556 » » » » » So(s.ID, ShouldEqual, 1)
557 » » » » })
558
559 » » » » Convey("[]P", func() {
560 » » » » » fplss := make([]FakePLS, 7)
561 » » » » » for i := range fplss {
562 » » » » » » fplss[i].Value = int64(i)
563 » » » » » » if i == 4 {
564 » » » » » » » fplss[i].IntID = int64(2 00)
565 » » » » » » }
566 » » » » » }
567 » » » » » So(ds.Put(fplss), ShouldBeNil)
568 » » » » » for i, fpls := range fplss {
569 » » » » » » expect := int64(i + 1)
570 » » » » » » if i == 4 {
571 » » » » » » » expect = 200
572 » » » » » » }
573 » » » » » » So(fpls.IntID, ShouldEqual, expe ct)
574 » » » » » }
575
576 » » » » » pm := PropertyMap{"Value": {MkProperty(0 )}, "$kind": {MkPropertyNI("Pmap")}}
577 » » » » » So(ds.Put(pm), ShouldBeNil)
578 » » » » » So(ds.KeyForObj(pm).IntID(), ShouldEqual , 1)
579 » » » » })
580
581 » » » » Convey("[]P (map)", func() {
582 » » » » » pms := make([]PropertyMap, 7)
583 » » » » » for i := range pms {
584 » » » » » » pms[i] = PropertyMap{
585 » » » » » » » "$kind": {MkProperty("Pm ap")},
586 » » » » » » » "Value": {MkProperty(i)} ,
587 » » » » » » }
588 » » » » » » if i == 4 {
589 » » » » » » » So(pms[i].SetMeta("id", int64(200)), ShouldBeTrue)
590 » » » » » » }
591 » » » » » }
592 » » » » » So(ds.Put(pms), ShouldBeNil)
593 » » » » » for i, pm := range pms {
594 » » » » » » expect := int64(i + 1)
595 » » » » » » if i == 4 {
596 » » » » » » » expect = 200
597 » » » » » » }
598 » » » » » » So(ds.KeyForObj(pm).String(), Sh ouldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
599 » » » » » }
600 » » » » })
601
602 » » » » Convey("[]*P", func() {
603 » » » » » fplss := make([]*FakePLS, 7)
604 » » » » » for i := range fplss {
605 » » » » » » fplss[i] = &FakePLS{Value: int64 (i)}
606 » » » » » » if i == 4 {
607 » » » » » » » fplss[i].IntID = int64(2 00)
608 » » » » » » }
609 » » » » » }
610 » » » » » So(ds.Put(fplss), ShouldBeNil)
611 » » » » » for i, fpls := range fplss {
612 » » » » » » expect := int64(i + 1)
613 » » » » » » if i == 4 {
614 » » » » » » » expect = 200
615 » » » » » » }
616 » » » » » » So(fpls.IntID, ShouldEqual, expe ct)
617 » » » » » }
618 » » » » })
619
620 » » » » Convey("[]*P (map)", func() {
621 » » » » » pms := make([]*PropertyMap, 7)
622 » » » » » for i := range pms {
623 » » » » » » pms[i] = &PropertyMap{
624 » » » » » » » "$kind": {MkProperty("Pm ap")},
625 » » » » » » » "Value": {MkProperty(i)} ,
626 » » » » » » }
627 » » » » » » if i == 4 {
628 » » » » » » » So(pms[i].SetMeta("id", int64(200)), ShouldBeTrue)
629 » » » » » » }
630 » » » » » }
631 » » » » » So(ds.Put(pms), ShouldBeNil)
632 » » » » » for i, pm := range pms {
633 » » » » » » expect := int64(i + 1)
634 » » » » » » if i == 4 {
635 » » » » » » » expect = 200
636 » » » » » » }
637 » » » » » » So(ds.KeyForObj(*pm).String(), S houldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
638 » » » » » }
639 » » » » })
640
641 » » » » Convey("[]I", func() {
642 » » » » » ifs := []interface{}{
643 » » » » » » &CommonStruct{Value: 0},
644 » » » » » » &FakePLS{Value: 1},
645 » » » » » » PropertyMap{"Value": {MkProperty (2)}, "$kind": {MkPropertyNI("Pmap")}},
646 » » » » » » &PropertyMap{"Value": {MkPropert y(3)}, "$kind": {MkPropertyNI("Pmap")}},
647 » » » » » }
648 » » » » » So(ds.Put(ifs), ShouldBeNil)
649 » » » » » for i := range ifs {
650 » » » » » » switch i {
651 » » » » » » case 0:
652 » » » » » » » So(ifs[i].(*CommonStruct ).ID, ShouldEqual, 1)
653 » » » » » » case 1:
654 » » » » » » » fpls := ifs[i].(*FakePLS )
655 » » » » » » » So(fpls.IntID, ShouldEqu al, 2)
656 » » » » » » case 2:
657 » » » » » » » So(ds.KeyForObj(ifs[i].( PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,3")
658 » » » » » » case 3:
659 » » » » » » » So(ds.KeyForObj(*ifs[i]. (*PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,4")
660 » » » » » » }
661 » » » » » }
662 » » » » })
663 » » » })
664 » » })
665
666 » » Convey("Testing PutMulti", func() {
667 » » » Convey("Fails for something other than a slice.", func() {
471 cs := CommonStruct{} 668 cs := CommonStruct{}
472 » » » » So(func() { ds.Put(cs) }, ShouldPanicLike, 669 » » » » So(func() { ds.PutMulti(&cs) }, ShouldPanicLike,
473 » » » » » "invalid Put input type (datastore.Commo nStruct): not a pointer") 670 » » » » » "argument must be a slice, not *datastor e.CommonStruct")
474 » » » }) 671 » » » })
475 672
476 » » » Convey("get with *Key is an error", func() { 673 » » » Convey("Succeeds for a slice.", func() {
477 » » » » So(func() { ds.Get(&Key{}) }, ShouldPanicLike, 674 » » » » cs := []CommonStruct{{Value: 0}, {Value: 1}}
478 » » » » » "invalid Get input type (*datastore.Key) : not user datatype") 675 » » » » So(ds.PutMulti(cs), ShouldBeNil)
479 » » » }) 676 » » » » So(cs[0].ID, ShouldEqual, 1)
480 677 » » » » So(cs[1].ID, ShouldEqual, 2)
481 » » » Convey("struct with no $kind is an error", func() { 678 » » » })
482 » » » » s := MGSWithNoKind{} 679
483 » » » » So(ds.Put(&s), ShouldErrLike, "unable to extract $kind") 680 » » » Convey("Returns an item error in a MultiError.", func() {
484 » » » }) 681 » » » » cs := []FakePLS{{Value: 0}, {Kind: "Fail"}}
485 682 » » » » err := ds.PutMulti(cs)
486 » » » Convey("struct with invalid but non-nil key is an error" , func() { 683 » » » » So(err, ShouldResemble, errors.MultiError{nil, e rrFail})
487 » » » » type BadParent struct { 684 » » » » So(cs[0].IntID, ShouldEqual, 1)
488 » » » » » ID int64 `gae:"$id"` 685 » » » })
489 » » » » » Parent *Key `gae:"$parent"` 686 » » })
490 » » » » }
491 » » » » // having an Incomplete parent makes an invalid key
492 » » » » bp := &BadParent{ID: 1, Parent: ds.MakeKey("Some thing", 0)}
493 » » » » So(ds.Put(bp), ShouldErrLike, ErrInvalidKey)
494 » » » })
495 » » })
496
497 » » Convey("ok", func() {
498 » » » Convey("[]S", func() {
499 » » » » css := make([]CommonStruct, 7)
500 » » » » for i := range css {
501 » » » » » if i == 4 {
502 » » » » » » css[i].ID = 200
503 » » » » » }
504 » » » » » css[i].Value = int64(i)
505 » » » » }
506 » » » » So(ds.PutMulti(css), ShouldBeNil)
507 » » » » for i, cs := range css {
508 » » » » » expect := int64(i + 1)
509 » » » » » if i == 4 {
510 » » » » » » expect = 200
511 » » » » » }
512 » » » » » So(cs.ID, ShouldEqual, expect)
513 » » » » }
514 » » » })
515
516 » » » Convey("[]*S", func() {
517 » » » » css := make([]*CommonStruct, 7)
518 » » » » for i := range css {
519 » » » » » css[i] = &CommonStruct{Value: int64(i)}
520 » » » » » if i == 4 {
521 » » » » » » css[i].ID = 200
522 » » » » » }
523 » » » » }
524 » » » » So(ds.PutMulti(css), ShouldBeNil)
525 » » » » for i, cs := range css {
526 » » » » » expect := int64(i + 1)
527 » » » » » if i == 4 {
528 » » » » » » expect = 200
529 » » » » » }
530 » » » » » So(cs.ID, ShouldEqual, expect)
531 » » » » }
532
533 » » » » s := &CommonStruct{}
534 » » » » So(ds.Put(s), ShouldBeNil)
535 » » » » So(s.ID, ShouldEqual, 1)
536 » » » })
537
538 » » » Convey("[]P", func() {
539 » » » » fplss := make([]FakePLS, 7)
540 » » » » for i := range fplss {
541 » » » » » fplss[i].Value = int64(i)
542 » » » » » if i == 4 {
543 » » » » » » fplss[i].IntID = int64(200)
544 » » » » » }
545 » » » » }
546 » » » » So(ds.PutMulti(fplss), ShouldBeNil)
547 » » » » for i, fpls := range fplss {
548 » » » » » expect := int64(i + 1)
549 » » » » » if i == 4 {
550 » » » » » » expect = 200
551 » » » » » }
552 » » » » » So(fpls.IntID, ShouldEqual, expect)
553 » » » » }
554
555 » » » » pm := PropertyMap{"Value": {MkProperty(0)}, "$ki nd": {MkPropertyNI("Pmap")}}
556 » » » » So(ds.Put(pm), ShouldBeNil)
557 » » » » So(ds.KeyForObj(pm).IntID(), ShouldEqual, 1)
558 » » » })
559
560 » » » Convey("[]P (map)", func() {
561 » » » » pms := make([]PropertyMap, 7)
562 » » » » for i := range pms {
563 » » » » » pms[i] = PropertyMap{
564 » » » » » » "$kind": {MkProperty("Pmap")},
565 » » » » » » "Value": {MkProperty(i)},
566 » » » » » }
567 » » » » » if i == 4 {
568 » » » » » » So(pms[i].SetMeta("id", int64(20 0)), ShouldBeTrue)
569 » » » » » }
570 » » » » }
571 » » » » So(ds.PutMulti(pms), ShouldBeNil)
572 » » » » for i, pm := range pms {
573 » » » » » expect := int64(i + 1)
574 » » » » » if i == 4 {
575 » » » » » » expect = 200
576 » » » » » }
577 » » » » » So(ds.KeyForObj(pm).String(), ShouldEqua l, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
578 » » » » }
579 » » » })
580
581 » » » Convey("[]*P", func() {
582 » » » » fplss := make([]*FakePLS, 7)
583 » » » » for i := range fplss {
584 » » » » » fplss[i] = &FakePLS{Value: int64(i)}
585 » » » » » if i == 4 {
586 » » » » » » fplss[i].IntID = int64(200)
587 » » » » » }
588 » » » » }
589 » » » » So(ds.PutMulti(fplss), ShouldBeNil)
590 » » » » for i, fpls := range fplss {
591 » » » » » expect := int64(i + 1)
592 » » » » » if i == 4 {
593 » » » » » » expect = 200
594 » » » » » }
595 » » » » » So(fpls.IntID, ShouldEqual, expect)
596 » » » » }
597 » » » })
598
599 » » » Convey("[]*P (map)", func() {
600 » » » » pms := make([]*PropertyMap, 7)
601 » » » » for i := range pms {
602 » » » » » pms[i] = &PropertyMap{
603 » » » » » » "$kind": {MkProperty("Pmap")},
604 » » » » » » "Value": {MkProperty(i)},
605 » » » » » }
606 » » » » » if i == 4 {
607 » » » » » » So(pms[i].SetMeta("id", int64(20 0)), ShouldBeTrue)
608 » » » » » }
609 » » » » }
610 » » » » So(ds.PutMulti(pms), ShouldBeNil)
611 » » » » for i, pm := range pms {
612 » » » » » expect := int64(i + 1)
613 » » » » » if i == 4 {
614 » » » » » » expect = 200
615 » » » » » }
616 » » » » » So(ds.KeyForObj(*pm).String(), ShouldEqu al, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
617 » » » » }
618 » » » })
619
620 » » » Convey("[]I", func() {
621 » » » » ifs := []interface{}{
622 » » » » » &CommonStruct{Value: 0},
623 » » » » » &FakePLS{Value: 1},
624 » » » » » PropertyMap{"Value": {MkProperty(2)}, "$ kind": {MkPropertyNI("Pmap")}},
625 » » » » » &PropertyMap{"Value": {MkProperty(3)}, " $kind": {MkPropertyNI("Pmap")}},
626 » » » » }
627 » » » » So(ds.PutMulti(ifs), ShouldBeNil)
628 » » » » for i := range ifs {
629 » » » » » switch i {
630 » » » » » case 0:
631 » » » » » » So(ifs[i].(*CommonStruct).ID, Sh ouldEqual, 1)
632 » » » » » case 1:
633 » » » » » » fpls := ifs[i].(*FakePLS)
634 » » » » » » So(fpls.IntID, ShouldEqual, 2)
635 » » » » » case 2:
636 » » » » » » So(ds.KeyForObj(ifs[i].(Property Map)).String(), ShouldEqual, "s~aid:ns:/Pmap,3")
637 » » » » » case 3:
638 » » » » » » So(ds.KeyForObj(*ifs[i].(*Proper tyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,4")
639 » » » » » }
640 » » » » }
641 » » » })
642
643 » » })
644
645 }) 687 })
646 } 688 }
647 689
690 func TestExists(t *testing.T) {
691 t.Parallel()
692
693 Convey("A testing environment", t, func() {
694 c := info.Set(context.Background(), fakeInfo{})
695 c = SetRawFactory(c, fakeDatastoreFactory)
696 ds := Get(c)
697
698 k := ds.MakeKey("Hello", "world")
699
700 Convey("Exists", func() {
701 // Single key.
702 er, err := ds.Exists(k)
703 So(err, ShouldBeNil)
704 So(er.All(), ShouldBeTrue)
705
706 // Single key failure.
707 _, err = ds.Exists(ds.MakeKey("Fail", "boom"))
708 So(err, ShouldEqual, errFail)
709
710 // Single slice of keys.
711 er, err = ds.Exists([]*Key{k, ds.MakeKey("hello", "other ")})
712 So(err, ShouldBeNil)
713 So(er.All(), ShouldBeTrue)
714
715 // Single slice of keys failure.
716 er, err = ds.Exists([]*Key{k, ds.MakeKey("Fail", "boom") })
717 So(err, ShouldResemble, errors.MultiError{nil, errFail})
718 So(er.Get(0, 0), ShouldBeTrue)
719
720 // Single key missing.
721 er, err = ds.Exists(ds.MakeKey("DNE", "nope"))
722 So(err, ShouldBeNil)
723 So(er.Any(), ShouldBeFalse)
724
725 // Multi-arg keys with one missing.
726 er, err = ds.Exists(k, ds.MakeKey("DNE", "other"))
727 So(err, ShouldBeNil)
728 So(er.Get(0), ShouldBeTrue)
729 So(er.Get(1), ShouldBeFalse)
730
731 // Multi-arg keys with two missing.
732 er, err = ds.Exists(ds.MakeKey("DNE", "nope"), ds.MakeKe y("DNE", "other"))
733 So(err, ShouldBeNil)
734 So(er.Any(), ShouldBeFalse)
735
736 // Multi-arg mixed key/struct/slices.
737 er, err = ds.Exists(&CommonStruct{ID: 1}, []*CommonStruc t(nil), []*Key{ds.MakeKey("DNE", "nope"), ds.MakeKey("hello", "ohai")})
738 So(err, ShouldBeNil)
739 So(er.Get(0), ShouldBeTrue)
740 So(er.Get(1), ShouldBeTrue)
741 So(er.Get(2), ShouldBeFalse)
742 So(er.Get(2, 0), ShouldBeFalse)
743 So(er.Get(2, 1), ShouldBeTrue)
744 })
745
746 Convey("ExistsMulti", func() {
747 Convey("Returns no error if there are no failures.", fun c() {
748 bl, err := ds.ExistsMulti([]*Key{k, ds.MakeKey(" DNE", "nope"), ds.MakeKey("hello", "ohai")})
749 So(err, ShouldBeNil)
750 So(bl, ShouldResemble, BoolList{true, false, tru e})
751 })
752
753 Convey("Returns an item error in a MultiError.", func() {
754 _, err := ds.ExistsMulti([]*Key{k, ds.MakeKey("F ail", "boom")})
755 So(err, ShouldResemble, errors.MultiError{nil, e rrFail})
756 })
757 })
758 })
759 }
760
648 func TestDelete(t *testing.T) { 761 func TestDelete(t *testing.T) {
649 t.Parallel() 762 t.Parallel()
650 763
651 » Convey("Test Delete/DeleteMulti", t, func() { 764 » Convey("A testing environment", t, func() {
652 c := info.Set(context.Background(), fakeInfo{}) 765 c := info.Set(context.Background(), fakeInfo{})
653 c = SetRawFactory(c, fakeDatastoreFactory) 766 c = SetRawFactory(c, fakeDatastoreFactory)
654 ds := Get(c) 767 ds := Get(c)
655 So(ds, ShouldNotBeNil) 768 So(ds, ShouldNotBeNil)
656 769
657 » » Convey("bad", func() { 770 » » Convey("Testing Delete", func() {
658 » » » Convey("get single error for RPC failure", func() { 771 » » » Convey("bad", func() {
659 » » » » keys := []*Key{ 772 » » » » Convey("get single error for RPC failure", func( ) {
660 » » » » » MakeKey("s~aid", "ns", "FailAll", 1), 773 » » » » » keys := []*Key{
661 » » » » » MakeKey("s~aid", "ns", "Ok", 1), 774 » » » » » » MakeKey("s~aid", "ns", "FailAll" , 1),
662 » » » » } 775 » » » » » » MakeKey("s~aid", "ns", "Ok", 1),
663 » » » » So(ds.DeleteMulti(keys).Error(), ShouldEqual, "D eleteMulti fail all") 776 » » » » » }
664 » » » }) 777 » » » » » So(ds.Delete(keys), ShouldEqual, errFail All)
665 778 » » » » })
666 » » » Convey("get multi error for individual failure", func() { 779
667 » » » » keys := []*Key{ 780 » » » » Convey("get multi error for individual failure", func() {
668 » » » » » ds.MakeKey("Ok", 1), 781 » » » » » keys := []*Key{
669 » » » » » ds.MakeKey("Fail", 2), 782 » » » » » » ds.MakeKey("Ok", 1),
670 » » » » } 783 » » » » » » ds.MakeKey("Fail", 2),
671 » » » » So(ds.DeleteMulti(keys).Error(), ShouldEqual, "D eleteMulti fail") 784 » » » » » }
672 » » » }) 785 » » » » » So(ds.Delete(keys), ShouldResemble, erro rs.MultiError{nil, errFail})
673 786 » » » » })
674 » » » Convey("get single error when deleting a single", func() { 787
675 » » » » k := ds.MakeKey("Fail", 1) 788 » » » » Convey("get single error when deleting a single" , func() {
676 » » » » So(ds.Delete(k).Error(), ShouldEqual, "DeleteMul ti fail") 789 » » » » » k := ds.MakeKey("Fail", 1)
677 » » » }) 790 » » » » » So(ds.Delete(k), ShouldEqual, errFail)
678 » » }) 791 » » » » })
679 792 » » » })
793
794 » » » Convey("good", func() {
795 » » » » // Single struct.
796 » » » » So(ds.Delete(&CommonStruct{ID: 1}), ShouldBeNil)
797
798 » » » » // Single key.
799 » » » » So(ds.Delete(ds.MakeKey("hello", "ohai")), Shoul dBeNil)
800
801 » » » » // Single struct DNE.
802 » » » » So(ds.Delete(&CommonStruct{ID: noSuchEntityID}), ShouldEqual, ErrNoSuchEntity)
803
804 » » » » // Single key DNE.
805 » » » » So(ds.Delete(ds.MakeKey("DNE", "nope")), ShouldE qual, ErrNoSuchEntity)
806
807 » » » » // Mixed key/struct/slices.
808 » » » » err := ds.Delete(&CommonStruct{ID: 1}, []*Key{ds .MakeKey("hello", "ohai"), ds.MakeKey("DNE", "nope")})
809 » » » » So(err, ShouldResemble, errors.MultiError{nil, e rrors.MultiError{nil, ErrNoSuchEntity}})
810 » » » })
811 » » })
812
813 » » Convey("Testing DeleteMulti", func() {
814 » » » Convey("Succeeds for valid keys.", func() {
815 » » » » So(ds.DeleteMulti([]*Key{ds.MakeKey("hello", "oh ai")}), ShouldBeNil)
816 » » » » So(ds.DeleteMulti([]*Key{ds.MakeKey("hello", "oh ai"), ds.MakeKey("hello", "sup")}), ShouldBeNil)
817 » » » })
818
819 » » » Convey("Returns an item error in a MultiError.", func() {
820 » » » » So(ds.DeleteMulti([]*Key{ds.MakeKey("DNE", "oops ")}), ShouldResemble, errors.MultiError{ErrNoSuchEntity})
821 » » » })
822 » » })
680 }) 823 })
681 } 824 }
682 825
683 func TestGet(t *testing.T) { 826 func TestGet(t *testing.T) {
684 t.Parallel() 827 t.Parallel()
685 828
686 » Convey("Test Get/GetMulti", t, func() { 829 » Convey("A testing environment", t, func() {
687 c := info.Set(context.Background(), fakeInfo{}) 830 c := info.Set(context.Background(), fakeInfo{})
688 c = SetRawFactory(c, fakeDatastoreFactory) 831 c = SetRawFactory(c, fakeDatastoreFactory)
689 ds := Get(c) 832 ds := Get(c)
690 So(ds, ShouldNotBeNil) 833 So(ds, ShouldNotBeNil)
691 834
692 » » Convey("bad", func() { 835 » » Convey("Testing Get", func() {
693 » » » Convey("static can't serialize", func() { 836 » » » Convey("bad", func() {
694 » » » » toGet := []badStruct{{}, {}} 837 » » » » Convey("static can't serialize", func() {
695 » » » » So(func() { ds.GetMulti(toGet) }, ShouldPanicLik e, 838 » » » » » toGet := []badStruct{{}, {}}
696 » » » » » `field "Compy" has invalid type: complex 64`) 839 » » » » » So(func() { ds.Get(toGet) }, ShouldPanic Like,
697 » » » }) 840 » » » » » » `field "Compy" has invalid type: complex64`)
698 841 » » » » })
699 » » » Convey("can't get keys", func() { 842
700 » » » » fplss := []FakePLS{{failGetMeta: true}, {}} 843 » » » » Convey("can't get keys", func() {
701 » » » » So(ds.GetMulti(fplss), ShouldErrLike, "unable to extract $kind") 844 » » » » » fplss := []FakePLS{{failGetMeta: true}, {}}
702 » » » }) 845 » » » » » So(ds.Get(fplss), ShouldErrLike, "unable to extract $kind")
703 846 » » » » })
704 » » » Convey("get single error for RPC failure", func() { 847
705 » » » » fplss := []FakePLS{ 848 » » » » Convey("get single error for RPC failure", func( ) {
706 » » » » » {IntID: 1, Kind: "FailAll"}, 849 » » » » » fplss := []FakePLS{
707 » » » » » {IntID: 2}, 850 » » » » » » {IntID: 1, Kind: "FailAll"},
708 » » » » } 851 » » » » » » {IntID: 2},
709 » » » » So(ds.GetMulti(fplss).Error(), ShouldEqual, "Get Multi fail all") 852 » » » » » }
710 » » » }) 853 » » » » » So(ds.Get(fplss), ShouldEqual, errFailAl l)
711 854 » » » » })
712 » » » Convey("get multi error for individual failures", func() { 855
713 » » » » fplss := []FakePLS{{IntID: 1}, {IntID: 2, Kind: "Fail"}} 856 » » » » Convey("get multi error for individual failures" , func() {
714 » » » » So(ds.GetMulti(fplss), ShouldResemble, errors.Mu ltiError{nil, errors.New("GetMulti fail")}) 857 » » » » » fplss := []FakePLS{{IntID: 1}, {IntID: 2 , Kind: "Fail"}}
715 » » » }) 858 » » » » » So(ds.Get(fplss), ShouldResemble, errors .MultiError{nil, errFail})
716 859 » » » » })
717 » » » Convey("get with non-modifiable type is an error", func( ) { 860
861 » » » » Convey("get with non-modifiable type is an error ", func() {
862 » » » » » cs := CommonStruct{}
863 » » » » » So(func() { ds.Get(cs) }, ShouldPanicLik e,
864 » » » » » » "invalid input type (datastore.C ommonStruct): not a pointer")
865 » » » » })
866
867 » » » » Convey("get with nil is an error", func() {
868 » » » » » So(func() { ds.Get(nil) }, ShouldPanicLi ke,
869 » » » » » » "cannot use nil as single argume nt")
870 » » » » })
871
872 » » » » Convey("get with ptr-to-nonstruct is an error", func() {
873 » » » » » val := 100
874 » » » » » So(func() { ds.Get(&val) }, ShouldPanicL ike,
875 » » » » » » "invalid input type (*int): not a PLS or pointer-to-struct")
876 » » » » })
877
878 » » » » Convey("failure to save metadata is no problem t hough", func() {
879 » » » » » // It just won't save the key
880 » » » » » cs := &FakePLS{IntID: 10, failSetMeta: t rue}
881 » » » » » So(ds.Get(cs), ShouldBeNil)
882 » » » » })
883
884 » » » » Convey("vararg with errors", func() {
885 » » » » » successSlice := []CommonStruct{{ID: 1}, {ID: 2}}
886 » » » » » failSlice := []CommonStruct{{ID: noSuchE ntityID}, {ID: 3}}
887 » » » » » emptySlice := []CommonStruct(nil)
888 » » » » » cs0 := CommonStruct{ID: 4}
889 » » » » » cs1 := CommonStruct{ID: noSuchEntityID}
890 » » » » » fpls := FakePLS{StringID: "ohai"}
891
892 » » » » » err := ds.Get(successSlice, failSlice, e mptySlice, &cs0, &cs1, &fpls)
893 » » » » » So(err, ShouldResemble, errors.MultiErro r{
894 » » » » » » nil, errors.MultiError{ErrNoSuch Entity, nil}, nil, nil, ErrNoSuchEntity, nil})
895 » » » » » So(successSlice[0].Value, ShouldEqual, 1 )
896 » » » » » So(successSlice[1].Value, ShouldEqual, 2 )
897 » » » » » So(cs0.Value, ShouldEqual, 5)
898 » » » » » So(fpls.Value, ShouldEqual, 7)
899 » » » » })
900 » » » })
901
902 » » » Convey("ok", func() {
903 » » » » Convey("Get", func() {
904 » » » » » cs := &CommonStruct{ID: 1}
905 » » » » » So(ds.Get(cs), ShouldBeNil)
906 » » » » » So(cs.Value, ShouldEqual, 1)
907 » » » » })
908
909 » » » » Convey("Raw access too", func() {
910 » » » » » rds := ds.Raw()
911 » » » » » keys := []*Key{ds.MakeKey("Kind", 1)}
912 » » » » » So(rds.GetMulti(keys, nil, func(pm Prope rtyMap, err error) error {
913 » » » » » » So(err, ShouldBeNil)
914 » » » » » » So(pm["Value"][0].Value(), Shoul dEqual, 1)
915 » » » » » » return nil
916 » » » » » }), ShouldBeNil)
917 » » » » })
918
919 » » » » Convey("but general failure to save is fine on a Get", func() {
920 » » » » » cs := &FakePLS{failSave: true, IntID: 7}
921 » » » » » So(ds.Get(cs), ShouldBeNil)
922 » » » » })
923
924 » » » » Convey("vararg", func() {
925 » » » » » successSlice := []CommonStruct{{ID: 1}, {ID: 2}}
926 » » » » » cs := CommonStruct{ID: 3}
927
928 » » » » » err := ds.Get(successSlice, &cs)
929 » » » » » So(err, ShouldBeNil)
930 » » » » » So(successSlice[0].Value, ShouldEqual, 1 )
931 » » » » » So(successSlice[1].Value, ShouldEqual, 2 )
932 » » » » » So(cs.Value, ShouldEqual, 3)
933 » » » » })
934 » » » })
935 » » })
936
937 » » Convey("Testing GetMulti", func() {
938 » » » Convey("Fails for something other than a slice.", func() {
718 cs := CommonStruct{} 939 cs := CommonStruct{}
719 » » » » So(func() { ds.Get(cs) }, ShouldPanicLike, 940 » » » » So(func() { ds.GetMulti(&cs) }, ShouldPanicLike,
720 » » » » » "invalid Get input type (datastore.Commo nStruct): not a pointer") 941 » » » » » "argument must be a slice, not *datastor e.CommonStruct")
721 » » » }) 942 » » » })
722 943
723 » » » Convey("get with nil is an error", func() { 944 » » » Convey("Succeeds for a slice.", func() {
724 » » » » So(func() { ds.Get(nil) }, ShouldPanicLike, 945 » » » » cs := []CommonStruct{{ID: 1}}
725 » » » » » "invalid Get input type (<nil>): no type information") 946 » » » » So(ds.GetMulti(cs), ShouldBeNil)
726 » » » }) 947 » » » » So(cs[0].Value, ShouldEqual, 1)
727 948 » » » })
728 » » » Convey("get with ptr-to-nonstruct is an error", func() { 949
729 » » » » val := 100 950 » » » Convey("Returns an item error in a MultiError.", func() {
730 » » » » So(func() { ds.Get(&val) }, ShouldPanicLike, 951 » » » » cs := []CommonStruct{{ID: 1}, {ID: noSuchEntityI D}}
731 » » » » » "invalid Get input type (*int): does not point to a struct") 952 » » » » err := ds.GetMulti(cs)
732 » » » }) 953 » » » » So(err, ShouldResemble, errors.MultiError{nil, E rrNoSuchEntity})
733 954 » » » » So(cs[0].Value, ShouldEqual, 1)
734 » » » Convey("failure to save metadata is no problem though", func() { 955 » » » })
735 » » » » // It just won't save the key 956 » » })
736 » » » » cs := &FakePLS{IntID: 10, failSetMeta: true}
737 » » » » So(ds.Get(cs), ShouldBeNil)
738 » » » })
739 » » })
740
741 » » Convey("ok", func() {
742 » » » Convey("Get", func() {
743 » » » » cs := &CommonStruct{ID: 1}
744 » » » » So(ds.Get(cs), ShouldBeNil)
745 » » » » So(cs.Value, ShouldEqual, 1)
746 » » » })
747
748 » » » Convey("Raw access too", func() {
749 » » » » rds := ds.Raw()
750 » » » » keys := []*Key{ds.MakeKey("Kind", 1)}
751 » » » » So(rds.GetMulti(keys, nil, func(pm PropertyMap, err error) error {
752 » » » » » So(err, ShouldBeNil)
753 » » » » » So(pm["Value"][0].Value(), ShouldEqual, 1)
754 » » » » » return nil
755 » » » » }), ShouldBeNil)
756 » » » })
757
758 » » » Convey("but general failure to save is fine on a Get", f unc() {
759 » » » » cs := &FakePLS{failSave: true, IntID: 7}
760 » » » » So(ds.Get(cs), ShouldBeNil)
761 » » » })
762 » » })
763
764 }) 957 })
765 } 958 }
766 959
767 func TestGetAll(t *testing.T) { 960 func TestGetAll(t *testing.T) {
768 t.Parallel() 961 t.Parallel()
769 962
770 Convey("Test GetAll", t, func() { 963 Convey("Test GetAll", t, func() {
771 c := info.Set(context.Background(), fakeInfo{}) 964 c := info.Set(context.Background(), fakeInfo{})
772 c = SetRawFactory(c, fakeDatastoreFactory) 965 c = SetRawFactory(c, fakeDatastoreFactory)
773 ds := Get(c) 966 ds := Get(c)
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 So(ds.GetAll(q, &output), ShouldBeNil) 1029 So(ds.GetAll(q, &output), ShouldBeNil)
837 So(len(output), ShouldEqual, 5) 1030 So(len(output), ShouldEqual, 5)
838 for i, o := range output { 1031 for i, o := range output {
839 k, ok := o.GetMeta("key") 1032 k, ok := o.GetMeta("key")
840 So(ok, ShouldBeTrue) 1033 So(ok, ShouldBeTrue)
841 So(k.(*Key).IntID(), ShouldEqual, i+1) 1034 So(k.(*Key).IntID(), ShouldEqual, i+1)
842 So(o["Value"][0].Value().(int64), Should Equal, i) 1035 So(o["Value"][0].Value().(int64), Should Equal, i)
843 } 1036 }
844 }) 1037 })
845 1038
1039 Convey("*[]P (chan)", func() {
1040 output := []plsChan(nil)
1041 So(ds.GetAll(q, &output), ShouldBeNil)
1042 So(output, ShouldHaveLength, 5)
1043 for _, o := range output {
1044 So(ds.KeyForObj(o).StringID(), ShouldEqu al, "whyDoIExist")
1045 }
1046 })
1047
846 Convey("*[]*P", func() { 1048 Convey("*[]*P", func() {
847 output := []*FakePLS(nil) 1049 output := []*FakePLS(nil)
848 So(ds.GetAll(q, &output), ShouldBeNil) 1050 So(ds.GetAll(q, &output), ShouldBeNil)
849 So(len(output), ShouldEqual, 5) 1051 So(len(output), ShouldEqual, 5)
850 for i, o := range output { 1052 for i, o := range output {
851 So(o.gotLoaded, ShouldBeTrue) 1053 So(o.gotLoaded, ShouldBeTrue)
852 So(o.IntID, ShouldEqual, i+1) 1054 So(o.IntID, ShouldEqual, i+1)
853 So(o.Value, ShouldEqual, i) 1055 So(o.Value, ShouldEqual, i)
854 } 1056 }
855 }) 1057 })
856 1058
857 Convey("*[]*P (map)", func() { 1059 Convey("*[]*P (map)", func() {
858 output := []*PropertyMap(nil) 1060 output := []*PropertyMap(nil)
859 So(ds.GetAll(q, &output), ShouldBeNil) 1061 So(ds.GetAll(q, &output), ShouldBeNil)
860 So(len(output), ShouldEqual, 5) 1062 So(len(output), ShouldEqual, 5)
861 for i, op := range output { 1063 for i, op := range output {
862 o := *op 1064 o := *op
863 k, ok := o.GetMeta("key") 1065 k, ok := o.GetMeta("key")
864 So(ok, ShouldBeTrue) 1066 So(ok, ShouldBeTrue)
865 So(k.(*Key).IntID(), ShouldEqual, i+1) 1067 So(k.(*Key).IntID(), ShouldEqual, i+1)
866 So(o["Value"][0].Value().(int64), Should Equal, i) 1068 So(o["Value"][0].Value().(int64), Should Equal, i)
867 } 1069 }
868 }) 1070 })
869 1071
1072 Convey("*[]*P (chan)", func() {
1073 output := []*plsChan(nil)
1074 So(ds.GetAll(q, &output), ShouldBeNil)
1075 So(output, ShouldHaveLength, 5)
1076 for _, o := range output {
1077 So(ds.KeyForObj(o).StringID(), ShouldEqu al, "whyDoIExist")
1078 }
1079 })
1080
870 Convey("*[]*Key", func() { 1081 Convey("*[]*Key", func() {
871 output := []*Key(nil) 1082 output := []*Key(nil)
872 So(ds.GetAll(q, &output), ShouldBeNil) 1083 So(ds.GetAll(q, &output), ShouldBeNil)
873 So(len(output), ShouldEqual, 5) 1084 So(len(output), ShouldEqual, 5)
874 for i, k := range output { 1085 for i, k := range output {
875 So(k.IntID(), ShouldEqual, i+1) 1086 So(k.IntID(), ShouldEqual, i+1)
876 } 1087 }
877 }) 1088 })
878 1089
879 }) 1090 })
(...skipping 27 matching lines...) Expand all
907 1118
908 Convey("interface", func() { 1119 Convey("interface", func() {
909 assertBadTypePanics(func(pls PropertyLoadSaver) {}) 1120 assertBadTypePanics(func(pls PropertyLoadSaver) {})
910 }) 1121 })
911 1122
912 Convey("bad proto type", func() { 1123 Convey("bad proto type", func() {
913 cb := func(v int) { 1124 cb := func(v int) {
914 panic("never here!") 1125 panic("never here!")
915 } 1126 }
916 So(func() { ds.Run(q, cb) }, ShouldPanicLike, 1127 So(func() { ds.Run(q, cb) }, ShouldPanicLike,
917 » » » » » "invalid argument type: int") 1128 » » » » » "invalid argument type: int is not a PLS or pointer-to-struct")
918 }) 1129 })
919 1130
920 Convey("wrong # args", func() { 1131 Convey("wrong # args", func() {
921 assertBadTypePanics(func(v CommonStruct, _ Curso rCB, _ int) { 1132 assertBadTypePanics(func(v CommonStruct, _ Curso rCB, _ int) {
922 panic("never here!") 1133 panic("never here!")
923 }) 1134 })
924 }) 1135 })
925 1136
926 Convey("wrong ret type", func() { 1137 Convey("wrong ret type", func() {
927 assertBadTypePanics(func(v CommonStruct) bool { 1138 assertBadTypePanics(func(v CommonStruct) bool {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1012 i := 0 1223 i := 0
1013 So(ds.Run(q, func(pm *PropertyMap) { 1224 So(ds.Run(q, func(pm *PropertyMap) {
1014 k, ok := pm.GetMeta("key") 1225 k, ok := pm.GetMeta("key")
1015 So(ok, ShouldBeTrue) 1226 So(ok, ShouldBeTrue)
1016 So(k.(*Key).IntID(), ShouldEqual, i+1) 1227 So(k.(*Key).IntID(), ShouldEqual, i+1)
1017 So((*pm)["Value"][0].Value(), ShouldEqua l, i) 1228 So((*pm)["Value"][0].Value(), ShouldEqua l, i)
1018 i++ 1229 i++
1019 }), ShouldBeNil) 1230 }), ShouldBeNil)
1020 }) 1231 })
1021 1232
1233 Convey("*P (chan)", func() {
1234 So(ds.Run(q, func(c *plsChan) {
1235 So(ds.KeyForObj(c).StringID(), ShouldEqu al, "whyDoIExist")
1236 }), ShouldBeNil)
1237 })
1238
1022 Convey("S", func() { 1239 Convey("S", func() {
1023 i := 0 1240 i := 0
1024 So(ds.Run(q, func(cs CommonStruct) { 1241 So(ds.Run(q, func(cs CommonStruct) {
1025 So(cs.ID, ShouldEqual, i+1) 1242 So(cs.ID, ShouldEqual, i+1)
1026 So(cs.Value, ShouldEqual, i) 1243 So(cs.Value, ShouldEqual, i)
1027 i++ 1244 i++
1028 }), ShouldBeNil) 1245 }), ShouldBeNil)
1029 }) 1246 })
1030 1247
1031 Convey("P", func() { 1248 Convey("P", func() {
(...skipping 10 matching lines...) Expand all
1042 i := 0 1259 i := 0
1043 So(ds.Run(q, func(pm PropertyMap) { 1260 So(ds.Run(q, func(pm PropertyMap) {
1044 k, ok := pm.GetMeta("key") 1261 k, ok := pm.GetMeta("key")
1045 So(ok, ShouldBeTrue) 1262 So(ok, ShouldBeTrue)
1046 So(k.(*Key).IntID(), ShouldEqual, i+1) 1263 So(k.(*Key).IntID(), ShouldEqual, i+1)
1047 So(pm["Value"][0].Value(), ShouldEqual, i) 1264 So(pm["Value"][0].Value(), ShouldEqual, i)
1048 i++ 1265 i++
1049 }), ShouldBeNil) 1266 }), ShouldBeNil)
1050 }) 1267 })
1051 1268
1269 Convey("P (chan)", func() {
1270 So(ds.Run(q, func(c plsChan) {
1271 So(ds.KeyForObj(c).StringID(), ShouldEqu al, "whyDoIExist")
1272 }), ShouldBeNil)
1273 })
1274
1052 Convey("Key", func() { 1275 Convey("Key", func() {
1053 i := 0 1276 i := 0
1054 So(ds.Run(q, func(k *Key) { 1277 So(ds.Run(q, func(k *Key) {
1055 So(k.IntID(), ShouldEqual, i+1) 1278 So(k.IntID(), ShouldEqual, i+1)
1056 i++ 1279 i++
1057 }), ShouldBeNil) 1280 }), ShouldBeNil)
1058 }) 1281 })
1059 1282
1060 }) 1283 })
1061 }) 1284 })
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 if err != nil { 1801 if err != nil {
1579 panic(fmt.Errorf("failed to find absolute path f or `%s`", sameLevelDir)) 1802 panic(fmt.Errorf("failed to find absolute path f or `%s`", sameLevelDir))
1580 } 1803 }
1581 1804
1582 ids, err := FindAndParseIndexYAML(abs) 1805 ids, err := FindAndParseIndexYAML(abs)
1583 So(err, ShouldBeNil) 1806 So(err, ShouldBeNil)
1584 So(ids[1].Kind, ShouldEqual, "Test Foo") 1807 So(ids[1].Kind, ShouldEqual, "Test Foo")
1585 }) 1808 })
1586 }) 1809 })
1587 } 1810 }
OLDNEW
« no previous file with comments | « service/datastore/datastore.go ('k') | service/datastore/interface.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698