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

Unified Diff: service/datastore/pls_test.go

Issue 1292913002: Split off serialization and key functions to their own packages. (Closed) Base URL: https://github.com/luci/gae.git@make_queries_better
Patch Set: rebase Created 5 years, 4 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/key_test.go ('k') | service/datastore/raw_interface.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 959226af5ae02cadc8717f4aad79d4d6edc03e8b..c11cccff8d8136b571faca0ec8506177f8102038 100644
--- a/service/datastore/pls_test.go
+++ b/service/datastore/pls_test.go
@@ -18,6 +18,7 @@ import (
"time"
"github.com/luci/gae/service/blobstore"
+ . "github.com/luci/luci-go/common/testing/assertions"
. "github.com/smartystreets/goconvey/convey"
)
@@ -527,8 +528,120 @@ type Impossible4 struct {
Values []Complex
}
+// TODO(riannucci): see if there's a way to NOT have this be a duplicate of
+// key.Generic. I couldn't figure out the package interdependency, and this
+// allows things to be in separate packages.
+type genericKey struct {
+ kind string
+ sid string
+ iid int64
+
+ aid string
+ ns string
+
+ parent *genericKey
+}
+
+func (g *genericKey) Kind() string { return g.kind }
+func (g *genericKey) StringID() string { return g.sid }
+func (g *genericKey) IntID() int64 { return g.iid }
+func (g *genericKey) AppID() string { return g.aid }
+func (g *genericKey) Namespace() string { return g.ns }
+func (g *genericKey) Parent() Key { return g.parent }
+
+func marshalDSKey(b *bytes.Buffer, k *genericKey) {
+ if k.parent != nil {
+ marshalDSKey(b, k.parent)
+ }
+ b.WriteByte('/')
+ b.WriteString(k.kind)
+ b.WriteByte(',')
+ if k.sid != "" {
+ b.WriteString(k.sid)
+ } else {
+ b.WriteString(strconv.FormatInt(k.iid, 10))
+ }
+}
+
+func (g *genericKey) String() string {
+ if g == nil {
+ return ""
+ }
+ b := bytes.NewBuffer(make([]byte, 0, 512))
+ marshalDSKey(b, g)
+ return b.String()
+}
+
+func (g *genericKey) Incomplete() bool {
+ return g.iid == 0 && g.sid == ""
+}
+
+func (g *genericKey) Valid(allowSpecial bool, aid, ns string) bool {
+ if g == nil {
+ return false
+ }
+ if aid != g.AppID() || ns != g.Namespace() {
+ return false
+ }
+ for ; g != nil; g = g.parent {
+ if !allowSpecial && len(g.Kind()) >= 2 && g.Kind()[:2] == "__" {
+ return false
+ }
+ if g.Kind() == "" || g.AppID() == "" {
+ return false
+ }
+ if g.StringID() != "" && g.IntID() != 0 {
+ return false
+ }
+ if g.parent != nil {
+ if g.parent.Incomplete() {
+ return false
+ }
+ if g.parent.AppID() != g.AppID() || g.parent.Namespace() != g.Namespace() {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+func (g *genericKey) PartialValid(aid, ns string) bool {
+ if g.Incomplete() {
+ g = mkKey(g.AppID(), g.Namespace(), g.Kind(), 1, g.Parent()).(*genericKey)
+ }
+ return g.Valid(false, aid, ns)
+}
+
+var _ Key = (*genericKey)(nil)
+
+func mkKey(aid, ns string, pairs ...interface{}) Key {
+ ret := (*genericKey)(nil)
+ if len(pairs)%2 != 0 {
+ ret, _ = pairs[len(pairs)-1].(*genericKey)
+ pairs = pairs[:len(pairs)-1]
+ }
+ for i := 0; i < len(pairs); i += 2 {
+ kind := pairs[i].(string)
+ id := pairs[i+1]
+ ret = &genericKey{
+ kind: kind,
+ aid: aid,
+ ns: ns,
+ parent: ret,
+ }
+ ret.sid, _ = id.(string)
+ iid, ok := id.(int)
+ if ok {
+ ret.iid = int64(iid)
+ } else {
+ ret.iid, _ = id.(int64)
+ }
+ }
+ return ret
+}
+
type DerivedKey struct {
- K *GenericKey
+ K *genericKey
}
type IfaceKey struct {
@@ -799,13 +912,13 @@ var testCases = []testCase{
},
{
desc: "allow concrete Key implementors (save)",
- src: &DerivedKey{testKey2a.(*GenericKey)},
+ src: &DerivedKey{testKey2a.(*genericKey)},
want: &IfaceKey{testKey2b},
},
{
desc: "allow concrete Key implementors (load)",
src: &IfaceKey{testKey2b},
- want: &DerivedKey{testKey2a.(*GenericKey)},
+ want: &DerivedKey{testKey2a.(*genericKey)},
},
{
desc: "save []float64 load []int64",
@@ -1463,43 +1576,15 @@ func checkErr(want string, err error) string {
return ""
}
-func ShouldErrLike(actual interface{}, expected ...interface{}) string {
- e2s := func(o interface{}) (string, bool) {
- switch x := o.(type) {
- case nil:
- return "", true
- case string:
- return x, true
- case error:
- if x != nil {
- return x.Error(), true
- }
- return "", true
- }
- return fmt.Sprintf("unknown argument type %T, expected string, error or nil", actual), false
- }
-
- as, ok := e2s(actual)
- if !ok {
- return as
- }
-
- if len(expected) != 1 {
- return fmt.Sprintf("Assertion requires 1 expected value, got %d", len(expected))
- }
-
- err, ok := e2s(expected[0])
- if !ok {
- return err
- }
- return ShouldContainSubstring(as, err)
-}
-
func TestRoundTrip(t *testing.T) {
t.Parallel()
checkErr := func(actual interface{}, expected string) bool {
- So(actual, ShouldErrLike, expected)
+ if expected == "" {
+ So(actual, ShouldErrLike, nil)
+ } else {
+ So(actual, ShouldErrLike, expected)
+ }
return expected != ""
}
« no previous file with comments | « service/datastore/key_test.go ('k') | service/datastore/raw_interface.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698