1// Copyright 2019 The Go Cloud Development Kit Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package docstore 16 17import ( 18 "context" 19 "strings" 20 "testing" 21 22 "gocloud.dev/docstore/driver" 23 "gocloud.dev/gcerrors" 24) 25 26func TestQueryValidFilter(t *testing.T) { 27 for _, fp := range []FieldPath{"", ".a", "a..b", "b."} { 28 q := Query{dq: &driver.Query{}} 29 q.Where(fp, ">", 1) 30 if got := gcerrors.Code(q.err); got != gcerrors.InvalidArgument { 31 t.Errorf("fieldpath %q: got %s, want InvalidArgument", fp, got) 32 } 33 } 34 for _, op := range []string{"==", "!="} { 35 q := Query{dq: &driver.Query{}} 36 q.Where("a", op, 1) 37 if got := gcerrors.Code(q.err); got != gcerrors.InvalidArgument { 38 t.Errorf("op %s: got %s, want InvalidArgument", op, got) 39 } 40 } 41 for _, v := range []interface{}{nil, 5 + 2i, []byte("x"), func() {}, []int{}, map[string]bool{}} { 42 q := Query{dq: &driver.Query{}} 43 q.Where("a", "=", v) 44 if got := gcerrors.Code(q.err); got != gcerrors.InvalidArgument { 45 t.Errorf("value %+v: got %s, want InvalidArgument", v, got) 46 } 47 } 48} 49 50func TestInvalidQuery(t *testing.T) { 51 ctx := context.Background() 52 // We detect that these queries are invalid before they reach the driver. 53 c := &Collection{} 54 55 for _, test := range []struct { 56 desc string 57 appliesToGet bool 58 q *Query 59 contains string // error text must contain this string 60 }{ 61 {"negative Limit", true, c.Query().Limit(-1), "limit"}, 62 {"zero Limit", true, c.Query().Limit(0), "limit"}, 63 {"two Limits", true, c.Query().Limit(1).Limit(2), "limit"}, 64 {"empty OrderBy field", true, c.Query().OrderBy("", Ascending), "empty field"}, 65 {"bad OrderBy direction", true, c.Query().OrderBy("x", "y"), "direction"}, 66 {"two OrderBys", true, c.Query().OrderBy("x", Ascending).OrderBy("y", Descending), "orderby"}, 67 {"OrderBy not in Where", true, c.Query().OrderBy("x", Ascending).Where("y", ">", 1), "orderby"}, 68 {"any Limit", false, c.Query().Limit(1), "limit"}, 69 {"any OrderBy", false, c.Query().OrderBy("x", Descending), "orderby"}, 70 } { 71 check := func(err error) { 72 if gcerrors.Code(err) != gcerrors.InvalidArgument { 73 t.Errorf("%s: got %v, want InvalidArgument", test.desc, err) 74 return 75 } 76 if !strings.Contains(strings.ToLower(err.Error()), test.contains) { 77 t.Errorf("%s: got %q, wanted it to contain %q", test.desc, err.Error(), test.contains) 78 } 79 } 80 if test.appliesToGet { 81 check(test.q.Get(ctx).Next(ctx, nil)) 82 } 83 } 84} 85