Index: go/src/infra/gae/libs/wrapper/memory/testing_utils_test.go |
diff --git a/go/src/infra/gae/libs/wrapper/memory/testing_utils_test.go b/go/src/infra/gae/libs/wrapper/memory/testing_utils_test.go |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2e172bcabaf2e8def826100fbe80a52374ba8593 |
--- /dev/null |
+++ b/go/src/infra/gae/libs/wrapper/memory/testing_utils_test.go |
@@ -0,0 +1,122 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package memory |
+ |
+import ( |
+ "bytes" |
+ "fmt" |
+ "reflect" |
+ "time" |
+ |
+ "appengine/datastore" |
+ |
+ "github.com/luci/luci-go/common/funnybase" |
+) |
+ |
+type kv struct{ k, v []byte } |
+ |
+func indx(kind string, orders ...string) *qIndex { |
+ ancestor := false |
+ if kind[len(kind)-1] == '!' { |
+ ancestor = true |
+ kind = kind[:len(kind)-1] |
+ } |
+ ret := &qIndex{kind, ancestor, nil} |
+ for _, o := range orders { |
+ dir := qASC |
+ if o[0] == '-' { |
+ dir = qDEC |
+ o = o[1:] |
+ } |
+ ret.sortby = append(ret.sortby, qSortBy{o, dir}) |
+ } |
+ return ret |
+} |
+ |
+func pl(props ...datastore.Property) *propertyList { |
+ return (*propertyList)(&props) |
+} |
+ |
+func prop(name string, val interface{}, noIndex ...bool) (ret datastore.Property) { |
+ ret.Name = name |
+ ret.Value = val |
+ if len(noIndex) > 0 { |
+ ret.NoIndex = noIndex[0] |
+ } |
+ return |
+} |
+ |
+func key(kind string, id interface{}, parent ...*datastore.Key) *datastore.Key { |
+ stringID := "" |
+ intID := int64(0) |
+ switch x := id.(type) { |
+ case string: |
+ stringID = x |
+ case int: |
+ intID = int64(x) |
+ default: |
+ panic(fmt.Errorf("what the %T: %v", id, id)) |
+ } |
+ par := (*datastore.Key)(nil) |
+ if len(parent) > 0 { |
+ par = parent[0] |
+ } |
+ return newKey("ns", kind, stringID, intID, par) |
+} |
+ |
+func mustLoadLocation(loc string) *time.Location { |
+ if z, err := time.LoadLocation(loc); err != nil { |
+ panic(err) |
+ } else { |
+ return z |
+ } |
+} |
+ |
+// cat is a convenience method for concatenating anything with an underlying |
+// byte representation into a single []byte. |
+func cat(bytethings ...interface{}) []byte { |
+ buf := &bytes.Buffer{} |
+ for _, thing := range bytethings { |
+ switch x := thing.(type) { |
+ case int, int64: |
+ funnybase.Write(buf, reflect.ValueOf(x).Int()) |
+ case uint, uint64: |
+ funnybase.WriteUint(buf, reflect.ValueOf(x).Uint()) |
+ case float64: |
+ writeFloat64(buf, x) |
+ case byte, propValType: |
+ buf.WriteByte(byte(reflect.ValueOf(x).Uint())) |
+ case []byte, serializedPval: |
+ buf.Write(reflect.ValueOf(x).Convert(byteSliceType).Interface().([]byte)) |
+ case string: |
+ writeString(buf, x) |
+ case time.Time: |
+ writeTime(buf, x) |
+ case *datastore.Key: |
+ writeKey(buf, noNS, x) |
+ case *qIndex: |
+ x.WriteBinary(buf) |
+ default: |
+ panic(fmt.Errorf("I don't know how to deal with %T: %#v", thing, thing)) |
+ } |
+ } |
+ ret := buf.Bytes() |
+ if ret == nil { |
+ ret = []byte{} |
+ } |
+ return ret |
+} |
+ |
+func icat(bytethings ...interface{}) []byte { |
+ ret := cat(bytethings...) |
+ for i := range ret { |
+ ret[i] ^= 0xFF |
+ } |
+ return ret |
+} |
+ |
+func sat(bytethings ...interface{}) string { |
+ return string(cat(bytethings...)) |
+} |