| Index: impl/memory/raw_datastore_test.go | 
| diff --git a/impl/memory/raw_datastore_test.go b/impl/memory/raw_datastore_test.go | 
| index 829b3b0fc4cb20351de79196fc6450e6a825d4f8..b0ca0b4abcedb49eb1a1495a3208ed5382709564 100644 | 
| --- a/impl/memory/raw_datastore_test.go | 
| +++ b/impl/memory/raw_datastore_test.go | 
| @@ -34,7 +34,7 @@ func TestDatastoreKinder(t *testing.T) { | 
| So(key.Namespace(), ShouldEqual, "") | 
| So(key.String(), ShouldEqual, "/nerd,stringID") | 
| So(rdsS.KeyIncomplete(key), ShouldBeFalse) | 
| -				So(rdsS.KeyValid(key, "", false), ShouldBeTrue) | 
| +				So(rdsS.KeyValid(key, false, "dev~app", ""), ShouldBeTrue) | 
| }) | 
| }) | 
|  | 
| @@ -43,10 +43,17 @@ func TestDatastoreKinder(t *testing.T) { | 
|  | 
| func testGetMeta(c context.Context, k rdsS.Key) int64 { | 
| rds := rdsS.Get(c) | 
| -	k = rds.NewKey("__entity_group__", "", 1, rdsS.KeyRoot(k)) | 
| -	pmap := rdsS.PropertyMap{} | 
| -	rds.Get(k, pmap) | 
| -	return pmap["__version__"][0].Value().(int64) | 
| +	retval := int64(0) | 
| +	err := rds.GetMulti([]rdsS.Key{rds.NewKey("__entity_group__", "", 1, rdsS.KeyRoot(k))}, func(val rdsS.PropertyMap, err error) { | 
| +		if err != nil { | 
| +			panic(err) | 
| +		} | 
| +		retval = val["__version__"][0].Value().(int64) | 
| +	}) | 
| +	if err != nil { | 
| +		panic(err) | 
| +	} | 
| +	return retval | 
| } | 
|  | 
| var pls = rdsS.GetPLS | 
| @@ -54,6 +61,48 @@ var pls = rdsS.GetPLS | 
| func TestDatastoreSingleReadWriter(t *testing.T) { | 
| t.Parallel() | 
|  | 
| +	getOnePM := func(rds rdsS.Interface, key rdsS.Key) (pmap rdsS.PropertyMap, err error) { | 
| +		blankErr := rds.GetMulti([]rdsS.Key{key}, func(itmPmap rdsS.PropertyMap, itmErr error) { | 
| +			pmap = itmPmap | 
| +			err = itmErr | 
| +		}) | 
| +		So(blankErr, ShouldBeNil) | 
| +		return | 
| +	} | 
| + | 
| +	delOneErr := func(rds rdsS.Interface, key rdsS.Key) (err error) { | 
| +		blankErr := rds.DeleteMulti([]rdsS.Key{key}, func(itmErr error) { | 
| +			err = itmErr | 
| +		}) | 
| +		So(blankErr, ShouldBeNil) | 
| +		return | 
| +	} | 
| + | 
| +	delOne := func(rds rdsS.Interface, key rdsS.Key) { | 
| +		So(delOneErr(rds, key), ShouldBeNil) | 
| +	} | 
| + | 
| +	getOne := func(rds rdsS.Interface, key rdsS.Key, dst interface{}) { | 
| +		pm, err := getOnePM(rds, key) | 
| +		So(err, ShouldBeNil) | 
| +		So(pls(dst).Load(pm), ShouldBeNil) | 
| +	} | 
| + | 
| +	putOneErr := func(rds rdsS.Interface, key rdsS.Key, val interface{}) (retKey rdsS.Key, err error) { | 
| +		blankErr := rds.PutMulti([]rdsS.Key{key}, []rdsS.PropertyLoadSaver{pls(val)}, func(itmKey rdsS.Key, itmErr error) { | 
| +			err = itmErr | 
| +			retKey = itmKey | 
| +		}) | 
| +		So(blankErr, ShouldBeNil) | 
| +		return | 
| +	} | 
| + | 
| +	putOne := func(rds rdsS.Interface, key rdsS.Key, val interface{}) (retKey rdsS.Key) { | 
| +		key, err := putOneErr(rds, key, val) | 
| +		So(err, ShouldBeNil) | 
| +		return key | 
| +	} | 
| + | 
| Convey("Datastore single reads and writes", t, func() { | 
| c := Use(context.Background()) | 
| rds := rdsS.Get(c) | 
| @@ -64,96 +113,89 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| Val int | 
| } | 
|  | 
| -			Convey("invalid keys break", func() { | 
| -				k := rds.NewKey("Foo", "", 0, nil) | 
| -				So(rds.Get(k, nil), ShouldEqual, rdsS.ErrInvalidKey) | 
| - | 
| -				_, err := rds.Put(rds.NewKey("Foo", "", 0, k), pls(&Foo{})) | 
| -				So(err, ShouldEqual, rdsS.ErrInvalidKey) | 
| -			}) | 
| - | 
| Convey("getting objects that DNE is an error", func() { | 
| -				k := rds.NewKey("Foo", "", 1, nil) | 
| -				So(rds.Get(k, nil), ShouldEqual, rdsS.ErrNoSuchEntity) | 
| +				_, err := getOnePM(rds, rds.NewKey("Foo", "", 1, nil)) | 
| +				So(err, ShouldEqual, rdsS.ErrNoSuchEntity) | 
| }) | 
|  | 
| Convey("Can Put stuff", func() { | 
| // with an incomplete key! | 
| k := rds.NewKey("Foo", "", 0, nil) | 
| f := &Foo{Val: 10} | 
| -				k, err := rds.Put(k, pls(f)) | 
| -				So(err, ShouldBeNil) | 
| +				k = putOne(rds, k, f) | 
| So(k.String(), ShouldEqual, "/Foo,1") | 
|  | 
| Convey("and Get it back", func() { | 
| newFoo := &Foo{} | 
| -					err := rds.Get(k, pls(newFoo)) | 
| -					So(err, ShouldBeNil) | 
| +					getOne(rds, k, newFoo) | 
| So(newFoo, ShouldResemble, f) | 
|  | 
| Convey("and we can Delete it", func() { | 
| -						err := rds.Delete(k) | 
| -						So(err, ShouldBeNil) | 
| - | 
| -						err = rds.Get(k, pls(newFoo)) | 
| +						delOne(rds, k) | 
| +						_, err := getOnePM(rds, k) | 
| So(err, ShouldEqual, rdsS.ErrNoSuchEntity) | 
| }) | 
| }) | 
| Convey("Deleteing with a bogus key is bad", func() { | 
| -					err := rds.Delete(rds.NewKey("Foo", "wat", 100, nil)) | 
| -					So(err, ShouldEqual, rdsS.ErrInvalidKey) | 
| +					So(delOneErr(rds, rds.NewKey("Foo", "wat", 100, nil)), ShouldEqual, rdsS.ErrInvalidKey) | 
| }) | 
| Convey("Deleteing a DNE entity is fine", func() { | 
| -					err := rds.Delete(rds.NewKey("Foo", "wat", 0, nil)) | 
| -					So(err, ShouldBeNil) | 
| +					delOne(rds, rds.NewKey("Foo", "wat", 0, nil)) | 
| }) | 
|  | 
| Convey("with multiple puts", func() { | 
| So(testGetMeta(c, k), ShouldEqual, 1) | 
|  | 
| keys := []rdsS.Key{} | 
| -					plss := []rdsS.PropertyLoadSaver{} | 
| +					vals := []rdsS.PropertyLoadSaver{} | 
|  | 
| pkey := k | 
| for i := 0; i < 10; i++ { | 
| keys = append(keys, rds.NewKey("Foo", "", 0, pkey)) | 
| -						plss = append(plss, pls(&Foo{Val: 10})) | 
| +						vals = append(vals, pls(&Foo{Val: 10})) | 
| } | 
| -					keys, err := rds.PutMulti(keys, plss) | 
| +					i := 0 | 
| +					err := rds.PutMulti(keys, vals, func(k rdsS.Key, err error) { | 
| +						So(err, ShouldBeNil) | 
| +						keys[i] = k | 
| +						i++ | 
| +					}) | 
| So(err, ShouldBeNil) | 
| So(testGetMeta(c, k), ShouldEqual, 11) | 
|  | 
| Convey("ensure that group versions persist across deletes", func() { | 
| -						So(rds.Delete(k), ShouldBeNil) | 
| -						for i := int64(1); i < 11; i++ { | 
| -							So(rds.Delete(rds.NewKey("Foo", "", i, k)), ShouldBeNil) | 
| -						} | 
| -						// TODO(riannucci): replace with a Count query instead of this cast | 
| -						ents := rds.(*dsImpl).data.store.GetCollection("ents:") | 
| -						num, _ := ents.GetTotals() | 
| -						// /__entity_root_ids__,Foo | 
| -						// /Foo,1/__entity_group__,1 | 
| -						// /Foo,1/__entity_group_ids__,1 | 
| -						So(num, ShouldEqual, 3) | 
| - | 
| -						So(curVersion(ents, groupMetaKey(k)), ShouldEqual, 22) | 
| - | 
| -						k, err := rds.Put(k, pls(f)) | 
| +						keys = append(keys, pkey) | 
| +						err := rds.DeleteMulti(keys, func(err error) { | 
| +							So(err, ShouldBeNil) | 
| +						}) | 
| So(err, ShouldBeNil) | 
| + | 
| +						// TODO(riannucci): replace with a Count query instead of this cast | 
| +						/* | 
| +							ents := rds.(*dsImpl).data.store.GetCollection("ents:") | 
| +							num, _ := ents.GetTotals() | 
| +							// /__entity_root_ids__,Foo | 
| +							// /Foo,1/__entity_group__,1 | 
| +							// /Foo,1/__entity_group_ids__,1 | 
| +							So(num, ShouldEqual, 3) | 
| +						*/ | 
| + | 
| +						So(testGetMeta(c, k), ShouldEqual, 22) | 
| + | 
| +						putOne(rds, k, f) | 
| So(testGetMeta(c, k), ShouldEqual, 23) | 
| }) | 
|  | 
| -					Convey("can GetMulti", func() { | 
| -						plss := make([]rdsS.PropertyLoadSaver, len(keys)) | 
| -						for i := range plss { | 
| -							plss[i] = rdsS.PropertyMap{} | 
| -						} | 
| -						err := rds.GetMulti(keys, plss) | 
| +					Convey("can Get", func() { | 
| +						vals := []rdsS.PropertyMap{} | 
| +						err := rds.GetMulti(keys, func(pm rdsS.PropertyMap, err error) { | 
| +							So(err, ShouldBeNil) | 
| +							vals = append(vals, pm) | 
| +						}) | 
| So(err, ShouldBeNil) | 
| -						for _, pls := range plss { | 
| -							So(pls.(rdsS.PropertyMap), ShouldResemble, rdsS.PropertyMap{ | 
| -								"Val": {rdsS.MkProperty(10)}, | 
| -							}) | 
| + | 
| +						for _, val := range vals { | 
| +							So(val, ShouldResemble, rdsS.PropertyMap{"Val": {rdsS.MkProperty(10)}}) | 
| } | 
| }) | 
| }) | 
| @@ -165,25 +207,21 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| Val int | 
| } | 
| Convey("Put", func() { | 
| -				k := rds.NewKey("Foo", "", 0, nil) | 
| f := &Foo{Val: 10} | 
| -				k, err := rds.Put(k, pls(f)) | 
| -				So(err, ShouldBeNil) | 
| +				origKey := rds.NewKey("Foo", "", 0, nil) | 
| +				k := putOne(rds, origKey, f) | 
| So(k.String(), ShouldEqual, "/Foo,1") | 
|  | 
| Convey("can Put new entity groups", func() { | 
| err := rds.RunInTransaction(func(c context.Context) error { | 
| rds := rdsS.Get(c) | 
| -						So(rds, ShouldNotBeNil) | 
|  | 
| f1 := &Foo{Val: 100} | 
| -						k, err := rds.Put(rds.NewKey("Foo", "", 0, nil), pls(f1)) | 
| -						So(err, ShouldBeNil) | 
| +						k := putOne(rds, origKey, f1) | 
| So(k.String(), ShouldEqual, "/Foo,2") | 
|  | 
| f2 := &Foo{Val: 200} | 
| -						k, err = rds.Put(rds.NewKey("Foo", "", 0, nil), pls(f2)) | 
| -						So(err, ShouldBeNil) | 
| +						k = putOne(rds, origKey, f2) | 
| So(k.String(), ShouldEqual, "/Foo,3") | 
|  | 
| return nil | 
| @@ -191,60 +229,62 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| So(err, ShouldBeNil) | 
|  | 
| f := &Foo{} | 
| -					So(rds.Get(rds.NewKey("Foo", "", 2, nil), pls(f)), ShouldBeNil) | 
| +					getOne(rds, rds.NewKey("Foo", "", 2, nil), f) | 
| So(f.Val, ShouldEqual, 100) | 
|  | 
| -					f = &Foo{} | 
| -					So(rds.Get(rds.NewKey("Foo", "", 3, nil), pls(f)), ShouldBeNil) | 
| +					getOne(rds, rds.NewKey("Foo", "", 3, nil), f) | 
| So(f.Val, ShouldEqual, 200) | 
| }) | 
|  | 
| Convey("can Put new entities in a current group", func() { | 
| +					par := k | 
| err := rds.RunInTransaction(func(c context.Context) error { | 
| rds := rdsS.Get(c) | 
| So(rds, ShouldNotBeNil) | 
|  | 
| -						par := k | 
| - | 
| f1 := &Foo{Val: 100} | 
| -						k, err := rds.Put(rds.NewKey("Foo", "", 0, par), pls(f1)) | 
| -						So(err, ShouldBeNil) | 
| +						k := putOne(rds, rds.NewKey("Foo", "", 0, par), f1) | 
| So(k.String(), ShouldEqual, "/Foo,1/Foo,1") | 
|  | 
| f2 := &Foo{Val: 200} | 
| -						k, err = rds.Put(rds.NewKey("Foo", "", 0, par), pls(f2)) | 
| -						So(err, ShouldBeNil) | 
| +						k = putOne(rds, rds.NewKey("Foo", "", 0, par), f2) | 
| So(k.String(), ShouldEqual, "/Foo,1/Foo,2") | 
|  | 
| return nil | 
| }, nil) | 
| So(err, ShouldBeNil) | 
|  | 
| -					f1 := &Foo{} | 
| -					So(rds.Get(rds.NewKey("Foo", "", 1, k), pls(f1)), ShouldBeNil) | 
| -					So(f1.Val, ShouldEqual, 100) | 
| +					f := &Foo{} | 
| +					getOne(rds, rds.NewKey("Foo", "", 1, k), f) | 
| +					So(f.Val, ShouldEqual, 100) | 
|  | 
| -					f2 := &Foo{} | 
| -					So(rds.Get(rds.NewKey("Foo", "", 2, k), pls(f2)), ShouldBeNil) | 
| -					So(f2.Val, ShouldEqual, 200) | 
| +					getOne(rds, rds.NewKey("Foo", "", 2, k), f) | 
| +					So(f.Val, ShouldEqual, 200) | 
| }) | 
|  | 
| Convey("Deletes work too", func() { | 
| err := rds.RunInTransaction(func(c context.Context) error { | 
| rds := rdsS.Get(c) | 
| So(rds, ShouldNotBeNil) | 
| -						So(rds.Delete(k), ShouldBeNil) | 
| +						delOne(rds, k) | 
| return nil | 
| }, nil) | 
| So(err, ShouldBeNil) | 
| -					So(rds.Get(k, nil), ShouldEqual, rdsS.ErrNoSuchEntity) | 
| +					_, err = getOnePM(rds, k) | 
| +					So(err, ShouldEqual, rdsS.ErrNoSuchEntity) | 
| }) | 
|  | 
| Convey("A Get counts against your group count", func() { | 
| err := rds.RunInTransaction(func(c context.Context) error { | 
| rds := rdsS.Get(c) | 
| -						So(rds.Get(rds.NewKey("Foo", "", 20, nil), nil), ShouldEqual, rdsS.ErrNoSuchEntity) | 
| -						So(rds.Get(k, nil).Error(), ShouldContainSubstring, "cross-group") | 
| + | 
| +						_, err := getOnePM(rds, rds.NewKey("Foo", "", 20, nil)) | 
| +						So(err, ShouldEqual, rdsS.ErrNoSuchEntity) | 
| + | 
| +						err = rds.GetMulti([]rdsS.Key{k}, func(_ rdsS.PropertyMap, err error) { | 
| +							So(err, ShouldBeNil) | 
| +						}) | 
| +						So(err.Error(), ShouldContainSubstring, "cross-group") | 
| return nil | 
| }, nil) | 
| So(err, ShouldBeNil) | 
| @@ -255,16 +295,15 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| txnDS := rdsS.Get(c) | 
| So(txnDS, ShouldNotBeNil) | 
|  | 
| -						So(txnDS.Get(k, pls(f)), ShouldBeNil) | 
| +						getOne(txnDS, k, f) | 
| So(f.Val, ShouldEqual, 10) | 
|  | 
| // Don't ever do this in a real program unless you want to guarantee | 
| // a failed transaction :) | 
| f.Val = 11 | 
| -						_, err := rds.Put(k, pls(f)) | 
| -						So(err, ShouldBeNil) | 
| +						putOne(rds, k, f) | 
|  | 
| -						So(txnDS.Get(k, pls(f)), ShouldBeNil) | 
| +						getOne(txnDS, k, f) | 
| So(f.Val, ShouldEqual, 10) | 
|  | 
| return nil | 
| @@ -272,7 +311,7 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| So(err, ShouldBeNil) | 
|  | 
| f := &Foo{} | 
| -					So(rds.Get(k, pls(f)), ShouldBeNil) | 
| +					getOne(rds, k, f) | 
| So(f.Val, ShouldEqual, 11) | 
| }) | 
|  | 
| @@ -282,24 +321,21 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| So(txnDS, ShouldNotBeNil) | 
|  | 
| f := &Foo{} | 
| -						So(txnDS.Get(k, pls(f)), ShouldBeNil) | 
| +						getOne(txnDS, k, f) | 
| So(f.Val, ShouldEqual, 10) | 
|  | 
| // Don't ever do this in a real program unless you want to guarantee | 
| // a failed transaction :) | 
| f.Val = 11 | 
| +						putOne(rds, k, f) | 
|  | 
| -						_, err := rds.Put(k, pls(f)) | 
| -						So(err, ShouldBeNil) | 
| - | 
| -						So(txnDS.Get(k, pls(f)), ShouldBeNil) | 
| +						getOne(txnDS, k, f) | 
| So(f.Val, ShouldEqual, 10) | 
|  | 
| f.Val = 20 | 
| -						_, err = txnDS.Put(k, pls(f)) | 
| -						So(err, ShouldBeNil) | 
| +						putOne(txnDS, k, f) | 
|  | 
| -						So(txnDS.Get(k, pls(f)), ShouldBeNil) | 
| +						getOne(txnDS, k, f) | 
| So(f.Val, ShouldEqual, 10) // still gets 10 | 
|  | 
| return nil | 
| @@ -307,7 +343,7 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| So(err.Error(), ShouldContainSubstring, "concurrent") | 
|  | 
| f := &Foo{} | 
| -					So(rds.Get(k, pls(f)), ShouldBeNil) | 
| +					getOne(rds, k, f) | 
| So(f.Val, ShouldEqual, 11) | 
| }) | 
|  | 
| @@ -316,11 +352,14 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| txnDS := rdsS.Interface(nil) | 
| err := rds.RunInTransaction(func(c context.Context) error { | 
| txnDS = rdsS.Get(c) | 
| -						So(txnDS.Get(k, rdsS.PropertyMap{}), ShouldBeNil) | 
| +						getOnePM(txnDS, k) | 
| return nil | 
| }, nil) | 
| So(err, ShouldBeNil) | 
| -					So(txnDS.Get(k, rdsS.PropertyMap{}).Error(), ShouldContainSubstring, "expired") | 
| +					err = txnDS.GetMulti([]rdsS.Key{k}, func(_ rdsS.PropertyMap, err error) { | 
| +						So(err, ShouldBeNil) | 
| +					}) | 
| +					So(err.Error(), ShouldContainSubstring, "expired") | 
| }) | 
|  | 
| Convey("Nested transactions are rejected", func() { | 
| @@ -345,14 +384,12 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| err := rds.RunInTransaction(func(c context.Context) error { | 
| txnDS := rdsS.Get(c) | 
| f := &Foo{Val: 21} | 
| -						_, err = txnDS.Put(k, pls(f)) | 
| -						So(err, ShouldBeNil) | 
| +						putOne(txnDS, k, f) | 
|  | 
| err := rds.RunInTransaction(func(c context.Context) error { | 
| txnDS := rdsS.Get(c) | 
| f := &Foo{Val: 27} | 
| -							_, err := txnDS.Put(k, pls(f)) | 
| -							So(err, ShouldBeNil) | 
| +							putOne(txnDS, k, f) | 
| return nil | 
| }, nil) | 
| So(err, ShouldBeNil) | 
| @@ -362,7 +399,7 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| So(err.Error(), ShouldContainSubstring, "concurrent") | 
|  | 
| f := &Foo{} | 
| -					So(rds.Get(k, pls(f)), ShouldBeNil) | 
| +					getOne(rds, k, f) | 
| So(f.Val, ShouldEqual, 27) | 
| }) | 
|  | 
| @@ -371,10 +408,9 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| err := rds.RunInTransaction(func(c context.Context) error { | 
| rds := rdsS.Get(c) | 
| f := &Foo{Val: 200} | 
| -							_, err := rds.Put(k, pls(f)) | 
| -							So(err, ShouldBeNil) | 
| +							putOne(rds, k, f) | 
|  | 
| -							_, err = rds.Put(rds.NewKey("Foo", "", 2, nil), pls(f)) | 
| +							_, err := putOneErr(rds, rds.NewKey("Foo", "", 2, nil), f) | 
| So(err.Error(), ShouldContainSubstring, "cross-group") | 
| return err | 
| }, nil) | 
| @@ -387,11 +423,10 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| for i := int64(1); i < 26; i++ { | 
| k := rds.NewKey("Foo", "", i, nil) | 
| f := &Foo{Val: 200} | 
| -								_, err := rds.Put(k, pls(f)) | 
| -								So(err, ShouldBeNil) | 
| +								putOne(rds, k, f) | 
| } | 
| f := &Foo{Val: 200} | 
| -							_, err := rds.Put(rds.NewKey("Foo", "", 27, nil), pls(f)) | 
| +							_, err := putOneErr(rds, rds.NewKey("Foo", "", 27, nil), f) | 
| So(err.Error(), ShouldContainSubstring, "too many entity groups") | 
| return err | 
| }, &rdsS.TransactionOptions{XG: true}) | 
| @@ -404,15 +439,14 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| err := rds.RunInTransaction(func(c context.Context) error { | 
| rds := rdsS.Get(c) | 
| f := &Foo{Val: 200} | 
| -							_, err := rds.Put(k, pls(f)) | 
| -							So(err, ShouldBeNil) | 
| +							putOne(rds, k, f) | 
|  | 
| return fmt.Errorf("thingy") | 
| }, nil) | 
| So(err.Error(), ShouldEqual, "thingy") | 
|  | 
| f := &Foo{} | 
| -						So(rds.Get(k, pls(f)), ShouldBeNil) | 
| +						getOne(rds, k, f) | 
| So(f.Val, ShouldEqual, 10) | 
| }) | 
|  | 
| @@ -421,14 +455,13 @@ func TestDatastoreSingleReadWriter(t *testing.T) { | 
| rds.RunInTransaction(func(c context.Context) error { | 
| rds := rdsS.Get(c) | 
| f := &Foo{Val: 200} | 
| -								_, err := rds.Put(k, pls(f)) | 
| -								So(err, ShouldBeNil) | 
| +								putOne(rds, k, f) | 
| panic("wheeeeee") | 
| }, nil) | 
| }, ShouldPanic) | 
|  | 
| f := &Foo{} | 
| -						So(rds.Get(k, pls(f)), ShouldBeNil) | 
| +						getOne(rds, k, f) | 
| So(f.Val, ShouldEqual, 10) | 
| }) | 
| }) | 
|  |