You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

211 lines
4.9 KiB

  1. // Copyright 2014 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package datastore
  15. import (
  16. "bytes"
  17. "encoding/gob"
  18. "encoding/json"
  19. "testing"
  20. )
  21. func TestEqual(t *testing.T) {
  22. testCases := []struct {
  23. x, y *Key
  24. equal bool
  25. }{
  26. {
  27. x: nil,
  28. y: nil,
  29. equal: true,
  30. },
  31. {
  32. x: &Key{Kind: "kindA"},
  33. y: &Key{Kind: "kindA"},
  34. equal: true,
  35. },
  36. {
  37. x: &Key{Kind: "kindA", Name: "nameA"},
  38. y: &Key{Kind: "kindA", Name: "nameA"},
  39. equal: true,
  40. },
  41. {
  42. x: &Key{Kind: "kindA", Name: "nameA", Namespace: "gopherspace"},
  43. y: &Key{Kind: "kindA", Name: "nameA", Namespace: "gopherspace"},
  44. equal: true,
  45. },
  46. {
  47. x: &Key{Kind: "kindA", ID: 1337, Parent: &Key{Kind: "kindX", Name: "nameX"}},
  48. y: &Key{Kind: "kindA", ID: 1337, Parent: &Key{Kind: "kindX", Name: "nameX"}},
  49. equal: true,
  50. },
  51. {
  52. x: &Key{Kind: "kindA", Name: "nameA"},
  53. y: &Key{Kind: "kindB", Name: "nameA"},
  54. equal: false,
  55. },
  56. {
  57. x: &Key{Kind: "kindA", Name: "nameA"},
  58. y: &Key{Kind: "kindA", Name: "nameB"},
  59. equal: false,
  60. },
  61. {
  62. x: &Key{Kind: "kindA", Name: "nameA"},
  63. y: &Key{Kind: "kindA", ID: 1337},
  64. equal: false,
  65. },
  66. {
  67. x: &Key{Kind: "kindA", Name: "nameA"},
  68. y: &Key{Kind: "kindA", Name: "nameA", Namespace: "gopherspace"},
  69. equal: false,
  70. },
  71. {
  72. x: &Key{Kind: "kindA", ID: 1337, Parent: &Key{Kind: "kindX", Name: "nameX"}},
  73. y: &Key{Kind: "kindA", ID: 1337, Parent: &Key{Kind: "kindY", Name: "nameX"}},
  74. equal: false,
  75. },
  76. {
  77. x: &Key{Kind: "kindA", ID: 1337, Parent: &Key{Kind: "kindX", Name: "nameX"}},
  78. y: &Key{Kind: "kindA", ID: 1337},
  79. equal: false,
  80. },
  81. }
  82. for _, tt := range testCases {
  83. if got := tt.x.Equal(tt.y); got != tt.equal {
  84. t.Errorf("Equal(%v, %v) = %t; want %t", tt.x, tt.y, got, tt.equal)
  85. }
  86. if got := tt.y.Equal(tt.x); got != tt.equal {
  87. t.Errorf("Equal(%v, %v) = %t; want %t", tt.y, tt.x, got, tt.equal)
  88. }
  89. }
  90. }
  91. func TestEncoding(t *testing.T) {
  92. testCases := []struct {
  93. k *Key
  94. valid bool
  95. }{
  96. {
  97. k: nil,
  98. valid: false,
  99. },
  100. {
  101. k: &Key{},
  102. valid: false,
  103. },
  104. {
  105. k: &Key{Kind: "kindA"},
  106. valid: true,
  107. },
  108. {
  109. k: &Key{Kind: "kindA", Namespace: "gopherspace"},
  110. valid: true,
  111. },
  112. {
  113. k: &Key{Kind: "kindA", Name: "nameA"},
  114. valid: true,
  115. },
  116. {
  117. k: &Key{Kind: "kindA", ID: 1337},
  118. valid: true,
  119. },
  120. {
  121. k: &Key{Kind: "kindA", Name: "nameA", ID: 1337},
  122. valid: false,
  123. },
  124. {
  125. k: &Key{Kind: "kindA", Parent: &Key{Kind: "kindB", Name: "nameB"}},
  126. valid: true,
  127. },
  128. {
  129. k: &Key{Kind: "kindA", Parent: &Key{Kind: "kindB"}},
  130. valid: false,
  131. },
  132. {
  133. k: &Key{Kind: "kindA", Parent: &Key{Kind: "kindB", Name: "nameB", Namespace: "gopherspace"}},
  134. valid: false,
  135. },
  136. }
  137. for _, tt := range testCases {
  138. if got := tt.k.valid(); got != tt.valid {
  139. t.Errorf("valid(%v) = %t; want %t", tt.k, got, tt.valid)
  140. }
  141. // Check encoding/decoding for valid keys.
  142. if !tt.valid {
  143. continue
  144. }
  145. enc := tt.k.Encode()
  146. dec, err := DecodeKey(enc)
  147. if err != nil {
  148. t.Errorf("DecodeKey(%q) from %v: %v", enc, tt.k, err)
  149. continue
  150. }
  151. if !tt.k.Equal(dec) {
  152. t.Logf("Proto: %s", keyToProto(tt.k))
  153. t.Errorf("Decoded key %v not equal to %v", dec, tt.k)
  154. }
  155. b, err := json.Marshal(tt.k)
  156. if err != nil {
  157. t.Errorf("json.Marshal(%v): %v", tt.k, err)
  158. continue
  159. }
  160. key := &Key{}
  161. if err := json.Unmarshal(b, key); err != nil {
  162. t.Errorf("json.Unmarshal(%s) for key %v: %v", b, tt.k, err)
  163. continue
  164. }
  165. if !tt.k.Equal(key) {
  166. t.Errorf("JSON decoded key %v not equal to %v", dec, tt.k)
  167. }
  168. buf := &bytes.Buffer{}
  169. gobEnc := gob.NewEncoder(buf)
  170. if err := gobEnc.Encode(tt.k); err != nil {
  171. t.Errorf("gobEnc.Encode(%v): %v", tt.k, err)
  172. continue
  173. }
  174. gobDec := gob.NewDecoder(buf)
  175. key = &Key{}
  176. if err := gobDec.Decode(key); err != nil {
  177. t.Errorf("gobDec.Decode() for key %v: %v", tt.k, err)
  178. }
  179. if !tt.k.Equal(key) {
  180. t.Errorf("gob decoded key %v not equal to %v", dec, tt.k)
  181. }
  182. }
  183. }
  184. func TestInvalidKeyDecode(t *testing.T) {
  185. // Check that decoding an invalid key returns an err and doesn't panic.
  186. enc := NameKey("Kind", "Foo", nil).Encode()
  187. invalid := []string{
  188. "",
  189. "Laboratorio",
  190. enc + "Junk",
  191. enc[:len(enc)-4],
  192. }
  193. for _, enc := range invalid {
  194. key, err := DecodeKey(enc)
  195. if err == nil || key != nil {
  196. t.Errorf("DecodeKey(%q) = %v, %v; want nil, error", enc, key, err)
  197. }
  198. }
  199. }