| 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 // adapted from github.com/golang/appengine/datastore | 5 // adapted from github.com/golang/appengine/datastore |
| 6 | 6 |
| 7 package datastore | 7 package datastore |
| 8 | 8 |
| 9 import ( | 9 import ( |
| 10 "fmt" | 10 "fmt" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 ns string | 31 ns string |
| 32 } | 32 } |
| 33 | 33 |
| 34 func (f *fakeDatastore) mkKey(elems ...interface{}) *Key { | 34 func (f *fakeDatastore) mkKey(elems ...interface{}) *Key { |
| 35 return MakeKey(f.aid, f.ns, elems...) | 35 return MakeKey(f.aid, f.ns, elems...) |
| 36 } | 36 } |
| 37 | 37 |
| 38 func (f *fakeDatastore) Run(fq *FinalizedQuery, cb RawRunCB) error { | 38 func (f *fakeDatastore) Run(fq *FinalizedQuery, cb RawRunCB) error { |
| 39 lim, _ := fq.Limit() | 39 lim, _ := fq.Limit() |
| 40 | 40 |
| 41 cursCB := func() (Cursor, error) { |
| 42 return fakeCursor("CURSOR"), nil |
| 43 } |
| 44 |
| 41 for i := int32(0); i < lim; i++ { | 45 for i := int32(0); i < lim; i++ { |
| 42 if v, ok := fq.eqFilts["$err_single"]; ok { | 46 if v, ok := fq.eqFilts["$err_single"]; ok { |
| 43 idx := fq.eqFilts["$err_single_idx"][0].Value().(int64) | 47 idx := fq.eqFilts["$err_single_idx"][0].Value().(int64) |
| 44 if idx == int64(i) { | 48 if idx == int64(i) { |
| 45 return errors.New(v[0].Value().(string)) | 49 return errors.New(v[0].Value().(string)) |
| 46 } | 50 } |
| 47 } | 51 } |
| 48 k := f.mkKey("Kind", i+1) | 52 k := f.mkKey("Kind", i+1) |
| 49 if i == 10 { | 53 if i == 10 { |
| 50 k = f.mkKey("Kind", "eleven") | 54 k = f.mkKey("Kind", "eleven") |
| 51 } | 55 } |
| 52 pm := PropertyMap{"Value": {MkProperty(i)}} | 56 pm := PropertyMap{"Value": {MkProperty(i)}} |
| 53 » » if !cb(k, pm, nil) { | 57 » » if err := cb(k, pm, cursCB); err != nil { |
| 54 » » » break | 58 » » » if err == Stop { |
| 59 » » » » err = nil |
| 60 » » » } |
| 61 » » » return err |
| 55 } | 62 } |
| 56 } | 63 } |
| 57 return nil | 64 return nil |
| 58 } | 65 } |
| 59 | 66 |
| 60 func (f *fakeDatastore) PutMulti(keys []*Key, vals []PropertyMap, cb PutMultiCB)
error { | 67 func (f *fakeDatastore) PutMulti(keys []*Key, vals []PropertyMap, cb PutMultiCB)
error { |
| 61 if keys[0].Kind() == "FailAll" { | 68 if keys[0].Kind() == "FailAll" { |
| 62 return errors.New("PutMulti fail all") | 69 return errors.New("PutMulti fail all") |
| 63 } | 70 } |
| 64 _, assertExtra := vals[0].GetMeta("assertExtra") | 71 _, assertExtra := vals[0].GetMeta("assertExtra") |
| (...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 Convey("ok", func() { | 651 Convey("ok", func() { |
| 645 Convey("Get", func() { | 652 Convey("Get", func() { |
| 646 cs := &CommonStruct{ID: 1} | 653 cs := &CommonStruct{ID: 1} |
| 647 So(ds.Get(cs), ShouldBeNil) | 654 So(ds.Get(cs), ShouldBeNil) |
| 648 So(cs.Value, ShouldEqual, 1) | 655 So(cs.Value, ShouldEqual, 1) |
| 649 }) | 656 }) |
| 650 | 657 |
| 651 Convey("Raw access too", func() { | 658 Convey("Raw access too", func() { |
| 652 rds := ds.Raw() | 659 rds := ds.Raw() |
| 653 keys := []*Key{ds.MakeKey("Kind", 1)} | 660 keys := []*Key{ds.MakeKey("Kind", 1)} |
| 654 » » » » So(rds.GetMulti(keys, nil, func(pm PropertyMap,
err error) { | 661 » » » » So(rds.GetMulti(keys, nil, func(pm PropertyMap,
err error) error { |
| 655 So(err, ShouldBeNil) | 662 So(err, ShouldBeNil) |
| 656 So(pm["Value"][0].Value(), ShouldEqual,
1) | 663 So(pm["Value"][0].Value(), ShouldEqual,
1) |
| 664 return nil |
| 657 }), ShouldBeNil) | 665 }), ShouldBeNil) |
| 658 }) | 666 }) |
| 659 | 667 |
| 660 Convey("but general failure to save is fine on a Get", f
unc() { | 668 Convey("but general failure to save is fine on a Get", f
unc() { |
| 661 cs := &FakePLS{failSave: true, IntID: 7} | 669 cs := &FakePLS{failSave: true, IntID: 7} |
| 662 So(ds.Get(cs), ShouldBeNil) | 670 So(ds.Get(cs), ShouldBeNil) |
| 663 }) | 671 }) |
| 664 }) | 672 }) |
| 665 | 673 |
| 666 }) | 674 }) |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 Convey("bad", func() { | 801 Convey("bad", func() { |
| 794 assertBadTypePanics := func(cb interface{}) { | 802 assertBadTypePanics := func(cb interface{}) { |
| 795 So(func() { ds.Run(q, cb) }, ShouldPanicLike, | 803 So(func() { ds.Run(q, cb) }, ShouldPanicLike, |
| 796 "cb does not match the required callback
signature") | 804 "cb does not match the required callback
signature") |
| 797 } | 805 } |
| 798 | 806 |
| 799 Convey("not a function", func() { | 807 Convey("not a function", func() { |
| 800 assertBadTypePanics("I am a potato") | 808 assertBadTypePanics("I am a potato") |
| 801 }) | 809 }) |
| 802 | 810 |
| 811 Convey("nil", func() { |
| 812 assertBadTypePanics(nil) |
| 813 }) |
| 814 |
| 815 Convey("interface", func() { |
| 816 assertBadTypePanics(func(pls PropertyLoadSaver)
{}) |
| 817 }) |
| 818 |
| 803 Convey("bad proto type", func() { | 819 Convey("bad proto type", func() { |
| 804 » » » » cb := func(v int, _ CursorCB) bool { | 820 » » » » cb := func(v int) { |
| 805 panic("never here!") | 821 panic("never here!") |
| 806 } | 822 } |
| 807 So(func() { ds.Run(q, cb) }, ShouldPanicLike, | 823 So(func() { ds.Run(q, cb) }, ShouldPanicLike, |
| 808 "invalid argument type: int") | 824 "invalid argument type: int") |
| 809 }) | 825 }) |
| 810 | 826 |
| 811 Convey("wrong # args", func() { | 827 Convey("wrong # args", func() { |
| 812 » » » » assertBadTypePanics(func(v CommonStruct, _ Curso
rCB) { | 828 » » » » assertBadTypePanics(func(v CommonStruct, _ Curso
rCB, _ int) { |
| 813 panic("never here!") | 829 panic("never here!") |
| 814 }) | 830 }) |
| 815 }) | 831 }) |
| 816 | 832 |
| 817 Convey("wrong ret type", func() { | 833 Convey("wrong ret type", func() { |
| 818 » » » » assertBadTypePanics(func(v CommonStruct, _ Curso
rCB) error { | 834 » » » » assertBadTypePanics(func(v CommonStruct) bool { |
| 835 » » » » » panic("never here!") |
| 836 » » » » }) |
| 837 » » » }) |
| 838 |
| 839 » » » Convey("wrong # rets", func() { |
| 840 » » » » assertBadTypePanics(func(v CommonStruct) (int, e
rror) { |
| 819 panic("never here!") | 841 panic("never here!") |
| 820 }) | 842 }) |
| 821 }) | 843 }) |
| 822 | 844 |
| 823 Convey("bad 2nd arg", func() { | 845 Convey("bad 2nd arg", func() { |
| 824 » » » » assertBadTypePanics(func(v CommonStruct, _ Curso
r) bool { | 846 » » » » assertBadTypePanics(func(v CommonStruct, _ Curso
r) error { |
| 825 panic("never here!") | 847 panic("never here!") |
| 826 }) | 848 }) |
| 827 }) | 849 }) |
| 828 | 850 |
| 829 Convey("early abort on error", func() { | 851 Convey("early abort on error", func() { |
| 830 q = q.Eq("$err_single", "Query fail").Eq("$err_s
ingle_idx", 3) | 852 q = q.Eq("$err_single", "Query fail").Eq("$err_s
ingle_idx", 3) |
| 831 i := 0 | 853 i := 0 |
| 832 » » » » So(ds.Run(q, func(c CommonStruct, _ CursorCB) bo
ol { | 854 » » » » So(ds.Run(q, func(c CommonStruct) { |
| 833 i++ | 855 i++ |
| 834 return true | |
| 835 }), ShouldErrLike, "Query fail") | 856 }), ShouldErrLike, "Query fail") |
| 836 So(i, ShouldEqual, 3) | 857 So(i, ShouldEqual, 3) |
| 837 }) | 858 }) |
| 838 | 859 |
| 839 Convey("return error on serialization failure", func() { | 860 Convey("return error on serialization failure", func() { |
| 840 » » » » So(ds.Run(q, func(_ permaBad, _ CursorCB) bool { | 861 » » » » So(ds.Run(q, func(_ permaBad) { |
| 841 panic("never here") | 862 panic("never here") |
| 842 }).Error(), ShouldEqual, "permaBad") | 863 }).Error(), ShouldEqual, "permaBad") |
| 843 }) | 864 }) |
| 844 }) | 865 }) |
| 845 | 866 |
| 846 Convey("ok", func() { | 867 Convey("ok", func() { |
| 868 Convey("can return error to stop", func() { |
| 869 i := 0 |
| 870 So(ds.Run(q, func(c CommonStruct) error { |
| 871 i++ |
| 872 return Stop |
| 873 }), ShouldBeNil) |
| 874 So(i, ShouldEqual, 1) |
| 875 |
| 876 i = 0 |
| 877 So(ds.Run(q, func(c CommonStruct, _ CursorCB) er
ror { |
| 878 i++ |
| 879 return fmt.Errorf("my error") |
| 880 }), ShouldErrLike, "my error") |
| 881 So(i, ShouldEqual, 1) |
| 882 }) |
| 883 |
| 884 Convey("Can optionally get cursor function", func() { |
| 885 i := 0 |
| 886 So(ds.Run(q, func(c CommonStruct, ccb CursorCB)
{ |
| 887 i++ |
| 888 curs, err := ccb() |
| 889 So(err, ShouldBeNil) |
| 890 So(curs.String(), ShouldEqual, "CURSOR") |
| 891 }), ShouldBeNil) |
| 892 So(i, ShouldEqual, 5) |
| 893 }) |
| 894 |
| 847 Convey("*S", func() { | 895 Convey("*S", func() { |
| 848 i := 0 | 896 i := 0 |
| 849 » » » » So(ds.Run(q, func(cs *CommonStruct, _ CursorCB)
bool { | 897 » » » » So(ds.Run(q, func(cs *CommonStruct) { |
| 850 So(cs.ID, ShouldEqual, i+1) | 898 So(cs.ID, ShouldEqual, i+1) |
| 851 So(cs.Value, ShouldEqual, i) | 899 So(cs.Value, ShouldEqual, i) |
| 852 i++ | 900 i++ |
| 853 return true | |
| 854 }), ShouldBeNil) | 901 }), ShouldBeNil) |
| 855 }) | 902 }) |
| 856 | 903 |
| 857 Convey("*P", func() { | 904 Convey("*P", func() { |
| 858 i := 0 | 905 i := 0 |
| 859 » » » » So(ds.Run(q.Limit(12), func(fpls *FakePLS, _ Cur
sorCB) bool { | 906 » » » » So(ds.Run(q.Limit(12), func(fpls *FakePLS) { |
| 860 So(fpls.gotLoaded, ShouldBeTrue) | 907 So(fpls.gotLoaded, ShouldBeTrue) |
| 861 if i == 10 { | 908 if i == 10 { |
| 862 So(fpls.StringID, ShouldEqual, "
eleven") | 909 So(fpls.StringID, ShouldEqual, "
eleven") |
| 863 } else { | 910 } else { |
| 864 So(fpls.IntID, ShouldEqual, i+1) | 911 So(fpls.IntID, ShouldEqual, i+1) |
| 865 } | 912 } |
| 866 So(fpls.Value, ShouldEqual, i) | 913 So(fpls.Value, ShouldEqual, i) |
| 867 i++ | 914 i++ |
| 868 return true | |
| 869 }), ShouldBeNil) | 915 }), ShouldBeNil) |
| 870 }) | 916 }) |
| 871 | 917 |
| 872 Convey("*P (map)", func() { | 918 Convey("*P (map)", func() { |
| 873 i := 0 | 919 i := 0 |
| 874 » » » » So(ds.Run(q, func(pm *PropertyMap, _ CursorCB) b
ool { | 920 » » » » So(ds.Run(q, func(pm *PropertyMap) { |
| 875 k, ok := pm.GetMeta("key") | 921 k, ok := pm.GetMeta("key") |
| 876 So(ok, ShouldBeTrue) | 922 So(ok, ShouldBeTrue) |
| 877 So(k.(*Key).IntID(), ShouldEqual, i+1) | 923 So(k.(*Key).IntID(), ShouldEqual, i+1) |
| 878 So((*pm)["Value"][0].Value(), ShouldEqua
l, i) | 924 So((*pm)["Value"][0].Value(), ShouldEqua
l, i) |
| 879 i++ | 925 i++ |
| 880 return true | |
| 881 }), ShouldBeNil) | 926 }), ShouldBeNil) |
| 882 }) | 927 }) |
| 883 | 928 |
| 884 Convey("S", func() { | 929 Convey("S", func() { |
| 885 i := 0 | 930 i := 0 |
| 886 » » » » So(ds.Run(q, func(cs CommonStruct, _ CursorCB) b
ool { | 931 » » » » So(ds.Run(q, func(cs CommonStruct) { |
| 887 So(cs.ID, ShouldEqual, i+1) | 932 So(cs.ID, ShouldEqual, i+1) |
| 888 So(cs.Value, ShouldEqual, i) | 933 So(cs.Value, ShouldEqual, i) |
| 889 i++ | 934 i++ |
| 890 return true | |
| 891 }), ShouldBeNil) | 935 }), ShouldBeNil) |
| 892 }) | 936 }) |
| 893 | 937 |
| 894 Convey("P", func() { | 938 Convey("P", func() { |
| 895 i := 0 | 939 i := 0 |
| 896 » » » » So(ds.Run(q, func(fpls FakePLS, _ CursorCB) bool
{ | 940 » » » » So(ds.Run(q, func(fpls FakePLS) { |
| 897 So(fpls.gotLoaded, ShouldBeTrue) | 941 So(fpls.gotLoaded, ShouldBeTrue) |
| 898 So(fpls.IntID, ShouldEqual, i+1) | 942 So(fpls.IntID, ShouldEqual, i+1) |
| 899 So(fpls.Value, ShouldEqual, i) | 943 So(fpls.Value, ShouldEqual, i) |
| 900 i++ | 944 i++ |
| 901 return true | |
| 902 }), ShouldBeNil) | 945 }), ShouldBeNil) |
| 903 }) | 946 }) |
| 904 | 947 |
| 905 Convey("P (map)", func() { | 948 Convey("P (map)", func() { |
| 906 i := 0 | 949 i := 0 |
| 907 » » » » So(ds.Run(q, func(pm PropertyMap, _ CursorCB) bo
ol { | 950 » » » » So(ds.Run(q, func(pm PropertyMap) { |
| 908 k, ok := pm.GetMeta("key") | 951 k, ok := pm.GetMeta("key") |
| 909 So(ok, ShouldBeTrue) | 952 So(ok, ShouldBeTrue) |
| 910 So(k.(*Key).IntID(), ShouldEqual, i+1) | 953 So(k.(*Key).IntID(), ShouldEqual, i+1) |
| 911 So(pm["Value"][0].Value(), ShouldEqual,
i) | 954 So(pm["Value"][0].Value(), ShouldEqual,
i) |
| 912 i++ | 955 i++ |
| 913 return true | |
| 914 }), ShouldBeNil) | 956 }), ShouldBeNil) |
| 915 }) | 957 }) |
| 916 | 958 |
| 917 Convey("Key", func() { | 959 Convey("Key", func() { |
| 918 i := 0 | 960 i := 0 |
| 919 » » » » So(ds.Run(q, func(k *Key, _ CursorCB) bool { | 961 » » » » So(ds.Run(q, func(k *Key) { |
| 920 So(k.IntID(), ShouldEqual, i+1) | 962 So(k.IntID(), ShouldEqual, i+1) |
| 921 i++ | 963 i++ |
| 922 return true | |
| 923 }), ShouldBeNil) | 964 }), ShouldBeNil) |
| 924 }) | 965 }) |
| 925 | 966 |
| 926 }) | 967 }) |
| 927 }) | 968 }) |
| 928 } | 969 } |
| 929 | 970 |
| 930 type fixedDataDatastore struct { | 971 type fixedDataDatastore struct { |
| 931 RawInterface | 972 RawInterface |
| 932 | 973 |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1212 Convey("extra field with bad type", func() { | 1253 Convey("extra field with bad type", func() { |
| 1213 type Bad struct { | 1254 type Bad struct { |
| 1214 A int64 `gae:",extra"` | 1255 A int64 `gae:",extra"` |
| 1215 } | 1256 } |
| 1216 So(func() { GetPLS(&Bad{}) }, ShouldPanicLike, | 1257 So(func() { GetPLS(&Bad{}) }, ShouldPanicLike, |
| 1217 "struct 'extra' field has invalid type i
nt64") | 1258 "struct 'extra' field has invalid type i
nt64") |
| 1218 }) | 1259 }) |
| 1219 }) | 1260 }) |
| 1220 }) | 1261 }) |
| 1221 } | 1262 } |
| OLD | NEW |