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

Unified Diff: service/datastore/pls_test.go

Issue 2342063003: Differentiate between single- and multi- props. (Closed)
Patch Set: Slice is now always a clone. This is marginally worse performance, but a much safer UI. Created 4 years, 3 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
« no previous file with comments | « service/datastore/pls_impl.go ('k') | service/datastore/properties.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"),
})
})
})
« no previous file with comments | « service/datastore/pls_impl.go ('k') | service/datastore/properties.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698