key_test.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // Copyright 2011 Google Inc. All Rights Reserved.
  2. // Use of this source code is governed by the Apache 2.0
  3. // license that can be found in the LICENSE file.
  4. package datastore
  5. import (
  6. "bytes"
  7. "encoding/gob"
  8. "encoding/json"
  9. "testing"
  10. "golang.org/x/net/context"
  11. "google.golang.org/appengine/internal"
  12. )
  13. func TestKeyEncoding(t *testing.T) {
  14. testCases := []struct {
  15. desc string
  16. key *Key
  17. exp string
  18. }{
  19. {
  20. desc: "A simple key with an int ID",
  21. key: &Key{
  22. kind: "Person",
  23. intID: 1,
  24. appID: "glibrary",
  25. },
  26. exp: "aghnbGlicmFyeXIMCxIGUGVyc29uGAEM",
  27. },
  28. {
  29. desc: "A simple key with a string ID",
  30. key: &Key{
  31. kind: "Graph",
  32. stringID: "graph:7-day-active",
  33. appID: "glibrary",
  34. },
  35. exp: "aghnbGlicmFyeXIdCxIFR3JhcGgiEmdyYXBoOjctZGF5LWFjdGl2ZQw",
  36. },
  37. {
  38. desc: "A key with a parent",
  39. key: &Key{
  40. kind: "WordIndex",
  41. intID: 1033,
  42. parent: &Key{
  43. kind: "WordIndex",
  44. intID: 1020032,
  45. appID: "glibrary",
  46. },
  47. appID: "glibrary",
  48. },
  49. exp: "aghnbGlicmFyeXIhCxIJV29yZEluZGV4GIChPgwLEglXb3JkSW5kZXgYiQgM",
  50. },
  51. }
  52. for _, tc := range testCases {
  53. enc := tc.key.Encode()
  54. if enc != tc.exp {
  55. t.Errorf("%s: got %q, want %q", tc.desc, enc, tc.exp)
  56. }
  57. key, err := DecodeKey(tc.exp)
  58. if err != nil {
  59. t.Errorf("%s: failed decoding key: %v", tc.desc, err)
  60. continue
  61. }
  62. if !key.Equal(tc.key) {
  63. t.Errorf("%s: decoded key %v, want %v", tc.desc, key, tc.key)
  64. }
  65. }
  66. }
  67. func TestKeyGob(t *testing.T) {
  68. k := &Key{
  69. kind: "Gopher",
  70. intID: 3,
  71. parent: &Key{
  72. kind: "Mom",
  73. stringID: "narwhal",
  74. appID: "gopher-con",
  75. },
  76. appID: "gopher-con",
  77. }
  78. buf := new(bytes.Buffer)
  79. if err := gob.NewEncoder(buf).Encode(k); err != nil {
  80. t.Fatalf("gob encode failed: %v", err)
  81. }
  82. k2 := new(Key)
  83. if err := gob.NewDecoder(buf).Decode(k2); err != nil {
  84. t.Fatalf("gob decode failed: %v", err)
  85. }
  86. if !k2.Equal(k) {
  87. t.Errorf("gob round trip of %v produced %v", k, k2)
  88. }
  89. }
  90. func TestNilKeyGob(t *testing.T) {
  91. type S struct {
  92. Key *Key
  93. }
  94. s1 := new(S)
  95. buf := new(bytes.Buffer)
  96. if err := gob.NewEncoder(buf).Encode(s1); err != nil {
  97. t.Fatalf("gob encode failed: %v", err)
  98. }
  99. s2 := new(S)
  100. if err := gob.NewDecoder(buf).Decode(s2); err != nil {
  101. t.Fatalf("gob decode failed: %v", err)
  102. }
  103. if s2.Key != nil {
  104. t.Errorf("gob round trip of nil key produced %v", s2.Key)
  105. }
  106. }
  107. func TestKeyJSON(t *testing.T) {
  108. k := &Key{
  109. kind: "Gopher",
  110. intID: 2,
  111. parent: &Key{
  112. kind: "Mom",
  113. stringID: "narwhal",
  114. appID: "gopher-con",
  115. },
  116. appID: "gopher-con",
  117. }
  118. exp := `"` + k.Encode() + `"`
  119. buf, err := json.Marshal(k)
  120. if err != nil {
  121. t.Fatalf("json.Marshal failed: %v", err)
  122. }
  123. if s := string(buf); s != exp {
  124. t.Errorf("JSON encoding of key %v: got %q, want %q", k, s, exp)
  125. }
  126. k2 := new(Key)
  127. if err := json.Unmarshal(buf, k2); err != nil {
  128. t.Fatalf("json.Unmarshal failed: %v", err)
  129. }
  130. if !k2.Equal(k) {
  131. t.Errorf("JSON round trip of %v produced %v", k, k2)
  132. }
  133. }
  134. func TestNilKeyJSON(t *testing.T) {
  135. type S struct {
  136. Key *Key
  137. }
  138. s1 := new(S)
  139. buf, err := json.Marshal(s1)
  140. if err != nil {
  141. t.Fatalf("json.Marshal failed: %v", err)
  142. }
  143. s2 := new(S)
  144. if err := json.Unmarshal(buf, s2); err != nil {
  145. t.Fatalf("json.Unmarshal failed: %v", err)
  146. }
  147. if s2.Key != nil {
  148. t.Errorf("JSON round trip of nil key produced %v", s2.Key)
  149. }
  150. }
  151. func TestIncompleteKeyWithParent(t *testing.T) {
  152. c := internal.WithAppIDOverride(context.Background(), "s~some-app")
  153. // fadduh is a complete key.
  154. fadduh := NewKey(c, "Person", "", 1, nil)
  155. if fadduh.Incomplete() {
  156. t.Fatalf("fadduh is incomplete")
  157. }
  158. // robert is an incomplete key with fadduh as a parent.
  159. robert := NewIncompleteKey(c, "Person", fadduh)
  160. if !robert.Incomplete() {
  161. t.Fatalf("robert is complete")
  162. }
  163. // Both should be valid keys.
  164. if !fadduh.valid() {
  165. t.Errorf("fadduh is invalid: %v", fadduh)
  166. }
  167. if !robert.valid() {
  168. t.Errorf("robert is invalid: %v", robert)
  169. }
  170. }
  171. func TestNamespace(t *testing.T) {
  172. key := &Key{
  173. kind: "Person",
  174. intID: 1,
  175. appID: "s~some-app",
  176. namespace: "mynamespace",
  177. }
  178. if g, w := key.Namespace(), "mynamespace"; g != w {
  179. t.Errorf("key.Namespace() = %q, want %q", g, w)
  180. }
  181. }