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

Side by Side Diff: service/datastore/serialize/serialize_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 unified diff | Download patch
« no previous file with comments | « service/datastore/serialize/serialize.go ('k') | service/datastore/serialize_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 datastore 5 package serialize
6 6
7 import ( 7 import (
8 "bytes" 8 "bytes"
9 "fmt"
9 "io" 10 "io"
10 "testing" 11 "testing"
11 "time" 12 "time"
12 13
13 "github.com/luci/gae/service/blobstore" 14 "github.com/luci/gae/service/blobstore"
15 ds "github.com/luci/gae/service/datastore"
16 "github.com/luci/gae/service/datastore/dskey"
14 "github.com/luci/luci-go/common/cmpbin" 17 "github.com/luci/luci-go/common/cmpbin"
18 . "github.com/luci/luci-go/common/testing/assertions"
15 . "github.com/smartystreets/goconvey/convey" 19 . "github.com/smartystreets/goconvey/convey"
16 ) 20 )
17 21
18 func init() { 22 func init() {
19 WritePropertyMapDeterministic = true 23 WritePropertyMapDeterministic = true
20 } 24 }
21 25
26 var (
27 mp = ds.MkProperty
28 mpNI = ds.MkPropertyNI
29 )
30
22 type dspmapTC struct { 31 type dspmapTC struct {
23 name string 32 name string
24 » props PropertyMap 33 » props ds.PropertyMap
34 }
35
36 // TODO(riannucci): dedup with datastore/key testing file.
37 func mkKey(aid, ns string, elems ...interface{}) ds.Key {
38 » if len(elems)%2 != 0 {
39 » » panic("odd number of tokens")
40 » }
41 » toks := make([]ds.KeyTok, len(elems)/2)
42 » for i := 0; i < len(elems); i += 2 {
43 » » toks[i/2].Kind = elems[i].(string)
44 » » switch x := elems[i+1].(type) {
45 » » case string:
46 » » » toks[i/2].StringID = x
47 » » case int:
48 » » » toks[i/2].IntID = int64(x)
49 » » default:
50 » » » panic("bad token id")
51 » » }
52 » }
53 » return dskey.NewToks(aid, ns, toks)
54 }
55
56 func mkBuf(data []byte) Buffer {
57 » return Invertible(bytes.NewBuffer(data))
58 }
59
60 // TODO(riannucci): dedup with datastore/key testing file
61 func ShouldEqualKey(actual interface{}, expected ...interface{}) string {
62 » if len(expected) != 1 {
63 » » return fmt.Sprintf("Assertion requires 1 expected value, got %d" , len(expected))
64 » }
65 » if dskey.Equal(actual.(ds.Key), expected[0].(ds.Key)) {
66 » » return ""
67 » }
68 » return fmt.Sprintf("Expected: %q\nActual: %q", actual, expected[0])
25 } 69 }
26 70
27 func TestPropertyMapSerialization(t *testing.T) { 71 func TestPropertyMapSerialization(t *testing.T) {
28 t.Parallel() 72 t.Parallel()
29 73
30 tests := []dspmapTC{ 74 tests := []dspmapTC{
31 { 75 {
32 "basic", 76 "basic",
33 » » » PropertyMap{ 77 » » » ds.PropertyMap{
34 "R": {mp(false), mp(2.1), mpNI(3)}, 78 "R": {mp(false), mp(2.1), mpNI(3)},
35 "S": {mp("hello"), mp("world")}, 79 "S": {mp("hello"), mp("world")},
36 }, 80 },
37 }, 81 },
38 { 82 {
39 "keys", 83 "keys",
40 » » » PropertyMap{ 84 » » » ds.PropertyMap{
41 "DS": {mp(mkKey("appy", "ns", "Foo", 7)), mp(mkKey("other", "", "Yot", "wheeep"))}, 85 "DS": {mp(mkKey("appy", "ns", "Foo", 7)), mp(mkKey("other", "", "Yot", "wheeep"))},
42 "blobstore": {mp(blobstore.Key("sup")), mp(blobs tore.Key("nerds"))}, 86 "blobstore": {mp(blobstore.Key("sup")), mp(blobs tore.Key("nerds"))},
43 }, 87 },
44 }, 88 },
45 { 89 {
46 "geo", 90 "geo",
47 » » » PropertyMap{ 91 » » » ds.PropertyMap{
48 » » » » "G": {mp(GeoPoint{Lat: 1, Lng: 2})}, 92 » » » » "G": {mp(ds.GeoPoint{Lat: 1, Lng: 2})},
49 }, 93 },
50 }, 94 },
51 { 95 {
52 "data", 96 "data",
53 » » » PropertyMap{ 97 » » » ds.PropertyMap{
54 "S": {mp("sup"), mp("fool"), mp("nerd") }, 98 "S": {mp("sup"), mp("fool"), mp("nerd") },
55 "D.Foo.Nerd": {mp([]byte("sup")), mp([]byte("foo l"))}, 99 "D.Foo.Nerd": {mp([]byte("sup")), mp([]byte("foo l"))},
56 » » » » "B": {mp(ByteString("sup")), mp(ByteStr ing("fool"))}, 100 » » » » "B": {mp(ds.ByteString("sup")), mp(ds.B yteString("fool"))},
57 }, 101 },
58 }, 102 },
59 { 103 {
60 "time", 104 "time",
61 » » » PropertyMap{ 105 » » » ds.PropertyMap{
62 "T": { 106 "T": {
63 mp(time.Now().UTC()), 107 mp(time.Now().UTC()),
64 mp(time.Now().Add(time.Second).UTC())}, 108 mp(time.Now().Add(time.Second).UTC())},
65 }, 109 },
66 }, 110 },
67 { 111 {
68 "empty vals", 112 "empty vals",
69 » » » PropertyMap{ 113 » » » ds.PropertyMap{
70 "T": {mp(true), mp(true)}, 114 "T": {mp(true), mp(true)},
71 "F": {mp(false), mp(false)}, 115 "F": {mp(false), mp(false)},
72 "N": {mp(nil), mp(nil)}, 116 "N": {mp(nil), mp(nil)},
73 "E": {}, 117 "E": {},
74 }, 118 },
75 }, 119 },
76 } 120 }
77 121
78 Convey("PropertyMap serialization", t, func() { 122 Convey("PropertyMap serialization", t, func() {
79 Convey("round trip", func() { 123 Convey("round trip", func() {
80 for _, tc := range tests { 124 for _, tc := range tests {
81 tc := tc 125 tc := tc
82 Convey(tc.name, func() { 126 Convey(tc.name, func() {
83 » » » » » buf := &bytes.Buffer{} 127 » » » » » data := ToBytesWithContext(tc.props)
84 » » » » » tc.props.Write(buf, WithContext) 128 » » » » » dec, err := ReadPropertyMap(mkBuf(data), WithContext, "", "")
85 » » » » » dec := PropertyMap{}
86 » » » » » err := dec.Read(buf, WithContext, "", "" )
87 So(err, ShouldBeNil) 129 So(err, ShouldBeNil)
88 So(dec, ShouldResemble, tc.props) 130 So(dec, ShouldResemble, tc.props)
89 }) 131 })
90 } 132 }
91 }) 133 })
92 }) 134 })
93 } 135 }
94 136
95 func TestSerializationReadMisc(t *testing.T) { 137 func TestSerializationReadMisc(t *testing.T) {
96 t.Parallel() 138 t.Parallel()
97 139
98 Convey("Misc Serialization tests", t, func() { 140 Convey("Misc Serialization tests", t, func() {
99 » » buf := &bytes.Buffer{} 141 » » Convey("GeoPoint", func() {
142 » » » buf := mkBuf(nil)
143 » » » cmpbin.WriteFloat64(buf, 10)
144 » » » cmpbin.WriteFloat64(buf, 20)
145 » » » So(string(ToBytes(ds.GeoPoint{Lat: 10, Lng: 20})), Shoul dEqual, buf.String())
146 » » })
147
148 » » Convey("IndexColumn", func() {
149 » » » buf := mkBuf(nil)
150 » » » buf.WriteByte(1)
151 » » » cmpbin.WriteString(buf, "hi")
152 » » » So(string(ToBytes(ds.IndexColumn{Property: "hi", Directi on: ds.DESCENDING})),
153 » » » » ShouldEqual, buf.String())
154 » » })
155
156 » » Convey("KeyTok", func() {
157 » » » buf := mkBuf(nil)
158 » » » cmpbin.WriteString(buf, "foo")
159 » » » buf.WriteByte(byte(ds.PTInt))
160 » » » cmpbin.WriteInt(buf, 20)
161 » » » So(string(ToBytes(ds.KeyTok{Kind: "foo", IntID: 20})),
162 » » » » ShouldEqual, buf.String())
163 » » })
164
165 » » Convey("Property", func() {
166 » » » buf := mkBuf(nil)
167 » » » buf.WriteByte(byte(ds.PTString))
168 » » » cmpbin.WriteString(buf, "nerp")
169 » » » So(string(ToBytes(mp("nerp"))),
170 » » » » ShouldEqual, buf.String())
171 » » })
172
173 » » Convey("Time", func() {
174 » » » tp := mp(time.Now().UTC())
175 » » » So(string(ToBytes(tp.Value())), ShouldEqual, string(ToBy tes(tp)[1:]))
176 » » })
177
178 » » Convey("Bad ToBytes", func() {
179 » » » So(func() { ToBytes(100.7) }, ShouldPanic)
180 » » » So(func() { ToBytesWithContext(100.7) }, ShouldPanic)
181 » » })
182
100 Convey("ReadKey", func() { 183 Convey("ReadKey", func() {
101 Convey("good cases", func() { 184 Convey("good cases", func() {
102 Convey("w/ ctx decodes normally w/ ctx", func() { 185 Convey("w/ ctx decodes normally w/ ctx", func() {
103 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10) 186 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10)
104 » » » » » WriteKey(buf, WithContext, k) 187 » » » » » data := ToBytesWithContext(k)
105 » » » » » dk, err := ReadKey(buf, WithContext, "", "") 188 » » » » » dk, err := ReadKey(mkBuf(data), WithCont ext, "", "")
106 So(err, ShouldBeNil) 189 So(err, ShouldBeNil)
107 So(dk, ShouldEqualKey, k) 190 So(dk, ShouldEqualKey, k)
108 }) 191 })
109 Convey("w/ ctx decodes normally w/o ctx", func() { 192 Convey("w/ ctx decodes normally w/o ctx", func() {
110 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10) 193 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10)
111 » » » » » WriteKey(buf, WithContext, k) 194 » » » » » data := ToBytesWithContext(k)
112 » » » » » dk, err := ReadKey(buf, WithoutContext, "spam", "nerd") 195 » » » » » dk, err := ReadKey(mkBuf(data), WithoutC ontext, "spam", "nerd")
113 So(err, ShouldBeNil) 196 So(err, ShouldBeNil)
114 So(dk, ShouldEqualKey, mkKey("spam", "ne rd", "knd", "yo", "other", 10)) 197 So(dk, ShouldEqualKey, mkKey("spam", "ne rd", "knd", "yo", "other", 10))
115 }) 198 })
116 Convey("w/o ctx decodes normally w/ ctx", func() { 199 Convey("w/o ctx decodes normally w/ ctx", func() {
117 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10) 200 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10)
118 » » » » » WriteKey(buf, WithoutContext, k) 201 » » » » » data := ToBytes(k)
119 » » » » » dk, err := ReadKey(buf, WithContext, "sp am", "nerd") 202 » » » » » dk, err := ReadKey(mkBuf(data), WithCont ext, "spam", "nerd")
120 So(err, ShouldBeNil) 203 So(err, ShouldBeNil)
121 So(dk, ShouldEqualKey, mkKey("", "", "kn d", "yo", "other", 10)) 204 So(dk, ShouldEqualKey, mkKey("", "", "kn d", "yo", "other", 10))
122 }) 205 })
123 Convey("w/o ctx decodes normally w/o ctx", func( ) { 206 Convey("w/o ctx decodes normally w/o ctx", func( ) {
124 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10) 207 k := mkKey("aid", "ns", "knd", "yo", "ot her", 10)
125 » » » » » WriteKey(buf, WithoutContext, k) 208 » » » » » data := ToBytes(k)
126 » » » » » dk, err := ReadKey(buf, WithoutContext, "spam", "nerd") 209 » » » » » dk, err := ReadKey(mkBuf(data), WithoutC ontext, "spam", "nerd")
127 So(err, ShouldBeNil) 210 So(err, ShouldBeNil)
128 So(dk, ShouldEqualKey, mkKey("spam", "ne rd", "knd", "yo", "other", 10)) 211 So(dk, ShouldEqualKey, mkKey("spam", "ne rd", "knd", "yo", "other", 10))
129 }) 212 })
130 Convey("IntIDs always sort before StringIDs", fu nc() { 213 Convey("IntIDs always sort before StringIDs", fu nc() {
131 // -1 writes as almost all 1's in the fi rst byte under cmpbin, even 214 // -1 writes as almost all 1's in the fi rst byte under cmpbin, even
132 // though it's technically not a valid k ey. 215 // though it's technically not a valid k ey.
133 k := mkKey("aid", "ns", "knd", -1) 216 k := mkKey("aid", "ns", "knd", -1)
134 » » » » » WriteKey(buf, WithoutContext, k) 217 » » » » » data := ToBytes(k)
135 218
136 k = mkKey("aid", "ns", "knd", "hat") 219 k = mkKey("aid", "ns", "knd", "hat")
137 » » » » » buf2 := &bytes.Buffer{} 220 » » » » » data2 := ToBytes(k)
138 » » » » » WriteKey(buf2, WithoutContext, k)
139 221
140 » » » » » So(bytes.Compare(buf.Bytes(), buf2.Bytes ()), ShouldBeLessThan, 0) 222 » » » » » So(string(data), ShouldBeLessThan, strin g(data2))
141 }) 223 })
142 }) 224 })
143 225
144 Convey("err cases", func() { 226 Convey("err cases", func() {
227 buf := mkBuf(nil)
145 Convey("nil", func() { 228 Convey("nil", func() {
146 _, err := ReadKey(buf, WithContext, "", "") 229 _, err := ReadKey(buf, WithContext, "", "")
147 So(err, ShouldEqual, io.EOF) 230 So(err, ShouldEqual, io.EOF)
148 }) 231 })
149 Convey("str", func() { 232 Convey("str", func() {
150 buf.WriteString("sup") 233 buf.WriteString("sup")
151 _, err := ReadKey(buf, WithContext, "", "") 234 _, err := ReadKey(buf, WithContext, "", "")
152 So(err, ShouldErrLike, "expected actualC tx") 235 So(err, ShouldErrLike, "expected actualC tx")
153 }) 236 })
154 Convey("truncated 1", func() { 237 Convey("truncated 1", func() {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 cmpbin.WriteString(buf, "hi") 276 cmpbin.WriteString(buf, "hi")
194 _, err := ReadKey(buf, WithContext, "", "") 277 _, err := ReadKey(buf, WithContext, "", "")
195 So(err, ShouldEqual, io.EOF) 278 So(err, ShouldEqual, io.EOF)
196 }) 279 })
197 Convey("partial token 2", func() { 280 Convey("partial token 2", func() {
198 buf.WriteByte(1) // actualCtx == 1 281 buf.WriteByte(1) // actualCtx == 1
199 cmpbin.WriteString(buf, "aid") 282 cmpbin.WriteString(buf, "aid")
200 cmpbin.WriteString(buf, "ns") 283 cmpbin.WriteString(buf, "ns")
201 cmpbin.WriteUint(buf, 2) 284 cmpbin.WriteUint(buf, 2)
202 cmpbin.WriteString(buf, "hi") 285 cmpbin.WriteString(buf, "hi")
203 » » » » » buf.WriteByte(byte(PTString)) 286 » » » » » buf.WriteByte(byte(ds.PTString))
204 _, err := ReadKey(buf, WithContext, "", "") 287 _, err := ReadKey(buf, WithContext, "", "")
205 So(err, ShouldEqual, io.EOF) 288 So(err, ShouldEqual, io.EOF)
206 }) 289 })
207 Convey("bad token (invalid type)", func() { 290 Convey("bad token (invalid type)", func() {
208 buf.WriteByte(1) // actualCtx == 1 291 buf.WriteByte(1) // actualCtx == 1
209 cmpbin.WriteString(buf, "aid") 292 cmpbin.WriteString(buf, "aid")
210 cmpbin.WriteString(buf, "ns") 293 cmpbin.WriteString(buf, "ns")
211 cmpbin.WriteUint(buf, 2) 294 cmpbin.WriteUint(buf, 2)
212 cmpbin.WriteString(buf, "hi") 295 cmpbin.WriteString(buf, "hi")
213 » » » » » buf.WriteByte(byte(PTBlobKey)) 296 » » » » » buf.WriteByte(byte(ds.PTBlobKey))
214 _, err := ReadKey(buf, WithContext, "", "") 297 _, err := ReadKey(buf, WithContext, "", "")
215 So(err, ShouldErrLike, "invalid type PTB lobKey") 298 So(err, ShouldErrLike, "invalid type PTB lobKey")
216 }) 299 })
217 Convey("bad token (invalid IntID)", func() { 300 Convey("bad token (invalid IntID)", func() {
218 buf.WriteByte(1) // actualCtx == 1 301 buf.WriteByte(1) // actualCtx == 1
219 cmpbin.WriteString(buf, "aid") 302 cmpbin.WriteString(buf, "aid")
220 cmpbin.WriteString(buf, "ns") 303 cmpbin.WriteString(buf, "ns")
221 cmpbin.WriteUint(buf, 2) 304 cmpbin.WriteUint(buf, 2)
222 cmpbin.WriteString(buf, "hi") 305 cmpbin.WriteString(buf, "hi")
223 » » » » » buf.WriteByte(byte(PTInt)) 306 » » » » » buf.WriteByte(byte(ds.PTInt))
224 cmpbin.WriteInt(buf, -2) 307 cmpbin.WriteInt(buf, -2)
225 _, err := ReadKey(buf, WithContext, "", "") 308 _, err := ReadKey(buf, WithContext, "", "")
226 So(err, ShouldErrLike, "zero/negative") 309 So(err, ShouldErrLike, "zero/negative")
227 }) 310 })
228 }) 311 })
229 }) 312 })
230 313
231 Convey("ReadGeoPoint", func() { 314 Convey("ReadGeoPoint", func() {
232 » » » gp := GeoPoint{} 315 » » » buf := mkBuf(nil)
233 Convey("trunc 1", func() { 316 Convey("trunc 1", func() {
234 » » » » err := gp.Read(buf) 317 » » » » _, err := ReadGeoPoint(buf)
235 So(err, ShouldEqual, io.EOF) 318 So(err, ShouldEqual, io.EOF)
236 }) 319 })
237 Convey("trunc 2", func() { 320 Convey("trunc 2", func() {
238 cmpbin.WriteFloat64(buf, 100) 321 cmpbin.WriteFloat64(buf, 100)
239 » » » » err := gp.Read(buf) 322 » » » » _, err := ReadGeoPoint(buf)
240 So(err, ShouldEqual, io.EOF) 323 So(err, ShouldEqual, io.EOF)
241 }) 324 })
242 Convey("invalid", func() { 325 Convey("invalid", func() {
243 cmpbin.WriteFloat64(buf, 100) 326 cmpbin.WriteFloat64(buf, 100)
244 cmpbin.WriteFloat64(buf, 1000) 327 cmpbin.WriteFloat64(buf, 1000)
245 » » » » err := gp.Read(buf) 328 » » » » _, err := ReadGeoPoint(buf)
246 So(err, ShouldErrLike, "invalid GeoPoint") 329 So(err, ShouldErrLike, "invalid GeoPoint")
247 }) 330 })
248 }) 331 })
249 332
250 Convey("WriteTime", func() { 333 Convey("WriteTime", func() {
251 Convey("in non-UTC!", func() { 334 Convey("in non-UTC!", func() {
252 pst, err := time.LoadLocation("America/Los_Angel es") 335 pst, err := time.LoadLocation("America/Los_Angel es")
253 So(err, ShouldBeNil) 336 So(err, ShouldBeNil)
254 So(func() { 337 So(func() {
255 » » » » » WriteTime(buf, time.Now().In(pst)) 338 » » » » » WriteTime(mkBuf(nil), time.Now().In(pst) )
256 }, ShouldPanic) 339 }, ShouldPanic)
257 }) 340 })
258 }) 341 })
259 342
260 Convey("ReadTime", func() { 343 Convey("ReadTime", func() {
261 Convey("trunc 1", func() { 344 Convey("trunc 1", func() {
262 » » » » _, err := ReadTime(buf) 345 » » » » _, err := ReadTime(mkBuf(nil))
263 So(err, ShouldEqual, io.EOF) 346 So(err, ShouldEqual, io.EOF)
264 }) 347 })
265 }) 348 })
266 349
267 Convey("ReadProperty", func() { 350 Convey("ReadProperty", func() {
268 » » » p := Property{} 351 » » » buf := mkBuf(nil)
269 Convey("trunc 1", func() { 352 Convey("trunc 1", func() {
270 » » » » err := p.Read(buf, WithContext, "", "") 353 » » » » p, err := ReadProperty(buf, WithContext, "", "")
271 So(err, ShouldEqual, io.EOF) 354 So(err, ShouldEqual, io.EOF)
272 » » » » So(p.Type(), ShouldEqual, PTNull) 355 » » » » So(p.Type(), ShouldEqual, ds.PTNull)
273 So(p.Value(), ShouldBeNil) 356 So(p.Value(), ShouldBeNil)
274 }) 357 })
275 Convey("trunc (PTBytes)", func() { 358 Convey("trunc (PTBytes)", func() {
276 » » » » buf.WriteByte(byte(PTBytes)) 359 » » » » buf.WriteByte(byte(ds.PTBytes))
277 » » » » err := p.Read(buf, WithContext, "", "") 360 » » » » _, err := ReadProperty(buf, WithContext, "", "")
278 So(err, ShouldEqual, io.EOF) 361 So(err, ShouldEqual, io.EOF)
279 }) 362 })
280 Convey("trunc (PTBlobKey)", func() { 363 Convey("trunc (PTBlobKey)", func() {
281 » » » » buf.WriteByte(byte(PTBlobKey)) 364 » » » » buf.WriteByte(byte(ds.PTBlobKey))
282 » » » » err := p.Read(buf, WithContext, "", "") 365 » » » » _, err := ReadProperty(buf, WithContext, "", "")
283 So(err, ShouldEqual, io.EOF) 366 So(err, ShouldEqual, io.EOF)
284 }) 367 })
285 Convey("invalid type", func() { 368 Convey("invalid type", func() {
286 » » » » buf.WriteByte(byte(PTUnknown + 1)) 369 » » » » buf.WriteByte(byte(ds.PTUnknown + 1))
287 » » » » err := p.Read(buf, WithContext, "", "") 370 » » » » _, err := ReadProperty(buf, WithContext, "", "")
288 So(err, ShouldErrLike, "unknown type!") 371 So(err, ShouldErrLike, "unknown type!")
289 }) 372 })
290 }) 373 })
291 374
292 Convey("ReadPropertyMap", func() { 375 Convey("ReadPropertyMap", func() {
293 » » » pm := PropertyMap{} 376 » » » buf := mkBuf(nil)
294 Convey("trunc 1", func() { 377 Convey("trunc 1", func() {
295 » » » » err := pm.Read(buf, WithContext, "", "") 378 » » » » _, err := ReadPropertyMap(buf, WithContext, "", "")
296 So(err, ShouldEqual, io.EOF) 379 So(err, ShouldEqual, io.EOF)
297 }) 380 })
298 Convey("too many rows", func() { 381 Convey("too many rows", func() {
299 cmpbin.WriteUint(buf, 1000000) 382 cmpbin.WriteUint(buf, 1000000)
300 » » » » err := pm.Read(buf, WithContext, "", "") 383 » » » » _, err := ReadPropertyMap(buf, WithContext, "", "")
301 So(err, ShouldErrLike, "huge number of rows") 384 So(err, ShouldErrLike, "huge number of rows")
302 }) 385 })
303 Convey("trunc 2", func() { 386 Convey("trunc 2", func() {
304 cmpbin.WriteUint(buf, 10) 387 cmpbin.WriteUint(buf, 10)
305 » » » » err := pm.Read(buf, WithContext, "", "") 388 » » » » _, err := ReadPropertyMap(buf, WithContext, "", "")
306 So(err, ShouldEqual, io.EOF) 389 So(err, ShouldEqual, io.EOF)
307 }) 390 })
308 Convey("trunc 3", func() { 391 Convey("trunc 3", func() {
309 cmpbin.WriteUint(buf, 10) 392 cmpbin.WriteUint(buf, 10)
310 cmpbin.WriteString(buf, "ohai") 393 cmpbin.WriteString(buf, "ohai")
311 » » » » err := pm.Read(buf, WithContext, "", "") 394 » » » » _, err := ReadPropertyMap(buf, WithContext, "", "")
312 So(err, ShouldEqual, io.EOF) 395 So(err, ShouldEqual, io.EOF)
313 }) 396 })
314 Convey("too many values", func() { 397 Convey("too many values", func() {
315 cmpbin.WriteUint(buf, 10) 398 cmpbin.WriteUint(buf, 10)
316 cmpbin.WriteString(buf, "ohai") 399 cmpbin.WriteString(buf, "ohai")
317 cmpbin.WriteUint(buf, 100000) 400 cmpbin.WriteUint(buf, 100000)
318 » » » » err := pm.Read(buf, WithContext, "", "") 401 » » » » _, err := ReadPropertyMap(buf, WithContext, "", "")
319 So(err, ShouldErrLike, "huge number of propertie s") 402 So(err, ShouldErrLike, "huge number of propertie s")
320 }) 403 })
321 Convey("trunc 4", func() { 404 Convey("trunc 4", func() {
322 cmpbin.WriteUint(buf, 10) 405 cmpbin.WriteUint(buf, 10)
323 cmpbin.WriteString(buf, "ohai") 406 cmpbin.WriteString(buf, "ohai")
324 cmpbin.WriteUint(buf, 10) 407 cmpbin.WriteUint(buf, 10)
325 » » » » err := pm.Read(buf, WithContext, "", "") 408 » » » » _, err := ReadPropertyMap(buf, WithContext, "", "")
326 So(err, ShouldEqual, io.EOF) 409 So(err, ShouldEqual, io.EOF)
327 }) 410 })
328 }) 411 })
412
413 Convey("IndexDefinition", func() {
414 id := ds.IndexDefinition{Kind: "kind"}
415 data := ToBytes(id)
416 So(string(data), ShouldStartWith, string(ds.IndexBuiltin QueryPrefix()))
417 newID, err := ReadIndexDefinition(mkBuf(data))
418 So(err, ShouldBeNil)
419 So(newID, ShouldResemble, id)
420
421 id.SortBy = append(id.SortBy, ds.IndexColumn{Property: " prop"})
422 data = ToBytes(id)
423 So(string(data), ShouldStartWith, string(ds.IndexBuiltin QueryPrefix()))
424 newID, err = ReadIndexDefinition(mkBuf(data))
425 So(err, ShouldBeNil)
426 So(newID, ShouldResemble, id)
427
428 id.SortBy = append(id.SortBy, ds.IndexColumn{Property: " other", Direction: ds.DESCENDING})
429 id.Ancestor = true
430 data = ToBytes(id)
431 So(string(data), ShouldStartWith, string(ds.IndexComplex QueryPrefix()))
432 newID, err = ReadIndexDefinition(mkBuf(data))
433 So(err, ShouldBeNil)
434 So(newID, ShouldResemble, id)
435
436 // invalid
437 id.SortBy = append(id.SortBy, ds.IndexColumn{Property: " ", Direction: ds.DESCENDING})
438 data = ToBytes(id)
439 So(string(data), ShouldStartWith, string(ds.IndexComplex QueryPrefix()))
440 newID, err = ReadIndexDefinition(mkBuf(data))
441 So(err, ShouldBeNil)
442 So(newID, ShouldResemble, id)
443
444 Convey("too many", func() {
445 id := ds.IndexDefinition{Kind: "wat"}
446 for i := 0; i < MaxIndexColumns+1; i++ {
447 id.SortBy = append(id.SortBy, ds.IndexCo lumn{Property: "Hi", Direction: ds.ASCENDING})
448 }
449 data := ToBytes(id)
450 newID, err = ReadIndexDefinition(mkBuf(data))
451 So(err, ShouldErrLike, "over 64 sort orders")
452 })
453 })
329 }) 454 })
330 } 455 }
OLDNEW
« no previous file with comments | « service/datastore/serialize/serialize.go ('k') | service/datastore/serialize_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698