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

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: Update documentation and fix/clarify behavior on ExistsResult. 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
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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 262
254 type MGSWithNoKind struct { 263 type MGSWithNoKind struct {
255 S string 264 S string
256 } 265 }
257 266
258 func (s *MGSWithNoKind) GetMeta(key string) (interface{}, bool) { 267 func (s *MGSWithNoKind) GetMeta(key string) (interface{}, bool) {
259 return nil, false 268 return nil, false
260 } 269 }
261 270
262 func (s *MGSWithNoKind) GetAllMeta() PropertyMap { 271 func (s *MGSWithNoKind) GetAllMeta() PropertyMap {
263 » return PropertyMap{} 272 » return PropertyMap{"$kind": []Property{MkProperty("wang")}}
264 } 273 }
265 274
266 func (s *MGSWithNoKind) SetMeta(key string, val interface{}) bool { 275 func (s *MGSWithNoKind) SetMeta(key string, val interface{}) bool {
267 return false 276 return false
268 } 277 }
269 278
270 var _ MetaGetterSetter = (*MGSWithNoKind)(nil) 279 var _ MetaGetterSetter = (*MGSWithNoKind)(nil)
271 280
272 func TestKeyForObj(t *testing.T) { 281 func TestKeyForObj(t *testing.T) {
273 t.Parallel() 282 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`) 329 So(ds.KeyForObj(pm).String(), ShouldEqual, `s~ai d:ns:/Hello,"world"/Sup,100`)
321 }) 330 })
322 331
323 Convey("a pls with $id, $parent", func() { 332 Convey("a pls with $id, $parent", func() {
324 pls := GetPLS(&CommonStruct{ID: 1}) 333 pls := GetPLS(&CommonStruct{ID: 1})
325 So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a id:ns:/CommonStruct,1`) 334 So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a id:ns:/CommonStruct,1`)
326 335
327 So(pls.SetMeta("parent", k), ShouldBeTrue) 336 So(pls.SetMeta("parent", k), ShouldBeTrue)
328 So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a id:ns:/Hello,"world"/CommonStruct,1`) 337 So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a id:ns:/Hello,"world"/CommonStruct,1`)
329 }) 338 })
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 }) 339 })
363 340
364 Convey("bad", func() { 341 Convey("bad", func() {
365 Convey("a propmap without $kind", func() { 342 Convey("a propmap without $kind", func() {
366 pm := PropertyMap{} 343 pm := PropertyMap{}
367 So(pm.SetMeta("id", 100), ShouldBeTrue) 344 So(pm.SetMeta("id", 100), ShouldBeTrue)
368 So(func() { ds.KeyForObj(pm) }, ShouldPanic) 345 So(func() { ds.KeyForObj(pm) }, ShouldPanic)
369 }) 346 })
370 347
371 Convey("a bad object", func() { 348 Convey("a bad object", func() {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 var broken permaBad 389 var broken permaBad
413 390
414 So(func() { PopulateKey(&broken, k) }, ShouldPanic) 391 So(func() { PopulateKey(&broken, k) }, ShouldPanic)
415 }) 392 })
416 }) 393 })
417 } 394 }
418 395
419 func TestPut(t *testing.T) { 396 func TestPut(t *testing.T) {
420 t.Parallel() 397 t.Parallel()
421 398
422 » Convey("Test Put/PutMulti", t, func() { 399 » Convey("A testing environment", t, func() {
423 c := info.Set(context.Background(), fakeInfo{}) 400 c := info.Set(context.Background(), fakeInfo{})
424 c = SetRawFactory(c, fakeDatastoreFactory) 401 c = SetRawFactory(c, fakeDatastoreFactory)
425 ds := Get(c) 402 ds := Get(c)
426 403
427 » » Convey("bad", func() { 404 » » Convey("Testing Put", func() {
428 » » » Convey("static can't serialize", func() { 405 » » » Convey("bad", func() {
429 » » » » bss := []badStruct{{}, {}} 406 » » » » Convey("static can't serialize", func() {
430 » » » » So(func() { ds.PutMulti(bss) }, ShouldPanicLike, 407 » » » » » bss := []badStruct{{}, {}}
431 » » » » » `field "Compy" has invalid type`) 408 » » » » » So(func() { ds.Put(bss) }, ShouldPanicLi ke,
432 » » » }) 409 » » » » » » `field "Compy" has invalid type` )
433 410 » » » » })
434 » » » Convey("static ptr can't serialize", func() { 411
435 » » » » bss := []*badStruct{{}, {}} 412 » » » » Convey("static ptr can't serialize", func() {
436 » » » » So(func() { ds.PutMulti(bss) }, ShouldPanicLike, 413 » » » » » bss := []*badStruct{{}, {}}
437 » » » » » `field "Compy" has invalid type: complex 64`) 414 » » » » » So(func() { ds.Put(bss) }, ShouldPanicLi ke,
438 » » » }) 415 » » » » » » `field "Compy" has invalid type: complex64`)
439 416 » » » » })
440 » » » Convey("static bad type (non-slice)", func() { 417
441 » » » » So(func() { ds.PutMulti(100) }, ShouldPanicLike, 418 » » » » Convey("static bad type", func() {
442 » » » » » "invalid argument type: expected slice, got int") 419 » » » » » So(func() { ds.Put(100) }, ShouldPanicLi ke,
443 » » » }) 420 » » » » » » "invalid input type (int): not a PLS or pointer-to-struct")
444 421 » » » » })
445 » » » Convey("static bad type (slice of bad type)", func() { 422
446 » » » » So(func() { ds.PutMulti([]int{}) }, ShouldPanicL ike, 423 » » » » Convey("static bad type (slice of bad type)", fu nc() {
447 » » » » » "invalid argument type: []int") 424 » » » » » So(func() { ds.Put([]int{}) }, ShouldPan icLike,
448 » » » }) 425 » » » » » » "invalid input type ([]int): not a PLS or pointer-to-struct")
449 426 » » » » })
450 » » » Convey("dynamic can't serialize", func() { 427
451 » » » » fplss := []FakePLS{{failSave: true}, {}} 428 » » » » Convey("dynamic can't serialize", func() {
452 » » » » So(ds.PutMulti(fplss), ShouldErrLike, "FakePLS.S ave") 429 » » » » » fplss := []FakePLS{{failSave: true}, {}}
453 » » » }) 430 » » » » » So(ds.Put(fplss), ShouldErrLike, "FakePL S.Save")
454 431 » » » » })
455 » » » Convey("can't get keys", func() { 432
456 » » » » fplss := []FakePLS{{failGetMeta: true}, {}} 433 » » » » Convey("can't get keys", func() {
457 » » » » So(ds.PutMulti(fplss), ShouldErrLike, "unable to extract $kind") 434 » » » » » fplss := []FakePLS{{failGetMeta: true}, {}}
458 » » » }) 435 » » » » » So(ds.Put(fplss), ShouldErrLike, "unable to extract $kind")
459 436 » » » » })
460 » » » Convey("get single error for RPC failure", func() { 437
461 » » » » fplss := []FakePLS{{Kind: "FailAll"}, {}} 438 » » » » Convey("get single error for RPC failure", func( ) {
462 » » » » So(ds.PutMulti(fplss), ShouldErrLike, "PutMulti fail all") 439 » » » » » fplss := []FakePLS{{Kind: "FailAll"}, {} }
463 » » » }) 440 » » » » » So(ds.Put(fplss), ShouldEqual, errFailAl l)
464 441 » » » » })
465 » » » Convey("get multi error for individual failures", func() { 442
466 » » » » fplss := []FakePLS{{}, {Kind: "Fail"}} 443 » » » » Convey("get multi error for individual failures" , func() {
467 » » » » So(ds.PutMulti(fplss), ShouldResemble, errors.Mu ltiError{nil, errors.New("PutMulti fail")}) 444 » » » » » fplss := []FakePLS{{}, {Kind: "Fail"}}
468 » » » }) 445 » » » » » So(ds.Put(fplss), ShouldResemble, errors .MultiError{nil, errFail})
469 446 » » » » })
470 » » » Convey("put with non-modifyable type is an error", func( ) { 447
448 » » » » Convey("put with non-modifyable type is an error ", func() {
449 » » » » » cs := CommonStruct{}
450 » » » » » So(func() { ds.Put(cs) }, ShouldPanicLik e,
451 » » » » » » "invalid input type (datastore.C ommonStruct): not a pointer")
452 » » » » })
453
454 » » » » Convey("get with *Key is an error", func() {
455 » » » » » So(func() { ds.Get(&Key{}) }, ShouldPani cLike,
456 » » » » » » "invalid input type (*datastore. Key): not user datatype")
457 » » » » })
458
459 » » » » Convey("struct with no $kind is an error", func( ) {
460 » » » » » s := MGSWithNoKind{}
461 » » » » » So(ds.Put(&s), ShouldErrLike, "unable to extract $kind")
462 » » » » })
463
464 » » » » Convey("struct with invalid but non-nil key is a n error", func() {
465 » » » » » type BadParent struct {
466 » » » » » » ID int64 `gae:"$id"`
467 » » » » » » Parent *Key `gae:"$parent"`
468 » » » » » }
469 » » » » » // having an Incomplete parent makes an invalid key
470 » » » » » bp := &BadParent{ID: 1, Parent: ds.MakeK ey("Something", 0)}
471 » » » » » So(ds.Put(bp), ShouldErrLike, ErrInvalid Key)
472 » » » » })
473
474 » » » » Convey("vararg with errors", func() {
475 » » » » » successSlice := []CommonStruct{{Value: 0 }, {Value: 1}}
476 » » » » » failSlice := []FakePLS{{Kind: "Fail"}, { Value: 3}}
477 » » » » » emptySlice := []CommonStruct(nil)
478 » » » » » cs0 := CommonStruct{Value: 4}
479 » » » » » cs1 := FakePLS{Kind: "Fail", Value: 5}
480 » » » » » fpls := FakePLS{StringID: "ohai", Value: 6}
481
482 » » » » » err := ds.Put(successSlice, failSlice, e mptySlice, &cs0, &cs1, &fpls)
483 » » » » » So(err, ShouldResemble, errors.MultiErro r{
484 » » » » » » nil, errors.MultiError{errFail, nil}, nil, nil, errFail, nil})
485 » » » » » So(successSlice[0].ID, ShouldEqual, 1)
486 » » » » » So(successSlice[1].ID, ShouldEqual, 2)
487 » » » » » So(cs0.ID, ShouldEqual, 5)
488 » » » » })
489 » » » })
490
491 » » » Convey("ok", func() {
492 » » » » Convey("[]S", func() {
493 » » » » » css := make([]CommonStruct, 7)
494 » » » » » for i := range css {
495 » » » » » » if i == 4 {
496 » » » » » » » css[i].ID = 200
497 » » » » » » }
498 » » » » » » css[i].Value = int64(i)
499 » » » » » }
500 » » » » » So(ds.Put(css), ShouldBeNil)
501 » » » » » for i, cs := range css {
502 » » » » » » expect := int64(i + 1)
503 » » » » » » if i == 4 {
504 » » » » » » » expect = 200
505 » » » » » » }
506 » » » » » » So(cs.ID, ShouldEqual, expect)
507 » » » » » }
508 » » » » })
509
510 » » » » Convey("[]*S", func() {
511 » » » » » css := make([]*CommonStruct, 7)
512 » » » » » for i := range css {
513 » » » » » » css[i] = &CommonStruct{Value: in t64(i)}
514 » » » » » » if i == 4 {
515 » » » » » » » css[i].ID = 200
516 » » » » » » }
517 » » » » » }
518 » » » » » So(ds.Put(css), ShouldBeNil)
519 » » » » » for i, cs := range css {
520 » » » » » » expect := int64(i + 1)
521 » » » » » » if i == 4 {
522 » » » » » » » expect = 200
523 » » » » » » }
524 » » » » » » So(cs.ID, ShouldEqual, expect)
525 » » » » » }
526
527 » » » » » s := &CommonStruct{}
528 » » » » » So(ds.Put(s), ShouldBeNil)
529 » » » » » So(s.ID, ShouldEqual, 1)
530 » » » » })
531
532 » » » » Convey("[]P", func() {
533 » » » » » fplss := make([]FakePLS, 7)
534 » » » » » for i := range fplss {
535 » » » » » » fplss[i].Value = int64(i)
536 » » » » » » if i == 4 {
537 » » » » » » » fplss[i].IntID = int64(2 00)
538 » » » » » » }
539 » » » » » }
540 » » » » » So(ds.Put(fplss), ShouldBeNil)
541 » » » » » for i, fpls := range fplss {
542 » » » » » » expect := int64(i + 1)
543 » » » » » » if i == 4 {
544 » » » » » » » expect = 200
545 » » » » » » }
546 » » » » » » So(fpls.IntID, ShouldEqual, expe ct)
547 » » » » » }
548
549 » » » » » pm := PropertyMap{"Value": {MkProperty(0 )}, "$kind": {MkPropertyNI("Pmap")}}
550 » » » » » So(ds.Put(pm), ShouldBeNil)
551 » » » » » So(ds.KeyForObj(pm).IntID(), ShouldEqual , 1)
552 » » » » })
553
554 » » » » Convey("[]P (map)", func() {
555 » » » » » pms := make([]PropertyMap, 7)
556 » » » » » for i := range pms {
557 » » » » » » pms[i] = PropertyMap{
558 » » » » » » » "$kind": {MkProperty("Pm ap")},
559 » » » » » » » "Value": {MkProperty(i)} ,
560 » » » » » » }
561 » » » » » » if i == 4 {
562 » » » » » » » So(pms[i].SetMeta("id", int64(200)), ShouldBeTrue)
563 » » » » » » }
564 » » » » » }
565 » » » » » So(ds.Put(pms), ShouldBeNil)
566 » » » » » for i, pm := range pms {
567 » » » » » » expect := int64(i + 1)
568 » » » » » » if i == 4 {
569 » » » » » » » expect = 200
570 » » » » » » }
571 » » » » » » So(ds.KeyForObj(pm).String(), Sh ouldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
572 » » » » » }
573 » » » » })
574
575 » » » » Convey("[]*P", func() {
576 » » » » » fplss := make([]*FakePLS, 7)
577 » » » » » for i := range fplss {
578 » » » » » » fplss[i] = &FakePLS{Value: int64 (i)}
579 » » » » » » if i == 4 {
580 » » » » » » » fplss[i].IntID = int64(2 00)
581 » » » » » » }
582 » » » » » }
583 » » » » » So(ds.Put(fplss), ShouldBeNil)
584 » » » » » for i, fpls := range fplss {
585 » » » » » » expect := int64(i + 1)
586 » » » » » » if i == 4 {
587 » » » » » » » expect = 200
588 » » » » » » }
589 » » » » » » So(fpls.IntID, ShouldEqual, expe ct)
590 » » » » » }
591 » » » » })
592
593 » » » » Convey("[]*P (map)", func() {
594 » » » » » pms := make([]*PropertyMap, 7)
595 » » » » » for i := range pms {
596 » » » » » » pms[i] = &PropertyMap{
597 » » » » » » » "$kind": {MkProperty("Pm ap")},
598 » » » » » » » "Value": {MkProperty(i)} ,
599 » » » » » » }
600 » » » » » » if i == 4 {
601 » » » » » » » So(pms[i].SetMeta("id", int64(200)), ShouldBeTrue)
602 » » » » » » }
603 » » » » » }
604 » » » » » So(ds.Put(pms), ShouldBeNil)
605 » » » » » for i, pm := range pms {
606 » » » » » » expect := int64(i + 1)
607 » » » » » » if i == 4 {
608 » » » » » » » expect = 200
609 » » » » » » }
610 » » » » » » So(ds.KeyForObj(*pm).String(), S houldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
611 » » » » » }
612 » » » » })
613
614 » » » » Convey("[]I", func() {
615 » » » » » ifs := []interface{}{
616 » » » » » » &CommonStruct{Value: 0},
617 » » » » » » &FakePLS{Value: 1},
618 » » » » » » PropertyMap{"Value": {MkProperty (2)}, "$kind": {MkPropertyNI("Pmap")}},
619 » » » » » » &PropertyMap{"Value": {MkPropert y(3)}, "$kind": {MkPropertyNI("Pmap")}},
620 » » » » » }
621 » » » » » So(ds.Put(ifs), ShouldBeNil)
622 » » » » » for i := range ifs {
623 » » » » » » switch i {
624 » » » » » » case 0:
625 » » » » » » » So(ifs[i].(*CommonStruct ).ID, ShouldEqual, 1)
626 » » » » » » case 1:
627 » » » » » » » fpls := ifs[i].(*FakePLS )
628 » » » » » » » So(fpls.IntID, ShouldEqu al, 2)
629 » » » » » » case 2:
630 » » » » » » » So(ds.KeyForObj(ifs[i].( PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,3")
631 » » » » » » case 3:
632 » » » » » » » So(ds.KeyForObj(*ifs[i]. (*PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,4")
633 » » » » » » }
634 » » » » » }
635 » » » » })
636 » » » })
637 » » })
638
639 » » Convey("Testing PutMulti", func() {
640 » » » Convey("Fails for something other than a slice.", func() {
471 cs := CommonStruct{} 641 cs := CommonStruct{}
472 » » » » So(func() { ds.Put(cs) }, ShouldPanicLike, 642 » » » » So(func() { ds.PutMulti(&cs) }, ShouldPanicLike,
473 » » » » » "invalid Put input type (datastore.Commo nStruct): not a pointer") 643 » » » » » "argument must be a slice, not *datastor e.CommonStruct")
474 » » » }) 644 » » » })
475 645
476 » » » Convey("get with *Key is an error", func() { 646 » » » Convey("Succeeds for a slice.", func() {
477 » » » » So(func() { ds.Get(&Key{}) }, ShouldPanicLike, 647 » » » » cs := []CommonStruct{{Value: 0}, {Value: 1}}
478 » » » » » "invalid Get input type (*datastore.Key) : not user datatype") 648 » » » » So(ds.PutMulti(cs), ShouldBeNil)
479 » » » }) 649 » » » » So(cs[0].ID, ShouldEqual, 1)
480 650 » » » » So(cs[1].ID, ShouldEqual, 2)
481 » » » Convey("struct with no $kind is an error", func() { 651 » » » })
482 » » » » s := MGSWithNoKind{} 652
483 » » » » So(ds.Put(&s), ShouldErrLike, "unable to extract $kind") 653 » » » Convey("Returns an item error in a MultiError.", func() {
484 » » » }) 654 » » » » cs := []FakePLS{{Value: 0}, {Kind: "Fail"}}
485 655 » » » » err := ds.PutMulti(cs)
486 » » » Convey("struct with invalid but non-nil key is an error" , func() { 656 » » » » So(err, ShouldResemble, errors.MultiError{nil, e rrFail})
487 » » » » type BadParent struct { 657 » » » » So(cs[0].IntID, ShouldEqual, 1)
488 » » » » » ID int64 `gae:"$id"` 658 » » » })
489 » » » » » Parent *Key `gae:"$parent"` 659 » » })
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 }) 660 })
646 } 661 }
647 662
663 func TestExists(t *testing.T) {
664 t.Parallel()
665
666 Convey("A testing environment", t, func() {
667 c := info.Set(context.Background(), fakeInfo{})
668 c = SetRawFactory(c, fakeDatastoreFactory)
669 ds := Get(c)
670
671 k := ds.MakeKey("Hello", "world")
672
673 Convey("Exists", func() {
674 // Single key.
675 er, err := ds.Exists(k)
676 So(err, ShouldBeNil)
677 So(er.All(), ShouldBeTrue)
678
679 // Single key failure.
680 _, err = ds.Exists(ds.MakeKey("Fail", "boom"))
681 So(err, ShouldEqual, errFail)
682
683 // Single slice of keys.
684 er, err = ds.Exists([]*Key{k, ds.MakeKey("hello", "other ")})
685 So(err, ShouldBeNil)
686 So(er.All(), ShouldBeTrue)
687
688 // Single slice of keys failure.
689 er, err = ds.Exists([]*Key{k, ds.MakeKey("Fail", "boom") })
690 So(err, ShouldResemble, errors.MultiError{nil, errFail})
691 So(er.Get(0, 0), ShouldBeTrue)
692
693 // Single key missing.
694 er, err = ds.Exists(ds.MakeKey("DNE", "nope"))
695 So(err, ShouldBeNil)
696 So(er.Any(), ShouldBeFalse)
697
698 // Multi-arg keys with one missing.
699 er, err = ds.Exists(k, ds.MakeKey("DNE", "other"))
700 So(err, ShouldBeNil)
701 So(er.Get(0), ShouldBeTrue)
702 So(er.Get(1), ShouldBeFalse)
703
704 // Multi-arg keys with two missing.
705 er, err = ds.Exists(ds.MakeKey("DNE", "nope"), ds.MakeKe y("DNE", "other"))
706 So(err, ShouldBeNil)
707 So(er.Any(), ShouldBeFalse)
708
709 // Multi-arg mixed key/struct/slices.
710 er, err = ds.Exists(&CommonStruct{ID: 1}, []*CommonStruc t(nil), []*Key{ds.MakeKey("DNE", "nope"), ds.MakeKey("hello", "ohai")})
711 So(err, ShouldBeNil)
712 So(er.Get(0), ShouldBeTrue)
713 So(er.Get(1), ShouldBeTrue)
714 So(er.Get(2), ShouldBeFalse)
715 So(er.Get(2, 0), ShouldBeFalse)
716 So(er.Get(2, 1), ShouldBeTrue)
717 })
718
719 Convey("ExistsMulti", func() {
720 Convey("Returns no error if there are no failures.", fun c() {
721 bl, err := ds.ExistsMulti([]*Key{k, ds.MakeKey(" DNE", "nope"), ds.MakeKey("hello", "ohai")})
722 So(err, ShouldBeNil)
723 So(bl, ShouldResemble, BoolList{true, false, tru e})
724 })
725
726 Convey("Returns an item error in a MultiError.", func() {
727 _, err := ds.ExistsMulti([]*Key{k, ds.MakeKey("F ail", "boom")})
728 So(err, ShouldResemble, errors.MultiError{nil, e rrFail})
729 })
730 })
731 })
732 }
733
648 func TestDelete(t *testing.T) { 734 func TestDelete(t *testing.T) {
649 t.Parallel() 735 t.Parallel()
650 736
651 » Convey("Test Delete/DeleteMulti", t, func() { 737 » Convey("A testing environment", t, func() {
652 c := info.Set(context.Background(), fakeInfo{}) 738 c := info.Set(context.Background(), fakeInfo{})
653 c = SetRawFactory(c, fakeDatastoreFactory) 739 c = SetRawFactory(c, fakeDatastoreFactory)
654 ds := Get(c) 740 ds := Get(c)
655 So(ds, ShouldNotBeNil) 741 So(ds, ShouldNotBeNil)
656 742
657 » » Convey("bad", func() { 743 » » Convey("Testing Delete", func() {
658 » » » Convey("get single error for RPC failure", func() { 744 » » » Convey("bad", func() {
659 » » » » keys := []*Key{ 745 » » » » Convey("get single error for RPC failure", func( ) {
660 » » » » » MakeKey("s~aid", "ns", "FailAll", 1), 746 » » » » » keys := []*Key{
661 » » » » » MakeKey("s~aid", "ns", "Ok", 1), 747 » » » » » » MakeKey("s~aid", "ns", "FailAll" , 1),
662 » » » » } 748 » » » » » » MakeKey("s~aid", "ns", "Ok", 1),
663 » » » » So(ds.DeleteMulti(keys).Error(), ShouldEqual, "D eleteMulti fail all") 749 » » » » » }
664 » » » }) 750 » » » » » So(ds.Delete(keys), ShouldEqual, errFail All)
665 751 » » » » })
666 » » » Convey("get multi error for individual failure", func() { 752
667 » » » » keys := []*Key{ 753 » » » » Convey("get multi error for individual failure", func() {
668 » » » » » ds.MakeKey("Ok", 1), 754 » » » » » keys := []*Key{
669 » » » » » ds.MakeKey("Fail", 2), 755 » » » » » » ds.MakeKey("Ok", 1),
670 » » » » } 756 » » » » » » ds.MakeKey("Fail", 2),
671 » » » » So(ds.DeleteMulti(keys).Error(), ShouldEqual, "D eleteMulti fail") 757 » » » » » }
672 » » » }) 758 » » » » » So(ds.Delete(keys), ShouldResemble, erro rs.MultiError{nil, errFail})
673 759 » » » » })
674 » » » Convey("get single error when deleting a single", func() { 760
675 » » » » k := ds.MakeKey("Fail", 1) 761 » » » » Convey("get single error when deleting a single" , func() {
676 » » » » So(ds.Delete(k).Error(), ShouldEqual, "DeleteMul ti fail") 762 » » » » » k := ds.MakeKey("Fail", 1)
677 » » » }) 763 » » » » » So(ds.Delete(k), ShouldEqual, errFail)
678 » » }) 764 » » » » })
679 765 » » » })
766
767 » » » Convey("good", func() {
768 » » » » // Single struct.
769 » » » » So(ds.Delete(&CommonStruct{ID: 1}), ShouldBeNil)
770
771 » » » » // Single key.
772 » » » » So(ds.Delete(ds.MakeKey("hello", "ohai")), Shoul dBeNil)
773
774 » » » » // Single struct DNE.
775 » » » » So(ds.Delete(&CommonStruct{ID: noSuchEntityID}), ShouldEqual, ErrNoSuchEntity)
776
777 » » » » // Single key DNE.
778 » » » » So(ds.Delete(ds.MakeKey("DNE", "nope")), ShouldE qual, ErrNoSuchEntity)
779
780 » » » » // Mixed key/struct/slices.
781 » » » » err := ds.Delete(&CommonStruct{ID: 1}, []*Key{ds .MakeKey("hello", "ohai"), ds.MakeKey("DNE", "nope")})
782 » » » » So(err, ShouldResemble, errors.MultiError{nil, e rrors.MultiError{nil, ErrNoSuchEntity}})
783 » » » })
784 » » })
785
786 » » Convey("Testing DeleteMulti", func() {
787 » » » Convey("Succeeds for valid keys.", func() {
788 » » » » So(ds.DeleteMulti([]*Key{ds.MakeKey("hello", "oh ai")}), ShouldBeNil)
789 » » » » So(ds.DeleteMulti([]*Key{ds.MakeKey("hello", "oh ai"), ds.MakeKey("hello", "sup")}), ShouldBeNil)
790 » » » })
791
792 » » » Convey("Returns an item error in a MultiError.", func() {
793 » » » » So(ds.DeleteMulti([]*Key{ds.MakeKey("DNE", "oops ")}), ShouldResemble, errors.MultiError{ErrNoSuchEntity})
794 » » » })
795 » » })
680 }) 796 })
681 } 797 }
682 798
683 func TestGet(t *testing.T) { 799 func TestGet(t *testing.T) {
684 t.Parallel() 800 t.Parallel()
685 801
686 » Convey("Test Get/GetMulti", t, func() { 802 » Convey("A testing environment", t, func() {
687 c := info.Set(context.Background(), fakeInfo{}) 803 c := info.Set(context.Background(), fakeInfo{})
688 c = SetRawFactory(c, fakeDatastoreFactory) 804 c = SetRawFactory(c, fakeDatastoreFactory)
689 ds := Get(c) 805 ds := Get(c)
690 So(ds, ShouldNotBeNil) 806 So(ds, ShouldNotBeNil)
691 807
692 » » Convey("bad", func() { 808 » » Convey("Testing Get", func() {
693 » » » Convey("static can't serialize", func() { 809 » » » Convey("bad", func() {
694 » » » » toGet := []badStruct{{}, {}} 810 » » » » Convey("static can't serialize", func() {
695 » » » » So(func() { ds.GetMulti(toGet) }, ShouldPanicLik e, 811 » » » » » toGet := []badStruct{{}, {}}
696 » » » » » `field "Compy" has invalid type: complex 64`) 812 » » » » » So(func() { ds.Get(toGet) }, ShouldPanic Like,
697 » » » }) 813 » » » » » » `field "Compy" has invalid type: complex64`)
698 814 » » » » })
699 » » » Convey("can't get keys", func() { 815
700 » » » » fplss := []FakePLS{{failGetMeta: true}, {}} 816 » » » » Convey("can't get keys", func() {
701 » » » » So(ds.GetMulti(fplss), ShouldErrLike, "unable to extract $kind") 817 » » » » » fplss := []FakePLS{{failGetMeta: true}, {}}
702 » » » }) 818 » » » » » So(ds.Get(fplss), ShouldErrLike, "unable to extract $kind")
703 819 » » » » })
704 » » » Convey("get single error for RPC failure", func() { 820
705 » » » » fplss := []FakePLS{ 821 » » » » Convey("get single error for RPC failure", func( ) {
706 » » » » » {IntID: 1, Kind: "FailAll"}, 822 » » » » » fplss := []FakePLS{
707 » » » » » {IntID: 2}, 823 » » » » » » {IntID: 1, Kind: "FailAll"},
708 » » » » } 824 » » » » » » {IntID: 2},
709 » » » » So(ds.GetMulti(fplss).Error(), ShouldEqual, "Get Multi fail all") 825 » » » » » }
710 » » » }) 826 » » » » » So(ds.Get(fplss), ShouldEqual, errFailAl l)
711 827 » » » » })
712 » » » Convey("get multi error for individual failures", func() { 828
713 » » » » fplss := []FakePLS{{IntID: 1}, {IntID: 2, Kind: "Fail"}} 829 » » » » Convey("get multi error for individual failures" , func() {
714 » » » » So(ds.GetMulti(fplss), ShouldResemble, errors.Mu ltiError{nil, errors.New("GetMulti fail")}) 830 » » » » » fplss := []FakePLS{{IntID: 1}, {IntID: 2 , Kind: "Fail"}}
715 » » » }) 831 » » » » » So(ds.Get(fplss), ShouldResemble, errors .MultiError{nil, errFail})
716 832 » » » » })
717 » » » Convey("get with non-modifiable type is an error", func( ) { 833
834 » » » » Convey("get with non-modifiable type is an error ", func() {
835 » » » » » cs := CommonStruct{}
836 » » » » » So(func() { ds.Get(cs) }, ShouldPanicLik e,
837 » » » » » » "invalid input type (datastore.C ommonStruct): not a pointer")
838 » » » » })
839
840 » » » » Convey("get with nil is an error", func() {
841 » » » » » So(func() { ds.Get(nil) }, ShouldPanicLi ke,
842 » » » » » » "cannot use nil as single argume nt")
843 » » » » })
844
845 » » » » Convey("get with ptr-to-nonstruct is an error", func() {
846 » » » » » val := 100
847 » » » » » So(func() { ds.Get(&val) }, ShouldPanicL ike,
848 » » » » » » "invalid input type (*int): not a PLS or pointer-to-struct")
849 » » » » })
850
851 » » » » Convey("failure to save metadata is no problem t hough", func() {
852 » » » » » // It just won't save the key
853 » » » » » cs := &FakePLS{IntID: 10, failSetMeta: t rue}
854 » » » » » So(ds.Get(cs), ShouldBeNil)
855 » » » » })
856
857 » » » » Convey("vararg with errors", func() {
858 » » » » » successSlice := []CommonStruct{{ID: 1}, {ID: 2}}
859 » » » » » failSlice := []CommonStruct{{ID: noSuchE ntityID}, {ID: 3}}
860 » » » » » emptySlice := []CommonStruct(nil)
861 » » » » » cs0 := CommonStruct{ID: 4}
862 » » » » » cs1 := CommonStruct{ID: noSuchEntityID}
863 » » » » » fpls := FakePLS{StringID: "ohai"}
864
865 » » » » » err := ds.Get(successSlice, failSlice, e mptySlice, &cs0, &cs1, &fpls)
866 » » » » » So(err, ShouldResemble, errors.MultiErro r{
867 » » » » » » nil, errors.MultiError{ErrNoSuch Entity, nil}, nil, nil, ErrNoSuchEntity, nil})
868 » » » » » So(successSlice[0].Value, ShouldEqual, 1 )
869 » » » » » So(successSlice[1].Value, ShouldEqual, 2 )
870 » » » » » So(cs0.Value, ShouldEqual, 5)
871 » » » » » So(fpls.Value, ShouldEqual, 7)
872 » » » » })
873 » » » })
874
875 » » » Convey("ok", func() {
876 » » » » Convey("Get", func() {
877 » » » » » cs := &CommonStruct{ID: 1}
878 » » » » » So(ds.Get(cs), ShouldBeNil)
879 » » » » » So(cs.Value, ShouldEqual, 1)
880 » » » » })
881
882 » » » » Convey("Raw access too", func() {
883 » » » » » rds := ds.Raw()
884 » » » » » keys := []*Key{ds.MakeKey("Kind", 1)}
885 » » » » » So(rds.GetMulti(keys, nil, func(pm Prope rtyMap, err error) error {
886 » » » » » » So(err, ShouldBeNil)
887 » » » » » » So(pm["Value"][0].Value(), Shoul dEqual, 1)
888 » » » » » » return nil
889 » » » » » }), ShouldBeNil)
890 » » » » })
891
892 » » » » Convey("but general failure to save is fine on a Get", func() {
893 » » » » » cs := &FakePLS{failSave: true, IntID: 7}
894 » » » » » So(ds.Get(cs), ShouldBeNil)
895 » » » » })
896
897 » » » » Convey("vararg", func() {
898 » » » » » successSlice := []CommonStruct{{ID: 1}, {ID: 2}}
899 » » » » » cs := CommonStruct{ID: 3}
900
901 » » » » » err := ds.Get(successSlice, &cs)
902 » » » » » So(err, ShouldBeNil)
903 » » » » » So(successSlice[0].Value, ShouldEqual, 1 )
904 » » » » » So(successSlice[1].Value, ShouldEqual, 2 )
905 » » » » » So(cs.Value, ShouldEqual, 3)
906 » » » » })
907 » » » })
908 » » })
909
910 » » Convey("Testing GetMulti", func() {
911 » » » Convey("Fails for something other than a slice.", func() {
718 cs := CommonStruct{} 912 cs := CommonStruct{}
719 » » » » So(func() { ds.Get(cs) }, ShouldPanicLike, 913 » » » » So(func() { ds.GetMulti(&cs) }, ShouldPanicLike,
720 » » » » » "invalid Get input type (datastore.Commo nStruct): not a pointer") 914 » » » » » "argument must be a slice, not *datastor e.CommonStruct")
721 » » » }) 915 » » » })
722 916
723 » » » Convey("get with nil is an error", func() { 917 » » » Convey("Succeeds for a slice.", func() {
724 » » » » So(func() { ds.Get(nil) }, ShouldPanicLike, 918 » » » » cs := []CommonStruct{{ID: 1}}
725 » » » » » "invalid Get input type (<nil>): no type information") 919 » » » » So(ds.GetMulti(cs), ShouldBeNil)
726 » » » }) 920 » » » » So(cs[0].Value, ShouldEqual, 1)
727 921 » » » })
728 » » » Convey("get with ptr-to-nonstruct is an error", func() { 922
729 » » » » val := 100 923 » » » Convey("Returns an item error in a MultiError.", func() {
730 » » » » So(func() { ds.Get(&val) }, ShouldPanicLike, 924 » » » » cs := []CommonStruct{{ID: 1}, {ID: noSuchEntityI D}}
731 » » » » » "invalid Get input type (*int): does not point to a struct") 925 » » » » err := ds.GetMulti(cs)
732 » » » }) 926 » » » » So(err, ShouldResemble, errors.MultiError{nil, E rrNoSuchEntity})
733 927 » » » » So(cs[0].Value, ShouldEqual, 1)
734 » » » Convey("failure to save metadata is no problem though", func() { 928 » » » })
735 » » » » // It just won't save the key 929 » » })
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 }) 930 })
765 } 931 }
766 932
767 func TestGetAll(t *testing.T) { 933 func TestGetAll(t *testing.T) {
768 t.Parallel() 934 t.Parallel()
769 935
770 Convey("Test GetAll", t, func() { 936 Convey("Test GetAll", t, func() {
771 c := info.Set(context.Background(), fakeInfo{}) 937 c := info.Set(context.Background(), fakeInfo{})
772 c = SetRawFactory(c, fakeDatastoreFactory) 938 c = SetRawFactory(c, fakeDatastoreFactory)
773 ds := Get(c) 939 ds := Get(c)
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 1073
908 Convey("interface", func() { 1074 Convey("interface", func() {
909 assertBadTypePanics(func(pls PropertyLoadSaver) {}) 1075 assertBadTypePanics(func(pls PropertyLoadSaver) {})
910 }) 1076 })
911 1077
912 Convey("bad proto type", func() { 1078 Convey("bad proto type", func() {
913 cb := func(v int) { 1079 cb := func(v int) {
914 panic("never here!") 1080 panic("never here!")
915 } 1081 }
916 So(func() { ds.Run(q, cb) }, ShouldPanicLike, 1082 So(func() { ds.Run(q, cb) }, ShouldPanicLike,
917 » » » » » "invalid argument type: int") 1083 » » » » » "invalid argument type: int is not a PLS or pointer-to-struct")
918 }) 1084 })
919 1085
920 Convey("wrong # args", func() { 1086 Convey("wrong # args", func() {
921 assertBadTypePanics(func(v CommonStruct, _ Curso rCB, _ int) { 1087 assertBadTypePanics(func(v CommonStruct, _ Curso rCB, _ int) {
922 panic("never here!") 1088 panic("never here!")
923 }) 1089 })
924 }) 1090 })
925 1091
926 Convey("wrong ret type", func() { 1092 Convey("wrong ret type", func() {
927 assertBadTypePanics(func(v CommonStruct) bool { 1093 assertBadTypePanics(func(v CommonStruct) bool {
(...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 if err != nil { 1744 if err != nil {
1579 panic(fmt.Errorf("failed to find absolute path f or `%s`", sameLevelDir)) 1745 panic(fmt.Errorf("failed to find absolute path f or `%s`", sameLevelDir))
1580 } 1746 }
1581 1747
1582 ids, err := FindAndParseIndexYAML(abs) 1748 ids, err := FindAndParseIndexYAML(abs)
1583 So(err, ShouldBeNil) 1749 So(err, ShouldBeNil)
1584 So(ids[1].Kind, ShouldEqual, "Test Foo") 1750 So(ids[1].Kind, ShouldEqual, "Test Foo")
1585 }) 1751 })
1586 }) 1752 })
1587 } 1753 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698