| 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 package datastore | 5 package datastore |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "encoding/json" | 8 "encoding/json" |
| 9 "fmt" | 9 "fmt" |
| 10 "testing" | 10 "testing" |
| 11 | 11 |
| 12 . "github.com/luci/luci-go/common/testing/assertions" | 12 . "github.com/luci/luci-go/common/testing/assertions" |
| 13 . "github.com/smartystreets/goconvey/convey" | 13 . "github.com/smartystreets/goconvey/convey" |
| 14 ) | 14 ) |
| 15 | 15 |
| 16 func ShouldEqualKey(actual interface{}, expected ...interface{}) string { | 16 func ShouldEqualKey(actual interface{}, expected ...interface{}) string { |
| 17 if len(expected) != 1 { | 17 if len(expected) != 1 { |
| 18 return fmt.Sprintf("Assertion requires 1 expected value, got %d"
, len(expected)) | 18 return fmt.Sprintf("Assertion requires 1 expected value, got %d"
, len(expected)) |
| 19 } | 19 } |
| 20 if actual.(*Key).Equal(expected[0].(*Key)) { | 20 if actual.(*Key).Equal(expected[0].(*Key)) { |
| 21 return "" | 21 return "" |
| 22 } | 22 } |
| 23 return fmt.Sprintf("Expected: %q\nActual: %q", actual, expected[0]) | 23 return fmt.Sprintf("Expected: %q\nActual: %q", actual, expected[0]) |
| 24 } | 24 } |
| 25 | 25 |
| 26 func TestKeyEncode(t *testing.T) { | 26 func TestKeyEncode(t *testing.T) { |
| 27 t.Parallel() | 27 t.Parallel() |
| 28 | 28 |
| 29 » kc := KeyContext{"appid", "ns"} | 29 » kc := MkKeyContext("appid", "ns") |
| 30 keys := []*Key{ | 30 keys := []*Key{ |
| 31 kc.MakeKey("kind", 1), | 31 kc.MakeKey("kind", 1), |
| 32 kc.MakeKey("nerd", "moo"), | 32 kc.MakeKey("nerd", "moo"), |
| 33 kc.MakeKey("parent", 10, "renerd", "moo"), | 33 kc.MakeKey("parent", 10, "renerd", "moo"), |
| 34 } | 34 } |
| 35 | 35 |
| 36 Convey("Key Round trip", t, func() { | 36 Convey("Key Round trip", t, func() { |
| 37 for _, k := range keys { | 37 for _, k := range keys { |
| 38 k := k | 38 k := k |
| 39 Convey(k.String(), func() { | 39 Convey(k.String(), func() { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 55 | 55 |
| 56 dec := &Key{} | 56 dec := &Key{} |
| 57 So(dec.UnmarshalJSON(data), ShouldBeNil) | 57 So(dec.UnmarshalJSON(data), ShouldBeNil) |
| 58 So(dec, ShouldEqualKey, k) | 58 So(dec, ShouldEqualKey, k) |
| 59 }) | 59 }) |
| 60 } | 60 } |
| 61 }) | 61 }) |
| 62 | 62 |
| 63 Convey("NewKey", t, func() { | 63 Convey("NewKey", t, func() { |
| 64 Convey("single", func() { | 64 Convey("single", func() { |
| 65 » » » k := KeyContext{"appid", "ns"}.NewKey("kind", "", 1, nil
) | 65 » » » k := MkKeyContext("appid", "ns").NewKey("kind", "", 1, n
il) |
| 66 So(k, ShouldEqualKey, keys[0]) | 66 So(k, ShouldEqualKey, keys[0]) |
| 67 }) | 67 }) |
| 68 | 68 |
| 69 Convey("empty", func() { | 69 Convey("empty", func() { |
| 70 » » » So(KeyContext{"appid", "ns"}.NewKeyToks(nil), ShouldBeNi
l) | 70 » » » So(MkKeyContext("appid", "ns").NewKeyToks(nil), ShouldBe
Nil) |
| 71 }) | 71 }) |
| 72 | 72 |
| 73 Convey("nest", func() { | 73 Convey("nest", func() { |
| 74 » » » kc := KeyContext{"appid", "ns"} | 74 » » » kc := MkKeyContext("appid", "ns") |
| 75 k := kc.NewKey("renerd", "moo", 0, kc.NewKey("parent", "
", 10, nil)) | 75 k := kc.NewKey("renerd", "moo", 0, kc.NewKey("parent", "
", 10, nil)) |
| 76 So(k, ShouldEqualKey, keys[2]) | 76 So(k, ShouldEqualKey, keys[2]) |
| 77 }) | 77 }) |
| 78 }) | 78 }) |
| 79 | 79 |
| 80 Convey("Key bad encoding", t, func() { | 80 Convey("Key bad encoding", t, func() { |
| 81 Convey("extra junk before", func() { | 81 Convey("extra junk before", func() { |
| 82 enc := keys[2].Encode() | 82 enc := keys[2].Encode() |
| 83 _, err := NewKeyEncoded("/" + enc) | 83 _, err := NewKeyEncoded("/" + enc) |
| 84 So(err, ShouldErrLike, "illegal base64") | 84 So(err, ShouldErrLike, "illegal base64") |
| (...skipping 13 matching lines...) Expand all Loading... |
| 98 err = dec.UnmarshalJSON(append(data, '!')) | 98 err = dec.UnmarshalJSON(append(data, '!')) |
| 99 So(err, ShouldErrLike, "bad JSON key") | 99 So(err, ShouldErrLike, "bad JSON key") |
| 100 }) | 100 }) |
| 101 }) | 101 }) |
| 102 } | 102 } |
| 103 | 103 |
| 104 func TestKeyValidity(t *testing.T) { | 104 func TestKeyValidity(t *testing.T) { |
| 105 t.Parallel() | 105 t.Parallel() |
| 106 | 106 |
| 107 Convey("keys validity", t, func() { | 107 Convey("keys validity", t, func() { |
| 108 » » kc := KeyContext{"aid", "ns"} | 108 » » kc := MkKeyContext("aid", "ns") |
| 109 | 109 |
| 110 Convey("incomplete", func() { | 110 Convey("incomplete", func() { |
| 111 So(kc.MakeKey("kind", 1).IsIncomplete(), ShouldBeFalse) | 111 So(kc.MakeKey("kind", 1).IsIncomplete(), ShouldBeFalse) |
| 112 So(kc.MakeKey("kind", 0).IsIncomplete(), ShouldBeTrue) | 112 So(kc.MakeKey("kind", 0).IsIncomplete(), ShouldBeTrue) |
| 113 }) | 113 }) |
| 114 | 114 |
| 115 Convey("invalid", func() { | 115 Convey("invalid", func() { |
| 116 So(kc.MakeKey("hat", "face", "__kind__", 1).Valid(true,
kc), ShouldBeTrue) | 116 So(kc.MakeKey("hat", "face", "__kind__", 1).Valid(true,
kc), ShouldBeTrue) |
| 117 | 117 |
| 118 bads := []*Key{ | 118 bads := []*Key{ |
| 119 » » » » KeyContext{"aid", "ns"}.NewKeyToks([]KeyTok{{"Ki
nd", 1, "1"}}), | 119 » » » » MkKeyContext("aid", "ns").NewKeyToks([]KeyTok{{"
Kind", 1, "1"}}), |
| 120 » » » » KeyContext{"", "ns"}.MakeKey("", "ns", "hat", "f
ace"), | 120 » » » » MkKeyContext("", "ns").MakeKey("", "ns", "hat",
"face"), |
| 121 kc.MakeKey("base", 1, "", "id"), | 121 kc.MakeKey("base", 1, "", "id"), |
| 122 kc.MakeKey("hat", "face", "__kind__", 1), | 122 kc.MakeKey("hat", "face", "__kind__", 1), |
| 123 kc.MakeKey("hat", 0, "kind", 1), | 123 kc.MakeKey("hat", 0, "kind", 1), |
| 124 } | 124 } |
| 125 for _, k := range bads { | 125 for _, k := range bads { |
| 126 Convey(k.String(), func() { | 126 Convey(k.String(), func() { |
| 127 So(k.Valid(false, kc), ShouldBeFalse) | 127 So(k.Valid(false, kc), ShouldBeFalse) |
| 128 }) | 128 }) |
| 129 } | 129 } |
| 130 }) | 130 }) |
| 131 | 131 |
| 132 Convey("partially valid", func() { | 132 Convey("partially valid", func() { |
| 133 So(kc.MakeKey("kind", "").PartialValid(kc), ShouldBeTrue
) | 133 So(kc.MakeKey("kind", "").PartialValid(kc), ShouldBeTrue
) |
| 134 So(kc.MakeKey("kind", "", "child", "").PartialValid(kc),
ShouldBeFalse) | 134 So(kc.MakeKey("kind", "", "child", "").PartialValid(kc),
ShouldBeFalse) |
| 135 }) | 135 }) |
| 136 }) | 136 }) |
| 137 } | 137 } |
| 138 | 138 |
| 139 func TestMiscKey(t *testing.T) { | 139 func TestMiscKey(t *testing.T) { |
| 140 t.Parallel() | 140 t.Parallel() |
| 141 | 141 |
| 142 Convey("KeyRoot", t, func() { | 142 Convey("KeyRoot", t, func() { |
| 143 » » kc := KeyContext{"appid", "ns"} | 143 » » kc := MkKeyContext("appid", "ns") |
| 144 | 144 |
| 145 k := kc.MakeKey("parent", 10, "renerd", "moo") | 145 k := kc.MakeKey("parent", 10, "renerd", "moo") |
| 146 r := kc.MakeKey("parent", 10) | 146 r := kc.MakeKey("parent", 10) |
| 147 So(k.Root(), ShouldEqualKey, r) | 147 So(k.Root(), ShouldEqualKey, r) |
| 148 }) | 148 }) |
| 149 | 149 |
| 150 Convey("KeysEqual", t, func() { | 150 Convey("KeysEqual", t, func() { |
| 151 » » kc := KeyContext{"a", "n"} | 151 » » kc := MkKeyContext("a", "n") |
| 152 | 152 |
| 153 k1 := kc.MakeKey("knd", 1) | 153 k1 := kc.MakeKey("knd", 1) |
| 154 k2 := kc.MakeKey("knd", 1) | 154 k2 := kc.MakeKey("knd", 1) |
| 155 So(k1.Equal(k2), ShouldBeTrue) | 155 So(k1.Equal(k2), ShouldBeTrue) |
| 156 k3 := kc.MakeKey("knd", 2) | 156 k3 := kc.MakeKey("knd", 2) |
| 157 So(k1.Equal(k3), ShouldBeFalse) | 157 So(k1.Equal(k3), ShouldBeFalse) |
| 158 }) | 158 }) |
| 159 | 159 |
| 160 Convey("KeyString", t, func() { | 160 Convey("KeyString", t, func() { |
| 161 » » kc := KeyContext{"a", "n"} | 161 » » kc := MkKeyContext("a", "n") |
| 162 | 162 |
| 163 k1 := kc.MakeKey("knd", 1, "other", "wat") | 163 k1 := kc.MakeKey("knd", 1, "other", "wat") |
| 164 So(k1.String(), ShouldEqual, "a:n:/knd,1/other,\"wat\"") | 164 So(k1.String(), ShouldEqual, "a:n:/knd,1/other,\"wat\"") |
| 165 }) | 165 }) |
| 166 | 166 |
| 167 Convey("HasAncestor", t, func() { | 167 Convey("HasAncestor", t, func() { |
| 168 » » kc := KeyContext{"a", "n"} | 168 » » kc := MkKeyContext("a", "n") |
| 169 | 169 |
| 170 k1 := kc.MakeKey("kind", 1) | 170 k1 := kc.MakeKey("kind", 1) |
| 171 k2 := kc.MakeKey("kind", 1, "other", "wat") | 171 k2 := kc.MakeKey("kind", 1, "other", "wat") |
| 172 k3 := kc.MakeKey("kind", 1, "other", "wat", "extra", "data") | 172 k3 := kc.MakeKey("kind", 1, "other", "wat", "extra", "data") |
| 173 » » k4 := KeyContext{"something", "n"}.MakeKey("kind", 1) | 173 » » k4 := MkKeyContext("something", "n").MakeKey("kind", 1) |
| 174 k5 := kc.MakeKey("kind", 1, "other", "meep") | 174 k5 := kc.MakeKey("kind", 1, "other", "meep") |
| 175 | 175 |
| 176 So(k1.HasAncestor(k1), ShouldBeTrue) | 176 So(k1.HasAncestor(k1), ShouldBeTrue) |
| 177 So(k1.HasAncestor(k2), ShouldBeFalse) | 177 So(k1.HasAncestor(k2), ShouldBeFalse) |
| 178 So(k2.HasAncestor(k5), ShouldBeFalse) | 178 So(k2.HasAncestor(k5), ShouldBeFalse) |
| 179 So(k5.HasAncestor(k2), ShouldBeFalse) | 179 So(k5.HasAncestor(k2), ShouldBeFalse) |
| 180 So(k2.HasAncestor(k1), ShouldBeTrue) | 180 So(k2.HasAncestor(k1), ShouldBeTrue) |
| 181 So(k3.HasAncestor(k2), ShouldBeTrue) | 181 So(k3.HasAncestor(k2), ShouldBeTrue) |
| 182 So(k3.HasAncestor(k1), ShouldBeTrue) | 182 So(k3.HasAncestor(k1), ShouldBeTrue) |
| 183 So(k3.HasAncestor(k4), ShouldBeFalse) | 183 So(k3.HasAncestor(k4), ShouldBeFalse) |
| 184 }) | 184 }) |
| 185 | 185 |
| 186 Convey("*GenericKey supports json encoding", t, func() { | 186 Convey("*GenericKey supports json encoding", t, func() { |
| 187 type TestStruct struct { | 187 type TestStruct struct { |
| 188 Key *Key | 188 Key *Key |
| 189 } | 189 } |
| 190 t := &TestStruct{ | 190 t := &TestStruct{ |
| 191 » » » KeyContext{"aid", "ns"}.NewKey("kind", "id", 0, | 191 » » » MkKeyContext("aid", "ns").NewKey("kind", "id", 0, |
| 192 » » » » KeyContext{"aid", "ns"}.NewKey("parent", "", 1,
nil), | 192 » » » » MkKeyContext("aid", "ns").NewKey("parent", "", 1
, nil), |
| 193 )} | 193 )} |
| 194 d, err := json.Marshal(t) | 194 d, err := json.Marshal(t) |
| 195 So(err, ShouldBeNil) | 195 So(err, ShouldBeNil) |
| 196 t2 := &TestStruct{} | 196 t2 := &TestStruct{} |
| 197 err = json.Unmarshal(d, t2) | 197 err = json.Unmarshal(d, t2) |
| 198 So(err, ShouldBeNil) | 198 So(err, ShouldBeNil) |
| 199 So(t.Key, ShouldEqualKey, t2.Key) | 199 So(t.Key, ShouldEqualKey, t2.Key) |
| 200 }) | 200 }) |
| 201 } | 201 } |
| 202 | 202 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 230 Convey("KeyTok.Less() works", t, func() { | 230 Convey("KeyTok.Less() works", t, func() { |
| 231 So((KeyTok{"a", 0, "1"}).Less(KeyTok{"b", 0, "2"}), ShouldBeTrue
) | 231 So((KeyTok{"a", 0, "1"}).Less(KeyTok{"b", 0, "2"}), ShouldBeTrue
) |
| 232 So((KeyTok{"b", 0, "1"}).Less(KeyTok{"a", 0, "2"}), ShouldBeFals
e) | 232 So((KeyTok{"b", 0, "1"}).Less(KeyTok{"a", 0, "2"}), ShouldBeFals
e) |
| 233 So((KeyTok{"kind", 0, "1"}).Less(KeyTok{"kind", 0, "2"}), Should
BeTrue) | 233 So((KeyTok{"kind", 0, "1"}).Less(KeyTok{"kind", 0, "2"}), Should
BeTrue) |
| 234 So((KeyTok{"kind", 1, ""}).Less(KeyTok{"kind", 2, ""}), ShouldBe
True) | 234 So((KeyTok{"kind", 1, ""}).Less(KeyTok{"kind", 2, ""}), ShouldBe
True) |
| 235 So((KeyTok{"kind", 1, ""}).Less(KeyTok{"kind", 0, "1"}), ShouldB
eTrue) | 235 So((KeyTok{"kind", 1, ""}).Less(KeyTok{"kind", 0, "1"}), ShouldB
eTrue) |
| 236 }) | 236 }) |
| 237 | 237 |
| 238 Convey("Key comparison works", t, func() { | 238 Convey("Key comparison works", t, func() { |
| 239 s := []*Key{ | 239 s := []*Key{ |
| 240 » » » KeyContext{"A", ""}.MakeKey("kind", 1), | 240 » » » MkKeyContext("A", "").MakeKey("kind", 1), |
| 241 » » » KeyContext{"A", "n"}.MakeKey("kind", 1), | 241 » » » MkKeyContext("A", "n").MakeKey("kind", 1), |
| 242 » » » KeyContext{"A", "n"}.MakeKey("kind", 1, "something", "el
se"), | 242 » » » MkKeyContext("A", "n").MakeKey("kind", 1, "something", "
else"), |
| 243 » » » KeyContext{"A", "n"}.MakeKey("kind", "1"), | 243 » » » MkKeyContext("A", "n").MakeKey("kind", "1"), |
| 244 » » » KeyContext{"A", "n"}.MakeKey("kind", "1", "something", "
else"), | 244 » » » MkKeyContext("A", "n").MakeKey("kind", "1", "something",
"else"), |
| 245 » » » KeyContext{"A", "n"}.MakeKey("other", 1, "something", "e
lse"), | 245 » » » MkKeyContext("A", "n").MakeKey("other", 1, "something",
"else"), |
| 246 » » » KeyContext{"a", ""}.MakeKey("kind", 1), | 246 » » » MkKeyContext("a", "").MakeKey("kind", 1), |
| 247 » » » KeyContext{"a", "n"}.MakeKey("kind", 1), | 247 » » » MkKeyContext("a", "n").MakeKey("kind", 1), |
| 248 » » » KeyContext{"a", "n"}.MakeKey("kind", 2), | 248 » » » MkKeyContext("a", "n").MakeKey("kind", 2), |
| 249 » » » KeyContext{"a", "p"}.MakeKey("aleph", 1), | 249 » » » MkKeyContext("a", "p").MakeKey("aleph", 1), |
| 250 » » » KeyContext{"b", "n"}.MakeKey("kind", 2), | 250 » » » MkKeyContext("b", "n").MakeKey("kind", 2), |
| 251 } | 251 } |
| 252 | 252 |
| 253 for i := 1; i < len(s); i++ { | 253 for i := 1; i < len(s); i++ { |
| 254 So(s[i-1], shouldBeLess, s[i]) | 254 So(s[i-1], shouldBeLess, s[i]) |
| 255 So(s[i-1], shouldNotBeEqual, s[i]) | 255 So(s[i-1], shouldNotBeEqual, s[i]) |
| 256 So(s[i], shouldNotBeEqual, s[i-1]) | 256 So(s[i], shouldNotBeEqual, s[i-1]) |
| 257 So(s[i], shouldNotBeLess, s[i-1]) | 257 So(s[i], shouldNotBeLess, s[i-1]) |
| 258 } | 258 } |
| 259 }) | 259 }) |
| 260 } | 260 } |
| OLD | NEW |