Index: impl/memory/datastore_query_test.go |
diff --git a/impl/memory/datastore_query_test.go b/impl/memory/datastore_query_test.go |
index 8c2b4e891bed260f0900233c471feb55c54ec6d7..ee3611b16a42d01cec1f89f215e2ef76e86aa13c 100644 |
--- a/impl/memory/datastore_query_test.go |
+++ b/impl/memory/datastore_query_test.go |
@@ -6,98 +6,13 @@ package memory |
import ( |
"bytes" |
- "math" |
- "testing" |
- dsS "github.com/luci/gae/service/datastore" |
+ dstore "github.com/luci/gae/service/datastore" |
"github.com/luci/gae/service/datastore/serialize" |
"github.com/luci/luci-go/common/cmpbin" |
- . "github.com/luci/luci-go/common/testing/assertions" |
- . "github.com/smartystreets/goconvey/convey" |
- "golang.org/x/net/context" |
) |
iannucci
2015/09/18 04:31:52
I still need to fill this in. You can see some of
iannucci
2015/09/18 22:25:47
Done
|
-const ( |
- MaxUint = ^uint(0) |
- MaxInt = int(MaxUint >> 1) |
- IntIs32Bits = int64(MaxInt) < math.MaxInt64 |
-) |
- |
-func TestDatastoreQueries(t *testing.T) { |
- Convey("Datastore Query suport", t, func() { |
- c := Use(context.Background()) |
- ds := dsS.Get(c) |
- So(ds, ShouldNotBeNil) |
- |
- Convey("can create good queries", func() { |
- q := ds.NewQuery("Foo").Filter("farnsworth >", 20).KeysOnly().Limit(10).Offset(39) |
- |
- // normally you can only get cursors from inside of the memory |
- // implementation, so this construction is just for testing. |
- start := queryCursor(bjoin( |
- mkNum(2), |
- serialize.ToBytes(dsS.IndexColumn{Property: "farnsworth"}), |
- serialize.ToBytes(dsS.IndexColumn{Property: "__key__"}), |
- serialize.ToBytes(prop(200)), |
- serialize.ToBytes(prop(ds.NewKey("Foo", "id", 0, nil))))) |
- |
- So(start.String(), ShouldEqual, |
- `gYAAZzFdTeeb3d9zOxsAAF-v221Xy32_AIGHyIgAAUc32-AFabMAAA==`) |
- |
- end := queryCursor(bjoin( |
- mkNum(2), |
- serialize.ToBytes(dsS.IndexColumn{Property: "farnsworth"}), |
- serialize.ToBytes(dsS.IndexColumn{Property: "__key__"}), |
- serialize.ToBytes(prop(3000)), |
- serialize.ToBytes(prop(ds.NewKey("Foo", "zeta", 0, nil))))) |
- |
- q = q.Start(start).End(end) |
- So(q, ShouldNotBeNil) |
- So(q.(*queryImpl).err, ShouldBeNil) |
- rq, err := q.(*queryImpl).reduce("", false) |
- So(rq, ShouldNotBeNil) |
- So(err, ShouldBeNil) |
- }) |
- |
- Convey("ensures orders make sense", func() { |
- q := ds.NewQuery("Cool") |
- q = q.Filter("cat =", 19).Filter("bob =", 10).Order("bob").Order("bob") |
- |
- Convey("removes dups and equality orders", func() { |
- q = q.Order("wat") |
- qi := q.(*queryImpl) |
- So(qi.err, ShouldBeNil) |
- rq, err := qi.reduce("", false) |
- So(err, ShouldBeNil) |
- So(rq.suffixFormat, ShouldResemble, []dsS.IndexColumn{ |
- {Property: "wat"}, {Property: "__key__"}}) |
- }) |
- |
- Convey("if we equality-filter on __key__, that's just silly", func() { |
- q = q.Order("wat").Filter("__key__ =", ds.NewKey("Foo", "wat", 0, nil)) |
- _, err := q.(*queryImpl).reduce("", false) |
- So(err, ShouldErrLike, "query equality filter on __key__ is silly") |
- }) |
- |
- }) |
- |
- }) |
-} |
- |
-type queryTest struct { |
- // name is the name of the test case |
- name string |
- |
- // q is the input query |
- q dsS.Query |
- |
- // err is the error to expect after prepping the query (error, string or nil) |
- err interface{} |
- |
- // equivalentQuery is another query which ShouldResemble q. This is useful to |
- // see the effects of redundancy pruning on e.g. filters. |
- equivalentQuery dsS.Query |
-} |
+// TODO(riannucci): content |
type sillyCursor string |
@@ -113,13 +28,13 @@ func curs(pairs ...interface{}) queryCursor { |
for i := 0; i < len(pairs); i += 2 { |
k, v := pairs[i].(string), pairs[i+1] |
- col := dsS.IndexColumn{Property: k} |
+ col := dstore.IndexColumn{Property: k} |
post.SetInvert(false) |
if k[0] == '-' { |
post.SetInvert(false) |
col.Property = k[1:] |
- col.Direction = dsS.DESCENDING |
+ col.Direction = dstore.DESCENDING |
} |
serialize.WriteIndexColumn(pre, col) |
serialize.WriteProperty(post, serialize.WithoutContext, prop(v)) |
@@ -127,30 +42,8 @@ func curs(pairs ...interface{}) queryCursor { |
return queryCursor(bjoin(pre.Bytes(), post.Bytes())) |
} |
-var queryTests = []queryTest{ |
- {"only one inequality", |
- nq().Order("bob").Order("wat").Filter("bob >", 10).Filter("wat <", 29), |
- "inequality filters on multiple properties", nil}, |
- |
- {"bad filter ops", |
- nq().Filter("Bob !", "value"), |
- "invalid operator \"!\"", nil}, |
- |
- {"bad filter", |
- nq().Filter("Bob", "value"), |
- "invalid filter", nil}, |
- |
- {"bad order", |
- nq().Order("+Bob"), |
- "invalid order", nil}, |
- |
- {"empty order", |
- nq().Order(""), |
- "empty order", nil}, |
- |
- {"underflow offset", |
- nq().Offset(-20), |
- "negative query offset", nil}, |
+/* |
+* cases: |
{"bad cursors (empty)", |
nq().Start(queryCursor("")), |
@@ -178,129 +71,10 @@ var queryTests = []queryTest{ |
), |
"start cursor is invalid", nil}, |
- {"cursor set multiple times", |
- nq().Order("Luci").End( |
- curs("Luci", 100, "__key__", key("something", 1)), |
- ).End( |
- curs("Luci", 100, "__key__", key("something", 1)), |
- ), |
- "multiply defined", nil}, |
- |
{"cursor bad type", |
nq().Order("Luci").End(sillyCursor("I am a banana")), |
"unknown type", nil}, |
- {"projecting a keys-only query", |
- nq().Project("hello").KeysOnly(), |
- "cannot project a keysOnly query", nil}, |
- |
- {"projecting a keys-only query (reverse)", |
- nq().KeysOnly().Project("hello"), |
- "cannot project a keysOnly query", nil}, |
- |
- {"projecting an empty field", |
- nq().Project("hello", ""), |
- "cannot project on an empty field", nil}, |
- |
- {"projecting __key__", |
- nq().Project("hello", "__key__"), |
- "cannot project on __key__", nil}, |
- |
- {"projecting a duplicate", |
- nq().Project("hello", "hello"), |
- "cannot project on the same field twice", nil}, |
- |
- {"projecting a duplicate (style 2)", |
- nq().Project("hello").Project("hello"), |
- "cannot project on the same field twice", nil}, |
- |
- {"bad ancestors", |
- nq().Ancestor(key("goop", nil)), |
- dsS.ErrInvalidKey, nil}, |
- |
- {"nil ancestors", |
- nq().Ancestor(nil), |
- "nil query ancestor", nil}, |
- |
- {"Bad key filters", |
- nq().Filter("__key__ >", key("goop", nil)), |
- dsS.ErrInvalidKey, nil}, |
- |
- {"filters for __key__ that aren't keys", |
- nq().Filter("__key__ >", 10), |
- "is not a key", nil}, |
- |
- {"multiple inequalities", |
- nq().Filter("bob > ", 19).Filter("charlie < ", 20), |
- "inequality filters on multiple properties", nil}, |
- |
- {"inequality must be first sort order", |
- nq().Filter("bob > ", 19).Order("-charlie"), |
- "first sort order", nil}, |
- |
- {"inequality must be first sort order (reverse)", |
- nq().Order("-charlie").Filter("bob > ", 19), |
- "first sort order", nil}, |
- |
- {"equality filter projected field", |
- nq().Project("foo").Filter("foo = ", 10), |
- "cannot project", nil}, |
- |
- {"equality filter projected field (reverse)", |
- nq().Filter("foo = ", 10).Project("foo"), |
- "cannot project", nil}, |
- |
- {"kindless with non-__key__ filters", |
- nq("").Filter("face <", 25.3), |
- "kindless queries can only filter on __key__", nil}, |
- |
- {"kindless with non-__key__ orders", |
- nq("").Order("face"), |
- "invalid order for kindless query", nil}, |
- |
- {"kindless with descending-__key__ order", |
- nq("").Order("-__key__"), |
- "invalid order for kindless query", nil}, |
- |
- {"bad namespace", |
- nq("something", "sup").Order("__key__"), |
- "Namespace mismatched", nil}, |
- |
- {"distinct non-projection", |
- nq().Distinct().Filter("marla >", 1), |
- "only makes sense on projection queries", nil}, |
- |
- {"chained errors return the first", |
- nq().Ancestor(nil).Filter("hello", "wurld").Order(""), |
- "nil query ancestor", nil}, |
- |
- {"bad ancestor namespace", |
- nq("", "nerd").Ancestor(key("something", "correct")), |
- "bad namespace", nil}, |
- |
- {"multiple ancestors", |
- nq().Ancestor(key("something", "correct")).Ancestor(key("something", "else")), |
- "more than one ancestor", nil}, |
- |
- {"filter with illegal type", |
- nq().Filter("something =", complex(1, 2)), |
- "bad type complex", nil}, |
- |
- {"sort orders used for equality are ignored", |
- nq().Order("a").Order("b").Order("c").Filter("b =", 2), |
- nil, |
- nq().Order("a").Order("c").Filter("b =", 2)}, |
- |
- {"sort orders used for equality are ignored (reversed)", |
- nq().Filter("b =", 2).Order("a").Order("b").Order("c"), |
- nil, |
- nq().Order("a").Order("c").Filter("b =", 2)}, |
- |
- {"duplicate orders are ignored", |
- nq().Order("a").Order("a").Order("a"), |
- nil, |
- nq().Order("a")}, |
- |
{"overconstrained inequality (>= v <)", |
nq().Filter("bob >=", 10).Filter("bob <", 10), |
"done", nil}, |
@@ -314,41 +88,16 @@ var queryTests = []queryTest{ |
"done", nil}, |
{"silly inequality (=> v <=)", |
- nq().Filter("bob >=", 10).Filter("bob <=", 10), |
- nil, |
- nil}, |
- |
- {"Filtering on a reserved property is forbidden", |
- nq().Filter("__special__ >=", 10), |
- "filter on reserved property", |
- nil}, |
- |
- {"oob key filters with ancestor (highside)", |
- nq().Ancestor(key("Hello", 10)).Filter("__key__ <", key("Hello", 9)), |
- "__key__ inequality", |
- nil}, |
- |
- {"oob key filters with ancestor (lowside)", |
- nq().Ancestor(key("Hello", 10)).Filter("__key__ >", key("Hello", 11)), |
- "__key__ inequality", |
- nil}, |
- |
- {"in-bound key filters with ancestor OK", |
- nq().Ancestor(key("Hello", 10)).Filter("__key__ <", key("Something", "hi", key("Hello", 10))), |
+ nq().Gte("bob", 10).Lte("bob", 10), |
nil, |
nil}, |
- {"projection elements get filled in", |
- nq().Project("Foo", "Bar").Order("-Bar"), |
- nil, |
- nq().Project("Foo", "Bar").Order("-Bar").Order("Foo")}, |
- |
{"cursors get smooshed into the inquality range", |
- (nq().Filter("Foo >", 3).Filter("Foo <", 10). |
- Start(curs("Foo", 2, "__key__", key("Something", 1))). |
- End(curs("Foo", 20, "__key__", key("Something", 20)))), |
+ (nq().Gt("Foo >", 3).Lt("Foo <", 10). |
+ Start(curs("Foo", 2, "__key__", mkKey("Something", 1))). |
+ End(curs("Foo", 20, "__key__", mkKey("Something", 20)))), |
nil, |
- nq().Filter("Foo >", 3).Filter("Foo <", 10)}, |
+ nq().Gt("Foo >", 3).Lt("Foo <", 10)}, |
{"cursors could cause the whole query to be useless", |
(nq().Filter("Foo >", 3).Filter("Foo <", 10). |
@@ -357,45 +106,6 @@ var queryTests = []queryTest{ |
errQueryDone, |
nil}, |
- {"query without anything is fine", |
- nq(), |
- nil, |
- nil}, |
-} |
- |
-func init() { |
- // this is supremely stupid. The SDK uses 'int' which measn we have to |
- // use it too, but then THEY BOUNDS CHECK IT FOR 32 BITS... *sigh* |
- if !IntIs32Bits { |
- queryTests = append(queryTests, []queryTest{ |
- {"OOB limit (32 bit)", |
- nq().Limit(MaxInt), |
- "query limit overflow", nil}, |
- |
- {"OOB offset (32 bit)", |
- nq().Offset(MaxInt), |
- "query offset overflow", nil}, |
- }...) |
- } |
-} |
- |
-func TestQueries(t *testing.T) { |
- t.Parallel() |
- |
- Convey("queries have tons of condition checking", t, func() { |
- for _, tc := range queryTests { |
- Convey(tc.name, func() { |
- rq, err := tc.q.(*queryImpl).reduce("ns", false) |
- So(err, ShouldErrLike, tc.err) |
- |
- if tc.equivalentQuery != nil { |
- rq2, err := tc.equivalentQuery.(*queryImpl).reduce("ns", false) |
- So(err, ShouldBeNil) |
- So(rq, ShouldResemble, rq2) |
- } |
- }) |
- } |
- |
Convey("non-ancestor queries in a transaction", func() { |
_, err := nq().(*queryImpl).reduce("ns", true) |
So(err, ShouldErrLike, "Only ancestor queries") |
@@ -410,5 +120,5 @@ func TestQueries(t *testing.T) { |
_, err := q.(*queryImpl).reduce("ns", false) |
So(err, ShouldErrLike, "query is too large") |
}) |
- }) |
-} |
+ |
+*/ |