Index: service/datastore/pls_test.go |
diff --git a/service/datastore/pls_test.go b/service/datastore/pls_test.go |
index 50480f1be474143565f0efa0e7d079415ec66c59..a8217118cd4640de8396988bb2fd3d2cccfa13c1 100644 |
--- a/service/datastore/pls_test.go |
+++ b/service/datastore/pls_test.go |
@@ -367,17 +367,22 @@ func (d *Doubler) Save(withMeta bool) (PropertyMap, error) { |
return nil, err |
} |
+ double := func(prop *Property) { |
+ switch v := prop.Value().(type) { |
+ case string: |
+ // + means string concatenation. |
+ So(prop.SetValue(v+v, prop.IndexSetting()), ShouldBeNil) |
+ case int64: |
+ // + means integer addition. |
+ So(prop.SetValue(v+v, prop.IndexSetting()), ShouldBeNil) |
+ } |
+ } |
+ |
// Edit that map and send it on. |
- for _, props := range propMap { |
- for i := range props { |
- switch v := props[i].Value().(type) { |
- case string: |
- // + means string concatenation. |
- So(props[i].SetValue(v+v, props[i].IndexSetting()), ShouldBeNil) |
- case int64: |
- // + means integer addition. |
- So(props[i].SetValue(v+v, props[i].IndexSetting()), ShouldBeNil) |
- } |
+ for k, v := range propMap { |
+ if prop, ok := v.(Property); ok { |
+ double(&prop) |
+ propMap[k] = prop |
} |
} |
return propMap, nil |
@@ -392,19 +397,19 @@ type Deriver struct { |
} |
func (d *Deriver) Load(props PropertyMap) error { |
- for name, p := range props { |
+ for name := range props { |
if name != "S" { |
continue |
} |
- d.S = p[0].Value().(string) |
+ d.S = props.Slice(name)[0].Value().(string) |
d.Derived = "derived+" + d.S |
} |
return nil |
} |
func (d *Deriver) Save(withMeta bool) (PropertyMap, error) { |
- return map[string][]Property{ |
- "S": {mp(d.S)}, |
+ return map[string]PropertyData{ |
+ "S": mp(d.S), |
}, nil |
} |
@@ -419,7 +424,7 @@ type Augmenter struct { |
} |
func (a *Augmenter) Load(props PropertyMap) error { |
- if e := props["Extra"]; len(e) > 0 { |
+ if e := props.Slice("Extra"); len(e) > 0 { |
a.g = e[0].Value().(string) |
delete(props, "Extra") |
} |
@@ -434,7 +439,7 @@ func (a *Augmenter) Save(withMeta bool) (PropertyMap, error) { |
if err != nil { |
return nil, err |
} |
- props["Extra"] = []Property{MkProperty("ohai!")} |
+ props["Extra"] = MkProperty("ohai!") |
return props, nil |
} |
@@ -743,7 +748,7 @@ var testCases = []testCase{ |
desc: "geopoint as props", |
src: &G0{G: testGeoPt0}, |
want: PropertyMap{ |
- "G": {mp(testGeoPt0)}, |
+ "G": mp(testGeoPt0), |
}, |
}, |
{ |
@@ -797,14 +802,14 @@ var testCases = []testCase{ |
desc: "time as props", |
src: &T{T: time.Unix(1e9, 0).UTC()}, |
want: PropertyMap{ |
- "T": {mp(time.Unix(1e9, 0).UTC())}, |
+ "T": mp(time.Unix(1e9, 0).UTC()), |
}, |
}, |
{ |
desc: "uint32 save", |
src: &U0{U: 1}, |
want: PropertyMap{ |
- "U": {mp(1)}, |
+ "U": mp(1), |
}, |
}, |
{ |
@@ -828,7 +833,7 @@ var testCases = []testCase{ |
desc: "byte save", |
src: &U1{U: 1}, |
want: PropertyMap{ |
- "U": {mp(1)}, |
+ "U": mp(1), |
}, |
}, |
{ |
@@ -905,12 +910,12 @@ var testCases = []testCase{ |
desc: "use convertable slice (to map)", |
src: &Impossible{[]ImpossibleInner{{Convertable{1, 5, 9}}, {Convertable{2, 4, 6}}}}, |
want: PropertyMap{ |
- "Nested.wot": {mpNI("1,5,9"), mpNI("2,4,6")}, |
+ "Nested.wot": PropertySlice{mpNI("1,5,9"), mpNI("2,4,6")}, |
}, |
}, |
{ |
desc: "convertable slice (bad load)", |
- src: PropertyMap{"Nested.wot": {mpNI([]byte("ohai"))}}, |
+ src: PropertyMap{"Nested.wot": mpNI([]byte("ohai"))}, |
want: &Impossible{[]ImpossibleInner{{}}}, |
loadErr: "nope", |
}, |
@@ -954,9 +959,8 @@ var testCases = []testCase{ |
}, |
}, |
want: PropertyMap{ |
- "kewelmap": { |
- mpNI([]byte( |
- `{"epic":"success","no_way!":[true,"story"],"what":["is","really",100]}`))}, |
+ "kewelmap": mpNI([]byte( |
+ `{"epic":"success","no_way!":[true,"story"],"what":["is","really",100]}`)), |
}, |
}, |
{ |
@@ -974,13 +978,12 @@ var testCases = []testCase{ |
[]Complex{complex(1, 2), complex(3, 4)}, |
}, |
want: PropertyMap{ |
- "Values": { |
- mp(GeoPoint{Lat: 1, Lng: 2}), mp(GeoPoint{Lat: 3, Lng: 4})}, |
+ "Values": PropertySlice{mp(GeoPoint{Lat: 1, Lng: 2}), mp(GeoPoint{Lat: 3, Lng: 4})}, |
}, |
}, |
{ |
desc: "convertable complex slice (bad load)", |
- src: PropertyMap{"Values": {mp("hello")}}, |
+ src: PropertyMap{"Values": mp("hello")}, |
want: &Impossible4{[]Complex(nil)}, |
loadErr: "nope", |
}, |
@@ -1076,7 +1079,7 @@ var testCases = []testCase{ |
desc: "short ByteString as props", |
src: &B5{B: makeUint8Slice(3)}, |
want: PropertyMap{ |
- "B": {mp(makeUint8Slice(3))}, |
+ "B": mp(makeUint8Slice(3)), |
}, |
}, |
{ |
@@ -1086,16 +1089,16 @@ var testCases = []testCase{ |
// A and B are renamed to a and b; A and C are noindex, I is ignored. |
// Indexed properties are loaded before raw properties. Thus, the |
// result is: b, b, b, D, E, a, c. |
- "b1": { |
+ "b1": PropertySlice{ |
mp(21), |
mp(22), |
mp(23), |
}, |
- "D": {mp(4)}, |
- "E": {mp(5)}, |
- "a": {mpNI(1)}, |
- "C": {mpNI(3)}, |
- "J": {mpNI(7)}, |
+ "D": mp(4), |
+ "E": mp(5), |
+ "a": mpNI(1), |
+ "C": mpNI(3), |
+ "J": mpNI(7), |
}, |
}, |
{ |
@@ -1106,8 +1109,8 @@ var testCases = []testCase{ |
{ |
desc: "save props load tagged", |
src: PropertyMap{ |
- "A": {mpNI(11)}, |
- "a": {mpNI(12)}, |
+ "A": mpNI(11), |
+ "a": mpNI(12), |
}, |
want: &Tagged{A: 12}, |
loadErr: `cannot load field "A"`, |
@@ -1147,28 +1150,28 @@ var testCases = []testCase{ |
desc: "save struct load props", |
src: &X0{S: "s", I: 1}, |
want: PropertyMap{ |
- "S": {mp("s")}, |
- "I": {mp(1)}, |
+ "S": mp("s"), |
+ "I": mp(1), |
}, |
}, |
{ |
desc: "save props load struct", |
src: PropertyMap{ |
- "S": {mp("s")}, |
- "I": {mp(1)}, |
+ "S": mp("s"), |
+ "I": mp(1), |
}, |
want: &X0{S: "s", I: 1}, |
}, |
{ |
desc: "nil-value props", |
src: PropertyMap{ |
- "I": {mp(nil)}, |
- "B": {mp(nil)}, |
- "S": {mp(nil)}, |
- "F": {mp(nil)}, |
- "K": {mp(nil)}, |
- "T": {mp(nil)}, |
- "J": { |
+ "I": mp(nil), |
+ "B": mp(nil), |
+ "S": mp(nil), |
+ "F": mp(nil), |
+ "K": mp(nil), |
+ "T": mp(nil), |
+ "J": PropertySlice{ |
mp(nil), |
mp(7), |
mp(nil), |
@@ -1203,37 +1206,37 @@ var testCases = []testCase{ |
}, |
}, |
want: PropertyMap{ |
- "A": {mp(1)}, |
- "I.W": { |
+ "A": mp(1), |
+ "I.W": PropertySlice{ |
mp(10), |
mp(20), |
mp(30), |
}, |
- "I.X": { |
+ "I.X": PropertySlice{ |
mp("ten"), |
mp("twenty"), |
mp("thirty"), |
}, |
- "J.Y": {mp(3.14)}, |
- "Z": {mp(true)}, |
+ "J.Y": mp(3.14), |
+ "Z": mp(true), |
}, |
}, |
{ |
desc: "save props load outer-equivalent", |
src: PropertyMap{ |
- "A": {mp(1)}, |
- "I.W": { |
+ "A": mp(1), |
+ "I.W": PropertySlice{ |
mp(10), |
mp(20), |
mp(30), |
}, |
- "I.X": { |
+ "I.X": PropertySlice{ |
mp("ten"), |
mp("twenty"), |
mp("thirty"), |
}, |
- "J.Y": {mp(3.14)}, |
- "Z": {mp(true)}, |
+ "J.Y": mp(3.14), |
+ "Z": mp(true), |
}, |
want: &OuterEquivalent{ |
A: 1, |
@@ -1271,13 +1274,13 @@ var testCases = []testCase{ |
desc: "dotted names save", |
src: &Dotted{A: DottedA{B: DottedB{C: 88}}}, |
want: PropertyMap{ |
- "A0.A1.A2.B3.C4.C5": {mp(88)}, |
+ "A0.A1.A2.B3.C4.C5": mp(88), |
}, |
}, |
{ |
desc: "dotted names load", |
src: PropertyMap{ |
- "A0.A1.A2.B3.C4.C5": {mp(99)}, |
+ "A0.A1.A2.B3.C4.C5": mp(99), |
}, |
want: &Dotted{A: DottedA{B: DottedB{C: 99}}}, |
}, |
@@ -1295,15 +1298,15 @@ var testCases = []testCase{ |
desc: "augmenter save", |
src: &Augmenter{S: "s"}, |
want: PropertyMap{ |
- "S": {mp("s")}, |
- "Extra": {mp("ohai!")}, |
+ "S": mp("s"), |
+ "Extra": mp("ohai!"), |
}, |
}, |
{ |
desc: "augmenter load", |
src: PropertyMap{ |
- "S": {mp("s")}, |
- "Extra": {mp("kthxbye!")}, |
+ "S": mp("s"), |
+ "Extra": mp("kthxbye!"), |
}, |
want: &Augmenter{S: "s", g: "kthxbye!"}, |
}, |
@@ -1366,7 +1369,7 @@ var testCases = []testCase{ |
{ |
desc: "exotic type projection", |
src: PropertyMap{ |
- "BS": {mp([]byte("I'mABlobKey"))}, |
+ "BS": mp([]byte("I'mABlobKey")), |
}, |
want: &ExoticTypes{ |
BS: "I'mABlobKey", |
@@ -1380,46 +1383,46 @@ var testCases = []testCase{ |
{ |
desc: "mismatch (string)", |
src: PropertyMap{ |
- "K": {mp(199)}, |
- "S": {mp([]byte("cats"))}, |
- "F": {mp("nurbs")}, |
+ "K": mp(199), |
+ "S": mp([]byte("cats")), |
+ "F": mp("nurbs"), |
}, |
want: &MismatchTypes{}, |
loadErr: "type mismatch", |
}, |
{ |
desc: "mismatch (float)", |
- src: PropertyMap{"F": {mp(blobstore.Key("wot"))}}, |
+ src: PropertyMap{"F": mp(blobstore.Key("wot"))}, |
want: &MismatchTypes{}, |
loadErr: "type mismatch", |
}, |
{ |
desc: "mismatch (float/overflow)", |
- src: PropertyMap{"F": {mp(math.MaxFloat64)}}, |
+ src: PropertyMap{"F": mp(math.MaxFloat64)}, |
want: &MismatchTypes{}, |
loadErr: "overflows", |
}, |
{ |
desc: "mismatch (key)", |
- src: PropertyMap{"K": {mp(false)}}, |
+ src: PropertyMap{"K": mp(false)}, |
want: &MismatchTypes{}, |
loadErr: "type mismatch", |
}, |
{ |
desc: "mismatch (bool)", |
- src: PropertyMap{"B": {mp(testKey0)}}, |
+ src: PropertyMap{"B": mp(testKey0)}, |
want: &MismatchTypes{}, |
loadErr: "type mismatch", |
}, |
{ |
desc: "mismatch (time)", |
- src: PropertyMap{"T": {mp(GeoPoint{})}}, |
+ src: PropertyMap{"T": mp(GeoPoint{})}, |
want: &MismatchTypes{}, |
loadErr: "type mismatch", |
}, |
{ |
desc: "mismatch (geopoint)", |
- src: PropertyMap{"G": {mp(time.Now().UTC())}}, |
+ src: PropertyMap{"G": mp(time.Now().UTC())}, |
want: &MismatchTypes{}, |
loadErr: "type mismatch", |
}, |
@@ -1531,30 +1534,30 @@ var testCases = []testCase{ |
}, |
}, |
want: PropertyMap{ |
- "red.S": {mp("rouge")}, |
- "red.I": {mp(0)}, |
- "red.Nonymous.S": {mp("rosso0"), mp("rosso1")}, |
- "red.Nonymous.I": {mp(0), mp(0)}, |
- "red.Other": {mp("")}, |
- "green.S": {mp("vert")}, |
- "green.I": {mp(0)}, |
- "green.Nonymous.S": {mp("verde0"), mp("verde1"), mp("verde2")}, |
- "green.Nonymous.I": {mp(0), mp(0), mp(0)}, |
- "green.Other": {mp("")}, |
- "Blue.S": {mp("bleu")}, |
- "Blue.I": {mp(0)}, |
- "Blue.Nonymous.S": {mp("blu0"), mp("blu1"), mp("blu2"), mp("blu3")}, |
- "Blue.Nonymous.I": {mp(0), mp(0), mp(0), mp(0)}, |
- "Blue.Other": {mp("")}, |
+ "red.S": mp("rouge"), |
+ "red.I": mp(0), |
+ "red.Nonymous.S": PropertySlice{mp("rosso0"), mp("rosso1")}, |
+ "red.Nonymous.I": PropertySlice{mp(0), mp(0)}, |
+ "red.Other": mp(""), |
+ "green.S": mp("vert"), |
+ "green.I": mp(0), |
+ "green.Nonymous.S": PropertySlice{mp("verde0"), mp("verde1"), mp("verde2")}, |
+ "green.Nonymous.I": PropertySlice{mp(0), mp(0), mp(0)}, |
+ "green.Other": mp(""), |
+ "Blue.S": mp("bleu"), |
+ "Blue.I": mp(0), |
+ "Blue.Nonymous.S": PropertySlice{mp("blu0"), mp("blu1"), mp("blu2"), mp("blu3")}, |
+ "Blue.Nonymous.I": PropertySlice{mp(0), mp(0), mp(0), mp(0)}, |
+ "Blue.Other": mp(""), |
}, |
}, |
{ |
desc: "save props load structs with ragged fields", |
src: PropertyMap{ |
- "red.S": {mp("rot")}, |
- "green.Nonymous.I": {mp(10), mp(11), mp(12), mp(13)}, |
- "Blue.Nonymous.S": {mp("blau0"), mp("blau1"), mp("blau2")}, |
- "Blue.Nonymous.I": {mp(20), mp(21)}, |
+ "red.S": mp("rot"), |
+ "green.Nonymous.I": PropertySlice{mp(10), mp(11), mp(12), mp(13)}, |
+ "Blue.Nonymous.S": PropertySlice{mp("blau0"), mp("blau1"), mp("blau2")}, |
+ "Blue.Nonymous.I": PropertySlice{mp(20), mp(21)}, |
}, |
want: &N2{ |
N1: N1{ |
@@ -1590,10 +1593,10 @@ var testCases = []testCase{ |
} |
}{}, |
want: PropertyMap{ |
- "B.Y": {mp("")}, |
- "A.X": {mpNI("")}, |
- "A.Y": {mpNI("")}, |
- "B.X": {mpNI("")}, |
+ "B.Y": mp(""), |
+ "A.X": mpNI(""), |
+ "A.Y": mpNI(""), |
+ "B.X": mpNI(""), |
}, |
}, |
{ |
@@ -1602,8 +1605,8 @@ var testCases = []testCase{ |
Inner1 `gae:"foo"` |
}{}, |
want: PropertyMap{ |
- "foo.W": {mp(0)}, |
- "foo.X": {mp("")}, |
+ "foo.W": mp(0), |
+ "foo.X": mp(""), |
}, |
}, |
{ |
@@ -1627,7 +1630,7 @@ var testCases = []testCase{ |
i, J int64 |
}{i: 1, J: 2}, |
want: PropertyMap{ |
- "J": {mp(2)}, |
+ "J": mp(2), |
}, |
}, |
{ |
@@ -1638,7 +1641,7 @@ var testCases = []testCase{ |
J: json.RawMessage("rawr"), |
}, |
want: PropertyMap{ |
- "J": {mp([]byte("rawr"))}, |
+ "J": mp([]byte("rawr")), |
}, |
}, |
{ |
@@ -1685,6 +1688,7 @@ func TestRoundTrip(t *testing.T) { |
So(err, ShouldErrLike, tc.saveErr) |
return |
} |
+ So(err, ShouldBeNil) |
So(savedProps, ShouldNotBeNil) |
var got interface{} |
@@ -1799,7 +1803,7 @@ func TestMeta(t *testing.T) { |
Convey("StructPLS Miscellaneous", t, func() { |
Convey("a simple struct has a default $kind", func() { |
So(GetPLS(&Simple{}).GetAllMeta(), ShouldResemble, PropertyMap{ |
- "$kind": []Property{mpNI("Simple")}, |
+ "$kind": mpNI("Simple"), |
}) |
}) |
@@ -1875,9 +1879,9 @@ func TestMeta(t *testing.T) { |
pm, err := pls.Save(true) |
So(err, ShouldBeNil) |
So(pm, ShouldResemble, PropertyMap{ |
- "$when": {mpNI("tomorrow")}, |
- "$amt": {mpNI(100)}, |
- "$kind": {mpNI("OKDefaults")}, |
+ "$when": mpNI("tomorrow"), |
+ "$amt": mpNI(100), |
+ "$kind": mpNI("OKDefaults"), |
}) |
v, ok := pm.GetMeta("when") |
@@ -1983,8 +1987,8 @@ func TestMeta(t *testing.T) { |
So(idp.id, ShouldEqual, 27) |
So(mgs.GetAllMeta(), ShouldResemble, PropertyMap{ |
- "$id": {mpNI("happy|27")}, |
- "$kind": {mpNI("CoolKind")}, |
+ "$id": mpNI("happy|27"), |
+ "$kind": mpNI("CoolKind"), |
}) |
}) |
@@ -2003,20 +2007,20 @@ func TestMeta(t *testing.T) { |
So(ko.customKind, ShouldEqual, "") |
So(mgs.GetAllMeta(), ShouldResemble, PropertyMap{ |
- "$id": {mpNI(20)}, |
- "$kind": {mpNI("KindOverride")}, |
+ "$id": mpNI(20), |
+ "$kind": mpNI("KindOverride"), |
}) |
ko.customKind = "wut" |
So(mgs.GetAllMeta(), ShouldResemble, PropertyMap{ |
- "$id": {mpNI(20)}, |
- "$kind": {mpNI("wut")}, |
+ "$id": mpNI(20), |
+ "$kind": mpNI("wut"), |
}) |
props, err := GetPLS(ko).Save(true) |
So(err, ShouldBeNil) |
So(props, ShouldResemble, PropertyMap{ |
- "$id": {mpNI(20)}, |
- "$kind": {mpNI("wut")}, |
+ "$id": mpNI(20), |
+ "$kind": mpNI("wut"), |
}) |
}) |
@@ -2031,8 +2035,8 @@ func TestMeta(t *testing.T) { |
So(ide.EmbeddedID, ShouldResemble, EmbeddedID{"sup", 1337}) |
So(pls.GetAllMeta(), ShouldResemble, PropertyMap{ |
- "$id": {mpNI("sup|1337")}, |
- "$kind": {mpNI("IDEmbedder")}, |
+ "$id": mpNI("sup|1337"), |
+ "$kind": mpNI("IDEmbedder"), |
}) |
}) |
}) |