Index: service/datastore/pls_test.go |
diff --git a/service/datastore/pls_test.go b/service/datastore/pls_test.go |
index db44b6e67bb6823114ee91b6b51ff272ebc77a3e..9df3eebc28ab26b4c1b9621d386b40c414022125 100644 |
--- a/service/datastore/pls_test.go |
+++ b/service/datastore/pls_test.go |
@@ -154,6 +154,10 @@ type N2 struct { |
White N1 `gae:"-"` |
} |
+type N3 struct { |
+ ID uint32 `gae:"$id,200"` |
+} |
+ |
type O0 struct { |
I int64 |
} |
@@ -163,11 +167,15 @@ type O1 struct { |
} |
type U0 struct { |
- U uint |
+ U uint32 |
} |
type U1 struct { |
- U string |
+ U byte |
+} |
+ |
+type U2 struct { |
+ U int64 |
} |
type T struct { |
@@ -775,6 +783,12 @@ var testCases = []testCase{ |
loadErr: "overflow", |
}, |
{ |
+ desc: "underflow", |
+ src: &O0{I: math.MaxInt64}, |
+ want: &O1{}, |
+ loadErr: "overflow", |
+ }, |
+ { |
desc: "time", |
src: &T{T: time.Unix(1e9, 0).UTC()}, |
want: &T{T: time.Unix(1e9, 0).UTC()}, |
@@ -787,15 +801,52 @@ var testCases = []testCase{ |
}, |
}, |
{ |
- desc: "uint save", |
- src: &U0{U: 1}, |
- plsErr: `field "U" has invalid type: uint`, |
+ desc: "uint32 save", |
+ src: &U0{U: 1}, |
+ want: PropertyMap{ |
+ "U": {mp(1)}, |
+ }, |
}, |
{ |
- desc: "uint load", |
- src: &U1{U: "not a uint"}, |
- want: &U0{}, |
- plsLoadErr: `field "U" has invalid type: uint`, |
+ desc: "uint32 load", |
+ src: &U2{U: 100}, |
+ want: &U0{U: 100}, |
+ }, |
+ { |
+ desc: "uint32 load oob (neg)", |
+ src: &U2{U: -1}, |
+ want: &U0{}, |
+ loadErr: "overflow", |
+ }, |
+ { |
+ desc: "uint32 load oob (huge)", |
+ src: &U2{U: math.MaxInt64}, |
+ want: &U0{}, |
+ loadErr: "overflow", |
+ }, |
+ { |
+ desc: "byte save", |
+ src: &U1{U: 1}, |
+ want: PropertyMap{ |
+ "U": {mp(1)}, |
+ }, |
+ }, |
+ { |
+ desc: "byte load", |
+ src: &U2{U: 100}, |
+ want: &U1{U: 100}, |
+ }, |
+ { |
+ desc: "byte load oob (neg)", |
+ src: &U2{U: -1}, |
+ want: &U1{}, |
+ loadErr: "overflow", |
+ }, |
+ { |
+ desc: "byte load oob (huge)", |
+ src: &U2{U: math.MaxInt64}, |
+ want: &U1{}, |
+ loadErr: "overflow", |
}, |
{ |
desc: "zero", |
@@ -1601,32 +1652,9 @@ var testCases = []testCase{ |
}, |
} |
-// checkErr returns the empty string if either both want and err are zero, |
-// or if want is a non-empty substring of err's string representation. |
-func checkErr(want string, err error) string { |
- if err != nil { |
- got := err.Error() |
- if want == "" || strings.Index(got, want) == -1 { |
- return got |
- } |
- } else if want != "" { |
- return fmt.Sprintf("want error %q", want) |
- } |
- return "" |
-} |
- |
func TestRoundTrip(t *testing.T) { |
t.Parallel() |
- checkErr := func(actual interface{}, expected string) bool { |
- if expected == "" { |
- So(actual, ShouldErrLike, nil) |
- } else { |
- So(actual, ShouldErrLike, expected) |
- } |
- return expected != "" |
- } |
- |
getPLSErr := func(obj interface{}) (pls PropertyLoadSaver, err error) { |
defer func() { |
if v := recover(); v != nil { |
@@ -1645,14 +1673,16 @@ func TestRoundTrip(t *testing.T) { |
if !ok { |
var err error |
pls, err = getPLSErr(tc.src) |
- if checkErr(err, tc.plsErr) { |
+ if tc.plsErr != "" { |
+ So(err, ShouldErrLike, tc.plsErr) |
return |
} |
} |
So(pls, ShouldNotBeNil) |
savedProps, err := pls.Save(false) |
- if checkErr(err, tc.saveErr) { |
+ if tc.saveErr != "" { |
+ So(err, ShouldErrLike, tc.saveErr) |
return |
} |
So(savedProps, ShouldNotBeNil) |
@@ -1666,7 +1696,8 @@ func TestRoundTrip(t *testing.T) { |
if pls, ok = got.(PropertyLoadSaver); !ok { |
var err error |
pls, err = getPLSErr(got) |
- if checkErr(err, tc.plsLoadErr) { |
+ if tc.plsLoadErr != "" { |
+ So(err, ShouldErrLike, tc.plsLoadErr) |
return |
} |
} |
@@ -1675,7 +1706,8 @@ func TestRoundTrip(t *testing.T) { |
So(pls, ShouldNotBeNil) |
err = pls.Load(savedProps) |
- if checkErr(err, tc.loadErr) { |
+ if tc.loadErr != "" { |
+ So(err, ShouldErrLike, tc.loadErr) |
return |
} |
if tc.want == nil { |
@@ -1745,6 +1777,23 @@ func TestMeta(t *testing.T) { |
So(mgs.SetMeta("kind", "hi"), ShouldBeFalse) |
So(mgs.SetMeta("noob", "hi"), ShouldBeFalse) |
}) |
+ |
+ Convey("unsigned int meta fields work", func() { |
+ o := &N3{} |
+ mgs := getMGS(o) |
+ v, ok := mgs.GetMeta("id") |
+ So(v, ShouldEqual, int64(200)) |
+ So(ok, ShouldBeTrue) |
+ |
+ So(mgs.SetMeta("id", 20), ShouldBeTrue) |
+ So(o.ID, ShouldEqual, 20) |
+ |
+ So(mgs.SetMeta("id", math.MaxInt64), ShouldBeFalse) |
+ So(o.ID, ShouldEqual, 20) |
+ |
+ So(mgs.SetMeta("id", math.MaxUint32), ShouldBeTrue) |
+ So(o.ID, ShouldEqual, math.MaxUint32) |
+ }) |
}) |
Convey("StructPLS Miscellaneous", t, func() { |
@@ -1862,6 +1911,27 @@ func TestMeta(t *testing.T) { |
So(v, ShouldEqual, int64(10)) |
}) |
+ Convey("underflow", func() { |
+ type UnderflowMeta struct { |
+ ID int16 `gae:"$id"` |
+ } |
+ um := &UnderflowMeta{} |
+ mgs := getMGS(um) |
+ So(mgs.SetMeta("id", -20), ShouldBeTrue) |
+ So(mgs.SetMeta("id", math.MinInt64), ShouldBeFalse) |
+ }) |
+ |
+ Convey("negative default", func() { |
+ type UnderflowMeta struct { |
+ ID int16 `gae:"$id,-30"` |
+ } |
+ um := &UnderflowMeta{} |
+ mgs := getMGS(um) |
+ val, ok := mgs.GetMeta("id") |
+ So(ok, ShouldBeTrue) |
+ So(val, ShouldEqual, -30) |
+ }) |
+ |
Convey("Derived metadata fields", func() { |
type DerivedString string |
type DerivedInt int16 |