PageRenderTime 64ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/test/suite_0.py

http://pickled-object-database.googlecode.com/
Python | 1962 lines | 1317 code | 598 blank | 47 comment | 143 complexity | d439f8693c2f5e2b861cb4d1e2429043 MD5 | raw file
  1. import sys
  2. import os
  3. import unittest
  4. import inspect
  5. import figleaf
  6. import figleaf.annotate_html
  7. import shutil
  8. import exceptions
  9. import sqlite3
  10. class Tester(unittest.TestCase):
  11. org_modules = set(sys.modules.copy().keys())
  12. @classmethod
  13. def reporter_start(cls, use_figleaf = True):
  14. if use_figleaf:
  15. cls.figleaf_dir = inspect.getabsfile(sys.modules[__name__]).split('.')[-2].split(os.sep)[-1]
  16. if os.path.isdir(cls.figleaf_dir):
  17. shutil.rmtree(cls.figleaf_dir, ignore_errors = True)
  18. os.mkdir(cls.figleaf_dir)
  19. figleaf.start()
  20. cls.figleaf_use = use_figleaf
  21. @classmethod
  22. def reporter_stop(cls, viewer = None):
  23. if cls.figleaf_use:
  24. figleaf.stop()
  25. figleaf.annotate_html.report_as_html(figleaf.get_info(), directory = cls.figleaf_dir, exclude_patterns = [], files_list = {})
  26. print "\n\nWrote figleaf report to '" + cls.figleaf_dir + "' . . . "
  27. import pod
  28. print "\n\nUsing pod module:\n\t'" + inspect.getabsfile(pod) +"'"
  29. @classmethod
  30. def run_test(cls, test):
  31. unittest.TextTestRunner(verbosity=2).run(unittest.defaultTestLoader.loadTestsFromTestCase(test))
  32. def __le__(self, item):
  33. if 'first_equals_item' in self.__dict__:
  34. self.assertEqual(self.first_equals_item, item)
  35. del self.__dict__['first_equals_item']
  36. else:
  37. self.first_equals_item = item
  38. def __eq__(self, item):
  39. if not isinstance(item, (list, tuple)):
  40. item = tuple(item)
  41. self.assertEqual(item[0], item[1])
  42. def setUp(self):
  43. self.filename = 'suite_0.sqlite3.db'
  44. def clear_mod_imports(self):
  45. new_modules = set(sys.modules.copy().keys()) - Tester.org_modules
  46. for key in new_modules:
  47. del sys.modules[key]
  48. def tearDown(self):
  49. self.clear_mod_imports()
  50. if os.path.isfile(self.filename):
  51. #os.remove(self.filename)
  52. pass
  53. class raises(object):
  54. def __init__(self, *args):
  55. self.exceptions = tuple(args)
  56. def __call__(self, fn):
  57. excepted = False
  58. try:
  59. fn()
  60. except self.exceptions:
  61. excepted = True
  62. if excepted is False:
  63. raise exceptions.AssertionError, "Exceptions not raised: " + str(self.exceptions)
  64. """ THE BASICS """
  65. class Basics(Tester):
  66. def test_basics(self):
  67. self.basic_section_0()
  68. self.clear_mod_imports()
  69. self.basic_section_1()
  70. self.clear_mod_imports()
  71. def basic_section_0(self):
  72. import pod
  73. db = pod.Db(file = self.filename, remove = True, very_chatty = False)
  74. class Person(pod.Object):
  75. pass
  76. class Punk(Person):
  77. pass
  78. class Email(pod.Object):
  79. ctime = pod.typed.TimeCreate()
  80. email_0 = Email(title = 'FYI', age = 1)
  81. email_1 = Email(title = 'GO HOME', age = 2)
  82. email_2 = Email(title = 'HI', age = 3.3)
  83. Person(name = 'Fred', age = 32, emails = [email_0, email_1])
  84. Person(name = 'Hsing', age = 35.3, emails = [])
  85. Person(name = 'Joan', age = 22.3, emails = [email_2])
  86. Punk(name = 'Mred', age = 12, emails = [email_0, email_1])
  87. Punk(name = 'Xsing', age = 15.3, emails = [email_0, email_1, email_2])
  88. Punk(name = 'Yoan', age = 12.3, emails = [email_2])
  89. self <= [peep.name for peep in Person.where.age == 32]
  90. self <= ['Fred']
  91. self <= [peep.name for peep in Person.where.name[1:3] == 're']
  92. self <= ['Fred', 'Mred']
  93. self <= [peep.name for peep in (Person.where.name[-3:-1] == 're') | (Person.where.age == 35.3)]
  94. self <= ['Fred', 'Hsing', 'Mred']
  95. self <= [peep.name for peep in Person.where.emails == [email_2]]
  96. self <= ['Joan', 'Yoan']
  97. self <= [peep.name for peep in Person.where.age < 25]
  98. self <= ['Joan', 'Mred', 'Xsing', 'Yoan']
  99. self <= [peep.name for peep in (Person.where.emails == [email_2]) & (Person.where.age < 25)]
  100. self <= ['Joan', 'Yoan']
  101. self <= [peep.name for peep in (Person.where.emails == [email_2]) & (Person.where.age < 10)]
  102. self <= []
  103. self <= Email.get_count()
  104. self <= 3
  105. self <= Person.get_count()
  106. self <= 6
  107. self <= Person.get_count(child_classes = False)
  108. self <= 3
  109. self <= Punk.get_count(child_classes = False)
  110. self <= 3
  111. self <= [email.title for email in Email.ctime.younger_than(days = 1)]
  112. self <= ['FYI', 'GO HOME', 'HI']
  113. import time
  114. time.sleep(1)
  115. self <= [email.title for email in Email.ctime.older_than(seconds = 1)]
  116. self <= ['FYI', 'GO HOME', 'HI']
  117. db.commit(close = True)
  118. def basic_section_1(self):
  119. import pod
  120. db = pod.Db(file = self.filename, remove = True, very_chatty = False)
  121. class Person(pod.Object):
  122. name = pod.typed.String()
  123. age = pod.typed.Int(index = True)
  124. alive = pod.typed.Boolean()
  125. boss = pod.typed.PodObject()
  126. emails = pod.typed.Object()
  127. class Punk(Person):
  128. weight = pod.typed.Float()
  129. class Email(pod.Object):
  130. ctime = pod.typed.TimeCreate()
  131. email_0 = Email(title = 'FYI', age = 1)
  132. email_1 = Email(title = 'GO HOME', age = 2)
  133. email_2 = Email(title = 'HI', age = 3.3)
  134. boss = Person(name = 'Don', age = 55, emails = [email_0, email_1], random = 'FOO')
  135. Person(name = 'Fred', age = 32, emails = [email_0, email_1], boss = boss, random = 'FOO')
  136. Person(name = 'Hsing', age = 35.3, emails = [], boss = boss, random = 10.0)
  137. Person(name = 'Joan', age = 22.3, emails = [email_2], boss = boss, random = 20.0)
  138. Punk(name = 'Mred', age = 12, weight = 30.1, emails = [email_0, email_1], boss = boss, random = 30.0)
  139. Punk(name = 'Xsing', age = 15.3, weight = 40.1, emails = [email_0, email_1, email_2], boss = boss, random = 10.0)
  140. Punk(name = 'Yoan', age = 12.3, weight = 50.1, emails = [email_2], boss = None, random = 11.3, some_attr = [10, 20, 30])
  141. db.commit(clear_cache = False)
  142. self <= [peep.name for peep in (Person.age > 10) & (Person.where.random < 24.0)]
  143. self <= ['Hsing', 'Joan', 'Xsing', 'Yoan']
  144. self <= [peep.name for peep in (Person.age > 10) | (Person.where.random < 24.0)]
  145. self <= ['Don', 'Fred', 'Hsing', 'Joan', 'Mred', 'Xsing', 'Yoan']
  146. self <= [peep.name for peep in ((Person.age > 90) & (Person.where.random < 12.0)) | (Person.boss == boss)]
  147. self <= ['Fred', 'Hsing', 'Joan', 'Mred', 'Xsing']
  148. self <= [peep.name for peep in (Person.alive == None) & (Person.where.random == 'FOO')]
  149. self <= ['Don', 'Fred']
  150. for peep in Person.name[1:4] == 'red':
  151. peep.alive = True
  152. self <= [(peep.alive, peep.name) for peep in (Person.alive == True)]
  153. self <= [(True, 'Fred'), (True, 'Mred')]
  154. self <= [(peep.alive, peep.random) for peep in (Person.alive == True) & (Person.where.random > 25)]
  155. self <= [(True, 'FOO'), (True, 30.0)]
  156. self <= [(peep.alive, peep.name, peep.random) for peep in (Person.alive == True) & (Person.where.random > 25) | (Person.where.some_attr)]
  157. self <= [(True, 'Fred', 'FOO'), (True, 'Mred', 30.0), (None, 'Yoan', 11.300000000000001)]
  158. self <= [(peep.name, peep.age) for peep in Person.age == 32]
  159. self <= [('Fred', 32)]
  160. self <= [peep.name for peep in Person.name[1:3] == 're']
  161. self <= ['Fred', 'Mred']
  162. self <= [(peep.name, peep.age) for peep in (Person.name[-3:-1] == 're') | (Person.age == 35)] # We made this int, so type convert
  163. self <= [('Fred', 32), ('Hsing', 35.299999999999997), ('Mred', 12)]
  164. self <= [(peep.name,len(peep.emails)) for peep in Person.emails == [email_2]]
  165. self <= [('Joan', 1), ('Yoan', 1)]
  166. self <= [(peep.name, peep.age) for peep in Person.age < 25]
  167. self <= [('Joan', 22.300000000000001), ('Mred', 12), ('Xsing', 15.300000000000001), ('Yoan', 12.300000000000001)]
  168. self <= [(peep.name,len(peep.emails),peep.age) for peep in (Person.emails == [email_2]) & (Person.age < 25)]
  169. self <= [('Joan', 1, 22.300000000000001), ('Yoan', 1, 12.300000000000001)]
  170. self <= [peep.name for peep in (Person.emails == [email_2]) & (Person.age < 10)]
  171. self <= []
  172. self <= Email.get_count()
  173. self <= 3
  174. self <= Person.get_count()
  175. self <= 7
  176. self <= Person.get_count(child_classes = False)
  177. self <= 4
  178. self <= Punk.get_count(child_classes = False)
  179. self <= 3
  180. self <= [email.title for email in Email.ctime.younger_than(days = 1)]
  181. self <= ['FYI', 'GO HOME', 'HI']
  182. import time
  183. time.sleep(1)
  184. self <= [email.title for email in Email.ctime.older_than(seconds = 1)]
  185. self <= ['FYI', 'GO HOME', 'HI']
  186. db.commit(close = True)
  187. """ QUICK EXAMPLE """
  188. def test_quick_example_db(self):
  189. self.quick_example(clear_cache = True)
  190. def test_quick_example_cache(self):
  191. self.quick_example(clear_cache = False)
  192. def quick_example(self, clear_cache):
  193. import pod
  194. db = pod.Db(file = self.filename, remove = True) # First, make a connection to the database . . .
  195. class Person(pod.Object): # Now, any object that descends from pod.Object will be stored to last opened database connection.
  196. def __init__(self, name, age, best_friend = None, **kwargs):
  197. pod.Object.__init__(self, **kwargs)
  198. self.name = name
  199. self.age = age
  200. self.friends = set() # An attribute can be of any type, including collections
  201. if best_friend:
  202. self.add_friend(friend = best_friend, best = True)
  203. def add_friend(self, friend, best = False):
  204. self.friends.add(friend)
  205. friend.friends.add(self)
  206. if best:
  207. self.best_friend = friend # A member can even be another pod object.
  208. friend.best_friend = self
  209. # Now, add a class Tycoon that descends from Person . . .
  210. class Tycoon(Person):
  211. # Below, we add columns in order to allow faster raw SQL queries.
  212. # You don't need to do this -- it just makes querying on that attribute faster.
  213. # Add an SQL index for even faster querying at expense of slower insertion into db.
  214. age = pod.typed.Int(index = False)
  215. catch_phrase = pod.typed.String(index = True)
  216. yachts = pod.typed.Object(index = True)
  217. # Let's add another class that descends directly from pod.Object . . .
  218. class Yacht(pod.Object):
  219. owner = pod.typed.Object(index = True)
  220. # Now, add some Person, Tycoon, and Yacht objects to the database . . .
  221. fred = Person(name = 'Fred', age = 20, some_random_attr = 'foo')
  222. frank = Person(name = 'Frank', age = 80, some_other_random_attr = ['bar', 'baz'])
  223. don = Tycoon(name = 'Don', age = 63, best_friend = fred, catch_phrase = "You're fired!")
  224. george = Tycoon(name = 'George', age = 61, best_friend = frank, catch_phrase = "I guarantee it")
  225. george.yachts = [Yacht(owner = george, name = 'The One That Got Away'), Yacht(owner = george, name = 'The Trickle Downer')]
  226. # Now, commit this transaction. You can also call db.rollback() to cancel this transaction.
  227. db.commit(clear_cache = clear_cache)
  228. # Now, get some objects out of the db.
  229. if clear_cache:
  230. # Since the comparison is based upon the Python "id", this should fail as the query will return new objects.
  231. self.assertNotEqual(set((fred, frank, don, george)), set(peep for peep in Person))
  232. self.assertEqual(set((o.name, o.age) for o in (fred, frank, don, george)), set((peep.name, peep.age) for peep in Person))
  233. self.assertNotEqual(set((fred, frank)), set(peep for peep in Person if peep.name[0] == 'F'))
  234. self.assertEqual(set((o.name, o.age) for o in (fred, frank)), set((peep.name, peep.age) for peep in Person if peep.name[0] == 'F'))
  235. else:
  236. # Since the comparison is based upon the Python "id", this should succeed as the query will return the same objects.
  237. self.assertEqual(set((fred, frank, don, george)), set(peep for peep in Person))
  238. self.assertEqual(set((fred, frank)), set(peep for peep in Person if peep.name[0] == 'F'))
  239. # Or, if we added a column to the class header, we can query much more efficiently using sqlite3.
  240. for tyke in Tycoon.catch_phrase == "You're fired!":
  241. self.assertEqual(tyke.name, 'Don')
  242. self.assertEqual(tyke.age, 63)
  243. self.assertEqual(tyke.best_friend.name, 'Fred')
  244. # You can even query on pod objects . . .
  245. for exp, yacht in zip(george.yachts, Yacht.owner == george):
  246. self.assertEqual(yacht.owner.name, exp.owner.name)
  247. self.assertEqual(yacht.name, exp.name)
  248. # Or, for full SQL control, use a query object on any defined columns:
  249. query = pod.Query(select = Tycoon.age,
  250. where = (Tycoon.age < 62) | Tycoon.catch_phrase.startswith("Yo"),
  251. order_by = Tycoon.age.desc(),
  252. limit = 2)
  253. if clear_cache:
  254. query_results = [o for o in query]
  255. self.assertNotEqual([don, george], query_results)
  256. expect = [(o.name, o.age, o.catch_phrase, o.best_friend.name) for o in (don, george)]
  257. actual = [(o.name, o.age, o.catch_phrase, o.best_friend.name) for o in query_results]
  258. self.assertEqual(expect, actual)
  259. else:
  260. self.assertEqual([don, george], [o for o in query])
  261. # Just like regular Python objects, you can add attributes on the fly . . .
  262. don.another_random_attr = ['foo', 'bar', 'baz']
  263. # Now, commit the 'another_random_attr' change . . .
  264. db.commit(clear_cache = clear_cache)
  265. query = pod.Query(select = Tycoon.age, where = Tycoon.age == 63)
  266. if clear_cache:
  267. query_results = [o for o in query]
  268. self.assertEqual(len(query_results), 1)
  269. q = query_results[0]
  270. self.assertNotEqual(don, q)
  271. expect = [don.name, don.age, don.catch_phrase, don.best_friend.name, don.another_random_attr]
  272. actual = [q.name, q.age, q.catch_phrase, q.best_friend.name, q.another_random_attr]
  273. self.assertEqual(expect, actual)
  274. else:
  275. self.assertEqual([don], [o for o in query])
  276. # Finally, all Db instances and all pod.Object classes contain a 'store' attribute which can be used exactly like a shelve. Each 'store' is separate from all others . . .
  277. Tycoon.store.main_tycoon = george
  278. db.commit(clear_cache = clear_cache)
  279. # The store is useful for storing pointers to objects you want access to later on
  280. for yacht in Yacht.owner == Tycoon.store.main_tycoon:
  281. self.assertEqual(yacht.owner.name, 'George')
  282. db.commit(clear_cache = clear_cache, close = True)
  283. """ FRONT PAGE EXAMPLE """
  284. def test_front_page_db(self):
  285. self.front_page(clear_cache = True)
  286. def test_front_page_cache(self):
  287. self.front_page(clear_cache = False)
  288. def front_page(self, clear_cache):
  289. import pod
  290. import models_front
  291. db = pod.Db(file = self.filename, remove = True, attach = [models_front, pod.set])
  292. hsing = models_front.Person(name = 'Hsing', some_attr = 'foo') # Now, add some Person, Tycoon, and WorkerBee objects to
  293. helen = models_front.Person(name = 'Helen', some_other_attr = ['bar', 'baz']) # the database . . .
  294. don = models_front.Tycoon(name = 'Don', age = 63, catch_phrase = "You're fired!")
  295. george = models_front.Tycoon(name = 'George', age = 61, catch_phrase = "I guarantee it")
  296. bruce = models_front.WorkerBee(name = 'Bruce', age = 40, boss = don, random_attr = 10.23)
  297. azhar = models_front.WorkerBee(name = 'Azhar', age = 40, boss = george, random_attr = {'key': ['value', (1, 2, 3)]})
  298. self.assertEqual(set([peep.name for peep in models_front.Person]), set(['Hsing', 'Don', 'Bruce', 'Azhar', 'Helen', 'George']))
  299. self.assertEqual(set([peep.name for peep in models_front.Tycoon]), set(['Don', 'George']))
  300. self.assertEqual(set([peep.name for peep in models_front.WorkerBee]), set(['Bruce', 'Azhar']))
  301. db.commit(clear_cache = clear_cache, close = False)
  302. class Yacht(pod.Object):
  303. name = pod.typed.String(index = False)
  304. length = pod.typed.Float(index = True)
  305. awards = pod.typed.Object(index = True)
  306. owner = pod.typed.Object(index = True)
  307. def __init__(self, owner, **kwargs):
  308. pod.Object.__init__(self, **kwargs)
  309. self.owner = owner
  310. self.owner.yachts.append(self)
  311. self.photos = []
  312. db.attach(Yacht)
  313. Yacht(owner = george, name = 'The Trickle Downer', length = 40.5)
  314. Yacht(owner = george, name = 'The TARP Runner', length = 42.1, some_random_attr = 'foo')
  315. Yacht(owner = george, name = 'Mr. Pickles', length = 45.1, some_random_attr = 'foo')
  316. self.assertEqual(set([yacht.owner.name for yacht in Yacht.name == 'The Trickle Downer']), set(['George', 'George']))
  317. self.assertEqual(set([yacht.owner.name for yacht in Yacht.owner == george]), set(['George', 'George']))
  318. query = pod.Query(select = Yacht.name | Yacht.length, # Or, for full SQL control, use a query object on any defined
  319. where = (Yacht.length < 41) | (Yacht.length == 42.1), # typed. Conditionals are chained together with '|' or '&'.
  320. order_by = Yacht.length.desc(),
  321. limit = 2)
  322. self.assertEqual([yacht.length for yacht in query], [42.100000000000001, 40.5])
  323. db.commit(close = True)
  324. """ THE EXTENED TEST """
  325. class Extended(Tester):
  326. def test_mutables(self):
  327. self.mutants_0()
  328. self.clear_mod_imports()
  329. self.mutants_1()
  330. self.clear_mod_imports()
  331. def mutants_0(self):
  332. import pod
  333. db = pod.Db(file = self.filename, remove = True, very_chatty = False)
  334. class Person(pod.Object):
  335. pass
  336. class Place(pod.Object):
  337. pass
  338. peep = Person()
  339. place = Place()
  340. peep.mutant = [1, 2, 3]
  341. place.mutant = peep.mutant
  342. place.name = 'Fred'
  343. peep.mutant[2] = 'HI'
  344. db.commit(close = True)
  345. def mutants_1(self):
  346. import pod
  347. db = pod.Db(file = self.filename, remove = False, very_chatty = False)
  348. class Person(pod.Object):
  349. pass
  350. class Place(pod.Object):
  351. pass
  352. place = (Place.where.name == 'Fred').get_one()
  353. self <= place.mutant[2]
  354. self <= 'HI'
  355. db.commit(close = True)
  356. def test_features(self):
  357. self.feature_is_in()
  358. self.clear_mod_imports()
  359. def feature_is_in(self):
  360. import pod
  361. db = pod.Db(file = self.filename, remove = True, very_chatty = False)
  362. class Person(pod.Object):
  363. age = pod.typed.Int(index = True)
  364. class Punk(Person):
  365. pass
  366. class Poet(Person):
  367. pass
  368. peep = Person(name = 'Fred', age = 20)
  369. peep = Punk(name = 'Tony', age = 30)
  370. peep = Poet(name = 'Erza', age = 21)
  371. self <= set([peep.age for peep in Person.age.is_in([20, 30])])
  372. self <= set([20, 30])
  373. self <= set([peep.name for peep in Person.where.name.is_in(['Fred'])])
  374. self <= set(['Fred'])
  375. self <= set([peep.name for peep in Person.age.is_in([20, 30]) | Person.where.name.is_in(['Fred'])])
  376. self <= set(['Tony', 'Fred'])
  377. self <= set([peep.name for peep in Person.age.is_in([20, 30]) & Person.where.name.is_in(['Fred'])])
  378. self <= set(['Fred'])
  379. db.commit(close = True)
  380. """ NoSave Undefined Deleted """
  381. class NoSaveUndefinedDeleted(Tester):
  382. def test_nosave_undefined_deleted(self):
  383. self.nsud_0()
  384. self.clear_mod_imports()
  385. self.nsud_undefined_error()
  386. self.clear_mod_imports()
  387. self.nsud_check_if_exists_0()
  388. self.clear_mod_imports()
  389. self.nsud_check_if_exists_1()
  390. self.clear_mod_imports()
  391. self.nsud_undefined_no_error()
  392. self.clear_mod_imports()
  393. self.nsud_delete_attr()
  394. self.clear_mod_imports()
  395. self.nsud_deleted_attr_access()
  396. self.clear_mod_imports()
  397. def nsud_0(self):
  398. import pod
  399. db = pod.Db(file = self.filename, remove = True, very_chatty = False)
  400. class Person(pod.Object):
  401. age = pod.typed.Int()
  402. is_alive = pod.typed.Object()
  403. class Skater(Person):
  404. weight = pod.typed.Float()
  405. class Email(pod.Object):
  406. title = pod.typed.String()
  407. class Temp(pod.NoSave):
  408. def __init__(self, doit):
  409. self.doit = doit
  410. e0 = Email(title = 'HI')
  411. e1 = Email(title = 'BYE')
  412. t0 = Temp(doit = True)
  413. t1 = Temp(doit = False)
  414. self <= t0.get_full_id()
  415. self <= "0:0"
  416. p0 = Person(age = 32, weight = 204, random = '10', is_alive = True, attr = False, t0 = t0, e0 = e0, e1 = e1, es = [e0, e1])
  417. p1 = Person(age = 16, weight = 134, random = '5', is_alive = False, attr = None, t1 = t1, e0 = e0, p0 = p0)
  418. s0 = Skater(age = 10, weight = 204, random = '10', is_alive = None, attr = True, p0 = p0, p1 = p1, e0 = e0, e1 = e1, es = [e0, e1])
  419. s1 = Skater(age = 20, weight = 134, random = '5', is_alive = False, attr = None, p0 = p0, p1 = p1)
  420. db.commit()
  421. self <= p0.t0.__class__
  422. self <= Temp
  423. self <= [peep.age for peep in (Person.is_alive == True) | (Person.where.is_alive == False)]
  424. self <= [32, 16, 20]
  425. self <= [peep.age for peep in (Person.where.attr == None) | (Person.where.attr == True)]
  426. self <= [16, 10, 20]
  427. db.commit(close = True)
  428. def nsud_undefined_error(self):
  429. import pod
  430. db = pod.Db(file = self.filename, remove = False, very_chatty = False)
  431. class Person(pod.Object):
  432. age = pod.typed.Int()
  433. is_alive = pod.typed.Object()
  434. self <= len([peep for peep in Person])
  435. self <= 2
  436. p0 = [peep for peep in Person][0]
  437. p1 = [peep for peep in Person][1]
  438. self <= p1.p0
  439. self <= p0
  440. self <= p0.e0.get_full_id()
  441. self <= p1.e0.get_full_id()
  442. self <= p0.e0
  443. self <= p1.e0
  444. # Make sure Undefined instances are still same reference
  445. self <= p0.es
  446. self <= [p0.e0, p0.e1]
  447. self.assertRaises(pod.core.PodObjectUndefined, getattr, p0.e0, 'title')
  448. self.assertRaises(pod.core.PodObjectUndefined, getattr, p0.e1, 'title')
  449. self <= p0.t0
  450. self <= None
  451. self <= p1.t1
  452. self <= None
  453. db.commit(close = True)
  454. def nsud_undefined_no_error(self):
  455. import pod
  456. db = pod.Db(file = self.filename, remove = False, very_chatty = False)
  457. class Person(pod.Object):
  458. age = pod.typed.Int()
  459. is_alive = pod.typed.Object()
  460. self <= len([peep for peep in Person])
  461. self <= 2
  462. p0 = [peep for peep in Person][0]
  463. p1 = [peep for peep in Person][1]
  464. self <= p1.p0
  465. self <= p0
  466. self <= p0.e0.get_full_id()
  467. self <= p1.e0.get_full_id()
  468. self <= p0.e0
  469. self <= p1.e0
  470. # Make sure Undefined instances are still same reference
  471. self <= p0.es
  472. self <= [p0.e0, p0.e1]
  473. class Email(pod.Object):
  474. title = pod.typed.String()
  475. self <= p0.e0.title
  476. self <= 'HI'
  477. p0.e1.title = 'ADIOS'
  478. self <= p0.e1.title
  479. self <= 'ADIOS'
  480. db.commit(close = True)
  481. def nsud_check_if_exists_0(self):
  482. import pod
  483. db = pod.Db(file = self.filename, remove = False, very_chatty = False)
  484. class Person(pod.Object):
  485. age = pod.typed.Int()
  486. is_alive = pod.typed.Object()
  487. self <= len([peep for peep in Person])
  488. self <= 2
  489. p0 = [peep for peep in Person][0]
  490. p1 = [peep for peep in Person][1]
  491. self <= p1.p0
  492. self <= p0
  493. self <= p0.e0.get_full_id()
  494. self <= p1.e0.get_full_id()
  495. self <= p0.e0
  496. self <= p1.e0
  497. @Tester.raises(pod.core.PodObjectUndefined)
  498. def fn():
  499. self <= p0.e0.title
  500. self <= None
  501. db.commit(close = True)
  502. def nsud_check_if_exists_1(self):
  503. import pod
  504. db = pod.Db(file = self.filename, remove = False, very_chatty = False)
  505. class Person(pod.Object):
  506. age = pod.typed.Int()
  507. is_alive = pod.typed.Object()
  508. self <= len([peep for peep in Person])
  509. self <= 2
  510. p0 = [peep for peep in Person][0]
  511. p1 = [peep for peep in Person][1]
  512. self <= p1.p0
  513. self <= p0
  514. self <= p0.e0.get_full_id()
  515. self <= p1.e0.get_full_id()
  516. self <= p0.e0
  517. self <= p1.e0
  518. @Tester.raises(pod.core.PodObjectUndefined)
  519. def fn():
  520. self <= getattr(p0.e0, 'no_attr', None)
  521. self <= None
  522. db.commit(close = True)
  523. def nsud_delete_attr(self):
  524. import pod
  525. db = pod.Db(file = self.filename, remove = False, very_chatty = True)
  526. class Person(pod.Object):
  527. age = pod.typed.Int()
  528. is_alive = pod.typed.Object()
  529. class Skater(Person):
  530. weight = pod.typed.Float()
  531. class Email(pod.Object):
  532. title = pod.typed.String()
  533. p0 = pod.Query(where = Person, limit = 1).get_one()
  534. self <= [p0.e0, p0.e1]
  535. self <= p0.es
  536. p1 = [peep for peep in Person][1]
  537. self <= p0.e0
  538. self <= p1.e0
  539. # set e0 to have a mutable . . .
  540. p0.e0.a_list = [10, 20, 30]
  541. for e in p0.es:
  542. e.delete()
  543. self <= [e for e in Email]
  544. self <= []
  545. self <= object.__getattribute__(p0.e0, '__class__')
  546. self <= pod.core.Deleted
  547. self <= [p0.e0, p0.e1]
  548. self <= p0.es
  549. self.assertRaises(pod.core.PodObjectDeleted, getattr, p0.e0, 'title')
  550. self.assertRaises(pod.core.PodObjectDeleted, getattr, p0.e1, 'title')
  551. @Tester.raises(pod.core.PodObjectDeleted)
  552. def fn():
  553. p0.e0.name = 'Fred'
  554. p1 = [peep for peep in Person][1]
  555. self <= p0.e0
  556. self <= p1.e0
  557. db.commit(close = True)
  558. def nsud_deleted_attr_access(self):
  559. import pod
  560. db = pod.Db(file = self.filename, remove = False, very_chatty = False)
  561. class Person(pod.Object):
  562. age = pod.typed.Int()
  563. is_alive = pod.typed.Object()
  564. class Skater(Person):
  565. weight = pod.typed.Float()
  566. class Email(pod.Object):
  567. title = pod.typed.String()
  568. p0 = pod.Query(where = Person, limit = 1).get_one()
  569. self <= object.__getattribute__(p0.e0, '__class__')
  570. self <= Email
  571. @Tester.raises(pod.core.PodObjectDeleted)
  572. def fn():
  573. p0.e0.title # This function call a typed attribute, so throws error in load_attr_from_db
  574. @Tester.raises(pod.core.PodObjectDeleted)
  575. def fn():
  576. getattr(p0.e1, 'some_random_attr', None) # This function calls a dynamic attribute, so throws error in inst_check_if_exists
  577. self <= object.__getattribute__(p0.e0, '__class__')
  578. self <= Email
  579. self <= object.__getattribute__(p0.e1, '__class__')
  580. self <= Email
  581. self <= p0.es
  582. self <= [None, None]
  583. @Tester.raises(pod.core.PodObjectDeleted)
  584. def fn():
  585. p0.e0.title
  586. @Tester.raises(pod.core.PodObjectDeleted)
  587. def fn():
  588. p0.e0['title']
  589. @Tester.raises(pod.core.PodObjectDeleted)
  590. def fn():
  591. p0.e0.full_load()
  592. db.commit(close = True)
  593. """ RAW COLLECTIONS """
  594. class Collections(Tester):
  595. def test_collections(self):
  596. # list
  597. self.col_list_section_0()
  598. self.clear_mod_imports()
  599. self.col_list_section_1()
  600. self.clear_mod_imports()
  601. self.col_list_section_2()
  602. self.clear_mod_imports()
  603. self.col_list_section_3()
  604. self.clear_mod_imports()
  605. # dict
  606. self.col_dict_section()
  607. self.clear_mod_imports()
  608. # set
  609. self.col_set_section()
  610. self.clear_mod_imports()
  611. self.col_all_section()
  612. def col_list_section_0(self):
  613. import pod
  614. import pod.list
  615. db = pod.Db(file = self.filename, remove = True, very_chatty = False)
  616. self <= [i for i in pod.list.List]
  617. self <= []
  618. a_list = pod.list.List()
  619. self.assertRaises(IndexError, a_list.__getitem__, 0)
  620. class Person(pod.Object):
  621. pass
  622. peep = Person()
  623. b_list = pod.list.List([1, 2, 'k', {'peep': peep}, peep])
  624. self <= [i for i in b_list]
  625. self <= [1, 2, 'k', {'peep': peep}, peep]
  626. c_list = pod.list.List([0, 1, 2, 3, 4, 5, 6])
  627. c_list.append(7)
  628. c_list.extend([8, 9])
  629. self <= [i for i in c_list]
  630. self <= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  631. self <= (2 in c_list)
  632. self <= True
  633. self <= ('2' in c_list)
  634. self <= False
  635. c_list.remove(4)
  636. self <= [i for i in c_list]
  637. self <= [0, 1, 2, 3, 5, 6, 7, 8, 9]
  638. c_list.insert(4, 4)
  639. self <= [i for i in c_list]
  640. self <= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  641. c_list.reverse()
  642. self <= [i for i in c_list]
  643. self <= [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
  644. c_list.reverse()
  645. self <= [i for i in c_list]
  646. self <= [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  647. self <= c_list[4]
  648. self <= 4
  649. self <= c_list[-2]
  650. self <= 8
  651. self <= c_list[3:]
  652. self <= [3, 4, 5, 6, 7, 8, 9]
  653. self <= c_list[3::2]
  654. self <= [3, 5, 7, 9]
  655. self <= c_list[3:8:3]
  656. self <= [3, 6]
  657. self <= c_list[-3:-8:-1]
  658. self <= [7, 6, 5, 4, 3]
  659. self <= c_list[-3:-8:-2]
  660. self <= [7, 5, 3]
  661. self <= len(c_list)
  662. self <= 10
  663. c_list.clear()
  664. self <= [i for i in c_list]
  665. self <= []
  666. db.commit(close = True)
  667. def col_list_section_1(self):
  668. import pod
  669. import pod.list
  670. db = pod.Db(file = self.filename, remove = False, very_chatty = False)
  671. a_list = pod.list.List(name = 'A_LIST')
  672. self.assertRaises(IndexError, a_list.__getitem__, 0)
  673. class Person(pod.Object):
  674. pass
  675. peep = Person()
  676. a_list.append(peep)
  677. a_list.append(peep)
  678. self <= a_list.copy()
  679. self <= [peep, peep]
  680. a_list.remove(peep)
  681. self <= a_list.copy()
  682. self <= [peep]
  683. self <= a_list.pop()
  684. self <= peep
  685. self <= a_list.copy()
  686. self <= []
  687. a_list.append('you_know_it')
  688. a_list.append({10: 20})
  689. a_list.append(10)
  690. db.commit(close = True)
  691. def col_list_section_2(self):
  692. import pod
  693. import pod.list
  694. db = pod.Db(file = self.filename, remove = False, very_chatty = False)
  695. e_list = pod.list.List()
  696. self <= len(e_list)
  697. self <= 0
  698. e_list.append(10)
  699. e_list.append(20)
  700. e_list.append(e_list)
  701. self <= e_list[5:4]
  702. self <= []
  703. @Tester.raises(pod.list.PodListError)
  704. def fn():
  705. e_list[[10]]
  706. e_list[0] = 20
  707. e_list[1] = 10
  708. self <= [e for e in e_list]
  709. self <= [20, 10, e_list]
  710. some_list = [1, 2, 3]
  711. some_list[0:2] = [30,40]
  712. self <= some_list
  713. self <= [30, 40, 3]
  714. e_list[0:2] = [30, 40]
  715. self <= [e for e in e_list]
  716. self <= [30, 40, e_list]
  717. del e_list[0]
  718. del e_list[0:2]
  719. self <= [e for e in e_list]
  720. self <= []
  721. self <= e
  722. self <= e_list
  723. e_list.append(10)
  724. e_list[0] = 'hi'
  725. self <= e_list.copy()
  726. self <= ['hi']
  727. @Tester.raises(pod.list.PodListError)
  728. def fn():
  729. e.remove('10')
  730. e.remove('hi')
  731. self <= e.copy()
  732. self <= []
  733. e.append(10)
  734. e.append(20)
  735. e.append(10)
  736. e.append(e_list)
  737. self <= e.count(10)
  738. self <= 2
  739. self <= e.count(20)
  740. self <= 1
  741. self <= e.count(e_list)
  742. self <= 1
  743. self <= e.count(30)
  744. self <= 0
  745. e.remove(e_list)
  746. e.sort()
  747. self <= e.copy()
  748. self <= [10, 10, 20]
  749. self <= e.index(10)
  750. self <= 0
  751. self <= e.index(20)
  752. self <= 2
  753. @Tester.raises(pod.list.PodListError)
  754. def fn():
  755. e.index(50)
  756. # NOW DELETE
  757. e_list.delete()
  758. @Tester.raises(pod.core.PodObjectDeleted)
  759. def fn():
  760. for e in e_list.__iter__():
  761. print e
  762. db.commit(close = True)
  763. def col_list_section_3(self):
  764. import pod
  765. import pod.list
  766. db = pod.Db(file = self.filename, remove = False, very_chatty = False)
  767. a_list = (pod.list.List.where.name == 'A_LIST').get_one()
  768. self <= a_list.copy()
  769. self <= ['you_know_it', {10: 20}, 10]
  770. db.commit(close = True)
  771. def col_dict_section(self):
  772. import pod
  773. import pod.dict
  774. db = pod.Db(file = self.filename, remove = False)
  775. a_dict = pod.dict.Dict(dict = {10: 20}, name = 'A_DICT')
  776. b_dict = pod.dict.Dict(dict = {20: 20}, name = 'B_DICT')
  777. self.assertRaises(KeyError, a_dict.__getitem__, 'no_key')
  778. a_dict['some_key'] = [10, 20, 30]
  779. self <= a_dict.copy()
  780. self <= {10: 20, 'some_key': [10, 20, 30]}
  781. a_dict[10] = '10'
  782. self <= a_dict.keys()
  783. self <= [10, 'some_key']
  784. a_dict.update({'10': 10})
  785. self <= a_dict.items()
  786. self <= [(10, '10'), ('some_key', [10, 20, 30]), ('10', 10)]
  787. self <= a_dict.values()
  788. self <= ['10', [10, 20, 30], 10]
  789. a_dict.clear()
  790. self <= a_dict.copy()
  791. self <= {}
  792. a_dict['foo'] = 'bar'
  793. self <= a_dict.copy()
  794. self <= {'foo': 'bar'}
  795. self <= len(a_dict)
  796. self <= 1
  797. self <= ('foo' in a_dict)
  798. self <= True
  799. self <= ('you' in a_dict)
  800. self <= False
  801. a_dict['me'] = a_dict
  802. a_dict['b'] = 3
  803. self <= set([key for key in a_dict])
  804. self <= set(['me', 'foo', 'b'])
  805. self <= set([key for key in a_dict.iterkeys()])
  806. self <= set(['me', 'foo', 'b'])
  807. self <= a_dict.get('foo', 10)
  808. self <= 'bar'
  809. self <= a_dict.get('you')
  810. self <= None
  811. self <= a_dict.get('moo', a_dict)
  812. self <= a_dict
  813. del a_dict['me']
  814. self <= set([key for key in a_dict.itervalues()])
  815. self <= set([3, 'bar'])
  816. a_dict.setdefault('foo', 20)
  817. self <= set([key for key in a_dict.itervalues()])
  818. self <= set([3, 'bar'])
  819. a_dict.setdefault('moo', 30)
  820. self <= set([key for key in a_dict.itervalues()])
  821. self <= set([3, 'bar', 30])
  822. del a_dict['moo']
  823. del a_dict['b']
  824. @Tester.raises(KeyError)
  825. def fn():
  826. del a_dict['asdf']
  827. @Tester.raises(pod.dict.PodDictError)
  828. def fn():
  829. a_dict.fromkeys()
  830. @Tester.raises(pod.dict.PodDictError)
  831. def fn():
  832. a_dict.has_key()
  833. @Tester.raises(pod.dict.PodDictError)
  834. def fn():
  835. a_dict.pop('key')
  836. @Tester.raises(pod.dict.PodDictError)
  837. def fn():
  838. a_dict.popitem()
  839. db.commit(close = True)
  840. def col_set_section(self):
  841. import pod
  842. import pod.set
  843. db = pod.Db(file = self.filename, remove = False)
  844. a_set = pod.set.Set(set = [1, 2, 3], name = 'A_SET')
  845. b_set = pod.set.Set(set = [123, 342, 234])
  846. self <= a_set.copy()
  847. self <= set([1, 2, 3])
  848. self <= [i for i in a_set]
  849. self <= [1, 2, 3]
  850. a_set.add(2)
  851. self <= [i for i in a_set]
  852. self <= [1, 2, 3]
  853. a_set.remove(2)
  854. self <= [i for i in a_set]
  855. self <= [1, 3]
  856. class Person(pod.Object):
  857. pass
  858. peep_0 = Person()
  859. peep_1 = Person()
  860. a_set.add(peep_0)
  861. a_set.add(peep_1)
  862. a_set.add(peep_0)
  863. a_set.add(peep_1)
  864. a_set.add(peep_0)
  865. a_set.add(peep_1)
  866. self <= [i for i in a_set]
  867. self <= [1, 3, peep_0, peep_1]
  868. a_set.remove(peep_0)
  869. self <= [i for i in a_set]
  870. self <= [1, 3, peep_1]
  871. a_set.add(peep_0)
  872. self <= [i for i in a_set]
  873. self <= [1, 3, peep_1, peep_0]
  874. self <= a_set | (10, peep_0)
  875. self <= set([peep_0, 1, 10, 3, peep_1])
  876. self <= a_set & (3, 10, peep_1)
  877. self <= set([3, peep_1])
  878. self.assertRaises(KeyError, a_set.remove, 20)
  879. a_set.discard(20)
  880. a_set.discard(peep_1)
  881. self <= [i for i in a_set]
  882. self <= [1, 3, peep_0]
  883. a_set.remove(peep_0)
  884. self <= [i for i in a_set]
  885. self <= [1, 3]
  886. self <= a_set.copy()
  887. self <= set([1, 3])
  888. c_set = pod.set.Set()
  889. self <= len(c_set)
  890. self <= 0
  891. c_set.add(0)
  892. c_set.add(1)
  893. c_set.add(1)
  894. c_set.add(c_set)
  895. c_set.add(self)
  896. d_set = pod.set.Set()
  897. self <= len(d_set)
  898. self <= 0
  899. d_set.add(0)
  900. d_set.add(1)
  901. d_set.add(1)
  902. d_set.add(c_set)
  903. d_set.add(self)
  904. # now play with c_set again
  905. self <= (self in c_set)
  906. self <= True
  907. self <= ('k' in c_set)
  908. self <= False
  909. c_set.remove(self)
  910. c_set.remove(c_set)
  911. self <= (self in c_set)
  912. self <= False
  913. self <= (c_set in c_set)
  914. self <= False
  915. self <= set([c_set.pop(), c_set.pop()])
  916. self <= set([0, 1])
  917. self <= c_set.copy()
  918. self <= set([])
  919. @Tester.raises(KeyError)
  920. def fn():
  921. c_set.pop()
  922. c_set.add(10)
  923. c_set.add(10)
  924. c_set.add(self)
  925. c_set.add(c_set)
  926. c_set.clear()
  927. self <= c_set.copy()
  928. self <= set()
  929. e_set = pod.set.Set([1, 2, 3])
  930. x_set = pod.set.Set([1, 2, 3, 4, 5])
  931. self <= (e_set <= x_set)
  932. self <= True
  933. self <= (e_set <= x_set.copy())
  934. self <= True
  935. self <= (e_set < x_set)
  936. self <= True
  937. self <= (e_set < x_set.copy())
  938. self <= True
  939. self <= (e_set < e_set)
  940. self <= False
  941. self <= (e_set < e_set.copy())
  942. self <= False
  943. """ > """
  944. self <= (e_set > x_set)
  945. self <= False
  946. self <= (e_set > x_set.copy())
  947. self <= False
  948. self <= (e_set >= x_set)
  949. self <= False
  950. self <= (e_set >= x_set.copy())
  951. self <= False
  952. self <= (x_set > e_set)
  953. self <= True
  954. self <= (x_set > e_set.copy())
  955. self <= True
  956. self <= (x_set >= e_set)
  957. self <= True
  958. self <= (x_set >= e_set.copy())
  959. self <= True
  960. self <= (x_set >= x_set)
  961. self <= True
  962. self <= (x_set >= x_set.copy())
  963. self <= True
  964. self <= (x_set > x_set)
  965. self <= False
  966. self <= (x_set > x_set.copy())
  967. self <= False
  968. """ MINUS """
  969. self <= (x_set - e_set)
  970. self <= set([4, 5])
  971. self <= (e_set - x_set)
  972. self <= set([])
  973. """ XOR """
  974. self <= (e_set ^ x_set)
  975. self <= set([4, 5])
  976. self <= (x_set ^ e_set)
  977. self <= set([4, 5])
  978. """ AND OR """
  979. self <= (e_set & x_set)
  980. self <= set([1, 2, 3])
  981. self <= (e_set & x_set.copy())
  982. self <= set([1, 2, 3])
  983. self <= (e_set | x_set)
  984. self <= set([1, 2, 3, 4, 5])
  985. self <= (e_set | x_set.copy())
  986. self <= set([1, 2, 3, 4, 5])
  987. @Tester.raises(pod.set.PodSetError)
  988. def fn():
  989. c_set.isdisjoint(set())
  990. @Tester.raises(pod.set.PodSetError)
  991. def fn():
  992. c_set.intersection_update(set())
  993. @Tester.raises(pod.set.PodSetError)
  994. def fn():
  995. c_set.difference_update(set())
  996. @Tester.raises(pod.set.PodSetError)
  997. def fn():
  998. c_set.symmetric_difference_update(set())
  999. db.commit(close = True)
  1000. def col_all_section(self):
  1001. import pod
  1002. import pod.dict
  1003. db = pod.Db(file = self.filename, remove = False)
  1004. a_dict = (pod.dict.Dict.where.name == 'A_DICT').get_one()
  1005. self <= a_dict.values()
  1006. self <= ['bar']
  1007. a_dict['baz'] = [10, 20, {'10': '20'}]
  1008. self <= a_dict.copy()
  1009. self <= {'foo': 'bar', 'baz': [10, 20, {'10': '20'}]}
  1010. db.commit(clear_cache = True)
  1011. a_dict = (pod.dict.Dict.where.name == 'A_DICT').get_one()
  1012. self <= a_dict.copy()
  1013. self <= {'foo': 'bar', 'baz': [10, 20, {'10': '20'}]}
  1014. temp = a_dict['baz'][2]
  1015. self <= temp
  1016. self <= {'10': '20'}
  1017. temp['10'] = '10'
  1018. self <= temp
  1019. self <= {'10': '10'}
  1020. self <= a_dict.copy()
  1021. self <= {'foo': 'bar', 'baz': [10, 20, {'10': '10'}]}
  1022. temp['10'] = 'FOOBARBAZ'
  1023. self <= a_dict.copy()
  1024. self <= {'foo': 'bar', 'baz': [10, 20, {'10': 'FOOBARBAZ'}]}
  1025. self <= a_dict['baz'][2]
  1026. self <= {'10': 'FOOBARBAZ'}
  1027. db.commit(clear_cache = True)
  1028. a_dict = (pod.dict.Dict.where.name == 'A_DICT').get_one()
  1029. self <= a_dict.copy()
  1030. self <= {'foo': 'bar', 'baz': [10, 20, {'10': 'FOOBARBAZ'}]}
  1031. db.commit(close = True)
  1032. """ TIME MODULES """
  1033. class Timers(Tester):
  1034. def test_time_types(self):
  1035. Timer = self.time_create_section(remove = True)
  1036. self.time_section_0(Timer)
  1037. self.clear_mod_imports()
  1038. Timer = self.time_create_section(remove = False)
  1039. self.time_section_1(Timer)
  1040. def time_create_section(self, remove):
  1041. import pod
  1042. import time # You don't need to import time -- we're just going to use it below for our examples . . .
  1043. db = pod.Db(file = self.filename, remove = remove)
  1044. class Timer(pod.Object):
  1045. sometime = pod.typed.Time(date_string = '%Y-%m-%d')
  1046. uponatime = pod.typed.Time()
  1047. utctime = pod.typed.Time(local_time = False)
  1048. ctime = pod.typed.TimeCreate()
  1049. mtime = pod.typed.TimeLoad(date_string = '%Y-%m-%d %H:%M:%S')
  1050. t0 = Timer(sometime = '2007-1-15')
  1051. t1 = Timer(sometime = '2003-2-25')
  1052. t2 = Timer(sometime = '2009-4-27')
  1053. t3 = Timer(sometime = '2009-1-11')
  1054. # For the uponatime field, you have to provide a valid UTC time stamp since you didn't set a date_string in the constructor
  1055. t0.uponatime = Timer.uponatime.convert_time_to_utc_stamp(value = 2348923, local_time = True)
  1056. t1.uponatime = Timer.uponatime.convert_time_to_utc_stamp(value = 324234, local_time = False)
  1057. t2.uponatime = Timer.uponatime.convert_time_to_utc_stamp(value = '01/05/2006', date_string = '%d/%m/%Y', local_time = True)
  1058. t3.uponatime = Timer.uponatime.convert_time_to_utc_stamp(value = '02/04/2006 12:00:00', date_string = '%d/%m/%Y %H:%M:%S', local_time = True)
  1059. db.commit(clear_cache = True)
  1060. return Timer
  1061. def time_section_0(self, Timer):
  1062. self.assertEqual(Timer.get_count(), 4)
  1063. self.assertEqual(set([t.sometime for t in Timer.sometime.is_date(year = 2009)]), set(['2009-04-27','2009-01-11']))
  1064. self.assertEqual(Timer.sometime.is_date(year = 2009, month = 4).get_one().sometime, '2009-04-27')
  1065. set_one = set([t.sometime for t in Timer.sometime.post_dates(year = 2006) & Timer.sometime.pre_dates(year = 2008)])
  1066. set_two = set(['2007-01-15'])
  1067. self.assertEquals(set_one, set_two)
  1068. Timer.get_db().commit(close = True)
  1069. def time_section_1(self, Timer):
  1070. self.assertEqual(Timer.get_count(), 8)
  1071. self.assertEqual(set([t.sometime for t in Timer.sometime.is_date(year = 2009)]), set(['2009-04-27','2009-01-11']))
  1072. self.assertEqual([t.sometime for t in Timer.sometime.is_date(year = 2009, month = 4)], ['2009-04-27', '2009-04-27'])
  1073. list_one = [t.sometime for t in Timer.sometime.post_dates(year = 2006) & Timer.sometime.pre_dates(year = 2008)]
  1074. list_two = ['2007-01-15','2007-01-15']
  1075. self.assertEquals(list_one, list_two)
  1076. Timer.get_db().commit(close = True)
  1077. """ RAW QUERIES """
  1078. class Raw(Tester):
  1079. def test_raw_query(self):
  1080. import pod
  1081. db = pod.Db(file = self.filename, remove = True, very_chatty = False)
  1082. class Person(pod.Object):
  1083. name = pod.typed.String()
  1084. age = pod.typed.Int()
  1085. p0 = Person(name = 'Ali', age = 20)
  1086. p1 = Person(name = 'Jin', age = 25)
  1087. p2 = Person(name = 'Eli', age = 50)
  1088. db.commit()
  1089. self.assertEquals((2*Person.age+1 > 100).get_one().name, 'Eli')
  1090. if pod.db.PY_VERSION_IS_25 is False:
  1091. self.assertEquals((pod.fn.replace(Person.name, 'in', 'oe') == 'Joe').get_one().name, 'Jin')
  1092. self.assertEquals(set([p.name for p in pod.fn.replace(Person.name, 'li', 'mi').endswith('i')]), set(['Ali', 'Eli']))
  1093. class Customer(pod.Object):
  1094. name = pod.typed.String()
  1095. class Order(pod.Object):
  1096. cust_id = pod.typed.Int()
  1097. amount = pod.typed.Float()
  1098. month = pod.typed.String()
  1099. cust_0 = Customer(name = 'Abi')
  1100. cust_1 = Customer(name = 'Jin')
  1101. cust_2 = Customer(name = 'Ira')
  1102. order_0 = Order(cust_id = cust_0.id, amount = 10.99, month = 'Jan')
  1103. order_1 = Order(cust_id = cust_1.id, amount = 3.99, month = 'Jan')
  1104. order_2 = Order(cust_id = cust_0.id, amount = 1.99, month = 'Jan')
  1105. order_3 = Order(cust_id = cust_0.id, amount = 1.99, month = 'Feb')
  1106. order_4 = Order(cust_id = cust_2.id, amount = 23.99, month = 'Feb')
  1107. order_5 = Order(cust_id = cust_0.id, amount = 4.99, month = 'Feb')
  1108. order_6 = Order(cust_id = cust_2.id, amount = 4.29, month = 'Feb')
  1109. order_7 = Order(cust_id = cust_0.id, amount = 10.00, month = 'Mar')
  1110. order_8 = Order(cust_id = cust_1.id, amount = 20.99, month = 'Mar')
  1111. order_9 = Order(cust_id = cust_1.id, amount = 20.99, month = 'Mar')
  1112. db.commit()
  1113. query = pod.RawQuery(select = pod.fn.avg(Order.amount) >> 'avg' | Order.month,
  1114. group_by = Order.month,
  1115. )
  1116. self.assertEqual(set([(row.avg,row.month) for row in query]), set([(5.6566666666666663, 'Jan'), (17.326666666666664, 'Mar'), (8.8149999999999995, 'Feb')]))
  1117. for row in query:
  1118. self.assertEqual(row.avg, row[0])
  1119. self.assertEqual(row.avg, row['avg'])
  1120. self.assertEqual(row.month, row[1])
  1121. self.assertEqual(row.month, row['month'])
  1122. query = pod.RawQuery(select = Customer.name | Order.amount | Order.month,
  1123. where = (Order.amount > 10) & (Customer.id == Order.cust_id),
  1124. )
  1125. self <= [(row.name,row.amount,row.month) for row in query]
  1126. self <= [('Abi', 10.99, 'Jan'), ('Ira', 23.989999999999998, 'Feb'), ('Jin', 20.989999999999998, 'Mar'), ('Jin', 20.989999999999998, 'Mar')]
  1127. class MonthlyAvg(pod.Object):
  1128. month = pod.typed.String()
  1129. avg = pod.typed.Float()
  1130. query = pod.RawQuery(select = pod.fn.avg(Order.amount) >> 'avg' | Order.month,
  1131. group_by = Order.month,
  1132. cls = MonthlyAvg,
  1133. )
  1134. self.assertEqual(set([(row.avg,row.month) for row in query]), set([(5.6566666666666663, 'Jan'), (17.326666666666664, 'Mar'), (8.8149999999999995, 'Feb')]))
  1135. query = pod.RawQuery(select = pod.fn.avg(Order.amount) >> 'avg' | Order.month,
  1136. group_by = Order.month,
  1137. cls = MonthlyAvg,
  1138. )
  1139. for monthly_avg in query:
  1140. monthly_avg
  1141. monthly_avg.avg, monthly_avg.month
  1142. db.commit(close = True) # You need to commit these new 'MonthlyAvg' objects to the database.
  1143. """ RAW COLLECTIONS """
  1144. class AltSchema(Tester):
  1145. def test_schema(self):
  1146. # list
  1147. self.alt_schema_0()
  1148. self.clear_mod_imports()
  1149. self.alt_schema_1()
  1150. self.clear_mod_imports()
  1151. self.alt_schema_2()
  1152. self.clear_mod_imports()
  1153. self.alt_schema_3()
  1154. self.clear_mod_imports()
  1155. def alt_schema_0(self):
  1156. import pod
  1157. db = pod.Db(file = self.filename, dynamic_index = True, remove = True, chatty = True)
  1158. class Person(pod.Object):
  1159. name = pod.typed.String(index = False)
  1160. age = pod.typed.Int(index = True)
  1161. emails = pod.typed.Object(index = True)
  1162. skater = pod.typed.PodObject(index = True)
  1163. class Skater(Person):
  1164. peep = pod.typed.PodObject(index = False)
  1165. skater = None
  1166. for i in range(12):
  1167. peep = Person(name = 'Fred' + str(i), age = i, skater = skater, emails = [1, 2, 3])
  1168. skater = Skater(name = 'Maos' + str(i), age = i, skater = skater, emails = [peep, {10: 20}, (1,2,3)], peep = peep)
  1169. self <= [peep.name for peep in (Person.name[4:6] == '10') & (Person.age < 102)]
  1170. self <= ['Fred10', 'Maos10']
  1171. self <= len([skater.peep for skater in Skater if skater.peep.name[4:6] == '10'])
  1172. self <= 1
  1173. self <= set(Person.pod.type_get_current_table_indexes())
  1174. self <= set(['emails', 'skater', 'age'])
  1175. self <= set(Skater.pod.type_get_current_table_indexes())
  1176. self <= set(['skater', 'age', 'emails'])
  1177. self <= set(Person.pod.type_get_current_table_dict_indexes())
  1178. self <= set(['__main___Person_kvdict_pin_value', 'sqlite_autoindex___main___Person_kvdict_1'])
  1179. self <= set(Skater.pod.type_get_current_table_dict_indexes())
  1180. self <= set(['__main___Skater_kvdict_pin_value', 'sqlite_autoindex___main___Skater_kvdict_1'])
  1181. # Fake out mtime parameters
  1182. db.execute('UPDATE pod_classes SET mtime=? WHERE id=?', (10, Person.pod.id,))
  1183. db.execute('UPDATE pod_classes SET mtime=? WHERE id=?', (10, Skater.pod.id,))
  1184. db.commit(close = True)
  1185. def alt_schema_1(self):
  1186. import pod
  1187. db = pod.Db(file = self.filename, dynamic_index = False, remove = False, chatty = True, very_chatty = False)
  1188. class Person(pod.Object):
  1189. pass
  1190. class Skater(Person):
  1191. pass
  1192. self <= [peep.name for peep in (Person.where.name[4:6] == '10') & (Person.where.age < 102)]
  1193. self <= ['Fred10', 'Maos10']
  1194. self <= len([skater.peep for skater in Skater if skater.peep.name[4:6] == '10'])
  1195. self <= 1
  1196. self <= set(Person.pod.type_get_current_table_indexes())
  1197. self <= set([])
  1198. self <= set(Skater.pod.type_get_current_table_indexes())
  1199. self <= set([])
  1200. self <= set(Person.pod.type_get_current_table_dict_indexes())
  1201. self <= set(['sqlite_autoindex___main___Person_kvdict_1'])
  1202. self <= set(Skater.pod.type_get_current_table_dict_indexes())
  1203. self <= set(['sqlite_autoindex___main___Skater_kvdict_1'])
  1204. #Fake out mtime parameters
  1205. db.execute('UPDATE pod_classes SET mtime=? WHERE id=?', (10, Person.pod.id,))
  1206. db.execute('UPDATE pod_classes SET mtime=? WHERE id=?', (10, Skater.pod.id,))
  1207. db.commit(close = True)
  1208. def alt_schema_2(self):
  1209. import pod
  1210. db = pod.Db(file = self.filename, remove = False, chatty = True)
  1211. class Person(pod.Object):
  1212. POD_DYNAMIC_INDEX = True
  1213. name = pod.typed.String(index = False)
  1214. age = pod.typed.Int(index = True)
  1215. class Skater(Person):
  1216. peep = pod.typed.PodObject(index = False)
  1217. self <= [peep.name for peep in (Person.name[4:6] == '10') & (Person.age < 102)]
  1218. self <= ['Fred10', 'Maos10']
  1219. self <= len([skater.peep for skater in Skater if skater.peep.name[4:6] == '10'])
  1220. self <= 1
  1221. self <= set(Person.pod.type_get_current_table_indexes())
  1222. self <= set(['age'])
  1223. self <= set(Skater.pod.type_get_current_table_indexes())
  1224. self <= set(['age'])
  1225. self <= set(Person.pod.type_get_current_table_dict_indexes())
  1226. self <= set(['__main___Person_kvdict_pin_value', 'sqlite_autoindex___main___Person_kvdict_1'])
  1227. self <= set(Skater.pod.type_get_current_table_dict_indexes())
  1228. self <= set(['__main___Skater_kvdict_pin_value', 'sqlite_autoindex___main___Skater_kvdict_1'])
  1229. # Fake out mtime parameters
  1230. db.execute('UPDATE pod_classes SET mtime=? WHERE id=?', (10, Person.pod.id,))
  1231. db.execute('UPDATE pod_classes SET mtime=? WHERE id=?', (10, Skater.pod.id,))
  1232. db.commit(close = True)
  1233. def alt_schema_3(self):
  1234. import pod
  1235. db = pod.Db(file = self.filename, remove = False, chatty = True)
  1236. class Person(pod.Object):
  1237. POD_DYNAMIC_INDEX = False
  1238. name = pod.typed.String(index = True)
  1239. age = pod.typed.Int(index = False)
  1240. emails = pod.typed.Object(index = True)
  1241. skater = pod.typed.PodObject(index = True)
  1242. class Skater(Person):
  1243. pass
  1244. self <= [peep.name for peep in (Person.name[4:6] == '10') & (Person.age < 102)]
  1245. self <= ['Fred10', 'Maos10']
  1246. self <= len([skater.peep for skater in Skater if skater.peep.name[4:6] == '10'])
  1247. self <= 1
  1248. # Fake out mtime parameters
  1249. #db.execute('UPDATE pod_classes SET mtime=? WHERE id=?', (10, Person.pod.id,))
  1250. #db.execute('UPDATE pod_classes SET mtime=? WHERE id=?', (10, Skater.pod.id,))
  1251. db.commit(close = True)
  1252. def test_dynamic_index(self):
  1253. self.dynamic_index_0()
  1254. self.clear_mod_imports()
  1255. self.dynamic_index_1()
  1256. self.clear_mod_imports()
  1257. self.dynamic_index_2()
  1258. self.clear_mod_imports()
  1259. def dynamic_index_0(self):
  1260. import pod
  1261. db = pod.Db(file = self.filename, dynamic_index = True, remove = True, very_chatty = False)
  1262. class Person(pod.Object):
  1263. age = pod.typed.Int(index = True)
  1264. class Punk(Person):
  1265. weight = pod.typed.Float(index = True)
  1266. peep = Person(name = 'Fred', age = 20, some_attr = 'Name')
  1267. punk = Punk(name = 'Tony', age = 19, some_other_attr = 'Donny')
  1268. punk = Punk(name = 'Jony', age = 13, some_other_attr = 'Bonny')
  1269. punk = Punk(name = 'Mony', age = 13, some_other_attr = 'Ronny')
  1270. self <= Person.pod.type_get_current_table_indexes()
  1271. self <= ['age']
  1272. self <= Person.pod.type_get_current_table_dict_indexes()
  1273. self <= ['__main___Person_kvdict_pin_value', 'sqlite_autoindex___main___Person_kvdict_1']
  1274. db.execute('UPDATE pod_classes SET mtime=? WHERE id=?', (10, Person.pod.id,))
  1275. db.execute('UPDATE pod_classes SET mtime=? WHERE id=?', (10, Punk.pod.id,))
  1276. db.commit(close = True)
  1277. def dynamic_index_1(self):
  1278. import pod
  1279. db = pod.Db(file = self.filename, dynamic_index = False, remove = False, very_chatty = False)
  1280. class Person(pod.Object):
  1281. age = pod.typed.Int(index = False)
  1282. class Punk(Person):
  1283. POD_DYNAMIC_INDEX = True
  1284. weight = pod.typed.Float(index = False)
  1285. peep = Person(name = 'Fred', age = 20, some_attr = 'Name')
  1286. punk = Punk(name = 'Tony', age = 19, some_other_attr = 'Donny')
  1287. punk = Punk(name = 'Jony', age = 13, some_other_attr = 'Bonny')
  1288. punk = Punk(name = 'Mony', age = 13, some_other_attr = 'Ronny')
  1289. self <= Person.pod.type_get_current_table_indexes()
  1290. self <= []
  1291. self <= Punk.pod.type_get_current_table_indexes()
  1292. self <= []
  1293. self <= Person.pod.type_get_current_table_dict_indexes()
  1294. self <= ['sqlite_autoindex___main___Person_kvdict_1']
  1295. self <= Punk.pod.type_get_current_table_dict_indexes()
  1296. self <= ['__main___Punk_kvdict_pin_value', 'sqlite_autoindex___main___Punk_kvdict_1']
  1297. db.execute('UPDATE pod_classes SET mtime=? WHERE id=?', (10, Person.pod.id,))
  1298. db.execute('UPDATE pod_classes SET mtime=? WHERE id=?', (10, Punk.pod.id,))
  1299. db.commit(close = True)
  1300. def dynamic_index_2(self):
  1301. import pod
  1302. db = pod.Db(file = self.filename, dynamic_index = True, remove = False, very_chatty = False)
  1303. class Person(pod.Object):
  1304. age = pod.typed.Int(index = False)
  1305. class Punk(Person):
  1306. POD_DYNAMIC_INDEX = False
  1307. weight = pod.typed.Float(index = False)
  1308. peep = Person(name = 'Fred', age = 20, some_attr = 'Name')
  1309. punk = Punk(name = 'Tony', age = 19, some_other_attr = 'Donny')
  1310. punk = Punk(name = 'Jony', age = 13, some_other_attr = 'Bonny')
  1311. punk = Punk(name = 'Mony', age = 13, some_other_attr = 'Ronny')
  1312. self <= Person.pod.type_get_current_table_indexes()
  1313. self <= []
  1314. self <= Punk.pod.type_get_current_table_indexes()
  1315. self <= []
  1316. self <= Person.pod.type_get_current_table_dict_indexes()
  1317. self <= ['__main___Person_kvdict_pin_value', 'sqlite_autoindex___main___Person_kvdict_1']
  1318. self <= Punk.pod.type_get_current_table_dict_indexes()
  1319. self <= ['sqlite_autoindex___main___Punk_kvdict_1']
  1320. db.commit(close = True)
  1321. def test_dynamic_index_no_file_change(self):
  1322. self.dynamic_index_no_file_change_0()
  1323. self.clear_mod_imports()
  1324. self.dynamic_index_no_file_change_1()
  1325. self.clear_mod_imports()
  1326. self.dynamic_index_no_file_change_2()
  1327. self.clear_mod_imports()
  1328. def dynamic_index_no_file_change_0(self):
  1329. import pod
  1330. db = pod.Db(file = self.filename, dynamic_index = True, remove = True, very_chatty = False)
  1331. class Person(pod.Object):
  1332. pass
  1333. class Punk(Person):
  1334. weight = pod.typed.Float(index = True)
  1335. peep = Person(name = 'Fred', age = 20, some_attr = 'Name')
  1336. punk = Punk(name = 'Tony', age = 19, some_other_attr = 'Donny')
  1337. punk = Punk(name = 'Jony', age = 13, some_other_attr = 'Bonny')
  1338. punk = Punk(name = 'Mony', age = 13, some_other_attr = 'Ronny')
  1339. self <= Person.pod.type_get_current_table_indexes()
  1340. self <= []
  1341. self <= Person.pod.type_get_current_table_dict_indexes()
  1342. self <= ['__main___Person_kvdict_pin_value', 'sqlite_autoindex___main___Person_kvdict_1']
  1343. self <= Punk.pod.type_get_current_table_indexes()
  1344. self <= ['weight']
  1345. self <= Punk.pod.type_get_current_table_dict_indexes()
  1346. self <= ['__main___Punk_kvdict_pin_value', 'sqlite_autoindex___main___Punk_kvdict_1']
  1347. db.commit(close = True)
  1348. def dynamic_index_no_file_change_1(self):
  1349. import pod
  1350. db = pod.Db(file = self.filename, dynamic_index = False, remove = False, very_chatty = False)
  1351. class Person(pod.Object):
  1352. pass
  1353. class Punk(Person):
  1354. weight = pod.typed.Float(index = True)
  1355. peep = Person(name = 'Fred', age = 20, some_attr = 'Name')
  1356. punk = Punk(name = 'Tony', age = 19, some_other_attr = 'Donny')
  1357. punk = Punk(name = 'Jony', age = 13, some_other_attr = 'Bonny')
  1358. punk = Punk(name = 'Mony', age = 13, some_other_attr = 'Ronny')
  1359. self <= Person.pod.type_get_current_table_indexes()
  1360. self <= []
  1361. self <= Person.pod.type_get_current_table_dict_indexes()
  1362. self <= ['sqlite_autoindex___main___Person_kvdict_1']
  1363. self <= Punk.pod.type_get_current_table_indexes()
  1364. self <