Chromium Code Reviews| 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() { |