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 serialize | 5 package serialize |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "fmt" | 9 "fmt" |
10 "io" | 10 "io" |
11 "testing" | 11 "testing" |
12 "time" | 12 "time" |
13 | 13 |
14 "github.com/luci/gae/service/blobstore" | 14 "github.com/luci/gae/service/blobstore" |
15 ds "github.com/luci/gae/service/datastore" | 15 ds "github.com/luci/gae/service/datastore" |
16 "github.com/luci/gae/service/datastore/dskey" | |
17 "github.com/luci/luci-go/common/cmpbin" | 16 "github.com/luci/luci-go/common/cmpbin" |
18 . "github.com/luci/luci-go/common/testing/assertions" | 17 . "github.com/luci/luci-go/common/testing/assertions" |
19 . "github.com/smartystreets/goconvey/convey" | 18 . "github.com/smartystreets/goconvey/convey" |
20 ) | 19 ) |
21 | 20 |
22 func init() { | 21 func init() { |
23 WritePropertyMapDeterministic = true | 22 WritePropertyMapDeterministic = true |
24 } | 23 } |
25 | 24 |
26 var ( | 25 var ( |
27 mp = ds.MkProperty | 26 mp = ds.MkProperty |
28 mpNI = ds.MkPropertyNI | 27 mpNI = ds.MkPropertyNI |
29 ) | 28 ) |
30 | 29 |
31 type dspmapTC struct { | 30 type dspmapTC struct { |
32 name string | 31 name string |
33 props ds.PropertyMap | 32 props ds.PropertyMap |
34 } | 33 } |
35 | 34 |
36 // TODO(riannucci): dedup with datastore/key testing file. | 35 var mkKey = ds.MakeKey |
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 | 36 |
56 func mkBuf(data []byte) Buffer { | 37 func mkBuf(data []byte) Buffer { |
57 return Invertible(bytes.NewBuffer(data)) | 38 return Invertible(bytes.NewBuffer(data)) |
58 } | 39 } |
59 | 40 |
60 // TODO(riannucci): dedup with datastore/key testing file | 41 // TODO(riannucci): dedup with datastore/key testing file |
61 func ShouldEqualKey(actual interface{}, expected ...interface{}) string { | 42 func ShouldEqualKey(actual interface{}, expected ...interface{}) string { |
62 if len(expected) != 1 { | 43 if len(expected) != 1 { |
63 return fmt.Sprintf("Assertion requires 1 expected value, got %d"
, len(expected)) | 44 return fmt.Sprintf("Assertion requires 1 expected value, got %d"
, len(expected)) |
64 } | 45 } |
65 » if dskey.Equal(actual.(ds.Key), expected[0].(ds.Key)) { | 46 » if actual.(*ds.Key).Equal(expected[0].(*ds.Key)) { |
66 return "" | 47 return "" |
67 } | 48 } |
68 return fmt.Sprintf("Expected: %q\nActual: %q", actual, expected[0]) | 49 return fmt.Sprintf("Expected: %q\nActual: %q", actual, expected[0]) |
69 } | 50 } |
70 | 51 |
71 func TestPropertyMapSerialization(t *testing.T) { | 52 func TestPropertyMapSerialization(t *testing.T) { |
72 t.Parallel() | 53 t.Parallel() |
73 | 54 |
74 tests := []dspmapTC{ | 55 tests := []dspmapTC{ |
75 { | 56 { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 data := ToBytesWithContext(tc.props) | 107 data := ToBytesWithContext(tc.props) |
127 dec, err := ReadPropertyMap(mkBuf(data),
WithContext, "", "") | 108 dec, err := ReadPropertyMap(mkBuf(data),
WithContext, "", "") |
128 So(err, ShouldBeNil) | 109 So(err, ShouldBeNil) |
129 So(dec, ShouldResemble, tc.props) | 110 So(dec, ShouldResemble, tc.props) |
130 }) | 111 }) |
131 } | 112 } |
132 }) | 113 }) |
133 }) | 114 }) |
134 } | 115 } |
135 | 116 |
| 117 func die(err error) { |
| 118 if err != nil { |
| 119 panic(err) |
| 120 } |
| 121 } |
| 122 |
| 123 func wf(w io.Writer, v float64) int { |
| 124 ret, err := cmpbin.WriteFloat64(w, v) |
| 125 die(err) |
| 126 return ret |
| 127 } |
| 128 |
| 129 func ws(w io.ByteWriter, s string) int { |
| 130 ret, err := cmpbin.WriteString(w, s) |
| 131 die(err) |
| 132 return ret |
| 133 } |
| 134 |
| 135 func wi(w io.ByteWriter, i int64) int { |
| 136 ret, err := cmpbin.WriteInt(w, i) |
| 137 die(err) |
| 138 return ret |
| 139 } |
| 140 |
| 141 func wui(w io.ByteWriter, i uint64) int { |
| 142 ret, err := cmpbin.WriteUint(w, i) |
| 143 die(err) |
| 144 return ret |
| 145 } |
| 146 |
136 func TestSerializationReadMisc(t *testing.T) { | 147 func TestSerializationReadMisc(t *testing.T) { |
137 t.Parallel() | 148 t.Parallel() |
138 | 149 |
139 Convey("Misc Serialization tests", t, func() { | 150 Convey("Misc Serialization tests", t, func() { |
140 Convey("GeoPoint", func() { | 151 Convey("GeoPoint", func() { |
141 buf := mkBuf(nil) | 152 buf := mkBuf(nil) |
142 » » » cmpbin.WriteFloat64(buf, 10) | 153 » » » wf(buf, 10) |
143 » » » cmpbin.WriteFloat64(buf, 20) | 154 » » » wf(buf, 20) |
144 So(string(ToBytes(ds.GeoPoint{Lat: 10, Lng: 20})), Shoul
dEqual, buf.String()) | 155 So(string(ToBytes(ds.GeoPoint{Lat: 10, Lng: 20})), Shoul
dEqual, buf.String()) |
145 }) | 156 }) |
146 | 157 |
147 Convey("IndexColumn", func() { | 158 Convey("IndexColumn", func() { |
148 buf := mkBuf(nil) | 159 buf := mkBuf(nil) |
149 » » » buf.WriteByte(1) | 160 » » » die(buf.WriteByte(1)) |
150 » » » cmpbin.WriteString(buf, "hi") | 161 » » » ws(buf, "hi") |
151 » » » So(string(ToBytes(ds.IndexColumn{Property: "hi", Directi
on: ds.DESCENDING})), | 162 » » » So(string(ToBytes(ds.IndexColumn{Property: "hi", Descend
ing: true})), |
152 ShouldEqual, buf.String()) | 163 ShouldEqual, buf.String()) |
153 }) | 164 }) |
154 | 165 |
155 Convey("KeyTok", func() { | 166 Convey("KeyTok", func() { |
156 buf := mkBuf(nil) | 167 buf := mkBuf(nil) |
157 » » » cmpbin.WriteString(buf, "foo") | 168 » » » ws(buf, "foo") |
158 » » » buf.WriteByte(byte(ds.PTInt)) | 169 » » » die(buf.WriteByte(byte(ds.PTInt))) |
159 » » » cmpbin.WriteInt(buf, 20) | 170 » » » wi(buf, 20) |
160 So(string(ToBytes(ds.KeyTok{Kind: "foo", IntID: 20})), | 171 So(string(ToBytes(ds.KeyTok{Kind: "foo", IntID: 20})), |
161 ShouldEqual, buf.String()) | 172 ShouldEqual, buf.String()) |
162 }) | 173 }) |
163 | 174 |
164 Convey("Property", func() { | 175 Convey("Property", func() { |
165 buf := mkBuf(nil) | 176 buf := mkBuf(nil) |
166 » » » buf.WriteByte(0x80 | byte(ds.PTString)) | 177 » » » die(buf.WriteByte(0x80 | byte(ds.PTString))) |
167 » » » cmpbin.WriteString(buf, "nerp") | 178 » » » ws(buf, "nerp") |
168 So(string(ToBytes(mp("nerp"))), | 179 So(string(ToBytes(mp("nerp"))), |
169 ShouldEqual, buf.String()) | 180 ShouldEqual, buf.String()) |
170 }) | 181 }) |
171 | 182 |
172 Convey("Time", func() { | 183 Convey("Time", func() { |
173 tp := mp(time.Now().UTC()) | 184 tp := mp(time.Now().UTC()) |
174 So(string(ToBytes(tp.Value())), ShouldEqual, string(ToBy
tes(tp)[1:])) | 185 So(string(ToBytes(tp.Value())), ShouldEqual, string(ToBy
tes(tp)[1:])) |
175 }) | 186 }) |
176 | 187 |
177 Convey("Zero time", func() { | 188 Convey("Zero time", func() { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 }) | 241 }) |
231 }) | 242 }) |
232 | 243 |
233 Convey("err cases", func() { | 244 Convey("err cases", func() { |
234 buf := mkBuf(nil) | 245 buf := mkBuf(nil) |
235 Convey("nil", func() { | 246 Convey("nil", func() { |
236 _, err := ReadKey(buf, WithContext, "",
"") | 247 _, err := ReadKey(buf, WithContext, "",
"") |
237 So(err, ShouldEqual, io.EOF) | 248 So(err, ShouldEqual, io.EOF) |
238 }) | 249 }) |
239 Convey("str", func() { | 250 Convey("str", func() { |
240 » » » » » buf.WriteString("sup") | 251 » » » » » _, err := buf.WriteString("sup") |
241 » » » » » _, err := ReadKey(buf, WithContext, "",
"") | 252 » » » » » die(err) |
| 253 » » » » » _, err = ReadKey(buf, WithContext, "", "
") |
242 So(err, ShouldErrLike, "expected actualC
tx") | 254 So(err, ShouldErrLike, "expected actualC
tx") |
243 }) | 255 }) |
244 Convey("truncated 1", func() { | 256 Convey("truncated 1", func() { |
245 » » » » » buf.WriteByte(1) // actualCtx == 1 | 257 » » » » » die(buf.WriteByte(1)) // actualCtx == 1 |
246 _, err := ReadKey(buf, WithContext, "",
"") | 258 _, err := ReadKey(buf, WithContext, "",
"") |
247 So(err, ShouldEqual, io.EOF) | 259 So(err, ShouldEqual, io.EOF) |
248 }) | 260 }) |
249 Convey("truncated 2", func() { | 261 Convey("truncated 2", func() { |
250 » » » » » buf.WriteByte(1) // actualCtx == 1 | 262 » » » » » die(buf.WriteByte(1)) // actualCtx == 1 |
251 » » » » » cmpbin.WriteString(buf, "aid") | 263 » » » » » ws(buf, "aid") |
252 _, err := ReadKey(buf, WithContext, "",
"") | 264 _, err := ReadKey(buf, WithContext, "",
"") |
253 So(err, ShouldEqual, io.EOF) | 265 So(err, ShouldEqual, io.EOF) |
254 }) | 266 }) |
255 Convey("truncated 3", func() { | 267 Convey("truncated 3", func() { |
256 » » » » » buf.WriteByte(1) // actualCtx == 1 | 268 » » » » » die(buf.WriteByte(1)) // actualCtx == 1 |
257 » » » » » cmpbin.WriteString(buf, "aid") | 269 » » » » » ws(buf, "aid") |
258 » » » » » cmpbin.WriteString(buf, "ns") | 270 » » » » » ws(buf, "ns") |
259 _, err := ReadKey(buf, WithContext, "",
"") | 271 _, err := ReadKey(buf, WithContext, "",
"") |
260 So(err, ShouldEqual, io.EOF) | 272 So(err, ShouldEqual, io.EOF) |
261 }) | 273 }) |
262 Convey("huge key", func() { | 274 Convey("huge key", func() { |
263 » » » » » buf.WriteByte(1) // actualCtx == 1 | 275 » » » » » die(buf.WriteByte(1)) // actualCtx == 1 |
264 » » » » » cmpbin.WriteString(buf, "aid") | 276 » » » » » ws(buf, "aid") |
265 » » » » » cmpbin.WriteString(buf, "ns") | 277 » » » » » ws(buf, "ns") |
266 for i := 1; i < 60; i++ { | 278 for i := 1; i < 60; i++ { |
267 » » » » » » buf.WriteByte(1) | 279 » » » » » » die(buf.WriteByte(1)) |
268 » » » » » » WriteKeyTok(buf, ds.KeyTok{Kind:
"sup", IntID: int64(i)}) | 280 » » » » » » die(WriteKeyTok(buf, ds.KeyTok{K
ind: "sup", IntID: int64(i)})) |
269 } | 281 } |
270 » » » » » buf.WriteByte(0) | 282 » » » » » die(buf.WriteByte(0)) |
271 _, err := ReadKey(buf, WithContext, "",
"") | 283 _, err := ReadKey(buf, WithContext, "",
"") |
272 So(err, ShouldErrLike, "huge key") | 284 So(err, ShouldErrLike, "huge key") |
273 }) | 285 }) |
274 Convey("insufficient tokens", func() { | 286 Convey("insufficient tokens", func() { |
275 » » » » » buf.WriteByte(1) // actualCtx == 1 | 287 » » » » » die(buf.WriteByte(1)) // actualCtx == 1 |
276 » » » » » cmpbin.WriteString(buf, "aid") | 288 » » » » » ws(buf, "aid") |
277 » » » » » cmpbin.WriteString(buf, "ns") | 289 » » » » » ws(buf, "ns") |
278 » » » » » cmpbin.WriteUint(buf, 2) | 290 » » » » » wui(buf, 2) |
279 _, err := ReadKey(buf, WithContext, "",
"") | 291 _, err := ReadKey(buf, WithContext, "",
"") |
280 So(err, ShouldEqual, io.EOF) | 292 So(err, ShouldEqual, io.EOF) |
281 }) | 293 }) |
282 Convey("partial token 1", func() { | 294 Convey("partial token 1", func() { |
283 » » » » » buf.WriteByte(1) // actualCtx == 1 | 295 » » » » » die(buf.WriteByte(1)) // actualCtx == 1 |
284 » » » » » cmpbin.WriteString(buf, "aid") | 296 » » » » » ws(buf, "aid") |
285 » » » » » cmpbin.WriteString(buf, "ns") | 297 » » » » » ws(buf, "ns") |
286 » » » » » buf.WriteByte(1) | 298 » » » » » die(buf.WriteByte(1)) |
287 » » » » » cmpbin.WriteString(buf, "hi") | 299 » » » » » ws(buf, "hi") |
288 _, err := ReadKey(buf, WithContext, "",
"") | 300 _, err := ReadKey(buf, WithContext, "",
"") |
289 So(err, ShouldEqual, io.EOF) | 301 So(err, ShouldEqual, io.EOF) |
290 }) | 302 }) |
291 Convey("partial token 2", func() { | 303 Convey("partial token 2", func() { |
292 » » » » » buf.WriteByte(1) // actualCtx == 1 | 304 » » » » » die(buf.WriteByte(1)) // actualCtx == 1 |
293 » » » » » cmpbin.WriteString(buf, "aid") | 305 » » » » » ws(buf, "aid") |
294 » » » » » cmpbin.WriteString(buf, "ns") | 306 » » » » » ws(buf, "ns") |
295 » » » » » buf.WriteByte(1) | 307 » » » » » die(buf.WriteByte(1)) |
296 » » » » » cmpbin.WriteString(buf, "hi") | 308 » » » » » ws(buf, "hi") |
297 » » » » » buf.WriteByte(byte(ds.PTString)) | 309 » » » » » die(buf.WriteByte(byte(ds.PTString))) |
298 _, err := ReadKey(buf, WithContext, "",
"") | 310 _, err := ReadKey(buf, WithContext, "",
"") |
299 So(err, ShouldEqual, io.EOF) | 311 So(err, ShouldEqual, io.EOF) |
300 }) | 312 }) |
301 Convey("bad token (invalid type)", func() { | 313 Convey("bad token (invalid type)", func() { |
302 » » » » » buf.WriteByte(1) // actualCtx == 1 | 314 » » » » » die(buf.WriteByte(1)) // actualCtx == 1 |
303 » » » » » cmpbin.WriteString(buf, "aid") | 315 » » » » » ws(buf, "aid") |
304 » » » » » cmpbin.WriteString(buf, "ns") | 316 » » » » » ws(buf, "ns") |
305 » » » » » buf.WriteByte(1) | 317 » » » » » die(buf.WriteByte(1)) |
306 » » » » » cmpbin.WriteString(buf, "hi") | 318 » » » » » ws(buf, "hi") |
307 » » » » » buf.WriteByte(byte(ds.PTBlobKey)) | 319 » » » » » die(buf.WriteByte(byte(ds.PTBlobKey))) |
308 _, err := ReadKey(buf, WithContext, "",
"") | 320 _, err := ReadKey(buf, WithContext, "",
"") |
309 So(err, ShouldErrLike, "invalid type PTB
lobKey") | 321 So(err, ShouldErrLike, "invalid type PTB
lobKey") |
310 }) | 322 }) |
311 Convey("bad token (invalid IntID)", func() { | 323 Convey("bad token (invalid IntID)", func() { |
312 » » » » » buf.WriteByte(1) // actualCtx == 1 | 324 » » » » » die(buf.WriteByte(1)) // actualCtx == 1 |
313 » » » » » cmpbin.WriteString(buf, "aid") | 325 » » » » » ws(buf, "aid") |
314 » » » » » cmpbin.WriteString(buf, "ns") | 326 » » » » » ws(buf, "ns") |
315 » » » » » buf.WriteByte(1) | 327 » » » » » die(buf.WriteByte(1)) |
316 » » » » » cmpbin.WriteString(buf, "hi") | 328 » » » » » ws(buf, "hi") |
317 » » » » » buf.WriteByte(byte(ds.PTInt)) | 329 » » » » » die(buf.WriteByte(byte(ds.PTInt))) |
318 » » » » » cmpbin.WriteInt(buf, -2) | 330 » » » » » wi(buf, -2) |
319 _, err := ReadKey(buf, WithContext, "",
"") | 331 _, err := ReadKey(buf, WithContext, "",
"") |
320 So(err, ShouldErrLike, "zero/negative") | 332 So(err, ShouldErrLike, "zero/negative") |
321 }) | 333 }) |
322 }) | 334 }) |
323 }) | 335 }) |
324 | 336 |
325 Convey("ReadGeoPoint", func() { | 337 Convey("ReadGeoPoint", func() { |
326 buf := mkBuf(nil) | 338 buf := mkBuf(nil) |
327 Convey("trunc 1", func() { | 339 Convey("trunc 1", func() { |
328 _, err := ReadGeoPoint(buf) | 340 _, err := ReadGeoPoint(buf) |
329 So(err, ShouldEqual, io.EOF) | 341 So(err, ShouldEqual, io.EOF) |
330 }) | 342 }) |
331 Convey("trunc 2", func() { | 343 Convey("trunc 2", func() { |
332 » » » » cmpbin.WriteFloat64(buf, 100) | 344 » » » » wf(buf, 100) |
333 _, err := ReadGeoPoint(buf) | 345 _, err := ReadGeoPoint(buf) |
334 So(err, ShouldEqual, io.EOF) | 346 So(err, ShouldEqual, io.EOF) |
335 }) | 347 }) |
336 Convey("invalid", func() { | 348 Convey("invalid", func() { |
337 » » » » cmpbin.WriteFloat64(buf, 100) | 349 » » » » wf(buf, 100) |
338 » » » » cmpbin.WriteFloat64(buf, 1000) | 350 » » » » wf(buf, 1000) |
339 _, err := ReadGeoPoint(buf) | 351 _, err := ReadGeoPoint(buf) |
340 So(err, ShouldErrLike, "invalid GeoPoint") | 352 So(err, ShouldErrLike, "invalid GeoPoint") |
341 }) | 353 }) |
342 }) | 354 }) |
343 | 355 |
344 Convey("WriteTime", func() { | 356 Convey("WriteTime", func() { |
345 Convey("in non-UTC!", func() { | 357 Convey("in non-UTC!", func() { |
346 pst, err := time.LoadLocation("America/Los_Angel
es") | 358 pst, err := time.LoadLocation("America/Los_Angel
es") |
347 So(err, ShouldBeNil) | 359 So(err, ShouldBeNil) |
348 So(func() { | 360 So(func() { |
349 » » » » » WriteTime(mkBuf(nil), time.Now().In(pst)
) | 361 » » » » » die(WriteTime(mkBuf(nil), time.Now().In(
pst))) |
350 }, ShouldPanic) | 362 }, ShouldPanic) |
351 }) | 363 }) |
352 }) | 364 }) |
353 | 365 |
354 Convey("ReadTime", func() { | 366 Convey("ReadTime", func() { |
355 Convey("trunc 1", func() { | 367 Convey("trunc 1", func() { |
356 _, err := ReadTime(mkBuf(nil)) | 368 _, err := ReadTime(mkBuf(nil)) |
357 So(err, ShouldEqual, io.EOF) | 369 So(err, ShouldEqual, io.EOF) |
358 }) | 370 }) |
359 }) | 371 }) |
360 | 372 |
361 Convey("ReadProperty", func() { | 373 Convey("ReadProperty", func() { |
362 buf := mkBuf(nil) | 374 buf := mkBuf(nil) |
363 Convey("trunc 1", func() { | 375 Convey("trunc 1", func() { |
364 p, err := ReadProperty(buf, WithContext, "", "") | 376 p, err := ReadProperty(buf, WithContext, "", "") |
365 So(err, ShouldEqual, io.EOF) | 377 So(err, ShouldEqual, io.EOF) |
366 So(p.Type(), ShouldEqual, ds.PTNull) | 378 So(p.Type(), ShouldEqual, ds.PTNull) |
367 So(p.Value(), ShouldBeNil) | 379 So(p.Value(), ShouldBeNil) |
368 }) | 380 }) |
369 Convey("trunc (PTBytes)", func() { | 381 Convey("trunc (PTBytes)", func() { |
370 » » » » buf.WriteByte(byte(ds.PTBytes)) | 382 » » » » die(buf.WriteByte(byte(ds.PTBytes))) |
371 _, err := ReadProperty(buf, WithContext, "", "") | 383 _, err := ReadProperty(buf, WithContext, "", "") |
372 So(err, ShouldEqual, io.EOF) | 384 So(err, ShouldEqual, io.EOF) |
373 }) | 385 }) |
374 Convey("trunc (PTBlobKey)", func() { | 386 Convey("trunc (PTBlobKey)", func() { |
375 » » » » buf.WriteByte(byte(ds.PTBlobKey)) | 387 » » » » die(buf.WriteByte(byte(ds.PTBlobKey))) |
376 _, err := ReadProperty(buf, WithContext, "", "") | 388 _, err := ReadProperty(buf, WithContext, "", "") |
377 So(err, ShouldEqual, io.EOF) | 389 So(err, ShouldEqual, io.EOF) |
378 }) | 390 }) |
379 Convey("invalid type", func() { | 391 Convey("invalid type", func() { |
380 » » » » buf.WriteByte(byte(ds.PTUnknown + 1)) | 392 » » » » die(buf.WriteByte(byte(ds.PTUnknown + 1))) |
381 _, err := ReadProperty(buf, WithContext, "", "") | 393 _, err := ReadProperty(buf, WithContext, "", "") |
382 So(err, ShouldErrLike, "unknown type!") | 394 So(err, ShouldErrLike, "unknown type!") |
383 }) | 395 }) |
384 }) | 396 }) |
385 | 397 |
386 Convey("ReadPropertyMap", func() { | 398 Convey("ReadPropertyMap", func() { |
387 buf := mkBuf(nil) | 399 buf := mkBuf(nil) |
388 Convey("trunc 1", func() { | 400 Convey("trunc 1", func() { |
389 _, err := ReadPropertyMap(buf, WithContext, "",
"") | 401 _, err := ReadPropertyMap(buf, WithContext, "",
"") |
390 So(err, ShouldEqual, io.EOF) | 402 So(err, ShouldEqual, io.EOF) |
391 }) | 403 }) |
392 Convey("too many rows", func() { | 404 Convey("too many rows", func() { |
393 » » » » cmpbin.WriteUint(buf, 1000000) | 405 » » » » wui(buf, 1000000) |
394 _, err := ReadPropertyMap(buf, WithContext, "",
"") | 406 _, err := ReadPropertyMap(buf, WithContext, "",
"") |
395 So(err, ShouldErrLike, "huge number of rows") | 407 So(err, ShouldErrLike, "huge number of rows") |
396 }) | 408 }) |
397 Convey("trunc 2", func() { | 409 Convey("trunc 2", func() { |
398 » » » » cmpbin.WriteUint(buf, 10) | 410 » » » » wui(buf, 10) |
399 _, err := ReadPropertyMap(buf, WithContext, "",
"") | 411 _, err := ReadPropertyMap(buf, WithContext, "",
"") |
400 So(err, ShouldEqual, io.EOF) | 412 So(err, ShouldEqual, io.EOF) |
401 }) | 413 }) |
402 Convey("trunc 3", func() { | 414 Convey("trunc 3", func() { |
403 » » » » cmpbin.WriteUint(buf, 10) | 415 » » » » wui(buf, 10) |
404 » » » » cmpbin.WriteString(buf, "ohai") | 416 » » » » ws(buf, "ohai") |
405 _, err := ReadPropertyMap(buf, WithContext, "",
"") | 417 _, err := ReadPropertyMap(buf, WithContext, "",
"") |
406 So(err, ShouldEqual, io.EOF) | 418 So(err, ShouldEqual, io.EOF) |
407 }) | 419 }) |
408 Convey("too many values", func() { | 420 Convey("too many values", func() { |
409 » » » » cmpbin.WriteUint(buf, 10) | 421 » » » » wui(buf, 10) |
410 » » » » cmpbin.WriteString(buf, "ohai") | 422 » » » » ws(buf, "ohai") |
411 » » » » cmpbin.WriteUint(buf, 100000) | 423 » » » » wui(buf, 100000) |
412 _, err := ReadPropertyMap(buf, WithContext, "",
"") | 424 _, err := ReadPropertyMap(buf, WithContext, "",
"") |
413 So(err, ShouldErrLike, "huge number of propertie
s") | 425 So(err, ShouldErrLike, "huge number of propertie
s") |
414 }) | 426 }) |
415 Convey("trunc 4", func() { | 427 Convey("trunc 4", func() { |
416 » » » » cmpbin.WriteUint(buf, 10) | 428 » » » » wui(buf, 10) |
417 » » » » cmpbin.WriteString(buf, "ohai") | 429 » » » » ws(buf, "ohai") |
418 » » » » cmpbin.WriteUint(buf, 10) | 430 » » » » wui(buf, 10) |
419 _, err := ReadPropertyMap(buf, WithContext, "",
"") | 431 _, err := ReadPropertyMap(buf, WithContext, "",
"") |
420 So(err, ShouldEqual, io.EOF) | 432 So(err, ShouldEqual, io.EOF) |
421 }) | 433 }) |
422 }) | 434 }) |
423 | 435 |
424 Convey("IndexDefinition", func() { | 436 Convey("IndexDefinition", func() { |
425 id := ds.IndexDefinition{Kind: "kind"} | 437 id := ds.IndexDefinition{Kind: "kind"} |
426 data := ToBytes(*id.PrepForIdxTable()) | 438 data := ToBytes(*id.PrepForIdxTable()) |
427 newID, err := ReadIndexDefinition(mkBuf(data)) | 439 newID, err := ReadIndexDefinition(mkBuf(data)) |
428 So(err, ShouldBeNil) | 440 So(err, ShouldBeNil) |
429 So(newID.Flip(), ShouldResemble, id.Normalize()) | 441 So(newID.Flip(), ShouldResemble, id.Normalize()) |
430 | 442 |
431 id.SortBy = append(id.SortBy, ds.IndexColumn{Property: "
prop"}) | 443 id.SortBy = append(id.SortBy, ds.IndexColumn{Property: "
prop"}) |
432 data = ToBytes(*id.PrepForIdxTable()) | 444 data = ToBytes(*id.PrepForIdxTable()) |
433 newID, err = ReadIndexDefinition(mkBuf(data)) | 445 newID, err = ReadIndexDefinition(mkBuf(data)) |
434 So(err, ShouldBeNil) | 446 So(err, ShouldBeNil) |
435 So(newID.Flip(), ShouldResemble, id.Normalize()) | 447 So(newID.Flip(), ShouldResemble, id.Normalize()) |
436 | 448 |
437 » » » id.SortBy = append(id.SortBy, ds.IndexColumn{Property: "
other", Direction: ds.DESCENDING}) | 449 » » » id.SortBy = append(id.SortBy, ds.IndexColumn{Property: "
other", Descending: true}) |
438 id.Ancestor = true | 450 id.Ancestor = true |
439 data = ToBytes(*id.PrepForIdxTable()) | 451 data = ToBytes(*id.PrepForIdxTable()) |
440 newID, err = ReadIndexDefinition(mkBuf(data)) | 452 newID, err = ReadIndexDefinition(mkBuf(data)) |
441 So(err, ShouldBeNil) | 453 So(err, ShouldBeNil) |
442 So(newID.Flip(), ShouldResemble, id.Normalize()) | 454 So(newID.Flip(), ShouldResemble, id.Normalize()) |
443 | 455 |
444 // invalid | 456 // invalid |
445 » » » id.SortBy = append(id.SortBy, ds.IndexColumn{Property: "
", Direction: ds.DESCENDING}) | 457 » » » id.SortBy = append(id.SortBy, ds.IndexColumn{Property: "
", Descending: true}) |
446 data = ToBytes(*id.PrepForIdxTable()) | 458 data = ToBytes(*id.PrepForIdxTable()) |
447 newID, err = ReadIndexDefinition(mkBuf(data)) | 459 newID, err = ReadIndexDefinition(mkBuf(data)) |
448 So(err, ShouldBeNil) | 460 So(err, ShouldBeNil) |
449 So(newID.Flip(), ShouldResemble, id.Normalize()) | 461 So(newID.Flip(), ShouldResemble, id.Normalize()) |
450 | 462 |
451 Convey("too many", func() { | 463 Convey("too many", func() { |
452 id := ds.IndexDefinition{Kind: "wat"} | 464 id := ds.IndexDefinition{Kind: "wat"} |
453 for i := 0; i < MaxIndexColumns+1; i++ { | 465 for i := 0; i < MaxIndexColumns+1; i++ { |
454 » » » » » id.SortBy = append(id.SortBy, ds.IndexCo
lumn{Property: "Hi", Direction: ds.ASCENDING}) | 466 » » » » » id.SortBy = append(id.SortBy, ds.IndexCo
lumn{Property: "Hi", Descending: true}) |
455 } | 467 } |
456 data := ToBytes(*id.PrepForIdxTable()) | 468 data := ToBytes(*id.PrepForIdxTable()) |
457 newID, err = ReadIndexDefinition(mkBuf(data)) | 469 newID, err = ReadIndexDefinition(mkBuf(data)) |
458 So(err, ShouldErrLike, "over 64 sort orders") | 470 So(err, ShouldErrLike, "over 64 sort orders") |
459 }) | 471 }) |
460 }) | 472 }) |
461 }) | 473 }) |
462 } | 474 } |
OLD | NEW |