OLD | NEW |
1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
3 // that can be found in the LICENSE file. | 3 // that can be 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 "bytes" | 10 "bytes" |
11 "fmt" | 11 "fmt" |
12 "io/ioutil" | 12 "io/ioutil" |
13 "os" | 13 "os" |
14 "path/filepath" | 14 "path/filepath" |
15 "runtime" | 15 "runtime" |
16 "testing" | 16 "testing" |
17 | 17 |
18 "github.com/luci/gae/service/info" | 18 "github.com/luci/gae/service/info" |
19 "github.com/luci/luci-go/common/errors" | 19 "github.com/luci/luci-go/common/errors" |
| 20 |
| 21 "golang.org/x/net/context" |
| 22 |
20 . "github.com/luci/luci-go/common/testing/assertions" | 23 . "github.com/luci/luci-go/common/testing/assertions" |
21 . "github.com/smartystreets/goconvey/convey" | 24 . "github.com/smartystreets/goconvey/convey" |
22 "golang.org/x/net/context" | |
23 ) | 25 ) |
24 | 26 |
25 func fakeDatastoreFactory(c context.Context, wantTxn bool) RawInterface { | 27 func fakeDatastoreFactory(c context.Context) RawInterface { |
26 » i := info.Get(c) | 28 » return &fakeDatastore{Context: c} |
27 » fds := fakeDatastore{ | |
28 » » aid: i.FullyQualifiedAppID(), | |
29 » } | |
30 » fds.ns, _ = i.GetNamespace() | |
31 » return &fds | |
32 } | 29 } |
33 | 30 |
34 var ( | 31 var ( |
35 errFail = errors.New("Individual element fail") | 32 errFail = errors.New("Individual element fail") |
36 errFailAll = errors.New("Operation fail") | 33 errFailAll = errors.New("Operation fail") |
37 ) | 34 ) |
38 | 35 |
39 type fakeDatastore struct { | 36 type fakeDatastore struct { |
| 37 context.Context |
40 RawInterface | 38 RawInterface |
41 aid string | |
42 ns string | |
43 } | |
44 | |
45 func (f *fakeDatastore) mkKey(elems ...interface{}) *Key { | |
46 return MakeKey(f.aid, f.ns, elems...) | |
47 } | |
48 | |
49 func (f *fakeDatastore) newKey(kind, stringID string, intID int64, parent *Key)
*Key { | |
50 return NewKey(f.aid, f.ns, kind, stringID, intID, parent) | |
51 } | 39 } |
52 | 40 |
53 func (f *fakeDatastore) AllocateIDs(keys []*Key, cb NewKeyCB) error { | 41 func (f *fakeDatastore) AllocateIDs(keys []*Key, cb NewKeyCB) error { |
54 if keys[0].Kind() == "FailAll" { | 42 if keys[0].Kind() == "FailAll" { |
55 return errFailAll | 43 return errFailAll |
56 } | 44 } |
57 for i, k := range keys { | 45 for i, k := range keys { |
58 if k.Kind() == "Fail" { | 46 if k.Kind() == "Fail" { |
59 cb(nil, errFail) | 47 cb(nil, errFail) |
60 } else { | 48 } else { |
61 » » » cb(f.newKey(k.Kind(), "", int64(i+1), k.Parent()), nil) | 49 » » » cb(NewKey(f, k.Kind(), "", int64(i+1), k.Parent()), nil) |
62 } | 50 } |
63 } | 51 } |
64 return nil | 52 return nil |
65 } | 53 } |
66 | 54 |
67 func (f *fakeDatastore) Run(fq *FinalizedQuery, cb RawRunCB) error { | 55 func (f *fakeDatastore) Run(fq *FinalizedQuery, cb RawRunCB) error { |
68 lim, _ := fq.Limit() | 56 lim, _ := fq.Limit() |
69 | 57 |
70 cursCB := func() (Cursor, error) { | 58 cursCB := func() (Cursor, error) { |
71 return fakeCursor("CURSOR"), nil | 59 return fakeCursor("CURSOR"), nil |
72 } | 60 } |
73 | 61 |
74 for i := int32(0); i < lim; i++ { | 62 for i := int32(0); i < lim; i++ { |
75 if v, ok := fq.eqFilts["$err_single"]; ok { | 63 if v, ok := fq.eqFilts["$err_single"]; ok { |
76 idx := fq.eqFilts["$err_single_idx"][0].Value().(int64) | 64 idx := fq.eqFilts["$err_single_idx"][0].Value().(int64) |
77 if idx == int64(i) { | 65 if idx == int64(i) { |
78 return errors.New(v[0].Value().(string)) | 66 return errors.New(v[0].Value().(string)) |
79 } | 67 } |
80 } | 68 } |
81 » » k := f.mkKey("Kind", i+1) | 69 » » k := MakeKey(f, "Kind", i+1) |
82 if i == 10 { | 70 if i == 10 { |
83 » » » k = f.mkKey("Kind", "eleven") | 71 » » » k = MakeKey(f, "Kind", "eleven") |
84 } | 72 } |
85 pm := PropertyMap{"Value": {MkProperty(i)}} | 73 pm := PropertyMap{"Value": {MkProperty(i)}} |
86 if err := cb(k, pm, cursCB); err != nil { | 74 if err := cb(k, pm, cursCB); err != nil { |
87 if err == Stop { | 75 if err == Stop { |
88 err = nil | 76 err = nil |
89 } | 77 } |
90 return err | 78 return err |
91 } | 79 } |
92 } | 80 } |
93 return nil | 81 return nil |
94 } | 82 } |
95 | 83 |
96 func (f *fakeDatastore) PutMulti(keys []*Key, vals []PropertyMap, cb NewKeyCB) e
rror { | 84 func (f *fakeDatastore) PutMulti(keys []*Key, vals []PropertyMap, cb NewKeyCB) e
rror { |
97 if keys[0].Kind() == "FailAll" { | 85 if keys[0].Kind() == "FailAll" { |
98 return errFailAll | 86 return errFailAll |
99 } | 87 } |
100 _, assertExtra := vals[0].GetMeta("assertExtra") | 88 _, assertExtra := vals[0].GetMeta("assertExtra") |
101 for i, k := range keys { | 89 for i, k := range keys { |
102 err := error(nil) | 90 err := error(nil) |
103 if k.Kind() == "Fail" { | 91 if k.Kind() == "Fail" { |
104 err = errFail | 92 err = errFail |
105 } else { | 93 } else { |
106 So(vals[i]["Value"], ShouldResemble, []Property{MkProper
ty(i)}) | 94 So(vals[i]["Value"], ShouldResemble, []Property{MkProper
ty(i)}) |
107 if assertExtra { | 95 if assertExtra { |
108 So(vals[i]["Extra"], ShouldResemble, []Property{
MkProperty("whoa")}) | 96 So(vals[i]["Extra"], ShouldResemble, []Property{
MkProperty("whoa")}) |
109 } | 97 } |
110 if k.IsIncomplete() { | 98 if k.IsIncomplete() { |
111 » » » » k = NewKey(k.AppID(), k.Namespace(), k.Kind(), "
", int64(i+1), k.Parent()) | 99 » » » » k = k.KeyContext().NewKey(k.Kind(), "", int64(i+
1), k.Parent()) |
112 } | 100 } |
113 } | 101 } |
114 cb(k, err) | 102 cb(k, err) |
115 } | 103 } |
116 return nil | 104 return nil |
117 } | 105 } |
118 | 106 |
119 const noSuchEntityID = 0xdead | 107 const noSuchEntityID = 0xdead |
120 | 108 |
121 func (f *fakeDatastore) GetMulti(keys []*Key, _meta MultiMetaGetter, cb GetMulti
CB) error { | 109 func (f *fakeDatastore) GetMulti(keys []*Key, _meta MultiMetaGetter, cb GetMulti
CB) error { |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 } | 311 } |
324 | 312 |
325 var _ MetaGetterSetter = (*MGSWithNoKind)(nil) | 313 var _ MetaGetterSetter = (*MGSWithNoKind)(nil) |
326 | 314 |
327 func TestKeyForObj(t *testing.T) { | 315 func TestKeyForObj(t *testing.T) { |
328 t.Parallel() | 316 t.Parallel() |
329 | 317 |
330 Convey("Test interface.KeyForObj", t, func() { | 318 Convey("Test interface.KeyForObj", t, func() { |
331 c := info.Set(context.Background(), fakeInfo{}) | 319 c := info.Set(context.Background(), fakeInfo{}) |
332 c = SetRawFactory(c, fakeDatastoreFactory) | 320 c = SetRawFactory(c, fakeDatastoreFactory) |
333 ds := Get(c) | |
334 | 321 |
335 » » k := ds.MakeKey("Hello", "world") | 322 » » k := MakeKey(c, "Hello", "world") |
336 | 323 |
337 Convey("good", func() { | 324 Convey("good", func() { |
338 Convey("struct containing $key", func() { | 325 Convey("struct containing $key", func() { |
339 type keyStruct struct { | 326 type keyStruct struct { |
340 Key *Key `gae:"$key"` | 327 Key *Key `gae:"$key"` |
341 } | 328 } |
342 | 329 |
343 ks := &keyStruct{k} | 330 ks := &keyStruct{k} |
344 » » » » So(ds.KeyForObj(ks), ShouldEqual, k) | 331 » » » » So(KeyForObj(c, ks), ShouldEqual, k) |
345 }) | 332 }) |
346 | 333 |
347 Convey("struct containing default $id and $kind", func()
{ | 334 Convey("struct containing default $id and $kind", func()
{ |
348 type idStruct struct { | 335 type idStruct struct { |
349 id string `gae:"$id,wut"` | 336 id string `gae:"$id,wut"` |
350 knd string `gae:"$kind,SuperKind"` | 337 knd string `gae:"$kind,SuperKind"` |
351 } | 338 } |
352 | 339 |
353 » » » » So(ds.KeyForObj(&idStruct{}).String(), ShouldEqu
al, `s~aid:ns:/SuperKind,"wut"`) | 340 » » » » So(KeyForObj(c, &idStruct{}).String(), ShouldEqu
al, `s~aid:ns:/SuperKind,"wut"`) |
354 }) | 341 }) |
355 | 342 |
356 Convey("struct containing $id and $parent", func() { | 343 Convey("struct containing $id and $parent", func() { |
357 » » » » So(ds.KeyForObj(&CommonStruct{ID: 4}).String(),
ShouldEqual, `s~aid:ns:/CommonStruct,4`) | 344 » » » » So(KeyForObj(c, &CommonStruct{ID: 4}).String(),
ShouldEqual, `s~aid:ns:/CommonStruct,4`) |
358 | 345 |
359 » » » » So(ds.KeyForObj(&CommonStruct{ID: 4, Parent: k})
.String(), ShouldEqual, `s~aid:ns:/Hello,"world"/CommonStruct,4`) | 346 » » » » So(KeyForObj(c, &CommonStruct{ID: 4, Parent: k})
.String(), ShouldEqual, `s~aid:ns:/Hello,"world"/CommonStruct,4`) |
360 }) | 347 }) |
361 | 348 |
362 Convey("a propmap with $key", func() { | 349 Convey("a propmap with $key", func() { |
363 pm := PropertyMap{} | 350 pm := PropertyMap{} |
364 So(pm.SetMeta("key", k), ShouldBeTrue) | 351 So(pm.SetMeta("key", k), ShouldBeTrue) |
365 » » » » So(ds.KeyForObj(pm).String(), ShouldEqual, `s~ai
d:ns:/Hello,"world"`) | 352 » » » » So(KeyForObj(c, pm).String(), ShouldEqual, `s~ai
d:ns:/Hello,"world"`) |
366 }) | 353 }) |
367 | 354 |
368 Convey("a propmap with $id, $kind, $parent", func() { | 355 Convey("a propmap with $id, $kind, $parent", func() { |
369 pm := PropertyMap{} | 356 pm := PropertyMap{} |
370 So(pm.SetMeta("id", 100), ShouldBeTrue) | 357 So(pm.SetMeta("id", 100), ShouldBeTrue) |
371 So(pm.SetMeta("kind", "Sup"), ShouldBeTrue) | 358 So(pm.SetMeta("kind", "Sup"), ShouldBeTrue) |
372 » » » » So(ds.KeyForObj(pm).String(), ShouldEqual, `s~ai
d:ns:/Sup,100`) | 359 » » » » So(KeyForObj(c, pm).String(), ShouldEqual, `s~ai
d:ns:/Sup,100`) |
373 | 360 |
374 So(pm.SetMeta("parent", k), ShouldBeTrue) | 361 So(pm.SetMeta("parent", k), ShouldBeTrue) |
375 » » » » So(ds.KeyForObj(pm).String(), ShouldEqual, `s~ai
d:ns:/Hello,"world"/Sup,100`) | 362 » » » » So(KeyForObj(c, pm).String(), ShouldEqual, `s~ai
d:ns:/Hello,"world"/Sup,100`) |
376 }) | 363 }) |
377 | 364 |
378 Convey("a pls with $id, $parent", func() { | 365 Convey("a pls with $id, $parent", func() { |
379 pls := GetPLS(&CommonStruct{ID: 1}) | 366 pls := GetPLS(&CommonStruct{ID: 1}) |
380 » » » » So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a
id:ns:/CommonStruct,1`) | 367 » » » » So(KeyForObj(c, pls).String(), ShouldEqual, `s~a
id:ns:/CommonStruct,1`) |
381 | 368 |
382 So(pls.SetMeta("parent", k), ShouldBeTrue) | 369 So(pls.SetMeta("parent", k), ShouldBeTrue) |
383 » » » » So(ds.KeyForObj(pls).String(), ShouldEqual, `s~a
id:ns:/Hello,"world"/CommonStruct,1`) | 370 » » » » So(KeyForObj(c, pls).String(), ShouldEqual, `s~a
id:ns:/Hello,"world"/CommonStruct,1`) |
384 }) | 371 }) |
385 }) | 372 }) |
386 | 373 |
387 Convey("bad", func() { | 374 Convey("bad", func() { |
388 Convey("a propmap without $kind", func() { | 375 Convey("a propmap without $kind", func() { |
389 pm := PropertyMap{} | 376 pm := PropertyMap{} |
390 So(pm.SetMeta("id", 100), ShouldBeTrue) | 377 So(pm.SetMeta("id", 100), ShouldBeTrue) |
391 » » » » So(func() { ds.KeyForObj(pm) }, ShouldPanic) | 378 » » » » So(func() { KeyForObj(c, pm) }, ShouldPanic) |
392 }) | 379 }) |
393 | 380 |
394 Convey("a bad object", func() { | 381 Convey("a bad object", func() { |
395 type BadObj struct { | 382 type BadObj struct { |
396 ID int64 `gae:"$id"` | 383 ID int64 `gae:"$id"` |
397 | 384 |
398 NonSerializableField complex64 | 385 NonSerializableField complex64 |
399 } | 386 } |
400 | 387 |
401 » » » » So(func() { ds.KeyForObjErr(&BadObj{ID: 1}) }, S
houldPanicLike, | 388 » » » » So(func() { KeyForObj(c, &BadObj{ID: 1}) }, Shou
ldPanicLike, |
402 `field "NonSerializableField" has invali
d type: complex64`) | 389 `field "NonSerializableField" has invali
d type: complex64`) |
403 }) | 390 }) |
404 }) | 391 }) |
405 }) | 392 }) |
406 } | 393 } |
407 | 394 |
408 func TestPopulateKey(t *testing.T) { | 395 func TestPopulateKey(t *testing.T) { |
409 t.Parallel() | 396 t.Parallel() |
410 | 397 |
411 Convey("Test PopulateKey", t, func() { | 398 Convey("Test PopulateKey", t, func() { |
412 » » k := NewKey("app", "namespace", "kind", "", 1337, nil) | 399 » » k := KeyContext{"app", "namespace"}.NewKey("kind", "", 1337, nil
) |
413 | 400 |
414 Convey("Can set the key of a common struct.", func() { | 401 Convey("Can set the key of a common struct.", func() { |
415 var cs CommonStruct | 402 var cs CommonStruct |
416 | 403 |
417 So(PopulateKey(&cs, k), ShouldBeTrue) | 404 So(PopulateKey(&cs, k), ShouldBeTrue) |
418 So(cs.ID, ShouldEqual, 1337) | 405 So(cs.ID, ShouldEqual, 1337) |
419 }) | 406 }) |
420 | 407 |
421 Convey("Will not set the value of a singleton struct.", func() { | 408 Convey("Will not set the value of a singleton struct.", func() { |
422 var ss SingletonStruct | 409 var ss SingletonStruct |
(...skipping 15 matching lines...) Expand all Loading... |
438 }) | 425 }) |
439 }) | 426 }) |
440 } | 427 } |
441 | 428 |
442 func TestAllocateIDs(t *testing.T) { | 429 func TestAllocateIDs(t *testing.T) { |
443 t.Parallel() | 430 t.Parallel() |
444 | 431 |
445 Convey("A testing environment", t, func() { | 432 Convey("A testing environment", t, func() { |
446 c := info.Set(context.Background(), fakeInfo{}) | 433 c := info.Set(context.Background(), fakeInfo{}) |
447 c = SetRawFactory(c, fakeDatastoreFactory) | 434 c = SetRawFactory(c, fakeDatastoreFactory) |
448 ds := Get(c) | |
449 | 435 |
450 Convey("Testing AllocateIDs", func() { | 436 Convey("Testing AllocateIDs", func() { |
451 Convey("Will return nil if no entities are supplied.", f
unc() { | 437 Convey("Will return nil if no entities are supplied.", f
unc() { |
452 » » » » So(ds.AllocateIDs(), ShouldBeNil) | 438 » » » » So(AllocateIDs(c), ShouldBeNil) |
453 }) | 439 }) |
454 | 440 |
455 Convey("single struct", func() { | 441 Convey("single struct", func() { |
456 cs := CommonStruct{Value: 1} | 442 cs := CommonStruct{Value: 1} |
457 » » » » So(ds.AllocateIDs(&cs), ShouldBeNil) | 443 » » » » So(AllocateIDs(c, &cs), ShouldBeNil) |
458 So(cs.ID, ShouldEqual, 1) | 444 So(cs.ID, ShouldEqual, 1) |
459 }) | 445 }) |
460 | 446 |
461 Convey("struct slice", func() { | 447 Convey("struct slice", func() { |
462 csSlice := []*CommonStruct{{Value: 1}, {Value: 2
}} | 448 csSlice := []*CommonStruct{{Value: 1}, {Value: 2
}} |
463 » » » » So(ds.AllocateIDs(csSlice), ShouldBeNil) | 449 » » » » So(AllocateIDs(c, csSlice), ShouldBeNil) |
464 So(csSlice, ShouldResemble, []*CommonStruct{{ID:
1, Value: 1}, {ID: 2, Value: 2}}) | 450 So(csSlice, ShouldResemble, []*CommonStruct{{ID:
1, Value: 1}, {ID: 2, Value: 2}}) |
465 }) | 451 }) |
466 | 452 |
467 Convey("single key will fail", func() { | 453 Convey("single key will fail", func() { |
468 » » » » singleKey := ds.MakeKey("FooParent", "BarParent"
, "Foo", "Bar") | 454 » » » » singleKey := MakeKey(c, "FooParent", "BarParent"
, "Foo", "Bar") |
469 » » » » So(func() { ds.AllocateIDs(singleKey) }, ShouldP
anicLike, | 455 » » » » So(func() { AllocateIDs(c, singleKey) }, ShouldP
anicLike, |
470 "invalid input type (*datastore.Key): no
t a PLS, pointer-to-struct, or slice thereof") | 456 "invalid input type (*datastore.Key): no
t a PLS, pointer-to-struct, or slice thereof") |
471 }) | 457 }) |
472 | 458 |
473 Convey("key slice", func() { | 459 Convey("key slice", func() { |
474 » » » » k0 := ds.MakeKey("Foo", "Bar") | 460 » » » » k0 := MakeKey(c, "Foo", "Bar") |
475 » » » » k1 := ds.MakeKey("Baz", "Qux") | 461 » » » » k1 := MakeKey(c, "Baz", "Qux") |
476 keySlice := []*Key{k0, k1} | 462 keySlice := []*Key{k0, k1} |
477 » » » » So(ds.AllocateIDs(keySlice), ShouldBeNil) | 463 » » » » So(AllocateIDs(c, keySlice), ShouldBeNil) |
478 » » » » So(keySlice[0].Equal(ds.MakeKey("Foo", 1)), Shou
ldBeTrue) | 464 » » » » So(keySlice[0].Equal(MakeKey(c, "Foo", 1)), Shou
ldBeTrue) |
479 » » » » So(keySlice[1].Equal(ds.MakeKey("Baz", 2)), Shou
ldBeTrue) | 465 » » » » So(keySlice[1].Equal(MakeKey(c, "Baz", 2)), Shou
ldBeTrue) |
480 | 466 |
481 // The original keys should not have changed. | 467 // The original keys should not have changed. |
482 » » » » So(k0.Equal(ds.MakeKey("Foo", "Bar")), ShouldBeT
rue) | 468 » » » » So(k0.Equal(MakeKey(c, "Foo", "Bar")), ShouldBeT
rue) |
483 » » » » So(k1.Equal(ds.MakeKey("Baz", "Qux")), ShouldBeT
rue) | 469 » » » » So(k1.Equal(MakeKey(c, "Baz", "Qux")), ShouldBeT
rue) |
484 }) | 470 }) |
485 | 471 |
486 Convey("fail all key slice", func() { | 472 Convey("fail all key slice", func() { |
487 » » » » keySlice := []*Key{ds.MakeKey("FailAll", "oops")
, ds.MakeKey("Baz", "Qux")} | 473 » » » » keySlice := []*Key{MakeKey(c, "FailAll", "oops")
, MakeKey(c, "Baz", "Qux")} |
488 » » » » So(ds.AllocateIDs(keySlice), ShouldEqual, errFai
lAll) | 474 » » » » So(AllocateIDs(c, keySlice), ShouldEqual, errFai
lAll) |
489 So(keySlice[0].StringID(), ShouldEqual, "oops") | 475 So(keySlice[0].StringID(), ShouldEqual, "oops") |
490 So(keySlice[1].StringID(), ShouldEqual, "Qux") | 476 So(keySlice[1].StringID(), ShouldEqual, "Qux") |
491 }) | 477 }) |
492 | 478 |
493 Convey("fail key slice", func() { | 479 Convey("fail key slice", func() { |
494 » » » » keySlice := []*Key{ds.MakeKey("Fail", "oops"), d
s.MakeKey("Baz", "Qux")} | 480 » » » » keySlice := []*Key{MakeKey(c, "Fail", "oops"), M
akeKey(c, "Baz", "Qux")} |
495 » » » » So(ds.AllocateIDs(keySlice), ShouldResemble, err
ors.MultiError{errFail, nil}) | 481 » » » » So(AllocateIDs(c, keySlice), ShouldResemble, err
ors.MultiError{errFail, nil}) |
496 So(keySlice[0].StringID(), ShouldEqual, "oops") | 482 So(keySlice[0].StringID(), ShouldEqual, "oops") |
497 So(keySlice[1].IntID(), ShouldEqual, 2) | 483 So(keySlice[1].IntID(), ShouldEqual, 2) |
498 }) | 484 }) |
499 | 485 |
500 Convey("vararg with errors", func() { | 486 Convey("vararg with errors", func() { |
501 successSlice := []CommonStruct{{Value: 0}, {Valu
e: 1}} | 487 successSlice := []CommonStruct{{Value: 0}, {Valu
e: 1}} |
502 failSlice := []FakePLS{{Kind: "Fail"}, {Value: 3
}} | 488 failSlice := []FakePLS{{Kind: "Fail"}, {Value: 3
}} |
503 emptySlice := []CommonStruct(nil) | 489 emptySlice := []CommonStruct(nil) |
504 cs0 := CommonStruct{Value: 4} | 490 cs0 := CommonStruct{Value: 4} |
505 cs1 := FakePLS{Kind: "Fail", Value: 5} | 491 cs1 := FakePLS{Kind: "Fail", Value: 5} |
506 » » » » keySlice := []*Key{ds.MakeKey("Foo", "Bar"), ds.
MakeKey("Baz", "Qux")} | 492 » » » » keySlice := []*Key{MakeKey(c, "Foo", "Bar"), Mak
eKey(c, "Baz", "Qux")} |
507 fpls := FakePLS{StringID: "ohai", Value: 6} | 493 fpls := FakePLS{StringID: "ohai", Value: 6} |
508 | 494 |
509 » » » » err := ds.AllocateIDs(successSlice, failSlice, e
mptySlice, &cs0, &cs1, keySlice, &fpls) | 495 » » » » err := AllocateIDs(c, successSlice, failSlice, e
mptySlice, &cs0, &cs1, keySlice, &fpls) |
510 So(err, ShouldResemble, errors.MultiError{ | 496 So(err, ShouldResemble, errors.MultiError{ |
511 nil, errors.MultiError{errFail, nil}, ni
l, nil, errFail, nil, nil}) | 497 nil, errors.MultiError{errFail, nil}, ni
l, nil, errFail, nil, nil}) |
512 So(successSlice[0].ID, ShouldEqual, 1) | 498 So(successSlice[0].ID, ShouldEqual, 1) |
513 So(successSlice[1].ID, ShouldEqual, 2) | 499 So(successSlice[1].ID, ShouldEqual, 2) |
514 So(failSlice[1].IntID, ShouldEqual, 4) | 500 So(failSlice[1].IntID, ShouldEqual, 4) |
515 So(cs0.ID, ShouldEqual, 5) | 501 So(cs0.ID, ShouldEqual, 5) |
516 » » » » So(keySlice[0].Equal(ds.MakeKey("Foo", 7)), Shou
ldBeTrue) | 502 » » » » So(keySlice[0].Equal(MakeKey(c, "Foo", 7)), Shou
ldBeTrue) |
517 » » » » So(keySlice[1].Equal(ds.MakeKey("Baz", 8)), Shou
ldBeTrue) | 503 » » » » So(keySlice[1].Equal(MakeKey(c, "Baz", 8)), Shou
ldBeTrue) |
518 So(fpls.IntID, ShouldEqual, 9) | 504 So(fpls.IntID, ShouldEqual, 9) |
519 }) | 505 }) |
520 }) | 506 }) |
521 }) | 507 }) |
522 } | 508 } |
523 | 509 |
524 func TestPut(t *testing.T) { | 510 func TestPut(t *testing.T) { |
525 t.Parallel() | 511 t.Parallel() |
526 | 512 |
527 Convey("A testing environment", t, func() { | 513 Convey("A testing environment", t, func() { |
528 c := info.Set(context.Background(), fakeInfo{}) | 514 c := info.Set(context.Background(), fakeInfo{}) |
529 c = SetRawFactory(c, fakeDatastoreFactory) | 515 c = SetRawFactory(c, fakeDatastoreFactory) |
530 ds := Get(c) | |
531 | 516 |
532 Convey("Testing Put", func() { | 517 Convey("Testing Put", func() { |
533 Convey("bad", func() { | 518 Convey("bad", func() { |
534 Convey("static can't serialize", func() { | 519 Convey("static can't serialize", func() { |
535 bss := []badStruct{{}, {}} | 520 bss := []badStruct{{}, {}} |
536 » » » » » So(func() { ds.Put(bss) }, ShouldPanicLi
ke, | 521 » » » » » So(func() { Put(c, bss) }, ShouldPanicLi
ke, |
537 `field "Compy" has invalid type`
) | 522 `field "Compy" has invalid type`
) |
538 }) | 523 }) |
539 | 524 |
540 Convey("static ptr can't serialize", func() { | 525 Convey("static ptr can't serialize", func() { |
541 bss := []*badStruct{{}, {}} | 526 bss := []*badStruct{{}, {}} |
542 » » » » » So(func() { ds.Put(bss) }, ShouldPanicLi
ke, | 527 » » » » » So(func() { Put(c, bss) }, ShouldPanicLi
ke, |
543 `field "Compy" has invalid type:
complex64`) | 528 `field "Compy" has invalid type:
complex64`) |
544 }) | 529 }) |
545 | 530 |
546 Convey("static bad type", func() { | 531 Convey("static bad type", func() { |
547 » » » » » So(func() { ds.Put(100) }, ShouldPanicLi
ke, | 532 » » » » » So(func() { Put(c, 100) }, ShouldPanicLi
ke, |
548 "invalid input type (int): not a
PLS, pointer-to-struct, or slice thereof") | 533 "invalid input type (int): not a
PLS, pointer-to-struct, or slice thereof") |
549 }) | 534 }) |
550 | 535 |
551 Convey("static bad type (slice of bad type)", fu
nc() { | 536 Convey("static bad type (slice of bad type)", fu
nc() { |
552 » » » » » So(func() { ds.Put([]int{}) }, ShouldPan
icLike, | 537 » » » » » So(func() { Put(c, []int{}) }, ShouldPan
icLike, |
553 "invalid input type ([]int): not
a PLS, pointer-to-struct, or slice thereof") | 538 "invalid input type ([]int): not
a PLS, pointer-to-struct, or slice thereof") |
554 }) | 539 }) |
555 | 540 |
556 Convey("dynamic can't serialize", func() { | 541 Convey("dynamic can't serialize", func() { |
557 fplss := []FakePLS{{failSave: true}, {}} | 542 fplss := []FakePLS{{failSave: true}, {}} |
558 » » » » » So(ds.Put(fplss), ShouldErrLike, "FakePL
S.Save") | 543 » » » » » So(Put(c, fplss), ShouldErrLike, "FakePL
S.Save") |
559 }) | 544 }) |
560 | 545 |
561 Convey("can't get keys", func() { | 546 Convey("can't get keys", func() { |
562 fplss := []FakePLS{{failGetMeta: true},
{}} | 547 fplss := []FakePLS{{failGetMeta: true},
{}} |
563 » » » » » So(ds.Put(fplss), ShouldErrLike, "unable
to extract $kind") | 548 » » » » » So(Put(c, fplss), ShouldErrLike, "unable
to extract $kind") |
564 }) | 549 }) |
565 | 550 |
566 Convey("get single error for RPC failure", func(
) { | 551 Convey("get single error for RPC failure", func(
) { |
567 fplss := []FakePLS{{Kind: "FailAll"}, {}
} | 552 fplss := []FakePLS{{Kind: "FailAll"}, {}
} |
568 » » » » » So(ds.Put(fplss), ShouldEqual, errFailAl
l) | 553 » » » » » So(Put(c, fplss), ShouldEqual, errFailAl
l) |
569 }) | 554 }) |
570 | 555 |
571 Convey("get multi error for individual failures"
, func() { | 556 Convey("get multi error for individual failures"
, func() { |
572 fplss := []FakePLS{{}, {Kind: "Fail"}} | 557 fplss := []FakePLS{{}, {Kind: "Fail"}} |
573 » » » » » So(ds.Put(fplss), ShouldResemble, errors
.MultiError{nil, errFail}) | 558 » » » » » So(Put(c, fplss), ShouldResemble, errors
.MultiError{nil, errFail}) |
574 }) | 559 }) |
575 | 560 |
576 Convey("get with *Key is an error", func() { | 561 Convey("get with *Key is an error", func() { |
577 » » » » » So(func() { ds.Get(&Key{}) }, ShouldPani
cLike, | 562 » » » » » So(func() { Get(c, &Key{}) }, ShouldPani
cLike, |
578 "invalid input type (*datastore.
Key): not a PLS, pointer-to-struct, or slice thereof") | 563 "invalid input type (*datastore.
Key): not a PLS, pointer-to-struct, or slice thereof") |
579 }) | 564 }) |
580 | 565 |
581 Convey("struct with no $kind is an error", func(
) { | 566 Convey("struct with no $kind is an error", func(
) { |
582 s := MGSWithNoKind{} | 567 s := MGSWithNoKind{} |
583 » » » » » So(ds.Put(&s), ShouldErrLike, "unable to
extract $kind") | 568 » » » » » So(Put(c, &s), ShouldErrLike, "unable to
extract $kind") |
584 }) | 569 }) |
585 | 570 |
586 Convey("struct with invalid but non-nil key is a
n error", func() { | 571 Convey("struct with invalid but non-nil key is a
n error", func() { |
587 type BadParent struct { | 572 type BadParent struct { |
588 ID int64 `gae:"$id"` | 573 ID int64 `gae:"$id"` |
589 Parent *Key `gae:"$parent"` | 574 Parent *Key `gae:"$parent"` |
590 } | 575 } |
591 // having an Incomplete parent makes an
invalid key | 576 // having an Incomplete parent makes an
invalid key |
592 » » » » » bp := &BadParent{ID: 1, Parent: ds.MakeK
ey("Something", 0)} | 577 » » » » » bp := &BadParent{ID: 1, Parent: MakeKey(
c, "Something", 0)} |
593 » » » » » So(ds.Put(bp), ShouldErrLike, ErrInvalid
Key) | 578 » » » » » So(Put(c, bp), ShouldErrLike, ErrInvalid
Key) |
594 }) | 579 }) |
595 | 580 |
596 Convey("vararg with errors", func() { | 581 Convey("vararg with errors", func() { |
597 successSlice := []CommonStruct{{Value: 0
}, {Value: 1}} | 582 successSlice := []CommonStruct{{Value: 0
}, {Value: 1}} |
598 failSlice := []FakePLS{{Kind: "Fail"}, {
Value: 3}} | 583 failSlice := []FakePLS{{Kind: "Fail"}, {
Value: 3}} |
599 emptySlice := []CommonStruct(nil) | 584 emptySlice := []CommonStruct(nil) |
600 cs0 := CommonStruct{Value: 4} | 585 cs0 := CommonStruct{Value: 4} |
601 failPLS := FakePLS{Kind: "Fail", Value:
5} | 586 failPLS := FakePLS{Kind: "Fail", Value:
5} |
602 fpls := FakePLS{StringID: "ohai", Value:
6} | 587 fpls := FakePLS{StringID: "ohai", Value:
6} |
603 | 588 |
604 » » » » » err := ds.Put(successSlice, failSlice, e
mptySlice, &cs0, &failPLS, &fpls) | 589 » » » » » err := Put(c, successSlice, failSlice, e
mptySlice, &cs0, &failPLS, &fpls) |
605 So(err, ShouldResemble, errors.MultiErro
r{ | 590 So(err, ShouldResemble, errors.MultiErro
r{ |
606 nil, errors.MultiError{errFail,
nil}, nil, nil, errFail, nil}) | 591 nil, errors.MultiError{errFail,
nil}, nil, nil, errFail, nil}) |
607 So(successSlice[0].ID, ShouldEqual, 1) | 592 So(successSlice[0].ID, ShouldEqual, 1) |
608 So(successSlice[1].ID, ShouldEqual, 2) | 593 So(successSlice[1].ID, ShouldEqual, 2) |
609 So(cs0.ID, ShouldEqual, 5) | 594 So(cs0.ID, ShouldEqual, 5) |
610 }) | 595 }) |
611 }) | 596 }) |
612 | 597 |
613 Convey("ok", func() { | 598 Convey("ok", func() { |
614 Convey("[]S", func() { | 599 Convey("[]S", func() { |
615 css := make([]CommonStruct, 7) | 600 css := make([]CommonStruct, 7) |
616 for i := range css { | 601 for i := range css { |
617 if i == 4 { | 602 if i == 4 { |
618 css[i].ID = 200 | 603 css[i].ID = 200 |
619 } | 604 } |
620 css[i].Value = int64(i) | 605 css[i].Value = int64(i) |
621 } | 606 } |
622 » » » » » So(ds.Put(css), ShouldBeNil) | 607 » » » » » So(Put(c, css), ShouldBeNil) |
623 for i, cs := range css { | 608 for i, cs := range css { |
624 expect := int64(i + 1) | 609 expect := int64(i + 1) |
625 if i == 4 { | 610 if i == 4 { |
626 expect = 200 | 611 expect = 200 |
627 } | 612 } |
628 So(cs.ID, ShouldEqual, expect) | 613 So(cs.ID, ShouldEqual, expect) |
629 } | 614 } |
630 }) | 615 }) |
631 | 616 |
632 Convey("[]*S", func() { | 617 Convey("[]*S", func() { |
633 css := make([]*CommonStruct, 7) | 618 css := make([]*CommonStruct, 7) |
634 for i := range css { | 619 for i := range css { |
635 css[i] = &CommonStruct{Value: in
t64(i)} | 620 css[i] = &CommonStruct{Value: in
t64(i)} |
636 if i == 4 { | 621 if i == 4 { |
637 css[i].ID = 200 | 622 css[i].ID = 200 |
638 } | 623 } |
639 } | 624 } |
640 » » » » » So(ds.Put(css), ShouldBeNil) | 625 » » » » » So(Put(c, css), ShouldBeNil) |
641 for i, cs := range css { | 626 for i, cs := range css { |
642 expect := int64(i + 1) | 627 expect := int64(i + 1) |
643 if i == 4 { | 628 if i == 4 { |
644 expect = 200 | 629 expect = 200 |
645 } | 630 } |
646 So(cs.ID, ShouldEqual, expect) | 631 So(cs.ID, ShouldEqual, expect) |
647 } | 632 } |
648 | 633 |
649 s := &CommonStruct{} | 634 s := &CommonStruct{} |
650 » » » » » So(ds.Put(s), ShouldBeNil) | 635 » » » » » So(Put(c, s), ShouldBeNil) |
651 So(s.ID, ShouldEqual, 1) | 636 So(s.ID, ShouldEqual, 1) |
652 }) | 637 }) |
653 | 638 |
654 Convey("[]P", func() { | 639 Convey("[]P", func() { |
655 fplss := make([]FakePLS, 7) | 640 fplss := make([]FakePLS, 7) |
656 for i := range fplss { | 641 for i := range fplss { |
657 fplss[i].Value = int64(i) | 642 fplss[i].Value = int64(i) |
658 if i == 4 { | 643 if i == 4 { |
659 fplss[i].IntID = int64(2
00) | 644 fplss[i].IntID = int64(2
00) |
660 } | 645 } |
661 } | 646 } |
662 » » » » » So(ds.Put(fplss), ShouldBeNil) | 647 » » » » » So(Put(c, fplss), ShouldBeNil) |
663 for i, fpls := range fplss { | 648 for i, fpls := range fplss { |
664 expect := int64(i + 1) | 649 expect := int64(i + 1) |
665 if i == 4 { | 650 if i == 4 { |
666 expect = 200 | 651 expect = 200 |
667 } | 652 } |
668 So(fpls.IntID, ShouldEqual, expe
ct) | 653 So(fpls.IntID, ShouldEqual, expe
ct) |
669 } | 654 } |
670 | 655 |
671 pm := PropertyMap{"Value": {MkProperty(0
)}, "$kind": {MkPropertyNI("Pmap")}} | 656 pm := PropertyMap{"Value": {MkProperty(0
)}, "$kind": {MkPropertyNI("Pmap")}} |
672 » » » » » So(ds.Put(pm), ShouldBeNil) | 657 » » » » » So(Put(c, pm), ShouldBeNil) |
673 » » » » » So(ds.KeyForObj(pm).IntID(), ShouldEqual
, 1) | 658 » » » » » So(KeyForObj(c, pm).IntID(), ShouldEqual
, 1) |
674 }) | 659 }) |
675 | 660 |
676 Convey("[]P (map)", func() { | 661 Convey("[]P (map)", func() { |
677 pms := make([]PropertyMap, 7) | 662 pms := make([]PropertyMap, 7) |
678 for i := range pms { | 663 for i := range pms { |
679 pms[i] = PropertyMap{ | 664 pms[i] = PropertyMap{ |
680 "$kind": {MkProperty("Pm
ap")}, | 665 "$kind": {MkProperty("Pm
ap")}, |
681 "Value": {MkProperty(i)}
, | 666 "Value": {MkProperty(i)}
, |
682 } | 667 } |
683 if i == 4 { | 668 if i == 4 { |
684 So(pms[i].SetMeta("id",
int64(200)), ShouldBeTrue) | 669 So(pms[i].SetMeta("id",
int64(200)), ShouldBeTrue) |
685 } | 670 } |
686 } | 671 } |
687 » » » » » So(ds.Put(pms), ShouldBeNil) | 672 » » » » » So(Put(c, pms), ShouldBeNil) |
688 for i, pm := range pms { | 673 for i, pm := range pms { |
689 expect := int64(i + 1) | 674 expect := int64(i + 1) |
690 if i == 4 { | 675 if i == 4 { |
691 expect = 200 | 676 expect = 200 |
692 } | 677 } |
693 » » » » » » So(ds.KeyForObj(pm).String(), Sh
ouldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect)) | 678 » » » » » » So(KeyForObj(c, pm).String(), Sh
ouldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect)) |
694 } | 679 } |
695 }) | 680 }) |
696 | 681 |
697 Convey("[]*P", func() { | 682 Convey("[]*P", func() { |
698 fplss := make([]*FakePLS, 7) | 683 fplss := make([]*FakePLS, 7) |
699 for i := range fplss { | 684 for i := range fplss { |
700 fplss[i] = &FakePLS{Value: int64
(i)} | 685 fplss[i] = &FakePLS{Value: int64
(i)} |
701 if i == 4 { | 686 if i == 4 { |
702 fplss[i].IntID = int64(2
00) | 687 fplss[i].IntID = int64(2
00) |
703 } | 688 } |
704 } | 689 } |
705 » » » » » So(ds.Put(fplss), ShouldBeNil) | 690 » » » » » So(Put(c, fplss), ShouldBeNil) |
706 for i, fpls := range fplss { | 691 for i, fpls := range fplss { |
707 expect := int64(i + 1) | 692 expect := int64(i + 1) |
708 if i == 4 { | 693 if i == 4 { |
709 expect = 200 | 694 expect = 200 |
710 } | 695 } |
711 So(fpls.IntID, ShouldEqual, expe
ct) | 696 So(fpls.IntID, ShouldEqual, expe
ct) |
712 } | 697 } |
713 }) | 698 }) |
714 | 699 |
715 Convey("[]*P (map)", func() { | 700 Convey("[]*P (map)", func() { |
716 pms := make([]*PropertyMap, 7) | 701 pms := make([]*PropertyMap, 7) |
717 for i := range pms { | 702 for i := range pms { |
718 pms[i] = &PropertyMap{ | 703 pms[i] = &PropertyMap{ |
719 "$kind": {MkProperty("Pm
ap")}, | 704 "$kind": {MkProperty("Pm
ap")}, |
720 "Value": {MkProperty(i)}
, | 705 "Value": {MkProperty(i)}
, |
721 } | 706 } |
722 if i == 4 { | 707 if i == 4 { |
723 So(pms[i].SetMeta("id",
int64(200)), ShouldBeTrue) | 708 So(pms[i].SetMeta("id",
int64(200)), ShouldBeTrue) |
724 } | 709 } |
725 } | 710 } |
726 » » » » » So(ds.Put(pms), ShouldBeNil) | 711 » » » » » So(Put(c, pms), ShouldBeNil) |
727 for i, pm := range pms { | 712 for i, pm := range pms { |
728 expect := int64(i + 1) | 713 expect := int64(i + 1) |
729 if i == 4 { | 714 if i == 4 { |
730 expect = 200 | 715 expect = 200 |
731 } | 716 } |
732 » » » » » » So(ds.KeyForObj(*pm).String(), S
houldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect)) | 717 » » » » » » So(KeyForObj(c, *pm).String(), S
houldEqual, fmt.Sprintf("s~aid:ns:/Pmap,%d", expect)) |
733 } | 718 } |
734 }) | 719 }) |
735 | 720 |
736 Convey("[]I", func() { | 721 Convey("[]I", func() { |
737 ifs := []interface{}{ | 722 ifs := []interface{}{ |
738 &CommonStruct{Value: 0}, | 723 &CommonStruct{Value: 0}, |
739 &FakePLS{Value: 1}, | 724 &FakePLS{Value: 1}, |
740 PropertyMap{"Value": {MkProperty
(2)}, "$kind": {MkPropertyNI("Pmap")}}, | 725 PropertyMap{"Value": {MkProperty
(2)}, "$kind": {MkPropertyNI("Pmap")}}, |
741 &PropertyMap{"Value": {MkPropert
y(3)}, "$kind": {MkPropertyNI("Pmap")}}, | 726 &PropertyMap{"Value": {MkPropert
y(3)}, "$kind": {MkPropertyNI("Pmap")}}, |
742 } | 727 } |
743 » » » » » So(ds.Put(ifs), ShouldBeNil) | 728 » » » » » So(Put(c, ifs), ShouldBeNil) |
744 for i := range ifs { | 729 for i := range ifs { |
745 switch i { | 730 switch i { |
746 case 0: | 731 case 0: |
747 So(ifs[i].(*CommonStruct
).ID, ShouldEqual, 1) | 732 So(ifs[i].(*CommonStruct
).ID, ShouldEqual, 1) |
748 case 1: | 733 case 1: |
749 fpls := ifs[i].(*FakePLS
) | 734 fpls := ifs[i].(*FakePLS
) |
750 So(fpls.IntID, ShouldEqu
al, 2) | 735 So(fpls.IntID, ShouldEqu
al, 2) |
751 case 2: | 736 case 2: |
752 » » » » » » » So(ds.KeyForObj(ifs[i].(
PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,3") | 737 » » » » » » » So(KeyForObj(c, ifs[i].(
PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,3") |
753 case 3: | 738 case 3: |
754 » » » » » » » So(ds.KeyForObj(*ifs[i].
(*PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,4") | 739 » » » » » » » So(KeyForObj(c, *ifs[i].
(*PropertyMap)).String(), ShouldEqual, "s~aid:ns:/Pmap,4") |
755 } | 740 } |
756 } | 741 } |
757 }) | 742 }) |
758 }) | 743 }) |
759 }) | 744 }) |
760 | |
761 Convey("Testing PutMulti", func() { | |
762 Convey("Fails for something other than a slice.", func()
{ | |
763 cs := CommonStruct{} | |
764 So(func() { ds.PutMulti(&cs) }, ShouldPanicLike, | |
765 "argument must be a slice, not *datastor
e.CommonStruct") | |
766 }) | |
767 | |
768 Convey("Succeeds for a slice.", func() { | |
769 cs := []CommonStruct{{Value: 0}, {Value: 1}} | |
770 So(ds.PutMulti(cs), ShouldBeNil) | |
771 So(cs[0].ID, ShouldEqual, 1) | |
772 So(cs[1].ID, ShouldEqual, 2) | |
773 }) | |
774 | |
775 Convey("Returns an item error in a MultiError.", func()
{ | |
776 cs := []FakePLS{{Value: 0}, {Kind: "Fail"}} | |
777 err := ds.PutMulti(cs) | |
778 So(err, ShouldResemble, errors.MultiError{nil, e
rrFail}) | |
779 So(cs[0].IntID, ShouldEqual, 1) | |
780 }) | |
781 }) | |
782 }) | 745 }) |
783 } | 746 } |
784 | 747 |
785 func TestExists(t *testing.T) { | 748 func TestExists(t *testing.T) { |
786 t.Parallel() | 749 t.Parallel() |
787 | 750 |
788 Convey("A testing environment", t, func() { | 751 Convey("A testing environment", t, func() { |
789 c := info.Set(context.Background(), fakeInfo{}) | 752 c := info.Set(context.Background(), fakeInfo{}) |
790 c = SetRawFactory(c, fakeDatastoreFactory) | 753 c = SetRawFactory(c, fakeDatastoreFactory) |
791 ds := Get(c) | |
792 | 754 |
793 » » k := ds.MakeKey("Hello", "world") | 755 » » k := MakeKey(c, "Hello", "world") |
794 | 756 |
795 Convey("Exists", func() { | 757 Convey("Exists", func() { |
796 // Single key. | 758 // Single key. |
797 » » » er, err := ds.Exists(k) | 759 » » » er, err := Exists(c, k) |
798 So(err, ShouldBeNil) | 760 So(err, ShouldBeNil) |
799 So(er.All(), ShouldBeTrue) | 761 So(er.All(), ShouldBeTrue) |
800 | 762 |
801 // Single key failure. | 763 // Single key failure. |
802 » » » _, err = ds.Exists(ds.MakeKey("Fail", "boom")) | 764 » » » _, err = Exists(c, MakeKey(c, "Fail", "boom")) |
803 So(err, ShouldEqual, errFail) | 765 So(err, ShouldEqual, errFail) |
804 | 766 |
805 // Single slice of keys. | 767 // Single slice of keys. |
806 » » » er, err = ds.Exists([]*Key{k, ds.MakeKey("hello", "other
")}) | 768 » » » er, err = Exists(c, []*Key{k, MakeKey(c, "hello", "other
")}) |
807 So(err, ShouldBeNil) | 769 So(err, ShouldBeNil) |
808 So(er.All(), ShouldBeTrue) | 770 So(er.All(), ShouldBeTrue) |
809 | 771 |
810 // Single slice of keys failure. | 772 // Single slice of keys failure. |
811 » » » er, err = ds.Exists([]*Key{k, ds.MakeKey("Fail", "boom")
}) | 773 » » » er, err = Exists(c, []*Key{k, MakeKey(c, "Fail", "boom")
}) |
812 So(err, ShouldResemble, errors.MultiError{nil, errFail}) | 774 So(err, ShouldResemble, errors.MultiError{nil, errFail}) |
813 So(er.Get(0, 0), ShouldBeTrue) | 775 So(er.Get(0, 0), ShouldBeTrue) |
814 | 776 |
815 // Single key missing. | 777 // Single key missing. |
816 » » » er, err = ds.Exists(ds.MakeKey("DNE", "nope")) | 778 » » » er, err = Exists(c, MakeKey(c, "DNE", "nope")) |
817 So(err, ShouldBeNil) | 779 So(err, ShouldBeNil) |
818 So(er.Any(), ShouldBeFalse) | 780 So(er.Any(), ShouldBeFalse) |
819 | 781 |
820 // Multi-arg keys with one missing. | 782 // Multi-arg keys with one missing. |
821 » » » er, err = ds.Exists(k, ds.MakeKey("DNE", "other")) | 783 » » » er, err = Exists(c, k, MakeKey(c, "DNE", "other")) |
822 So(err, ShouldBeNil) | 784 So(err, ShouldBeNil) |
823 So(er.Get(0), ShouldBeTrue) | 785 So(er.Get(0), ShouldBeTrue) |
824 So(er.Get(1), ShouldBeFalse) | 786 So(er.Get(1), ShouldBeFalse) |
825 | 787 |
826 // Multi-arg keys with two missing. | 788 // Multi-arg keys with two missing. |
827 » » » er, err = ds.Exists(ds.MakeKey("DNE", "nope"), ds.MakeKe
y("DNE", "other")) | 789 » » » er, err = Exists(c, MakeKey(c, "DNE", "nope"), MakeKey(c
, "DNE", "other")) |
828 So(err, ShouldBeNil) | 790 So(err, ShouldBeNil) |
829 So(er.Any(), ShouldBeFalse) | 791 So(er.Any(), ShouldBeFalse) |
830 | 792 |
831 // Single struct pointer. | 793 // Single struct pointer. |
832 » » » er, err = ds.Exists(&CommonStruct{ID: 1}) | 794 » » » er, err = Exists(c, &CommonStruct{ID: 1}) |
833 So(err, ShouldBeNil) | 795 So(err, ShouldBeNil) |
834 So(er.All(), ShouldBeTrue) | 796 So(er.All(), ShouldBeTrue) |
835 | 797 |
836 // Multi-arg mixed key/struct/slices. | 798 // Multi-arg mixed key/struct/slices. |
837 » » » er, err = ds.Exists( | 799 » » » er, err = Exists(c, |
838 &CommonStruct{ID: 1}, | 800 &CommonStruct{ID: 1}, |
839 []*CommonStruct(nil), | 801 []*CommonStruct(nil), |
840 » » » » []*Key{ds.MakeKey("DNE", "nope"), ds.MakeKey("he
llo", "ohai")}, | 802 » » » » []*Key{MakeKey(c, "DNE", "nope"), MakeKey(c, "he
llo", "ohai")}, |
841 ) | 803 ) |
842 So(err, ShouldBeNil) | 804 So(err, ShouldBeNil) |
843 So(er.Get(0), ShouldBeTrue) | 805 So(er.Get(0), ShouldBeTrue) |
844 So(er.Get(1), ShouldBeTrue) | 806 So(er.Get(1), ShouldBeTrue) |
845 So(er.Get(2), ShouldBeFalse) | 807 So(er.Get(2), ShouldBeFalse) |
846 So(er.Get(2, 0), ShouldBeFalse) | 808 So(er.Get(2, 0), ShouldBeFalse) |
847 So(er.Get(2, 1), ShouldBeTrue) | 809 So(er.Get(2, 1), ShouldBeTrue) |
848 }) | 810 }) |
849 | |
850 Convey("ExistsMulti", func() { | |
851 Convey("Returns no error if there are no failures.", fun
c() { | |
852 bl, err := ds.ExistsMulti([]*Key{k, ds.MakeKey("
DNE", "nope"), ds.MakeKey("hello", "ohai")}) | |
853 So(err, ShouldBeNil) | |
854 So(bl, ShouldResemble, BoolList{true, false, tru
e}) | |
855 }) | |
856 | |
857 Convey("Returns an item error in a MultiError.", func()
{ | |
858 _, err := ds.ExistsMulti([]*Key{k, ds.MakeKey("F
ail", "boom")}) | |
859 So(err, ShouldResemble, errors.MultiError{nil, e
rrFail}) | |
860 }) | |
861 }) | |
862 }) | 811 }) |
863 } | 812 } |
864 | 813 |
865 func TestDelete(t *testing.T) { | 814 func TestDelete(t *testing.T) { |
866 t.Parallel() | 815 t.Parallel() |
867 | 816 |
868 Convey("A testing environment", t, func() { | 817 Convey("A testing environment", t, func() { |
869 c := info.Set(context.Background(), fakeInfo{}) | 818 c := info.Set(context.Background(), fakeInfo{}) |
870 c = SetRawFactory(c, fakeDatastoreFactory) | 819 c = SetRawFactory(c, fakeDatastoreFactory) |
871 ds := Get(c) | |
872 So(ds, ShouldNotBeNil) | |
873 | 820 |
874 Convey("Testing Delete", func() { | 821 Convey("Testing Delete", func() { |
875 Convey("bad", func() { | 822 Convey("bad", func() { |
876 Convey("get single error for RPC failure", func(
) { | 823 Convey("get single error for RPC failure", func(
) { |
877 keys := []*Key{ | 824 keys := []*Key{ |
878 » » » » » » MakeKey("s~aid", "ns", "FailAll"
, 1), | 825 » » » » » » MakeKey(c, "s~aid", "ns", "FailA
ll", 1), |
879 » » » » » » MakeKey("s~aid", "ns", "Ok", 1), | 826 » » » » » » MakeKey(c, "s~aid", "ns", "Ok",
1), |
880 } | 827 } |
881 » » » » » So(ds.Delete(keys), ShouldEqual, errFail
All) | 828 » » » » » So(Delete(c, keys), ShouldEqual, errFail
All) |
882 }) | 829 }) |
883 | 830 |
884 Convey("get multi error for individual failure",
func() { | 831 Convey("get multi error for individual failure",
func() { |
885 keys := []*Key{ | 832 keys := []*Key{ |
886 » » » » » » ds.MakeKey("Ok", 1), | 833 » » » » » » MakeKey(c, "Ok", 1), |
887 » » » » » » ds.MakeKey("Fail", 2), | 834 » » » » » » MakeKey(c, "Fail", 2), |
888 } | 835 } |
889 » » » » » So(ds.Delete(keys), ShouldResemble, erro
rs.MultiError{nil, errFail}) | 836 » » » » » So(Delete(c, keys), ShouldResemble, erro
rs.MultiError{nil, errFail}) |
890 }) | 837 }) |
891 | 838 |
892 Convey("put with non-modifyable type is an error
", func() { | 839 Convey("put with non-modifyable type is an error
", func() { |
893 cs := CommonStruct{} | 840 cs := CommonStruct{} |
894 » » » » » So(func() { ds.Put(cs) }, ShouldPanicLik
e, | 841 » » » » » So(func() { Put(c, cs) }, ShouldPanicLik
e, |
895 "invalid input type (datastore.C
ommonStruct): not a pointer") | 842 "invalid input type (datastore.C
ommonStruct): not a pointer") |
896 }) | 843 }) |
897 | 844 |
898 Convey("get single error when deleting a single"
, func() { | 845 Convey("get single error when deleting a single"
, func() { |
899 » » » » » k := ds.MakeKey("Fail", 1) | 846 » » » » » k := MakeKey(c, "Fail", 1) |
900 » » » » » So(ds.Delete(k), ShouldEqual, errFail) | 847 » » » » » So(Delete(c, k), ShouldEqual, errFail) |
901 }) | 848 }) |
902 }) | 849 }) |
903 | 850 |
904 Convey("good", func() { | 851 Convey("good", func() { |
905 // Single struct pointer. | 852 // Single struct pointer. |
906 » » » » So(ds.Delete(&CommonStruct{ID: 1}), ShouldBeNil) | 853 » » » » So(Delete(c, &CommonStruct{ID: 1}), ShouldBeNil) |
907 | 854 |
908 // Single key. | 855 // Single key. |
909 » » » » So(ds.Delete(ds.MakeKey("hello", "ohai")), Shoul
dBeNil) | 856 » » » » So(Delete(c, MakeKey(c, "hello", "ohai")), Shoul
dBeNil) |
910 | 857 |
911 // Single struct DNE. | 858 // Single struct DNE. |
912 » » » » So(ds.Delete(&CommonStruct{ID: noSuchEntityID}),
ShouldEqual, ErrNoSuchEntity) | 859 » » » » So(Delete(c, &CommonStruct{ID: noSuchEntityID}),
ShouldEqual, ErrNoSuchEntity) |
913 | 860 |
914 // Single key DNE. | 861 // Single key DNE. |
915 » » » » So(ds.Delete(ds.MakeKey("DNE", "nope")), ShouldE
qual, ErrNoSuchEntity) | 862 » » » » So(Delete(c, MakeKey(c, "DNE", "nope")), ShouldE
qual, ErrNoSuchEntity) |
916 | 863 |
917 // Mixed key/struct/slices. | 864 // Mixed key/struct/slices. |
918 » » » » err := ds.Delete( | 865 » » » » err := Delete(c, |
919 &CommonStruct{ID: 1}, | 866 &CommonStruct{ID: 1}, |
920 » » » » » []*Key{ds.MakeKey("hello", "ohai"), ds.M
akeKey("DNE", "nope")}, | 867 » » » » » []*Key{MakeKey(c, "hello", "ohai"), Make
Key(c, "DNE", "nope")}, |
921 ) | 868 ) |
922 So(err, ShouldResemble, errors.MultiError{nil, e
rrors.MultiError{nil, ErrNoSuchEntity}}) | 869 So(err, ShouldResemble, errors.MultiError{nil, e
rrors.MultiError{nil, ErrNoSuchEntity}}) |
923 }) | 870 }) |
924 }) | 871 }) |
925 | |
926 Convey("Testing DeleteMulti", func() { | |
927 Convey("Succeeds for valid keys.", func() { | |
928 So(ds.DeleteMulti([]*Key{ds.MakeKey("hello", "oh
ai")}), ShouldBeNil) | |
929 So(ds.DeleteMulti([]*Key{ds.MakeKey("hello", "oh
ai"), ds.MakeKey("hello", "sup")}), ShouldBeNil) | |
930 }) | |
931 | |
932 Convey("Returns an item error in a MultiError.", func()
{ | |
933 So(ds.DeleteMulti([]*Key{ds.MakeKey("DNE", "oops
")}), ShouldResemble, errors.MultiError{ErrNoSuchEntity}) | |
934 }) | |
935 }) | |
936 }) | 872 }) |
937 } | 873 } |
938 | 874 |
939 func TestGet(t *testing.T) { | 875 func TestGet(t *testing.T) { |
940 t.Parallel() | 876 t.Parallel() |
941 | 877 |
942 Convey("A testing environment", t, func() { | 878 Convey("A testing environment", t, func() { |
943 c := info.Set(context.Background(), fakeInfo{}) | 879 c := info.Set(context.Background(), fakeInfo{}) |
944 c = SetRawFactory(c, fakeDatastoreFactory) | 880 c = SetRawFactory(c, fakeDatastoreFactory) |
945 ds := Get(c) | |
946 So(ds, ShouldNotBeNil) | |
947 | 881 |
948 Convey("Testing Get", func() { | 882 Convey("Testing Get", func() { |
949 Convey("bad", func() { | 883 Convey("bad", func() { |
950 Convey("static can't serialize", func() { | 884 Convey("static can't serialize", func() { |
951 toGet := []badStruct{{}, {}} | 885 toGet := []badStruct{{}, {}} |
952 » » » » » So(func() { ds.Get(toGet) }, ShouldPanic
Like, | 886 » » » » » So(func() { Get(c, toGet) }, ShouldPanic
Like, |
953 `field "Compy" has invalid type:
complex64`) | 887 `field "Compy" has invalid type:
complex64`) |
954 }) | 888 }) |
955 | 889 |
956 Convey("can't get keys", func() { | 890 Convey("can't get keys", func() { |
957 fplss := []FakePLS{{failGetMeta: true},
{}} | 891 fplss := []FakePLS{{failGetMeta: true},
{}} |
958 » » » » » So(ds.Get(fplss), ShouldErrLike, "unable
to extract $kind") | 892 » » » » » So(Get(c, fplss), ShouldErrLike, "unable
to extract $kind") |
959 }) | 893 }) |
960 | 894 |
961 Convey("get single error for RPC failure", func(
) { | 895 Convey("get single error for RPC failure", func(
) { |
962 fplss := []FakePLS{ | 896 fplss := []FakePLS{ |
963 {IntID: 1, Kind: "FailAll"}, | 897 {IntID: 1, Kind: "FailAll"}, |
964 {IntID: 2}, | 898 {IntID: 2}, |
965 } | 899 } |
966 » » » » » So(ds.Get(fplss), ShouldEqual, errFailAl
l) | 900 » » » » » So(Get(c, fplss), ShouldEqual, errFailAl
l) |
967 }) | 901 }) |
968 | 902 |
969 Convey("get multi error for individual failures"
, func() { | 903 Convey("get multi error for individual failures"
, func() { |
970 fplss := []FakePLS{{IntID: 1}, {IntID: 2
, Kind: "Fail"}} | 904 fplss := []FakePLS{{IntID: 1}, {IntID: 2
, Kind: "Fail"}} |
971 » » » » » So(ds.Get(fplss), ShouldResemble, errors
.MultiError{nil, errFail}) | 905 » » » » » So(Get(c, fplss), ShouldResemble, errors
.MultiError{nil, errFail}) |
972 }) | 906 }) |
973 | 907 |
974 Convey("get with non-modifiable type is an error
", func() { | 908 Convey("get with non-modifiable type is an error
", func() { |
975 cs := CommonStruct{} | 909 cs := CommonStruct{} |
976 » » » » » So(func() { ds.Get(cs) }, ShouldPanicLik
e, | 910 » » » » » So(func() { Get(c, cs) }, ShouldPanicLik
e, |
977 "invalid input type (datastore.C
ommonStruct): not a pointer") | 911 "invalid input type (datastore.C
ommonStruct): not a pointer") |
978 }) | 912 }) |
979 | 913 |
980 Convey("get with nil is an error", func() { | 914 Convey("get with nil is an error", func() { |
981 » » » » » So(func() { ds.Get(nil) }, ShouldPanicLi
ke, | 915 » » » » » So(func() { Get(c, nil) }, ShouldPanicLi
ke, |
982 "cannot use nil as single argume
nt") | 916 "cannot use nil as single argume
nt") |
983 }) | 917 }) |
984 | 918 |
985 Convey("get with ptr-to-nonstruct is an error",
func() { | 919 Convey("get with ptr-to-nonstruct is an error",
func() { |
986 val := 100 | 920 val := 100 |
987 » » » » » So(func() { ds.Get(&val) }, ShouldPanicL
ike, | 921 » » » » » So(func() { Get(c, &val) }, ShouldPanicL
ike, |
988 "invalid input type (*int): not
a PLS, pointer-to-struct, or slice thereof") | 922 "invalid input type (*int): not
a PLS, pointer-to-struct, or slice thereof") |
989 }) | 923 }) |
990 | 924 |
991 Convey("failure to save metadata is no problem t
hough", func() { | 925 Convey("failure to save metadata is no problem t
hough", func() { |
992 // It just won't save the key | 926 // It just won't save the key |
993 cs := &FakePLS{IntID: 10, failSetMeta: t
rue} | 927 cs := &FakePLS{IntID: 10, failSetMeta: t
rue} |
994 » » » » » So(ds.Get(cs), ShouldBeNil) | 928 » » » » » So(Get(c, cs), ShouldBeNil) |
995 }) | 929 }) |
996 | 930 |
997 Convey("vararg with errors", func() { | 931 Convey("vararg with errors", func() { |
998 successSlice := []CommonStruct{{ID: 1},
{ID: 2}} | 932 successSlice := []CommonStruct{{ID: 1},
{ID: 2}} |
999 failSlice := []CommonStruct{{ID: noSuchE
ntityID}, {ID: 3}} | 933 failSlice := []CommonStruct{{ID: noSuchE
ntityID}, {ID: 3}} |
1000 emptySlice := []CommonStruct(nil) | 934 emptySlice := []CommonStruct(nil) |
1001 cs0 := CommonStruct{ID: 4} | 935 cs0 := CommonStruct{ID: 4} |
1002 failPLS := CommonStruct{ID: noSuchEntity
ID} | 936 failPLS := CommonStruct{ID: noSuchEntity
ID} |
1003 fpls := FakePLS{StringID: "ohai"} | 937 fpls := FakePLS{StringID: "ohai"} |
1004 | 938 |
1005 » » » » » err := ds.Get(successSlice, failSlice, e
mptySlice, &cs0, &failPLS, &fpls) | 939 » » » » » err := Get(c, successSlice, failSlice, e
mptySlice, &cs0, &failPLS, &fpls) |
1006 So(err, ShouldResemble, errors.MultiErro
r{ | 940 So(err, ShouldResemble, errors.MultiErro
r{ |
1007 nil, errors.MultiError{ErrNoSuch
Entity, nil}, nil, nil, ErrNoSuchEntity, nil}) | 941 nil, errors.MultiError{ErrNoSuch
Entity, nil}, nil, nil, ErrNoSuchEntity, nil}) |
1008 So(successSlice[0].Value, ShouldEqual, 1
) | 942 So(successSlice[0].Value, ShouldEqual, 1
) |
1009 So(successSlice[1].Value, ShouldEqual, 2
) | 943 So(successSlice[1].Value, ShouldEqual, 2
) |
1010 So(cs0.Value, ShouldEqual, 5) | 944 So(cs0.Value, ShouldEqual, 5) |
1011 So(fpls.Value, ShouldEqual, 7) | 945 So(fpls.Value, ShouldEqual, 7) |
1012 }) | 946 }) |
1013 }) | 947 }) |
1014 | 948 |
1015 Convey("ok", func() { | 949 Convey("ok", func() { |
1016 Convey("Get", func() { | 950 Convey("Get", func() { |
1017 cs := &CommonStruct{ID: 1} | 951 cs := &CommonStruct{ID: 1} |
1018 » » » » » So(ds.Get(cs), ShouldBeNil) | 952 » » » » » So(Get(c, cs), ShouldBeNil) |
1019 So(cs.Value, ShouldEqual, 1) | 953 So(cs.Value, ShouldEqual, 1) |
1020 }) | 954 }) |
1021 | 955 |
1022 Convey("Raw access too", func() { | 956 Convey("Raw access too", func() { |
1023 » » » » » rds := ds.Raw() | 957 » » » » » rds := Raw(c) |
1024 » » » » » keys := []*Key{ds.MakeKey("Kind", 1)} | 958 » » » » » keys := []*Key{MakeKey(c, "Kind", 1)} |
1025 So(rds.GetMulti(keys, nil, func(pm Prope
rtyMap, err error) error { | 959 So(rds.GetMulti(keys, nil, func(pm Prope
rtyMap, err error) error { |
1026 So(err, ShouldBeNil) | 960 So(err, ShouldBeNil) |
1027 So(pm["Value"][0].Value(), Shoul
dEqual, 1) | 961 So(pm["Value"][0].Value(), Shoul
dEqual, 1) |
1028 return nil | 962 return nil |
1029 }), ShouldBeNil) | 963 }), ShouldBeNil) |
1030 }) | 964 }) |
1031 | 965 |
1032 Convey("but general failure to save is fine on a
Get", func() { | 966 Convey("but general failure to save is fine on a
Get", func() { |
1033 cs := &FakePLS{failSave: true, IntID: 7} | 967 cs := &FakePLS{failSave: true, IntID: 7} |
1034 » » » » » So(ds.Get(cs), ShouldBeNil) | 968 » » » » » So(Get(c, cs), ShouldBeNil) |
1035 }) | 969 }) |
1036 | 970 |
1037 Convey("vararg", func() { | 971 Convey("vararg", func() { |
1038 successSlice := []CommonStruct{{ID: 1},
{ID: 2}} | 972 successSlice := []CommonStruct{{ID: 1},
{ID: 2}} |
1039 cs := CommonStruct{ID: 3} | 973 cs := CommonStruct{ID: 3} |
1040 | 974 |
1041 » » » » » err := ds.Get(successSlice, &cs) | 975 » » » » » err := Get(c, successSlice, &cs) |
1042 So(err, ShouldBeNil) | 976 So(err, ShouldBeNil) |
1043 So(successSlice[0].Value, ShouldEqual, 1
) | 977 So(successSlice[0].Value, ShouldEqual, 1
) |
1044 So(successSlice[1].Value, ShouldEqual, 2
) | 978 So(successSlice[1].Value, ShouldEqual, 2
) |
1045 So(cs.Value, ShouldEqual, 3) | 979 So(cs.Value, ShouldEqual, 3) |
1046 }) | 980 }) |
1047 }) | 981 }) |
1048 }) | 982 }) |
1049 | |
1050 Convey("Testing GetMulti", func() { | |
1051 Convey("Fails for something other than a slice.", func()
{ | |
1052 cs := CommonStruct{} | |
1053 So(func() { ds.GetMulti(&cs) }, ShouldPanicLike, | |
1054 "argument must be a slice, not *datastor
e.CommonStruct") | |
1055 }) | |
1056 | |
1057 Convey("Succeeds for a slice.", func() { | |
1058 cs := []CommonStruct{{ID: 1}} | |
1059 So(ds.GetMulti(cs), ShouldBeNil) | |
1060 So(cs[0].Value, ShouldEqual, 1) | |
1061 }) | |
1062 | |
1063 Convey("Returns an item error in a MultiError.", func()
{ | |
1064 cs := []CommonStruct{{ID: 1}, {ID: noSuchEntityI
D}} | |
1065 err := ds.GetMulti(cs) | |
1066 So(err, ShouldResemble, errors.MultiError{nil, E
rrNoSuchEntity}) | |
1067 So(cs[0].Value, ShouldEqual, 1) | |
1068 }) | |
1069 }) | |
1070 }) | 983 }) |
1071 } | 984 } |
1072 | 985 |
1073 func TestGetAll(t *testing.T) { | 986 func TestGetAll(t *testing.T) { |
1074 t.Parallel() | 987 t.Parallel() |
1075 | 988 |
1076 Convey("Test GetAll", t, func() { | 989 Convey("Test GetAll", t, func() { |
1077 c := info.Set(context.Background(), fakeInfo{}) | 990 c := info.Set(context.Background(), fakeInfo{}) |
1078 c = SetRawFactory(c, fakeDatastoreFactory) | 991 c = SetRawFactory(c, fakeDatastoreFactory) |
1079 ds := Get(c) | |
1080 So(ds, ShouldNotBeNil) | |
1081 | 992 |
1082 q := NewQuery("").Limit(5) | 993 q := NewQuery("").Limit(5) |
1083 | 994 |
1084 Convey("bad", func() { | 995 Convey("bad", func() { |
1085 Convey("nil target", func() { | 996 Convey("nil target", func() { |
1086 » » » » So(func() { ds.GetAll(q, (*[]PropertyMap)(nil))
}, ShouldPanicLike, | 997 » » » » So(func() { GetAll(c, q, (*[]PropertyMap)(nil))
}, ShouldPanicLike, |
1087 "invalid GetAll dst: <nil>") | 998 "invalid GetAll dst: <nil>") |
1088 }) | 999 }) |
1089 | 1000 |
1090 Convey("bad type", func() { | 1001 Convey("bad type", func() { |
1091 output := 100 | 1002 output := 100 |
1092 » » » » So(func() { ds.GetAll(q, &output) }, ShouldPanic
Like, | 1003 » » » » So(func() { GetAll(c, q, &output) }, ShouldPanic
Like, |
1093 "invalid argument type: expected slice,
got int") | 1004 "invalid argument type: expected slice,
got int") |
1094 }) | 1005 }) |
1095 | 1006 |
1096 Convey("bad type (non pointer)", func() { | 1007 Convey("bad type (non pointer)", func() { |
1097 » » » » So(func() { ds.GetAll(q, "moo") }, ShouldPanicLi
ke, | 1008 » » » » So(func() { GetAll(c, q, "moo") }, ShouldPanicLi
ke, |
1098 "invalid GetAll dst: must have a ptr-to-
slice") | 1009 "invalid GetAll dst: must have a ptr-to-
slice") |
1099 }) | 1010 }) |
1100 | 1011 |
1101 Convey("bad type (underspecified)", func() { | 1012 Convey("bad type (underspecified)", func() { |
1102 output := []PropertyLoadSaver(nil) | 1013 output := []PropertyLoadSaver(nil) |
1103 » » » » So(func() { ds.GetAll(q, &output) }, ShouldPanic
Like, | 1014 » » » » So(func() { GetAll(c, q, &output) }, ShouldPanic
Like, |
1104 "invalid GetAll dst (non-concrete elemen
t type): *[]datastore.PropertyLoadSaver") | 1015 "invalid GetAll dst (non-concrete elemen
t type): *[]datastore.PropertyLoadSaver") |
1105 }) | 1016 }) |
1106 }) | 1017 }) |
1107 | 1018 |
1108 Convey("ok", func() { | 1019 Convey("ok", func() { |
1109 Convey("*[]S", func() { | 1020 Convey("*[]S", func() { |
1110 output := []CommonStruct(nil) | 1021 output := []CommonStruct(nil) |
1111 » » » » So(ds.GetAll(q, &output), ShouldBeNil) | 1022 » » » » So(GetAll(c, q, &output), ShouldBeNil) |
1112 So(len(output), ShouldEqual, 5) | 1023 So(len(output), ShouldEqual, 5) |
1113 for i, o := range output { | 1024 for i, o := range output { |
1114 So(o.ID, ShouldEqual, i+1) | 1025 So(o.ID, ShouldEqual, i+1) |
1115 So(o.Value, ShouldEqual, i) | 1026 So(o.Value, ShouldEqual, i) |
1116 } | 1027 } |
1117 }) | 1028 }) |
1118 | 1029 |
1119 Convey("*[]*S", func() { | 1030 Convey("*[]*S", func() { |
1120 output := []*CommonStruct(nil) | 1031 output := []*CommonStruct(nil) |
1121 » » » » So(ds.GetAll(q, &output), ShouldBeNil) | 1032 » » » » So(GetAll(c, q, &output), ShouldBeNil) |
1122 So(len(output), ShouldEqual, 5) | 1033 So(len(output), ShouldEqual, 5) |
1123 for i, o := range output { | 1034 for i, o := range output { |
1124 So(o.ID, ShouldEqual, i+1) | 1035 So(o.ID, ShouldEqual, i+1) |
1125 So(o.Value, ShouldEqual, i) | 1036 So(o.Value, ShouldEqual, i) |
1126 } | 1037 } |
1127 }) | 1038 }) |
1128 | 1039 |
1129 Convey("*[]P", func() { | 1040 Convey("*[]P", func() { |
1130 output := []FakePLS(nil) | 1041 output := []FakePLS(nil) |
1131 » » » » So(ds.GetAll(q, &output), ShouldBeNil) | 1042 » » » » So(GetAll(c, q, &output), ShouldBeNil) |
1132 So(len(output), ShouldEqual, 5) | 1043 So(len(output), ShouldEqual, 5) |
1133 for i, o := range output { | 1044 for i, o := range output { |
1134 So(o.gotLoaded, ShouldBeTrue) | 1045 So(o.gotLoaded, ShouldBeTrue) |
1135 So(o.IntID, ShouldEqual, i+1) | 1046 So(o.IntID, ShouldEqual, i+1) |
1136 So(o.Value, ShouldEqual, i) | 1047 So(o.Value, ShouldEqual, i) |
1137 } | 1048 } |
1138 }) | 1049 }) |
1139 | 1050 |
1140 Convey("*[]P (map)", func() { | 1051 Convey("*[]P (map)", func() { |
1141 output := []PropertyMap(nil) | 1052 output := []PropertyMap(nil) |
1142 » » » » So(ds.GetAll(q, &output), ShouldBeNil) | 1053 » » » » So(GetAll(c, q, &output), ShouldBeNil) |
1143 So(len(output), ShouldEqual, 5) | 1054 So(len(output), ShouldEqual, 5) |
1144 for i, o := range output { | 1055 for i, o := range output { |
1145 k, ok := o.GetMeta("key") | 1056 k, ok := o.GetMeta("key") |
1146 So(ok, ShouldBeTrue) | 1057 So(ok, ShouldBeTrue) |
1147 So(k.(*Key).IntID(), ShouldEqual, i+1) | 1058 So(k.(*Key).IntID(), ShouldEqual, i+1) |
1148 So(o["Value"][0].Value().(int64), Should
Equal, i) | 1059 So(o["Value"][0].Value().(int64), Should
Equal, i) |
1149 } | 1060 } |
1150 }) | 1061 }) |
1151 | 1062 |
1152 Convey("*[]P (chan)", func() { | 1063 Convey("*[]P (chan)", func() { |
1153 output := []plsChan(nil) | 1064 output := []plsChan(nil) |
1154 » » » » So(ds.GetAll(q, &output), ShouldBeNil) | 1065 » » » » So(GetAll(c, q, &output), ShouldBeNil) |
1155 So(output, ShouldHaveLength, 5) | 1066 So(output, ShouldHaveLength, 5) |
1156 for _, o := range output { | 1067 for _, o := range output { |
1157 » » » » » So(ds.KeyForObj(o).StringID(), ShouldEqu
al, "whyDoIExist") | 1068 » » » » » So(KeyForObj(c, o).StringID(), ShouldEqu
al, "whyDoIExist") |
1158 } | 1069 } |
1159 }) | 1070 }) |
1160 | 1071 |
1161 Convey("*[]*P", func() { | 1072 Convey("*[]*P", func() { |
1162 output := []*FakePLS(nil) | 1073 output := []*FakePLS(nil) |
1163 » » » » So(ds.GetAll(q, &output), ShouldBeNil) | 1074 » » » » So(GetAll(c, q, &output), ShouldBeNil) |
1164 So(len(output), ShouldEqual, 5) | 1075 So(len(output), ShouldEqual, 5) |
1165 for i, o := range output { | 1076 for i, o := range output { |
1166 So(o.gotLoaded, ShouldBeTrue) | 1077 So(o.gotLoaded, ShouldBeTrue) |
1167 So(o.IntID, ShouldEqual, i+1) | 1078 So(o.IntID, ShouldEqual, i+1) |
1168 So(o.Value, ShouldEqual, i) | 1079 So(o.Value, ShouldEqual, i) |
1169 } | 1080 } |
1170 }) | 1081 }) |
1171 | 1082 |
1172 Convey("*[]*P (map)", func() { | 1083 Convey("*[]*P (map)", func() { |
1173 output := []*PropertyMap(nil) | 1084 output := []*PropertyMap(nil) |
1174 » » » » So(ds.GetAll(q, &output), ShouldBeNil) | 1085 » » » » So(GetAll(c, q, &output), ShouldBeNil) |
1175 So(len(output), ShouldEqual, 5) | 1086 So(len(output), ShouldEqual, 5) |
1176 for i, op := range output { | 1087 for i, op := range output { |
1177 o := *op | 1088 o := *op |
1178 k, ok := o.GetMeta("key") | 1089 k, ok := o.GetMeta("key") |
1179 So(ok, ShouldBeTrue) | 1090 So(ok, ShouldBeTrue) |
1180 So(k.(*Key).IntID(), ShouldEqual, i+1) | 1091 So(k.(*Key).IntID(), ShouldEqual, i+1) |
1181 So(o["Value"][0].Value().(int64), Should
Equal, i) | 1092 So(o["Value"][0].Value().(int64), Should
Equal, i) |
1182 } | 1093 } |
1183 }) | 1094 }) |
1184 | 1095 |
1185 Convey("*[]*P (chan)", func() { | 1096 Convey("*[]*P (chan)", func() { |
1186 output := []*plsChan(nil) | 1097 output := []*plsChan(nil) |
1187 » » » » So(ds.GetAll(q, &output), ShouldBeNil) | 1098 » » » » So(GetAll(c, q, &output), ShouldBeNil) |
1188 So(output, ShouldHaveLength, 5) | 1099 So(output, ShouldHaveLength, 5) |
1189 for _, o := range output { | 1100 for _, o := range output { |
1190 » » » » » So(ds.KeyForObj(o).StringID(), ShouldEqu
al, "whyDoIExist") | 1101 » » » » » So(KeyForObj(c, o).StringID(), ShouldEqu
al, "whyDoIExist") |
1191 } | 1102 } |
1192 }) | 1103 }) |
1193 | 1104 |
1194 Convey("*[]*Key", func() { | 1105 Convey("*[]*Key", func() { |
1195 output := []*Key(nil) | 1106 output := []*Key(nil) |
1196 » » » » So(ds.GetAll(q, &output), ShouldBeNil) | 1107 » » » » So(GetAll(c, q, &output), ShouldBeNil) |
1197 So(len(output), ShouldEqual, 5) | 1108 So(len(output), ShouldEqual, 5) |
1198 for i, k := range output { | 1109 for i, k := range output { |
1199 So(k.IntID(), ShouldEqual, i+1) | 1110 So(k.IntID(), ShouldEqual, i+1) |
1200 } | 1111 } |
1201 }) | 1112 }) |
1202 | 1113 |
1203 }) | 1114 }) |
1204 }) | 1115 }) |
1205 } | 1116 } |
1206 | 1117 |
1207 func TestRun(t *testing.T) { | 1118 func TestRun(t *testing.T) { |
1208 t.Parallel() | 1119 t.Parallel() |
1209 | 1120 |
1210 Convey("Test Run", t, func() { | 1121 Convey("Test Run", t, func() { |
1211 c := info.Set(context.Background(), fakeInfo{}) | 1122 c := info.Set(context.Background(), fakeInfo{}) |
1212 c = SetRawFactory(c, fakeDatastoreFactory) | 1123 c = SetRawFactory(c, fakeDatastoreFactory) |
1213 ds := Get(c) | |
1214 So(ds, ShouldNotBeNil) | |
1215 | 1124 |
1216 q := NewQuery("kind").Limit(5) | 1125 q := NewQuery("kind").Limit(5) |
1217 | 1126 |
1218 Convey("bad", func() { | 1127 Convey("bad", func() { |
1219 assertBadTypePanics := func(cb interface{}) { | 1128 assertBadTypePanics := func(cb interface{}) { |
1220 » » » » So(func() { ds.Run(q, cb) }, ShouldPanicLike, | 1129 » » » » So(func() { Run(c, q, cb) }, ShouldPanicLike, |
1221 "cb does not match the required callback
signature") | 1130 "cb does not match the required callback
signature") |
1222 } | 1131 } |
1223 | 1132 |
1224 Convey("not a function", func() { | 1133 Convey("not a function", func() { |
1225 assertBadTypePanics("I am a potato") | 1134 assertBadTypePanics("I am a potato") |
1226 }) | 1135 }) |
1227 | 1136 |
1228 Convey("nil", func() { | 1137 Convey("nil", func() { |
1229 assertBadTypePanics(nil) | 1138 assertBadTypePanics(nil) |
1230 }) | 1139 }) |
1231 | 1140 |
1232 Convey("interface", func() { | 1141 Convey("interface", func() { |
1233 assertBadTypePanics(func(pls PropertyLoadSaver)
{}) | 1142 assertBadTypePanics(func(pls PropertyLoadSaver)
{}) |
1234 }) | 1143 }) |
1235 | 1144 |
1236 Convey("bad proto type", func() { | 1145 Convey("bad proto type", func() { |
1237 cb := func(v int) { | 1146 cb := func(v int) { |
1238 panic("never here!") | 1147 panic("never here!") |
1239 } | 1148 } |
1240 » » » » So(func() { ds.Run(q, cb) }, ShouldPanicLike, | 1149 » » » » So(func() { Run(c, q, cb) }, ShouldPanicLike, |
1241 "invalid argument type: int is not a PLS
or pointer-to-struct") | 1150 "invalid argument type: int is not a PLS
or pointer-to-struct") |
1242 }) | 1151 }) |
1243 | 1152 |
1244 Convey("wrong # args", func() { | 1153 Convey("wrong # args", func() { |
1245 assertBadTypePanics(func(v CommonStruct, _ Curso
rCB, _ int) { | 1154 assertBadTypePanics(func(v CommonStruct, _ Curso
rCB, _ int) { |
1246 panic("never here!") | 1155 panic("never here!") |
1247 }) | 1156 }) |
1248 }) | 1157 }) |
1249 | 1158 |
1250 Convey("wrong ret type", func() { | 1159 Convey("wrong ret type", func() { |
(...skipping 10 matching lines...) Expand all Loading... |
1261 | 1170 |
1262 Convey("bad 2nd arg", func() { | 1171 Convey("bad 2nd arg", func() { |
1263 assertBadTypePanics(func(v CommonStruct, _ Curso
r) error { | 1172 assertBadTypePanics(func(v CommonStruct, _ Curso
r) error { |
1264 panic("never here!") | 1173 panic("never here!") |
1265 }) | 1174 }) |
1266 }) | 1175 }) |
1267 | 1176 |
1268 Convey("early abort on error", func() { | 1177 Convey("early abort on error", func() { |
1269 q = q.Eq("$err_single", "Query fail").Eq("$err_s
ingle_idx", 3) | 1178 q = q.Eq("$err_single", "Query fail").Eq("$err_s
ingle_idx", 3) |
1270 i := 0 | 1179 i := 0 |
1271 » » » » So(ds.Run(q, func(c CommonStruct) { | 1180 » » » » So(Run(c, q, func(c CommonStruct) { |
1272 i++ | 1181 i++ |
1273 }), ShouldErrLike, "Query fail") | 1182 }), ShouldErrLike, "Query fail") |
1274 So(i, ShouldEqual, 3) | 1183 So(i, ShouldEqual, 3) |
1275 }) | 1184 }) |
1276 | 1185 |
1277 Convey("return error on serialization failure", func() { | 1186 Convey("return error on serialization failure", func() { |
1278 » » » » So(ds.Run(q, func(_ permaBad) { | 1187 » » » » So(Run(c, q, func(_ permaBad) { |
1279 panic("never here") | 1188 panic("never here") |
1280 }).Error(), ShouldEqual, "permaBad") | 1189 }).Error(), ShouldEqual, "permaBad") |
1281 }) | 1190 }) |
1282 }) | 1191 }) |
1283 | 1192 |
1284 Convey("ok", func() { | 1193 Convey("ok", func() { |
1285 Convey("can return error to stop", func() { | 1194 Convey("can return error to stop", func() { |
1286 i := 0 | 1195 i := 0 |
1287 » » » » So(ds.Run(q, func(c CommonStruct) error { | 1196 » » » » So(Run(c, q, func(c CommonStruct) error { |
1288 i++ | 1197 i++ |
1289 return Stop | 1198 return Stop |
1290 }), ShouldBeNil) | 1199 }), ShouldBeNil) |
1291 So(i, ShouldEqual, 1) | 1200 So(i, ShouldEqual, 1) |
1292 | 1201 |
1293 i = 0 | 1202 i = 0 |
1294 » » » » So(ds.Run(q, func(c CommonStruct, _ CursorCB) er
ror { | 1203 » » » » So(Run(c, q, func(c CommonStruct, _ CursorCB) er
ror { |
1295 i++ | 1204 i++ |
1296 return fmt.Errorf("my error") | 1205 return fmt.Errorf("my error") |
1297 }), ShouldErrLike, "my error") | 1206 }), ShouldErrLike, "my error") |
1298 So(i, ShouldEqual, 1) | 1207 So(i, ShouldEqual, 1) |
1299 }) | 1208 }) |
1300 | 1209 |
1301 Convey("Can optionally get cursor function", func() { | 1210 Convey("Can optionally get cursor function", func() { |
1302 i := 0 | 1211 i := 0 |
1303 » » » » So(ds.Run(q, func(c CommonStruct, ccb CursorCB)
{ | 1212 » » » » So(Run(c, q, func(c CommonStruct, ccb CursorCB)
{ |
1304 i++ | 1213 i++ |
1305 curs, err := ccb() | 1214 curs, err := ccb() |
1306 So(err, ShouldBeNil) | 1215 So(err, ShouldBeNil) |
1307 So(curs.String(), ShouldEqual, "CURSOR") | 1216 So(curs.String(), ShouldEqual, "CURSOR") |
1308 }), ShouldBeNil) | 1217 }), ShouldBeNil) |
1309 So(i, ShouldEqual, 5) | 1218 So(i, ShouldEqual, 5) |
1310 }) | 1219 }) |
1311 | 1220 |
1312 Convey("*S", func() { | 1221 Convey("*S", func() { |
1313 i := 0 | 1222 i := 0 |
1314 » » » » So(ds.Run(q, func(cs *CommonStruct) { | 1223 » » » » So(Run(c, q, func(cs *CommonStruct) { |
1315 So(cs.ID, ShouldEqual, i+1) | 1224 So(cs.ID, ShouldEqual, i+1) |
1316 So(cs.Value, ShouldEqual, i) | 1225 So(cs.Value, ShouldEqual, i) |
1317 i++ | 1226 i++ |
1318 }), ShouldBeNil) | 1227 }), ShouldBeNil) |
1319 }) | 1228 }) |
1320 | 1229 |
1321 Convey("*P", func() { | 1230 Convey("*P", func() { |
1322 i := 0 | 1231 i := 0 |
1323 » » » » So(ds.Run(q.Limit(12), func(fpls *FakePLS) { | 1232 » » » » So(Run(c, q.Limit(12), func(fpls *FakePLS) { |
1324 So(fpls.gotLoaded, ShouldBeTrue) | 1233 So(fpls.gotLoaded, ShouldBeTrue) |
1325 if i == 10 { | 1234 if i == 10 { |
1326 So(fpls.StringID, ShouldEqual, "
eleven") | 1235 So(fpls.StringID, ShouldEqual, "
eleven") |
1327 } else { | 1236 } else { |
1328 So(fpls.IntID, ShouldEqual, i+1) | 1237 So(fpls.IntID, ShouldEqual, i+1) |
1329 } | 1238 } |
1330 So(fpls.Value, ShouldEqual, i) | 1239 So(fpls.Value, ShouldEqual, i) |
1331 i++ | 1240 i++ |
1332 }), ShouldBeNil) | 1241 }), ShouldBeNil) |
1333 }) | 1242 }) |
1334 | 1243 |
1335 Convey("*P (map)", func() { | 1244 Convey("*P (map)", func() { |
1336 i := 0 | 1245 i := 0 |
1337 » » » » So(ds.Run(q, func(pm *PropertyMap) { | 1246 » » » » So(Run(c, q, func(pm *PropertyMap) { |
1338 k, ok := pm.GetMeta("key") | 1247 k, ok := pm.GetMeta("key") |
1339 So(ok, ShouldBeTrue) | 1248 So(ok, ShouldBeTrue) |
1340 So(k.(*Key).IntID(), ShouldEqual, i+1) | 1249 So(k.(*Key).IntID(), ShouldEqual, i+1) |
1341 So((*pm)["Value"][0].Value(), ShouldEqua
l, i) | 1250 So((*pm)["Value"][0].Value(), ShouldEqua
l, i) |
1342 i++ | 1251 i++ |
1343 }), ShouldBeNil) | 1252 }), ShouldBeNil) |
1344 }) | 1253 }) |
1345 | 1254 |
1346 Convey("*P (chan)", func() { | 1255 Convey("*P (chan)", func() { |
1347 » » » » So(ds.Run(q, func(c *plsChan) { | 1256 » » » » So(Run(c, q, func(ch *plsChan) { |
1348 » » » » » So(ds.KeyForObj(c).StringID(), ShouldEqu
al, "whyDoIExist") | 1257 » » » » » So(KeyForObj(c, ch).StringID(), ShouldEq
ual, "whyDoIExist") |
1349 }), ShouldBeNil) | 1258 }), ShouldBeNil) |
1350 }) | 1259 }) |
1351 | 1260 |
1352 Convey("S", func() { | 1261 Convey("S", func() { |
1353 i := 0 | 1262 i := 0 |
1354 » » » » So(ds.Run(q, func(cs CommonStruct) { | 1263 » » » » So(Run(c, q, func(cs CommonStruct) { |
1355 So(cs.ID, ShouldEqual, i+1) | 1264 So(cs.ID, ShouldEqual, i+1) |
1356 So(cs.Value, ShouldEqual, i) | 1265 So(cs.Value, ShouldEqual, i) |
1357 i++ | 1266 i++ |
1358 }), ShouldBeNil) | 1267 }), ShouldBeNil) |
1359 }) | 1268 }) |
1360 | 1269 |
1361 Convey("P", func() { | 1270 Convey("P", func() { |
1362 i := 0 | 1271 i := 0 |
1363 » » » » So(ds.Run(q, func(fpls FakePLS) { | 1272 » » » » So(Run(c, q, func(fpls FakePLS) { |
1364 So(fpls.gotLoaded, ShouldBeTrue) | 1273 So(fpls.gotLoaded, ShouldBeTrue) |
1365 So(fpls.IntID, ShouldEqual, i+1) | 1274 So(fpls.IntID, ShouldEqual, i+1) |
1366 So(fpls.Value, ShouldEqual, i) | 1275 So(fpls.Value, ShouldEqual, i) |
1367 i++ | 1276 i++ |
1368 }), ShouldBeNil) | 1277 }), ShouldBeNil) |
1369 }) | 1278 }) |
1370 | 1279 |
1371 Convey("P (map)", func() { | 1280 Convey("P (map)", func() { |
1372 i := 0 | 1281 i := 0 |
1373 » » » » So(ds.Run(q, func(pm PropertyMap) { | 1282 » » » » So(Run(c, q, func(pm PropertyMap) { |
1374 k, ok := pm.GetMeta("key") | 1283 k, ok := pm.GetMeta("key") |
1375 So(ok, ShouldBeTrue) | 1284 So(ok, ShouldBeTrue) |
1376 So(k.(*Key).IntID(), ShouldEqual, i+1) | 1285 So(k.(*Key).IntID(), ShouldEqual, i+1) |
1377 So(pm["Value"][0].Value(), ShouldEqual,
i) | 1286 So(pm["Value"][0].Value(), ShouldEqual,
i) |
1378 i++ | 1287 i++ |
1379 }), ShouldBeNil) | 1288 }), ShouldBeNil) |
1380 }) | 1289 }) |
1381 | 1290 |
1382 Convey("P (chan)", func() { | 1291 Convey("P (chan)", func() { |
1383 » » » » So(ds.Run(q, func(c plsChan) { | 1292 » » » » So(Run(c, q, func(ch plsChan) { |
1384 » » » » » So(ds.KeyForObj(c).StringID(), ShouldEqu
al, "whyDoIExist") | 1293 » » » » » So(KeyForObj(c, ch).StringID(), ShouldEq
ual, "whyDoIExist") |
1385 }), ShouldBeNil) | 1294 }), ShouldBeNil) |
1386 }) | 1295 }) |
1387 | 1296 |
1388 Convey("Key", func() { | 1297 Convey("Key", func() { |
1389 i := 0 | 1298 i := 0 |
1390 » » » » So(ds.Run(q, func(k *Key) { | 1299 » » » » So(Run(c, q, func(k *Key) { |
1391 So(k.IntID(), ShouldEqual, i+1) | 1300 So(k.IntID(), ShouldEqual, i+1) |
1392 i++ | 1301 i++ |
1393 }), ShouldBeNil) | 1302 }), ShouldBeNil) |
1394 }) | 1303 }) |
1395 | 1304 |
1396 }) | 1305 }) |
1397 }) | 1306 }) |
1398 } | 1307 } |
1399 | 1308 |
1400 type fixedDataDatastore struct { | 1309 type fixedDataDatastore struct { |
(...skipping 26 matching lines...) Expand all Loading... |
1427 cb(k, nil) | 1336 cb(k, nil) |
1428 } | 1337 } |
1429 return nil | 1338 return nil |
1430 } | 1339 } |
1431 | 1340 |
1432 func TestSchemaChange(t *testing.T) { | 1341 func TestSchemaChange(t *testing.T) { |
1433 t.Parallel() | 1342 t.Parallel() |
1434 | 1343 |
1435 Convey("Test changing schemas", t, func() { | 1344 Convey("Test changing schemas", t, func() { |
1436 fds := fixedDataDatastore{} | 1345 fds := fixedDataDatastore{} |
1437 » » ds := &datastoreImpl{&fds, "", ""} | 1346 » » c := info.Set(context.Background(), fakeInfo{}) |
| 1347 » » c = SetRaw(c, &fds) |
1438 | 1348 |
1439 Convey("Can add fields", func() { | 1349 Convey("Can add fields", func() { |
1440 initial := PropertyMap{ | 1350 initial := PropertyMap{ |
1441 » » » » "$key": {mpNI(ds.MakeKey("Val", 10))}, | 1351 » » » » "$key": {mpNI(MakeKey(c, "Val", 10))}, |
1442 "Val": {mp(100)}, | 1352 "Val": {mp(100)}, |
1443 } | 1353 } |
1444 » » » So(ds.Put(initial), ShouldBeNil) | 1354 » » » So(Put(c, initial), ShouldBeNil) |
1445 | 1355 |
1446 type Val struct { | 1356 type Val struct { |
1447 ID int64 `gae:"$id"` | 1357 ID int64 `gae:"$id"` |
1448 | 1358 |
1449 Val int64 | 1359 Val int64 |
1450 TwoVal int64 // whoa, TWO vals! amazing | 1360 TwoVal int64 // whoa, TWO vals! amazing |
1451 } | 1361 } |
1452 tv := &Val{ID: 10, TwoVal: 2} | 1362 tv := &Val{ID: 10, TwoVal: 2} |
1453 » » » So(ds.Get(tv), ShouldBeNil) | 1363 » » » So(Get(c, tv), ShouldBeNil) |
1454 So(tv, ShouldResemble, &Val{ID: 10, Val: 100, TwoVal: 2}
) | 1364 So(tv, ShouldResemble, &Val{ID: 10, Val: 100, TwoVal: 2}
) |
1455 }) | 1365 }) |
1456 | 1366 |
1457 Convey("Removing fields", func() { | 1367 Convey("Removing fields", func() { |
1458 initial := PropertyMap{ | 1368 initial := PropertyMap{ |
1459 » » » » "$key": {mpNI(ds.MakeKey("Val", 10))}, | 1369 » » » » "$key": {mpNI(MakeKey(c, "Val", 10))}, |
1460 "Val": {mp(100)}, | 1370 "Val": {mp(100)}, |
1461 "TwoVal": {mp(200)}, | 1371 "TwoVal": {mp(200)}, |
1462 } | 1372 } |
1463 » » » So(ds.Put(initial), ShouldBeNil) | 1373 » » » So(Put(c, initial), ShouldBeNil) |
1464 | 1374 |
1465 Convey("is normally an error", func() { | 1375 Convey("is normally an error", func() { |
1466 type Val struct { | 1376 type Val struct { |
1467 ID int64 `gae:"$id"` | 1377 ID int64 `gae:"$id"` |
1468 | 1378 |
1469 Val int64 | 1379 Val int64 |
1470 } | 1380 } |
1471 tv := &Val{ID: 10} | 1381 tv := &Val{ID: 10} |
1472 » » » » So(ds.Get(tv), ShouldErrLike, | 1382 » » » » So(Get(c, tv), ShouldErrLike, |
1473 `gae: cannot load field "TwoVal" into a
"datastore.Val`) | 1383 `gae: cannot load field "TwoVal" into a
"datastore.Val`) |
1474 So(tv, ShouldResemble, &Val{ID: 10, Val: 100}) | 1384 So(tv, ShouldResemble, &Val{ID: 10, Val: 100}) |
1475 }) | 1385 }) |
1476 | 1386 |
1477 Convey("Unless you have an ,extra field!", func() { | 1387 Convey("Unless you have an ,extra field!", func() { |
1478 type Val struct { | 1388 type Val struct { |
1479 ID int64 `gae:"$id"` | 1389 ID int64 `gae:"$id"` |
1480 | 1390 |
1481 Val int64 | 1391 Val int64 |
1482 Extra PropertyMap `gae:",extra"` | 1392 Extra PropertyMap `gae:",extra"` |
1483 } | 1393 } |
1484 tv := &Val{ID: 10} | 1394 tv := &Val{ID: 10} |
1485 » » » » So(ds.Get(tv), ShouldBeNil) | 1395 » » » » So(Get(c, tv), ShouldBeNil) |
1486 So(tv, ShouldResemble, &Val{ | 1396 So(tv, ShouldResemble, &Val{ |
1487 ID: 10, | 1397 ID: 10, |
1488 Val: 100, | 1398 Val: 100, |
1489 Extra: PropertyMap{ | 1399 Extra: PropertyMap{ |
1490 "TwoVal": {mp(200)}, | 1400 "TwoVal": {mp(200)}, |
1491 }, | 1401 }, |
1492 }) | 1402 }) |
1493 }) | 1403 }) |
1494 }) | 1404 }) |
1495 | 1405 |
1496 Convey("Can round-trip extra fields", func() { | 1406 Convey("Can round-trip extra fields", func() { |
1497 type Expando struct { | 1407 type Expando struct { |
1498 ID int64 `gae:"$id"` | 1408 ID int64 `gae:"$id"` |
1499 | 1409 |
1500 Something int | 1410 Something int |
1501 Extra PropertyMap `gae:",extra"` | 1411 Extra PropertyMap `gae:",extra"` |
1502 } | 1412 } |
1503 ex := &Expando{10, 17, PropertyMap{ | 1413 ex := &Expando{10, 17, PropertyMap{ |
1504 "Hello": {mp("Hello")}, | 1414 "Hello": {mp("Hello")}, |
1505 "World": {mp(true)}, | 1415 "World": {mp(true)}, |
1506 }} | 1416 }} |
1507 » » » So(ds.Put(ex), ShouldBeNil) | 1417 » » » So(Put(c, ex), ShouldBeNil) |
1508 | 1418 |
1509 ex = &Expando{ID: 10} | 1419 ex = &Expando{ID: 10} |
1510 » » » So(ds.Get(ex), ShouldBeNil) | 1420 » » » So(Get(c, ex), ShouldBeNil) |
1511 So(ex, ShouldResemble, &Expando{ | 1421 So(ex, ShouldResemble, &Expando{ |
1512 ID: 10, | 1422 ID: 10, |
1513 Something: 17, | 1423 Something: 17, |
1514 Extra: PropertyMap{ | 1424 Extra: PropertyMap{ |
1515 "Hello": {mp("Hello")}, | 1425 "Hello": {mp("Hello")}, |
1516 "World": {mp(true)}, | 1426 "World": {mp(true)}, |
1517 }, | 1427 }, |
1518 }) | 1428 }) |
1519 }) | 1429 }) |
1520 | 1430 |
1521 Convey("Can read-but-not-write", func() { | 1431 Convey("Can read-but-not-write", func() { |
1522 initial := PropertyMap{ | 1432 initial := PropertyMap{ |
1523 » » » » "$key": {mpNI(ds.MakeKey("Convert", 10))}, | 1433 » » » » "$key": {mpNI(MakeKey(c, "Convert", 10))}, |
1524 "Val": {mp(100)}, | 1434 "Val": {mp(100)}, |
1525 "TwoVal": {mp(200)}, | 1435 "TwoVal": {mp(200)}, |
1526 } | 1436 } |
1527 » » » So(ds.Put(initial), ShouldBeNil) | 1437 » » » So(Put(c, initial), ShouldBeNil) |
1528 type Convert struct { | 1438 type Convert struct { |
1529 ID int64 `gae:"$id"` | 1439 ID int64 `gae:"$id"` |
1530 | 1440 |
1531 Val int64 | 1441 Val int64 |
1532 NewVal int64 | 1442 NewVal int64 |
1533 Extra PropertyMap `gae:"-,extra"` | 1443 Extra PropertyMap `gae:"-,extra"` |
1534 } | 1444 } |
1535 » » » c := &Convert{ID: 10} | 1445 » » » cnv := &Convert{ID: 10} |
1536 » » » So(ds.Get(c), ShouldBeNil) | 1446 » » » So(Get(c, cnv), ShouldBeNil) |
1537 » » » So(c, ShouldResemble, &Convert{ | 1447 » » » So(cnv, ShouldResemble, &Convert{ |
1538 ID: 10, Val: 100, NewVal: 0, Extra: PropertyMap{
"TwoVal": {mp(200)}}, | 1448 ID: 10, Val: 100, NewVal: 0, Extra: PropertyMap{
"TwoVal": {mp(200)}}, |
1539 }) | 1449 }) |
1540 » » » c.NewVal = c.Extra["TwoVal"][0].Value().(int64) | 1450 » » » cnv.NewVal = cnv.Extra["TwoVal"][0].Value().(int64) |
1541 » » » So(ds.Put(c), ShouldBeNil) | 1451 » » » So(Put(c, cnv), ShouldBeNil) |
1542 | 1452 |
1543 » » » c = &Convert{ID: 10} | 1453 » » » cnv = &Convert{ID: 10} |
1544 » » » So(ds.Get(c), ShouldBeNil) | 1454 » » » So(Get(c, cnv), ShouldBeNil) |
1545 » » » So(c, ShouldResemble, &Convert{ | 1455 » » » So(cnv, ShouldResemble, &Convert{ |
1546 ID: 10, Val: 100, NewVal: 200, Extra: nil, | 1456 ID: 10, Val: 100, NewVal: 200, Extra: nil, |
1547 }) | 1457 }) |
1548 }) | 1458 }) |
1549 | 1459 |
1550 Convey("Can black hole", func() { | 1460 Convey("Can black hole", func() { |
1551 initial := PropertyMap{ | 1461 initial := PropertyMap{ |
1552 » » » » "$key": {mpNI(ds.MakeKey("BlackHole", 10))}, | 1462 » » » » "$key": {mpNI(MakeKey(c, "BlackHole", 10))}, |
1553 "Val": {mp(100)}, | 1463 "Val": {mp(100)}, |
1554 "TwoVal": {mp(200)}, | 1464 "TwoVal": {mp(200)}, |
1555 } | 1465 } |
1556 » » » So(ds.Put(initial), ShouldBeNil) | 1466 » » » So(Put(c, initial), ShouldBeNil) |
1557 type BlackHole struct { | 1467 type BlackHole struct { |
1558 ID int64 `gae:"$id"` | 1468 ID int64 `gae:"$id"` |
1559 | 1469 |
1560 NewStuff string | 1470 NewStuff string |
1561 blackHole PropertyMap `gae:"-,extra"` | 1471 blackHole PropertyMap `gae:"-,extra"` |
1562 } | 1472 } |
1563 b := &BlackHole{ID: 10, NewStuff: "(╯°□°)╯︵ ┻━┻"} | 1473 b := &BlackHole{ID: 10, NewStuff: "(╯°□°)╯︵ ┻━┻"} |
1564 » » » So(ds.Get(b), ShouldBeNil) | 1474 » » » So(Get(c, b), ShouldBeNil) |
1565 So(b, ShouldResemble, &BlackHole{ID: 10, NewStuff: "(╯°□
°)╯︵ ┻━┻"}) | 1475 So(b, ShouldResemble, &BlackHole{ID: 10, NewStuff: "(╯°□
°)╯︵ ┻━┻"}) |
1566 }) | 1476 }) |
1567 | 1477 |
1568 Convey("Can change field types", func() { | 1478 Convey("Can change field types", func() { |
1569 initial := PropertyMap{ | 1479 initial := PropertyMap{ |
1570 » » » » "$key": {mpNI(ds.MakeKey("IntChange", 10))}, | 1480 » » » » "$key": {mpNI(MakeKey(c, "IntChange", 10))}, |
1571 "Val": {mp(100)}, | 1481 "Val": {mp(100)}, |
1572 } | 1482 } |
1573 » » » So(ds.Put(initial), ShouldBeNil) | 1483 » » » So(Put(c, initial), ShouldBeNil) |
1574 | 1484 |
1575 type IntChange struct { | 1485 type IntChange struct { |
1576 ID int64 `gae:"$id"` | 1486 ID int64 `gae:"$id"` |
1577 Val string | 1487 Val string |
1578 Extra PropertyMap `gae:"-,extra"` | 1488 Extra PropertyMap `gae:"-,extra"` |
1579 } | 1489 } |
1580 i := &IntChange{ID: 10} | 1490 i := &IntChange{ID: 10} |
1581 » » » So(ds.Get(i), ShouldBeNil) | 1491 » » » So(Get(c, i), ShouldBeNil) |
1582 So(i, ShouldResemble, &IntChange{ID: 10, Extra: Property
Map{"Val": {mp(100)}}}) | 1492 So(i, ShouldResemble, &IntChange{ID: 10, Extra: Property
Map{"Val": {mp(100)}}}) |
1583 i.Val = fmt.Sprint(i.Extra["Val"][0].Value()) | 1493 i.Val = fmt.Sprint(i.Extra["Val"][0].Value()) |
1584 » » » So(ds.Put(i), ShouldBeNil) | 1494 » » » So(Put(c, i), ShouldBeNil) |
1585 | 1495 |
1586 i = &IntChange{ID: 10} | 1496 i = &IntChange{ID: 10} |
1587 » » » So(ds.Get(i), ShouldBeNil) | 1497 » » » So(Get(c, i), ShouldBeNil) |
1588 So(i, ShouldResemble, &IntChange{ID: 10, Val: "100"}) | 1498 So(i, ShouldResemble, &IntChange{ID: 10, Val: "100"}) |
1589 }) | 1499 }) |
1590 | 1500 |
1591 Convey("Native fields have priority over Extra fields", func() { | 1501 Convey("Native fields have priority over Extra fields", func() { |
1592 type Dup struct { | 1502 type Dup struct { |
1593 ID int64 `gae:"$id"` | 1503 ID int64 `gae:"$id"` |
1594 Val int64 | 1504 Val int64 |
1595 Extra PropertyMap `gae:",extra"` | 1505 Extra PropertyMap `gae:",extra"` |
1596 } | 1506 } |
1597 d := &Dup{ID: 10, Val: 100, Extra: PropertyMap{ | 1507 d := &Dup{ID: 10, Val: 100, Extra: PropertyMap{ |
1598 "Val": {mp(200)}, | 1508 "Val": {mp(200)}, |
1599 "Other": {mp("other")}, | 1509 "Other": {mp("other")}, |
1600 }} | 1510 }} |
1601 » » » So(ds.Put(d), ShouldBeNil) | 1511 » » » So(Put(c, d), ShouldBeNil) |
1602 | 1512 |
1603 d = &Dup{ID: 10} | 1513 d = &Dup{ID: 10} |
1604 » » » So(ds.Get(d), ShouldBeNil) | 1514 » » » So(Get(c, d), ShouldBeNil) |
1605 So(d, ShouldResemble, &Dup{ | 1515 So(d, ShouldResemble, &Dup{ |
1606 ID: 10, Val: 100, Extra: PropertyMap{"Other": {m
p("other")}}, | 1516 ID: 10, Val: 100, Extra: PropertyMap{"Other": {m
p("other")}}, |
1607 }) | 1517 }) |
1608 }) | 1518 }) |
1609 | 1519 |
1610 Convey("Can change repeated field to non-repeating field", func(
) { | 1520 Convey("Can change repeated field to non-repeating field", func(
) { |
1611 initial := PropertyMap{ | 1521 initial := PropertyMap{ |
1612 » » » » "$key": {mpNI(ds.MakeKey("NonRepeating", 10))}, | 1522 » » » » "$key": {mpNI(MakeKey(c, "NonRepeating", 10))}, |
1613 "Val": {mp(100), mp(200), mp(400)}, | 1523 "Val": {mp(100), mp(200), mp(400)}, |
1614 } | 1524 } |
1615 » » » So(ds.Put(initial), ShouldBeNil) | 1525 » » » So(Put(c, initial), ShouldBeNil) |
1616 | 1526 |
1617 type NonRepeating struct { | 1527 type NonRepeating struct { |
1618 ID int64 `gae:"$id"` | 1528 ID int64 `gae:"$id"` |
1619 Val int64 | 1529 Val int64 |
1620 Extra PropertyMap `gae:",extra"` | 1530 Extra PropertyMap `gae:",extra"` |
1621 } | 1531 } |
1622 n := &NonRepeating{ID: 10} | 1532 n := &NonRepeating{ID: 10} |
1623 » » » So(ds.Get(n), ShouldBeNil) | 1533 » » » So(Get(c, n), ShouldBeNil) |
1624 So(n, ShouldResemble, &NonRepeating{ | 1534 So(n, ShouldResemble, &NonRepeating{ |
1625 ID: 10, Val: 0, Extra: PropertyMap{ | 1535 ID: 10, Val: 0, Extra: PropertyMap{ |
1626 "Val": {mp(100), mp(200), mp(400)}, | 1536 "Val": {mp(100), mp(200), mp(400)}, |
1627 }, | 1537 }, |
1628 }) | 1538 }) |
1629 }) | 1539 }) |
1630 | 1540 |
1631 Convey("Deals correctly with recursive types", func() { | 1541 Convey("Deals correctly with recursive types", func() { |
1632 initial := PropertyMap{ | 1542 initial := PropertyMap{ |
1633 » » » » "$key": {mpNI(ds.MakeKey("Outer", 10))}, | 1543 » » » » "$key": {mpNI(MakeKey(c, "Outer", 10))}, |
1634 "I.A": {mp(1), mp(2), mp(4)}, | 1544 "I.A": {mp(1), mp(2), mp(4)}, |
1635 "I.B": {mp(10), mp(20), mp(40)}, | 1545 "I.B": {mp(10), mp(20), mp(40)}, |
1636 "I.C": {mp(100), mp(200), mp(400)}, | 1546 "I.C": {mp(100), mp(200), mp(400)}, |
1637 } | 1547 } |
1638 » » » So(ds.Put(initial), ShouldBeNil) | 1548 » » » So(Put(c, initial), ShouldBeNil) |
1639 type Inner struct { | 1549 type Inner struct { |
1640 A int64 | 1550 A int64 |
1641 B int64 | 1551 B int64 |
1642 } | 1552 } |
1643 type Outer struct { | 1553 type Outer struct { |
1644 ID int64 `gae:"$id"` | 1554 ID int64 `gae:"$id"` |
1645 | 1555 |
1646 I []Inner | 1556 I []Inner |
1647 Extra PropertyMap `gae:",extra"` | 1557 Extra PropertyMap `gae:",extra"` |
1648 } | 1558 } |
1649 o := &Outer{ID: 10} | 1559 o := &Outer{ID: 10} |
1650 » » » So(ds.Get(o), ShouldBeNil) | 1560 » » » So(Get(c, o), ShouldBeNil) |
1651 So(o, ShouldResemble, &Outer{ | 1561 So(o, ShouldResemble, &Outer{ |
1652 ID: 10, | 1562 ID: 10, |
1653 I: []Inner{ | 1563 I: []Inner{ |
1654 {1, 10}, | 1564 {1, 10}, |
1655 {2, 20}, | 1565 {2, 20}, |
1656 {4, 40}, | 1566 {4, 40}, |
1657 }, | 1567 }, |
1658 Extra: PropertyMap{ | 1568 Extra: PropertyMap{ |
1659 "I.C": {mp(100), mp(200), mp(400)}, | 1569 "I.C": {mp(100), mp(200), mp(400)}, |
1660 }, | 1570 }, |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1914 if err != nil { | 1824 if err != nil { |
1915 panic(fmt.Errorf("failed to find absolute path f
or `%s`", sameLevelDir)) | 1825 panic(fmt.Errorf("failed to find absolute path f
or `%s`", sameLevelDir)) |
1916 } | 1826 } |
1917 | 1827 |
1918 ids, err := FindAndParseIndexYAML(abs) | 1828 ids, err := FindAndParseIndexYAML(abs) |
1919 So(err, ShouldBeNil) | 1829 So(err, ShouldBeNil) |
1920 So(ids[1].Kind, ShouldEqual, "Test Foo") | 1830 So(ids[1].Kind, ShouldEqual, "Test Foo") |
1921 }) | 1831 }) |
1922 }) | 1832 }) |
1923 } | 1833 } |
OLD | NEW |