/lib/appengine-ndb-experiment/ndb/key_test.py

https://code.google.com/p/webapp-improved/ · Python · 250 lines · 195 code · 48 blank · 7 comment · 7 complexity · 0045c0b9062be5b51d447c9067055555 MD5 · raw file

  1. """Tests for key.py."""
  2. import base64
  3. import pickle
  4. import unittest
  5. from google.appengine.api import datastore_errors
  6. from google.appengine.datastore import entity_pb
  7. from ndb import key
  8. class KeyTests(unittest.TestCase):
  9. def testShort(self):
  10. k0 = key.Key('Kind', None)
  11. self.assertEqual(k0.flat(), ['Kind', None])
  12. k1 = key.Key('Kind', 1)
  13. self.assertEqual(k1.flat(), ['Kind', 1])
  14. k2 = key.Key('Parent', 42, 'Kind', 1)
  15. self.assertEqual(k2.flat(), ['Parent', 42, 'Kind', 1])
  16. def testFlat(self):
  17. flat = ['Kind', 1]
  18. pairs = [(flat[i], flat[i+1]) for i in xrange(0, len(flat), 2)]
  19. k = key.Key(flat=flat)
  20. self.assertEqual(k.pairs(), pairs)
  21. self.assertEqual(k.flat(), flat)
  22. self.assertEqual(k.kind(), 'Kind')
  23. def testFlatLong(self):
  24. flat = ['Kind', 1, 'Subkind', 'foobar']
  25. pairs = [(flat[i], flat[i+1]) for i in xrange(0, len(flat), 2)]
  26. k = key.Key(flat=flat)
  27. self.assertEqual(k.pairs(), pairs)
  28. self.assertEqual(k.flat(), flat)
  29. self.assertEqual(k.kind(), 'Subkind')
  30. def testSerialized(self):
  31. flat = ['Kind', 1, 'Subkind', 'foobar']
  32. r = entity_pb.Reference()
  33. r.set_app('_')
  34. e = r.mutable_path().add_element()
  35. e.set_type(flat[0])
  36. e.set_id(flat[1])
  37. e = r.mutable_path().add_element()
  38. e.set_type(flat[2])
  39. e.set_name(flat[3])
  40. serialized = r.Encode()
  41. urlsafe = base64.urlsafe_b64encode(r.Encode()).rstrip('=')
  42. k = key.Key(flat=flat)
  43. self.assertEqual(k.serialized(), serialized)
  44. self.assertEqual(k.urlsafe(), urlsafe)
  45. self.assertEqual(k.reference(), r)
  46. k = key.Key(urlsafe=urlsafe)
  47. self.assertEqual(k.serialized(), serialized)
  48. self.assertEqual(k.urlsafe(), urlsafe)
  49. self.assertEqual(k.reference(), r)
  50. k = key.Key(serialized=serialized)
  51. self.assertEqual(k.serialized(), serialized)
  52. self.assertEqual(k.urlsafe(), urlsafe)
  53. self.assertEqual(k.reference(), r)
  54. k = key.Key(reference=r)
  55. self.assertTrue(k._reference() is not r)
  56. self.assertEqual(k.serialized(), serialized)
  57. self.assertEqual(k.urlsafe(), urlsafe)
  58. self.assertEqual(k.reference(), r)
  59. k = key.Key(reference=r, app=r.app(), namespace='')
  60. self.assertTrue(k._reference() is not r)
  61. self.assertEqual(k.serialized(), serialized)
  62. self.assertEqual(k.urlsafe(), urlsafe)
  63. self.assertEqual(k.reference(), r)
  64. k1 = key.Key('A', 1)
  65. self.assertEqual(k1.urlsafe(), 'agFfcgcLEgFBGAEM')
  66. k2 = key.Key(urlsafe=k1.urlsafe())
  67. self.assertEqual(k1, k2)
  68. def testId(self):
  69. k1 = key.Key('Kind', 'foo', app='app1', namespace='ns1')
  70. self.assertEqual(k1.id(), 'foo')
  71. k2 = key.Key('Subkind', 42, parent=k1)
  72. self.assertEqual(k2.id(), 42)
  73. k3 = key.Key('Subkind', 'bar', parent=k2)
  74. self.assertEqual(k3.id(), 'bar')
  75. # incomplete key
  76. k4 = key.Key('Subkind', None, parent=k3)
  77. self.assertEqual(k4.id(), None)
  78. def testStringId(self):
  79. k1 = key.Key('Kind', 'foo', app='app1', namespace='ns1')
  80. self.assertEqual(k1.string_id(), 'foo')
  81. k2 = key.Key('Subkind', 'bar', parent=k1)
  82. self.assertEqual(k2.string_id(), 'bar')
  83. k3 = key.Key('Subkind', 42, parent=k2)
  84. self.assertEqual(k3.string_id(), None)
  85. # incomplete key
  86. k4 = key.Key('Subkind', None, parent=k3)
  87. self.assertEqual(k4.string_id(), None)
  88. def testIntegerId(self):
  89. k1 = key.Key('Kind', 42, app='app1', namespace='ns1')
  90. self.assertEqual(k1.integer_id(), 42)
  91. k2 = key.Key('Subkind', 43, parent=k1)
  92. self.assertEqual(k2.integer_id(), 43)
  93. k3 = key.Key('Subkind', 'foobar', parent=k2)
  94. self.assertEqual(k3.integer_id(), None)
  95. # incomplete key
  96. k4 = key.Key('Subkind', None, parent=k3)
  97. self.assertEqual(k4.integer_id(), None)
  98. def testParent(self):
  99. p = key.Key('Kind', 1, app='app1', namespace='ns1')
  100. self.assertEqual(p.parent(), None)
  101. k = key.Key('Subkind', 'foobar', parent=p)
  102. self.assertEqual(k.flat(), ['Kind', 1, 'Subkind', 'foobar'])
  103. self.assertEqual(k.parent(), p)
  104. k = key.Key('Subkind', 'foobar', parent=p,
  105. app=p.app(), namespace=p.namespace())
  106. self.assertEqual(k.flat(), ['Kind', 1, 'Subkind', 'foobar'])
  107. self.assertEqual(k.parent(), p)
  108. def testRoot(self):
  109. p = key.Key('Kind', 1, app='app1', namespace='ns1')
  110. self.assertEqual(p.root(), p)
  111. k = key.Key('Subkind', 'foobar', parent=p)
  112. self.assertEqual(k.flat(), ['Kind', 1, 'Subkind', 'foobar'])
  113. self.assertEqual(k.root(), p)
  114. k2 = key.Key('Subsubkind', 42, parent=k,
  115. app=p.app(), namespace=p.namespace())
  116. self.assertEqual(k2.flat(), ['Kind', 1,
  117. 'Subkind', 'foobar',
  118. 'Subsubkind', 42])
  119. self.assertEqual(k2.root(), p)
  120. def testRepr_Inferior(self):
  121. k = key.Key('Kind', 1L, 'Subkind', 'foobar')
  122. self.assertEqual(repr(k),
  123. "Key('Kind', 1, 'Subkind', 'foobar')")
  124. self.assertEqual(repr(k), str(k))
  125. def testRepr_Toplevel(self):
  126. k = key.Key('Kind', 1)
  127. self.assertEqual(repr(k), "Key('Kind', 1)")
  128. def testRepr_Incomplete(self):
  129. k = key.Key('Kind', None)
  130. self.assertEqual(repr(k), "Key('Kind', None)")
  131. def testRepr_UnicodeKind(self):
  132. k = key.Key(u'\u1234', 1)
  133. self.assertEqual(repr(k), "Key('\\xe1\\x88\\xb4', 1)")
  134. def testRepr_UnicodeId(self):
  135. k = key.Key('Kind', u'\u1234')
  136. self.assertEqual(repr(k), "Key('Kind', '\\xe1\\x88\\xb4')")
  137. def testRepr_App(self):
  138. k = key.Key('Kind', 1, app='foo')
  139. self.assertEqual(repr(k), "Key('Kind', 1, app='foo')")
  140. def testRepr_Namespace(self):
  141. k = key.Key('Kind', 1, namespace='foo')
  142. self.assertEqual(repr(k), "Key('Kind', 1, namespace='foo')")
  143. def testUnicode(self):
  144. flat_input = [u'Kind\u1234', 1, 'Subkind', u'foobar\u4321']
  145. flat = [flat_input[0].encode('utf8'), flat_input[1],
  146. flat_input[2], flat_input[3].encode('utf8')]
  147. pairs = [(flat[i], flat[i+1]) for i in xrange(0, len(flat), 2)]
  148. k = key.Key(flat=flat_input)
  149. self.assertEqual(k.pairs(), pairs)
  150. self.assertEqual(k.flat(), flat)
  151. # TODO: test these more thoroughly
  152. r = k.reference()
  153. serialized = k.serialized()
  154. urlsafe = k.urlsafe()
  155. key.Key(urlsafe=urlsafe.decode('utf8'))
  156. key.Key(serialized=serialized.decode('utf8'))
  157. key.Key(reference=r)
  158. # TODO: this may not make sense -- the protobuf utf8-encodes values
  159. r = entity_pb.Reference()
  160. r.set_app('_')
  161. e = r.mutable_path().add_element()
  162. e.set_type(flat_input[0])
  163. e.set_name(flat_input[3])
  164. k = key.Key(reference=r)
  165. self.assertEqual(k.reference(), r)
  166. def testHash(self):
  167. flat = ['Kind', 1, 'Subkind', 'foobar']
  168. pairs = [(flat[i], flat[i+1]) for i in xrange(0, len(flat), 2)]
  169. k = key.Key(flat=flat)
  170. self.assertEqual(hash(k), hash(tuple(pairs)))
  171. def testPickling(self):
  172. flat = ['Kind', 1, 'Subkind', 'foobar']
  173. pairs = [(flat[i], flat[i+1]) for i in xrange(0, len(flat), 2)]
  174. k = key.Key(flat=flat)
  175. for proto in range(pickle.HIGHEST_PROTOCOL + 1):
  176. s = pickle.dumps(k, protocol=proto)
  177. kk = pickle.loads(s)
  178. self.assertEqual(k, kk)
  179. def testIncomplete(self):
  180. k = key.Key(flat=['Kind', None])
  181. self.assertRaises(datastore_errors.BadArgumentError,
  182. key.Key, flat=['Kind', None, 'Subkind', 1])
  183. self.assertRaises(AssertionError, key.Key, flat=['Kind', ()])
  184. def testKindFromModel(self):
  185. from ndb import model
  186. class M(model.Model):
  187. pass
  188. class N(model.Model):
  189. @classmethod
  190. def _get_kind(cls):
  191. return 'NN'
  192. k = key.Key(M, 1)
  193. self.assertEqual(k, key.Key('M', 1))
  194. k = key.Key('X', 1, N, 2, 'Y', 3)
  195. self.assertEqual(k, key.Key('X', 1, 'NN', 2, 'Y', 3))
  196. def testKindFromBadValue(self):
  197. # TODO: BadArgumentError
  198. self.assertRaises(Exception, key.Key, 42, 42)
  199. def main():
  200. unittest.main()
  201. if __name__ == '__main__':
  202. main()