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

Unified 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: Created 4 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: service/datastore/datastore_test.go
diff --git a/service/datastore/datastore_test.go b/service/datastore/datastore_test.go
index 27db51af6233a23cbc17265eeecf2064951d65c3..edb3d5fc91600c8f4f91988303c639b1975635bc 100644
--- a/service/datastore/datastore_test.go
+++ b/service/datastore/datastore_test.go
@@ -70,6 +70,11 @@ func (f *fakeDatastore) Run(fq *FinalizedQuery, cb RawRunCB) error {
return nil
}
+var (
+ errPutMultiFail = errors.New("PutMulti fail")
+ errPutMultiFailAll = errors.New("PutMulti fail all")
+)
+
func (f *fakeDatastore) PutMulti(keys []*Key, vals []PropertyMap, cb PutMultiCB) error {
if keys[0].Kind() == "FailAll" {
return errors.New("PutMulti fail all")
@@ -78,7 +83,7 @@ func (f *fakeDatastore) PutMulti(keys []*Key, vals []PropertyMap, cb PutMultiCB)
for i, k := range keys {
err := error(nil)
if k.Kind() == "Fail" {
- err = errors.New("PutMulti fail")
+ err = errPutMultiFail
} else {
So(vals[i]["Value"], ShouldResemble, []Property{MkProperty(i)})
if assertExtra {
@@ -93,6 +98,8 @@ func (f *fakeDatastore) PutMulti(keys []*Key, vals []PropertyMap, cb PutMultiCB)
return nil
}
+const noSuchEntityID = 0xdead
+
func (f *fakeDatastore) GetMulti(keys []*Key, _meta MultiMetaGetter, cb GetMultiCB) error {
if keys[0].Kind() == "FailAll" {
return errors.New("GetMulti fail all")
@@ -100,7 +107,7 @@ func (f *fakeDatastore) GetMulti(keys []*Key, _meta MultiMetaGetter, cb GetMulti
for i, k := range keys {
if k.Kind() == "Fail" {
cb(nil, errors.New("GetMulti fail"))
- } else if k.Kind() == "DNE" {
+ } else if k.Kind() == "DNE" || k.IntID() == noSuchEntityID {
cb(nil, ErrNoSuchEntity)
} else {
cb(PropertyMap{"Value": {MkProperty(i + 1)}}, nil)
@@ -260,7 +267,7 @@ func (s *MGSWithNoKind) GetMeta(key string) (interface{}, bool) {
}
func (s *MGSWithNoKind) GetAllMeta() PropertyMap {
- return PropertyMap{}
+ return PropertyMap{"$kind": []Property{MkProperty("wang")}}
}
func (s *MGSWithNoKind) SetMeta(key string, val interface{}) bool {
@@ -333,13 +340,13 @@ func TestKeyForObj(t *testing.T) {
So(err, ShouldBeNil)
So(e, ShouldBeTrue)
- bl, err := ds.ExistsMulti([]*Key{k, ds.MakeKey("hello", "other")})
+ bl, err := ds.ExistsMulti(k, ds.MakeKey("hello", "other"))
So(err, ShouldBeNil)
So(bl, ShouldResemble, BoolList{true, true})
So(bl.All(), ShouldBeTrue)
So(bl.Any(), ShouldBeTrue)
- bl, err = ds.ExistsMulti([]*Key{k, ds.MakeKey("DNE", "other")})
+ bl, err = ds.ExistsMulti(k, ds.MakeKey("DNE", "other"))
So(err, ShouldBeNil)
So(bl, ShouldResemble, BoolList{true, false})
So(bl.All(), ShouldBeFalse)
@@ -349,7 +356,7 @@ func TestKeyForObj(t *testing.T) {
So(err, ShouldBeNil)
So(e, ShouldBeFalse)
- bl, err = ds.ExistsMulti([]*Key{ds.MakeKey("DNE", "nope"), ds.MakeKey("DNE", "other")})
+ bl, err = ds.ExistsMulti(ds.MakeKey("DNE", "nope"), ds.MakeKey("DNE", "other"))
So(err, ShouldBeNil)
So(bl, ShouldResemble, BoolList{false, false})
So(bl.All(), ShouldBeFalse)
@@ -419,229 +426,266 @@ func TestPopulateKey(t *testing.T) {
func TestPut(t *testing.T) {
t.Parallel()
- Convey("Test Put/PutMulti", t, func() {
+ Convey("A testing environment", t, func() {
c := info.Set(context.Background(), fakeInfo{})
c = SetRawFactory(c, fakeDatastoreFactory)
ds := Get(c)
- Convey("bad", func() {
- Convey("static can't serialize", func() {
- bss := []badStruct{{}, {}}
- So(func() { ds.PutMulti(bss) }, ShouldPanicLike,
- `field "Compy" has invalid type`)
- })
+ Convey("Testing Put", func() {
dnj 2016/05/25 05:27:16 (Most of this is just an indentation. The new stuf
+ Convey("bad", func() {
+ Convey("static can't serialize", func() {
+ bss := []badStruct{{}, {}}
+ So(func() { ds.Put(bss) }, ShouldPanicLike,
+ `field "Compy" has invalid type`)
+ })
- Convey("static ptr can't serialize", func() {
- bss := []*badStruct{{}, {}}
- So(func() { ds.PutMulti(bss) }, ShouldPanicLike,
- `field "Compy" has invalid type: complex64`)
- })
+ Convey("static ptr can't serialize", func() {
+ bss := []*badStruct{{}, {}}
+ So(func() { ds.Put(bss) }, ShouldPanicLike,
+ `field "Compy" has invalid type: complex64`)
+ })
- Convey("static bad type (non-slice)", func() {
- So(func() { ds.PutMulti(100) }, ShouldPanicLike,
- "invalid argument type: expected slice, got int")
- })
+ Convey("static bad type", func() {
+ So(func() { ds.Put(100) }, ShouldPanicLike,
+ "invalid input type (int): not a PLS or pointer-to-struct")
+ })
- Convey("static bad type (slice of bad type)", func() {
- So(func() { ds.PutMulti([]int{}) }, ShouldPanicLike,
- "invalid argument type: []int")
- })
+ Convey("static bad type (slice of bad type)", func() {
+ So(func() { ds.Put([]int{}) }, ShouldPanicLike,
+ "invalid input type ([]int): not a PLS or pointer-to-struct")
+ })
- Convey("dynamic can't serialize", func() {
- fplss := []FakePLS{{failSave: true}, {}}
- So(ds.PutMulti(fplss), ShouldErrLike, "FakePLS.Save")
- })
+ Convey("dynamic can't serialize", func() {
+ fplss := []FakePLS{{failSave: true}, {}}
+ So(ds.Put(fplss), ShouldErrLike, "FakePLS.Save")
+ })
- Convey("can't get keys", func() {
- fplss := []FakePLS{{failGetMeta: true}, {}}
- So(ds.PutMulti(fplss), ShouldErrLike, "unable to extract $kind")
- })
+ Convey("can't get keys", func() {
+ fplss := []FakePLS{{failGetMeta: true}, {}}
+ So(ds.Put(fplss), ShouldErrLike, "unable to extract $kind")
+ })
- Convey("get single error for RPC failure", func() {
- fplss := []FakePLS{{Kind: "FailAll"}, {}}
- So(ds.PutMulti(fplss), ShouldErrLike, "PutMulti fail all")
- })
+ Convey("get single error for RPC failure", func() {
+ fplss := []FakePLS{{Kind: "FailAll"}, {}}
+ So(ds.Put(fplss), ShouldResemble, errPutMultiFailAll)
+ })
- Convey("get multi error for individual failures", func() {
- fplss := []FakePLS{{}, {Kind: "Fail"}}
- So(ds.PutMulti(fplss), ShouldResemble, errors.MultiError{nil, errors.New("PutMulti fail")})
- })
+ Convey("get multi error for individual failures", func() {
+ fplss := []FakePLS{{}, {Kind: "Fail"}}
+ So(ds.Put(fplss), ShouldResemble, errors.MultiError{nil, errPutMultiFail})
+ })
- Convey("put with non-modifyable type is an error", func() {
- cs := CommonStruct{}
- So(func() { ds.Put(cs) }, ShouldPanicLike,
- "invalid Put input type (datastore.CommonStruct): not a pointer")
- })
+ Convey("put with non-modifyable type is an error", func() {
+ cs := CommonStruct{}
+ So(func() { ds.Put(cs) }, ShouldPanicLike,
+ "invalid input type (datastore.CommonStruct): not a pointer")
+ })
- Convey("get with *Key is an error", func() {
- So(func() { ds.Get(&Key{}) }, ShouldPanicLike,
- "invalid Get input type (*datastore.Key): not user datatype")
- })
+ Convey("get with *Key is an error", func() {
+ So(func() { ds.Get(&Key{}) }, ShouldPanicLike,
+ "invalid input type (*datastore.Key): not user datatype")
+ })
- Convey("struct with no $kind is an error", func() {
- s := MGSWithNoKind{}
- So(ds.Put(&s), ShouldErrLike, "unable to extract $kind")
- })
+ Convey("struct with no $kind is an error", func() {
+ s := MGSWithNoKind{}
+ So(ds.Put(&s), ShouldErrLike, "unable to extract $kind")
+ })
- Convey("struct with invalid but non-nil key is an error", func() {
- type BadParent struct {
- ID int64 `gae:"$id"`
- Parent *Key `gae:"$parent"`
- }
- // having an Incomplete parent makes an invalid key
- bp := &BadParent{ID: 1, Parent: ds.MakeKey("Something", 0)}
- So(ds.Put(bp), ShouldErrLike, ErrInvalidKey)
+ Convey("struct with invalid but non-nil key is an error", func() {
+ type BadParent struct {
+ ID int64 `gae:"$id"`
+ Parent *Key `gae:"$parent"`
+ }
+ // having an Incomplete parent makes an invalid key
+ bp := &BadParent{ID: 1, Parent: ds.MakeKey("Something", 0)}
+ So(ds.Put(bp), ShouldErrLike, ErrInvalidKey)
+ })
+
+ Convey("vararg with errors", func() {
+ successSlice := []CommonStruct{{Value: 0}, {Value: 1}}
+ failSlice := []FakePLS{{Kind: "Fail"}, {Value: 3}}
+ cs0 := CommonStruct{Value: 4}
+ cs1 := FakePLS{Kind: "Fail", Value: 5}
+ fpls := FakePLS{StringID: "ohai", Value: 6}
+
+ err := ds.Put(successSlice, failSlice, &cs0, &cs1, &fpls)
+ So(err, ShouldResemble, errors.MultiError{
+ nil, errors.MultiError{errPutMultiFail, nil}, nil, errPutMultiFail, nil})
+ So(successSlice[0].ID, ShouldEqual, 1)
+ So(successSlice[1].ID, ShouldEqual, 2)
+ So(cs0.ID, ShouldEqual, 5)
+ })
})
- })
- Convey("ok", func() {
- Convey("[]S", func() {
- css := make([]CommonStruct, 7)
- for i := range css {
- if i == 4 {
- css[i].ID = 200
+ Convey("ok", func() {
+ Convey("[]S", func() {
+ css := make([]CommonStruct, 7)
+ for i := range css {
+ if i == 4 {
+ css[i].ID = 200
+ }
+ css[i].Value = int64(i)
}
- css[i].Value = int64(i)
- }
- So(ds.PutMulti(css), ShouldBeNil)
- for i, cs := range css {
- expect := int64(i + 1)
- if i == 4 {
- expect = 200
+ So(ds.Put(css), ShouldBeNil)
+ for i, cs := range css {
+ expect := int64(i + 1)
+ if i == 4 {
+ expect = 200
+ }
+ So(cs.ID, ShouldEqual, expect)
}
- So(cs.ID, ShouldEqual, expect)
- }
- })
+ })
- Convey("[]*S", func() {
- css := make([]*CommonStruct, 7)
- for i := range css {
- css[i] = &CommonStruct{Value: int64(i)}
- if i == 4 {
- css[i].ID = 200
+ Convey("[]*S", func() {
+ css := make([]*CommonStruct, 7)
+ for i := range css {
+ css[i] = &CommonStruct{Value: int64(i)}
+ if i == 4 {
+ css[i].ID = 200
+ }
}
- }
- So(ds.PutMulti(css), ShouldBeNil)
- for i, cs := range css {
- expect := int64(i + 1)
- if i == 4 {
- expect = 200
+ So(ds.Put(css), ShouldBeNil)
+ for i, cs := range css {
+ expect := int64(i + 1)
+ if i == 4 {
+ expect = 200
+ }
+ So(cs.ID, ShouldEqual, expect)
}
- So(cs.ID, ShouldEqual, expect)
- }
- s := &CommonStruct{}
- So(ds.Put(s), ShouldBeNil)
- So(s.ID, ShouldEqual, 1)
- })
+ s := &CommonStruct{}
+ So(ds.Put(s), ShouldBeNil)
+ So(s.ID, ShouldEqual, 1)
+ })
- Convey("[]P", func() {
- fplss := make([]FakePLS, 7)
- for i := range fplss {
- fplss[i].Value = int64(i)
- if i == 4 {
- fplss[i].IntID = int64(200)
+ Convey("[]P", func() {
+ fplss := make([]FakePLS, 7)
+ for i := range fplss {
+ fplss[i].Value = int64(i)
+ if i == 4 {
+ fplss[i].IntID = int64(200)
+ }
}
- }
- So(ds.PutMulti(fplss), ShouldBeNil)
- for i, fpls := range fplss {
- expect := int64(i + 1)
- if i == 4 {
- expect = 200
+ So(ds.Put(fplss), ShouldBeNil)
+ for i, fpls := range fplss {
+ expect := int64(i + 1)
+ if i == 4 {
+ expect = 200
+ }
+ So(fpls.IntID, ShouldEqual, expect)
}
- So(fpls.IntID, ShouldEqual, expect)
- }
- pm := PropertyMap{"Value": {MkProperty(0)}, "$kind": {MkPropertyNI("Pmap")}}
- So(ds.Put(pm), ShouldBeNil)
- So(ds.KeyForObj(pm).IntID(), ShouldEqual, 1)
- })
+ pm := PropertyMap{"Value": {MkProperty(0)}, "$kind": {MkPropertyNI("Pmap")}}
+ So(ds.Put(pm), ShouldBeNil)
+ So(ds.KeyForObj(pm).IntID(), ShouldEqual, 1)
+ })
- Convey("[]P (map)", func() {
- pms := make([]PropertyMap, 7)
- for i := range pms {
- pms[i] = PropertyMap{
- "$kind": {MkProperty("Pmap")},
- "Value": {MkProperty(i)},
+ Convey("[]P (map)", func() {
+ pms := make([]PropertyMap, 7)
+ for i := range pms {
+ pms[i] = PropertyMap{
+ "$kind": {MkProperty("Pmap")},
+ "Value": {MkProperty(i)},
+ }
+ if i == 4 {
+ So(pms[i].SetMeta("id", int64(200)), ShouldBeTrue)
+ }
}
- if i == 4 {
- So(pms[i].SetMeta("id", int64(200)), ShouldBeTrue)
+ So(ds.Put(pms), ShouldBeNil)
+ for i, pm := range pms {
+ expect := int64(i + 1)
+ if i == 4 {
+ expect = 200
+ }
+ So(ds.KeyForObj(pm).String(), ShouldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
}
- }
- So(ds.PutMulti(pms), ShouldBeNil)
- for i, pm := range pms {
- expect := int64(i + 1)
- if i == 4 {
- expect = 200
- }
- So(ds.KeyForObj(pm).String(), ShouldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
- }
- })
+ })
- Convey("[]*P", func() {
- fplss := make([]*FakePLS, 7)
- for i := range fplss {
- fplss[i] = &FakePLS{Value: int64(i)}
- if i == 4 {
- fplss[i].IntID = int64(200)
+ Convey("[]*P", func() {
+ fplss := make([]*FakePLS, 7)
+ for i := range fplss {
+ fplss[i] = &FakePLS{Value: int64(i)}
+ if i == 4 {
+ fplss[i].IntID = int64(200)
+ }
}
- }
- So(ds.PutMulti(fplss), ShouldBeNil)
- for i, fpls := range fplss {
- expect := int64(i + 1)
- if i == 4 {
- expect = 200
+ So(ds.Put(fplss), ShouldBeNil)
+ for i, fpls := range fplss {
+ expect := int64(i + 1)
+ if i == 4 {
+ expect = 200
+ }
+ So(fpls.IntID, ShouldEqual, expect)
}
- So(fpls.IntID, ShouldEqual, expect)
- }
- })
+ })
- Convey("[]*P (map)", func() {
- pms := make([]*PropertyMap, 7)
- for i := range pms {
- pms[i] = &PropertyMap{
- "$kind": {MkProperty("Pmap")},
- "Value": {MkProperty(i)},
+ Convey("[]*P (map)", func() {
+ pms := make([]*PropertyMap, 7)
+ for i := range pms {
+ pms[i] = &PropertyMap{
+ "$kind": {MkProperty("Pmap")},
+ "Value": {MkProperty(i)},
+ }
+ if i == 4 {
+ So(pms[i].SetMeta("id", int64(200)), ShouldBeTrue)
+ }
}
- if i == 4 {
- So(pms[i].SetMeta("id", int64(200)), ShouldBeTrue)
+ So(ds.Put(pms), ShouldBeNil)
+ for i, pm := range pms {
+ expect := int64(i + 1)
+ if i == 4 {
+ expect = 200
+ }
+ So(ds.KeyForObj(*pm).String(), ShouldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
}
- }
- So(ds.PutMulti(pms), ShouldBeNil)
- for i, pm := range pms {
- expect := int64(i + 1)
- if i == 4 {
- expect = 200
+ })
+
+ Convey("[]I", func() {
+ ifs := []interface{}{
+ &CommonStruct{Value: 0},
+ &FakePLS{Value: 1},
+ PropertyMap{"Value": {MkProperty(2)}, "$kind": {MkPropertyNI("Pmap")}},
+ &PropertyMap{"Value": {MkProperty(3)}, "$kind": {MkPropertyNI("Pmap")}},
}
- So(ds.KeyForObj(*pm).String(), ShouldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect))
- }
+ So(ds.Put(ifs), ShouldBeNil)
+ for i := range ifs {
+ switch i {
+ case 0:
+ So(ifs[i].(*CommonStruct).ID, ShouldEqual, 1)
+ case 1:
+ fpls := ifs[i].(*FakePLS)
+ So(fpls.IntID, ShouldEqual, 2)
+ case 2:
+ So(ds.KeyForObj(ifs[i].(PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,3")
+ case 3:
+ So(ds.KeyForObj(*ifs[i].(*PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,4")
+ }
+ }
+ })
})
+ })
- Convey("[]I", func() {
- ifs := []interface{}{
- &CommonStruct{Value: 0},
- &FakePLS{Value: 1},
- PropertyMap{"Value": {MkProperty(2)}, "$kind": {MkPropertyNI("Pmap")}},
- &PropertyMap{"Value": {MkProperty(3)}, "$kind": {MkPropertyNI("Pmap")}},
- }
- So(ds.PutMulti(ifs), ShouldBeNil)
- for i := range ifs {
- switch i {
- case 0:
- So(ifs[i].(*CommonStruct).ID, ShouldEqual, 1)
- case 1:
- fpls := ifs[i].(*FakePLS)
- So(fpls.IntID, ShouldEqual, 2)
- case 2:
- So(ds.KeyForObj(ifs[i].(PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,3")
- case 3:
- So(ds.KeyForObj(*ifs[i].(*PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,4")
- }
- }
+ Convey("Testing PutMulti", func() {
+ Convey("Fails for something other than a slice.", func() {
+ cs := CommonStruct{}
+ So(func() { ds.PutMulti(&cs) }, ShouldPanicLike,
+ "argument must be a slice, not *datastore.CommonStruct")
})
- })
+ Convey("Succeeds for a slice.", func() {
+ cs := []CommonStruct{{Value: 0}, {Value: 1}}
+ So(ds.PutMulti(cs), ShouldBeNil)
+ So(cs[0].ID, ShouldEqual, 1)
+ So(cs[1].ID, ShouldEqual, 2)
+ })
+ Convey("Returns an item error in a MultiError.", func() {
+ cs := []FakePLS{{Value: 0}, {Kind: "Fail"}}
+ err := ds.PutMulti(cs)
+ So(err, ShouldResemble, errors.MultiError{nil, errPutMultiFail})
+ So(cs[0].IntID, ShouldEqual, 1)
+ })
+ })
})
}
@@ -660,7 +704,7 @@ func TestDelete(t *testing.T) {
MakeKey("s~aid", "ns", "FailAll", 1),
MakeKey("s~aid", "ns", "Ok", 1),
}
- So(ds.DeleteMulti(keys).Error(), ShouldEqual, "DeleteMulti fail all")
+ So(ds.DeleteMulti(keys...).Error(), ShouldEqual, "DeleteMulti fail all")
})
Convey("get multi error for individual failure", func() {
@@ -668,7 +712,7 @@ func TestDelete(t *testing.T) {
ds.MakeKey("Ok", 1),
ds.MakeKey("Fail", 2),
}
- So(ds.DeleteMulti(keys).Error(), ShouldEqual, "DeleteMulti fail")
+ So(ds.DeleteMulti(keys...).Error(), ShouldEqual, "DeleteMulti fail")
})
Convey("get single error when deleting a single", func() {
@@ -683,84 +727,133 @@ func TestDelete(t *testing.T) {
func TestGet(t *testing.T) {
t.Parallel()
- Convey("Test Get/GetMulti", t, func() {
+ Convey("A testing environment", t, func() {
c := info.Set(context.Background(), fakeInfo{})
c = SetRawFactory(c, fakeDatastoreFactory)
ds := Get(c)
So(ds, ShouldNotBeNil)
- Convey("bad", func() {
- Convey("static can't serialize", func() {
- toGet := []badStruct{{}, {}}
- So(func() { ds.GetMulti(toGet) }, ShouldPanicLike,
- `field "Compy" has invalid type: complex64`)
- })
+ Convey("Testing Get", func() {
+ Convey("bad", func() {
+ Convey("static can't serialize", func() {
+ toGet := []badStruct{{}, {}}
+ So(func() { ds.Get(toGet) }, ShouldPanicLike,
+ `field "Compy" has invalid type: complex64`)
+ })
- Convey("can't get keys", func() {
- fplss := []FakePLS{{failGetMeta: true}, {}}
- So(ds.GetMulti(fplss), ShouldErrLike, "unable to extract $kind")
- })
+ Convey("can't get keys", func() {
+ fplss := []FakePLS{{failGetMeta: true}, {}}
+ So(ds.Get(fplss), ShouldErrLike, "unable to extract $kind")
+ })
- Convey("get single error for RPC failure", func() {
- fplss := []FakePLS{
- {IntID: 1, Kind: "FailAll"},
- {IntID: 2},
- }
- So(ds.GetMulti(fplss).Error(), ShouldEqual, "GetMulti fail all")
- })
+ Convey("get single error for RPC failure", func() {
+ fplss := []FakePLS{
+ {IntID: 1, Kind: "FailAll"},
+ {IntID: 2},
+ }
+ So(ds.Get(fplss).Error(), ShouldEqual, "GetMulti fail all")
+ })
- Convey("get multi error for individual failures", func() {
- fplss := []FakePLS{{IntID: 1}, {IntID: 2, Kind: "Fail"}}
- So(ds.GetMulti(fplss), ShouldResemble, errors.MultiError{nil, errors.New("GetMulti fail")})
- })
+ Convey("get multi error for individual failures", func() {
+ fplss := []FakePLS{{IntID: 1}, {IntID: 2, Kind: "Fail"}}
+ So(ds.Get(fplss), ShouldResemble, errors.MultiError{nil, errors.New("GetMulti fail")})
+ })
- Convey("get with non-modifiable type is an error", func() {
- cs := CommonStruct{}
- So(func() { ds.Get(cs) }, ShouldPanicLike,
- "invalid Get input type (datastore.CommonStruct): not a pointer")
- })
+ Convey("get with non-modifiable type is an error", func() {
+ cs := CommonStruct{}
+ So(func() { ds.Get(cs) }, ShouldPanicLike,
+ "invalid input type (datastore.CommonStruct): not a pointer")
+ })
- Convey("get with nil is an error", func() {
- So(func() { ds.Get(nil) }, ShouldPanicLike,
- "invalid Get input type (<nil>): no type information")
- })
+ Convey("get with nil is an error", func() {
+ So(func() { ds.Get(nil) }, ShouldPanicLike,
+ "cannot use nil as single argument")
+ })
+
+ Convey("get with ptr-to-nonstruct is an error", func() {
+ val := 100
+ So(func() { ds.Get(&val) }, ShouldPanicLike,
+ "invalid input type (*int): not a PLS or pointer-to-struct")
+ })
- Convey("get with ptr-to-nonstruct is an error", func() {
- val := 100
- So(func() { ds.Get(&val) }, ShouldPanicLike,
- "invalid Get input type (*int): does not point to a struct")
+ Convey("failure to save metadata is no problem though", func() {
+ // It just won't save the key
+ cs := &FakePLS{IntID: 10, failSetMeta: true}
+ So(ds.Get(cs), ShouldBeNil)
+ })
+
+ Convey("vararg with errors", func() {
+ successSlice := []CommonStruct{{ID: 1}, {ID: 2}}
+ failSlice := []CommonStruct{{ID: noSuchEntityID}, {ID: 3}}
+ cs0 := CommonStruct{ID: 4}
+ cs1 := CommonStruct{ID: noSuchEntityID}
+ fpls := FakePLS{StringID: "ohai"}
+
+ err := ds.Get(successSlice, failSlice, &cs0, &cs1, &fpls)
+ So(err, ShouldResemble, errors.MultiError{
+ nil, errors.MultiError{ErrNoSuchEntity, nil}, nil, ErrNoSuchEntity, nil})
+ So(successSlice[0].Value, ShouldEqual, 1)
+ So(successSlice[1].Value, ShouldEqual, 2)
+ So(cs0.Value, ShouldEqual, 5)
+ So(fpls.Value, ShouldEqual, 7)
+ })
})
- Convey("failure to save metadata is no problem though", func() {
- // It just won't save the key
- cs := &FakePLS{IntID: 10, failSetMeta: true}
- So(ds.Get(cs), ShouldBeNil)
+ Convey("ok", func() {
+ Convey("Get", func() {
+ cs := &CommonStruct{ID: 1}
+ So(ds.Get(cs), ShouldBeNil)
+ So(cs.Value, ShouldEqual, 1)
+ })
+
+ Convey("Raw access too", func() {
+ rds := ds.Raw()
+ keys := []*Key{ds.MakeKey("Kind", 1)}
+ So(rds.GetMulti(keys, nil, func(pm PropertyMap, err error) error {
+ So(err, ShouldBeNil)
+ So(pm["Value"][0].Value(), ShouldEqual, 1)
+ return nil
+ }), ShouldBeNil)
+ })
+
+ Convey("but general failure to save is fine on a Get", func() {
+ cs := &FakePLS{failSave: true, IntID: 7}
+ So(ds.Get(cs), ShouldBeNil)
+ })
+
+ Convey("vararg", func() {
+ successSlice := []CommonStruct{{ID: 1}, {ID: 2}}
+ cs := CommonStruct{ID: 3}
+
+ err := ds.Get(successSlice, &cs)
+ So(err, ShouldBeNil)
+ So(successSlice[0].Value, ShouldEqual, 1)
+ So(successSlice[1].Value, ShouldEqual, 2)
+ So(cs.Value, ShouldEqual, 3)
+ })
})
})
- Convey("ok", func() {
- Convey("Get", func() {
- cs := &CommonStruct{ID: 1}
- So(ds.Get(cs), ShouldBeNil)
- So(cs.Value, ShouldEqual, 1)
+ Convey("Testing GetMulti", func() {
+ Convey("Fails for something other than a slice.", func() {
+ cs := CommonStruct{}
+ So(func() { ds.GetMulti(&cs) }, ShouldPanicLike,
+ "argument must be a slice, not *datastore.CommonStruct")
})
- Convey("Raw access too", func() {
- rds := ds.Raw()
- keys := []*Key{ds.MakeKey("Kind", 1)}
- So(rds.GetMulti(keys, nil, func(pm PropertyMap, err error) error {
- So(err, ShouldBeNil)
- So(pm["Value"][0].Value(), ShouldEqual, 1)
- return nil
- }), ShouldBeNil)
+ Convey("Succeeds for a slice.", func() {
+ cs := []CommonStruct{{ID: 1}}
+ So(ds.GetMulti(cs), ShouldBeNil)
+ So(cs[0].Value, ShouldEqual, 1)
})
- Convey("but general failure to save is fine on a Get", func() {
- cs := &FakePLS{failSave: true, IntID: 7}
- So(ds.Get(cs), ShouldBeNil)
+ Convey("Returns an item error in a MultiError.", func() {
+ cs := []CommonStruct{{ID: 1}, {ID: noSuchEntityID}}
+ err := ds.GetMulti(cs)
+ So(err, ShouldResemble, errors.MultiError{nil, ErrNoSuchEntity})
+ So(cs[0].Value, ShouldEqual, 1)
})
})
-
})
}
@@ -914,7 +1007,7 @@ func TestRun(t *testing.T) {
panic("never here!")
}
So(func() { ds.Run(q, cb) }, ShouldPanicLike,
- "invalid argument type: int")
+ "invalid argument type: int is not a PLS or pointer-to-struct")
})
Convey("wrong # args", func() {

Powered by Google App Engine
This is Rietveld 408576698