OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package memory | 5 package memory |
6 | 6 |
7 import ( | 7 import ( |
8 "fmt" | 8 "fmt" |
9 "infra/gae/libs/meta" | 9 "infra/gae/libs/meta" |
10 "infra/gae/libs/wrapper" | 10 "infra/gae/libs/wrapper" |
| 11 "math" |
11 "testing" | 12 "testing" |
12 | 13 |
13 . "github.com/smartystreets/goconvey/convey" | 14 . "github.com/smartystreets/goconvey/convey" |
14 "golang.org/x/net/context" | 15 "golang.org/x/net/context" |
15 | 16 |
16 "appengine/datastore" | 17 "appengine/datastore" |
17 ) | 18 ) |
18 | 19 |
19 func TestDatastoreKinder(t *testing.T) { | 20 func TestDatastoreKinder(t *testing.T) { |
20 t.Parallel() | 21 t.Parallel() |
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 f := &Foo{ID: 1} | 516 f := &Foo{ID: 1} |
516 So(ds.Get(f), ShouldBeNil) | 517 So(ds.Get(f), ShouldBeNil) |
517 So(f.Val, ShouldEqual, 10) | 518 So(f.Val, ShouldEqual, 10) |
518 }) | 519 }) |
519 }) | 520 }) |
520 }) | 521 }) |
521 }) | 522 }) |
522 | 523 |
523 }) | 524 }) |
524 } | 525 } |
| 526 |
| 527 func TestDatastoreQueryer(t *testing.T) { |
| 528 Convey("Datastore Query suport", t, func() { |
| 529 c := Use(context.Background()) |
| 530 ds := wrapper.GetDS(c) |
| 531 So(ds, ShouldNotBeNil) |
| 532 |
| 533 Convey("can create good queries", func() { |
| 534 q := ds.NewQuery("Foo").KeysOnly().Limit(10).Offset(39) |
| 535 q = q.Start(queryCursor("kosmik")).End(queryCursor("krab
s")) |
| 536 So(q, ShouldNotBeNil) |
| 537 So(q.(*queryImpl).err, ShouldBeNil) |
| 538 qi := q.(*queryImpl).checkCorrectness("", false) |
| 539 So(qi.err, ShouldBeNil) |
| 540 }) |
| 541 |
| 542 Convey("normalize ensures orders make sense", func() { |
| 543 q := ds.NewQuery("Cool") |
| 544 q = q.Filter("cat =", 19).Filter("bob =", 10).Order("bob
").Order("bob") |
| 545 |
| 546 Convey("removes dups and equality orders", func() { |
| 547 q = q.Order("wat") |
| 548 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) |
| 549 So(qi.err, ShouldBeNil) |
| 550 So(qi.order, ShouldResemble, []queryOrder{{"wat"
, qASC}}) |
| 551 }) |
| 552 |
| 553 Convey("keeps inequality orders", func() { |
| 554 q = q.Order("wat") |
| 555 q := q.Filter("bob >", 10).Filter("wat <", 29) |
| 556 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) |
| 557 So(qi.order, ShouldResemble, []queryOrder{{"bob"
, qASC}, {"wat", qASC}}) |
| 558 So(qi.err.Error(), ShouldContainSubstring, "Only
one inequality") |
| 559 }) |
| 560 |
| 561 Convey("if we equality-filter on __key__, order is ditch
ed", func() { |
| 562 q = q.Order("wat") |
| 563 q := q.Filter("__key__ =", ds.NewKey("Foo", "wat
", 0, nil)) |
| 564 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) |
| 565 So(qi.order, ShouldResemble, []queryOrder(nil)) |
| 566 So(qi.err, ShouldBeNil) |
| 567 }) |
| 568 |
| 569 Convey("if we order by key and something else, key domin
ates", func() { |
| 570 q := q.Order("__key__").Order("wat") |
| 571 qi := q.(*queryImpl).normalize().checkCorrectnes
s("", false) |
| 572 So(qi.order, ShouldResemble, []queryOrder{{"__ke
y__", qASC}}) |
| 573 So(qi.err, ShouldBeNil) |
| 574 }) |
| 575 }) |
| 576 |
| 577 Convey("can create bad queries", func() { |
| 578 q := ds.NewQuery("Foo") |
| 579 |
| 580 Convey("bad filter ops", func() { |
| 581 q := q.Filter("Bob !", "value") |
| 582 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid operator \"!\"") |
| 583 }) |
| 584 Convey("bad filter", func() { |
| 585 q := q.Filter("Bob", "value") |
| 586 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid filter") |
| 587 }) |
| 588 Convey("bad order", func() { |
| 589 q := q.Order("+Bob") |
| 590 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid order") |
| 591 }) |
| 592 Convey("empty", func() { |
| 593 q := q.Order("") |
| 594 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "empty order") |
| 595 }) |
| 596 Convey("OOB limit", func() { |
| 597 q := q.Limit(math.MaxInt64) |
| 598 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "query limit overflow") |
| 599 }) |
| 600 Convey("underflow offset", func() { |
| 601 q := q.Offset(-29) |
| 602 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "negative query offset") |
| 603 }) |
| 604 Convey("OOB offset", func() { |
| 605 q := q.Offset(math.MaxInt64) |
| 606 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "query offset overflow") |
| 607 }) |
| 608 Convey("Bad cursors", func() { |
| 609 q := q.Start(queryCursor("")).End(queryCursor(""
)) |
| 610 So(q.(*queryImpl).err.Error(), ShouldContainSubs
tring, "invalid cursor") |
| 611 }) |
| 612 Convey("Bad ancestors", func() { |
| 613 q := q.Ancestor(ds.NewKey("Goop", "wat", 10, nil
)) |
| 614 So(q, ShouldNotBeNil) |
| 615 qi := q.(*queryImpl).checkCorrectness("", false) |
| 616 So(qi.err, ShouldEqual, datastore.ErrInvalidKey) |
| 617 }) |
| 618 Convey("nil ancestors", func() { |
| 619 qi := q.Ancestor(nil).(*queryImpl).checkCorrectn
ess("", false) |
| 620 So(qi.err.Error(), ShouldContainSubstring, "nil
query ancestor") |
| 621 }) |
| 622 Convey("Bad key filters", func() { |
| 623 q := q.Filter("__key__ =", ds.NewKey("Goop", "wa
t", 10, nil)) |
| 624 qi := q.(*queryImpl).checkCorrectness("", false) |
| 625 So(qi.err, ShouldEqual, datastore.ErrInvalidKey) |
| 626 }) |
| 627 Convey("non-ancestor queries in a transaction", func() { |
| 628 qi := q.(*queryImpl).checkCorrectness("", true) |
| 629 So(qi.err.Error(), ShouldContainSubstring, "Only
ancestor queries") |
| 630 }) |
| 631 Convey("absurd numbers of filters are prohibited", func(
) { |
| 632 q := q.Ancestor(ds.NewKey("thing", "wat", 0, nil
)) |
| 633 for i := 0; i < 100; i++ { |
| 634 q = q.Filter("something =", 10) |
| 635 } |
| 636 qi := q.(*queryImpl).checkCorrectness("", false) |
| 637 So(qi.err.Error(), ShouldContainSubstring, "quer
y is too large") |
| 638 }) |
| 639 Convey("filters for __key__ that aren't keys", func() { |
| 640 q := q.Filter("__key__ = ", 10) |
| 641 qi := q.(*queryImpl).checkCorrectness("", false) |
| 642 So(qi.err.Error(), ShouldContainSubstring, "must
be a Key") |
| 643 }) |
| 644 Convey("multiple inequalities", func() { |
| 645 q := q.Filter("bob > ", 19).Filter("charlie < ",
20) |
| 646 qi := q.(*queryImpl).checkCorrectness("", false) |
| 647 So(qi.err.Error(), ShouldContainSubstring, "one
inequality filter") |
| 648 }) |
| 649 Convey("bad sort orders", func() { |
| 650 q := q.Filter("bob > ", 19).Order("-charlie") |
| 651 qi := q.(*queryImpl).checkCorrectness("", false) |
| 652 So(qi.err.Error(), ShouldContainSubstring, "firs
t sort property") |
| 653 }) |
| 654 Convey("kindless with non-__key__ filters", func() { |
| 655 q := ds.NewQuery("").Filter("face <", 25.3) |
| 656 qi := q.(*queryImpl).checkCorrectness("", false) |
| 657 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for non-__key__") |
| 658 }) |
| 659 Convey("kindless with non-__key__ orders", func() { |
| 660 q := ds.NewQuery("").Order("face") |
| 661 qi := q.(*queryImpl).checkCorrectness("", false) |
| 662 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for all orders") |
| 663 }) |
| 664 Convey("kindless with decending-__key__ orders", func()
{ |
| 665 q := ds.NewQuery("").Order("-__key__") |
| 666 qi := q.(*queryImpl).checkCorrectness("", false) |
| 667 So(qi.err.Error(), ShouldContainSubstring, "kind
is required for all orders") |
| 668 }) |
| 669 }) |
| 670 |
| 671 }) |
| 672 } |
OLD | NEW |