Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

root/tags/1.4.0/test/zoo_fixture.py

Revision 163 (checked in by fumanchu, 3 years ago)

Reverted a special-case test for caching. Not sure why it was there in the first place.

  • Property svn:eol-style set to native
Line 
1 """Test fixture for Storage Managers."""
2
3 import datetime
4 import os
5 try:
6     import pythoncom
7 except ImportError:
8     pythoncom = None
9
10 try:
11     set
12 except NameError:
13     from sets import Set as set
14
15 import threading
16 import time
17 import unittest
18 import warnings
19
20 try:
21     import decimal
22 except ImportError:
23     decimal = None
24
25 try:
26     import fixedpoint
27 except ImportError:
28     fixedpoint = None
29
30 __all__ = ['Animal', 'Exhibit', 'Lecture', 'Vet', 'Visit', 'Zoo',
31            # Don't export the ZooTests class--it will break e.g. test_dejavu.
32            'arena', 'init', 'run', 'setup', 'teardown']
33
34 import dejavu
35 from dejavu import logic
36 from dejavu import Unit, UnitProperty, ToOne, ToMany
37 from dejavu.test import tools
38 from dejavu import engines
39
40
41 class EscapeProperty(UnitProperty):
42     def __set__(self, unit, value):
43         UnitProperty.__set__(self, unit, value)
44         # Zoo is a ToOne association, so it will return a unit or None.
45         z = unit.Zoo()
46         if z:
47             z.LastEscape = unit.LastEscape
48
49
50 class Animal(Unit):
51     Species = UnitProperty(hints={'bytes': 100})
52     ZooID = UnitProperty(int, index=True)
53     Legs = UnitProperty(int, default=4)
54     PreviousZoos = UnitProperty(list, hints={'bytes': 1000})
55     LastEscape = EscapeProperty(datetime.datetime)
56     Lifespan = UnitProperty(float, hints={'bytes': 4})
57     MotherID = UnitProperty(int)
58
59 Animal.many_to_one('ID', Animal, 'MotherID')
60
61
62 class Zoo(Unit):
63     Name = UnitProperty()
64     Founded = UnitProperty(datetime.date)
65     Opens = UnitProperty(datetime.time)
66     LastEscape = UnitProperty(datetime.datetime)
67    
68     if fixedpoint:
69         Admission = UnitProperty(fixedpoint.FixedPoint)
70     else:
71         Admission = UnitProperty(float)
72
73 Zoo.one_to_many('ID', Animal, 'ZooID')
74
75
76 class Vet(Unit):
77     """A Veterinarian."""
78     Name = UnitProperty()
79     ZooID = UnitProperty(int, index=True)
80
81 Vet.many_to_one('ZooID', Zoo, 'ID')
82
83
84 class Visit(Unit):
85     """Work done by a Veterinarian on an Animal."""
86     VetID = UnitProperty(int, index=True)
87     ZooID = UnitProperty(int, index=True)
88     AnimalID = UnitProperty(int, index=True)
89     Date = UnitProperty(datetime.date)
90
91 Vet.one_to_many('ID', Visit, 'VetID')
92 Animal.one_to_many('ID', Visit, 'AnimalID')
93
94
95 class Lecture(Visit):
96     """A Visit by a Vet to train staff (rather than visit an Animal)."""
97     AnimalID = None
98     Topic = UnitProperty()
99
100
101 class Exhibit(Unit):
102     # Make this a string to help test vs unicode.
103     Name = UnitProperty(str)
104     ZooID = UnitProperty(int)
105     Animals = UnitProperty(list)
106     PettingAllowed = UnitProperty(bool)
107     if decimal:
108         Acreage = UnitProperty(decimal.Decimal)
109     else:
110         Acreage = UnitProperty(float)
111    
112     # Remove the ID property (inherited from Unit) from the Exhibit class.
113     ID = None
114     sequencer = dejavu.UnitSequencerNull()
115     identifiers = (ZooID, Name)
116
117 Zoo.one_to_many('ID', Exhibit, 'ZooID')
118
119
120 Jan_1_2001 = datetime.date(2001, 1, 1)
121 every13days = [Jan_1_2001 + datetime.timedelta(x * 13) for x in range(20)]
122 every17days = [Jan_1_2001 + datetime.timedelta(x * 17) for x in range(20)]
123 del x
124
125 class ZooTests(unittest.TestCase):
126    
127     def test_1_model(self):
128         self.assertEqual(Zoo.Animal.__class__, dejavu.ToMany)
129         self.assertEqual(Zoo.Animal.nearClass, Zoo)
130         self.assertEqual(Zoo.Animal.nearKey, 'ID')
131         self.assertEqual(Zoo.Animal.farClass, Animal)
132         self.assertEqual(Zoo.Animal.farKey, 'ZooID')
133        
134         self.assertEqual(Animal.Zoo.__class__, dejavu.ToOne)
135         self.assertEqual(Animal.Zoo.nearClass, Animal)
136         self.assertEqual(Animal.Zoo.nearKey, 'ZooID')
137         self.assertEqual(Animal.Zoo.farClass, Zoo)
138         self.assertEqual(Animal.Zoo.farKey, 'ID')
139    
140     def test_2_populate(self):
141         box = arena.new_sandbox()
142        
143         # Notice this also tests that: a Unit which is only
144         # dirtied via __init__ is still saved.
145         WAP = Zoo(Name = 'Wild Animal Park',
146                   Founded = datetime.date(2000, 1, 1),
147                   # 59 can give rounding errors with divmod, which
148                   # AdapterFromADO needs to correct.
149                   Opens = datetime.time(8, 15, 59),
150                   LastEscape = datetime.datetime(2004, 7, 29, 5, 6, 7),
151                   Admission = "4.95",
152                   )
153         box.memorize(WAP)
154         # The object should get an ID automatically.
155         self.assertNotEqual(WAP.ID, None)
156        
157         SDZ = Zoo(Name = 'San Diego Zoo',
158                   # This early date should play havoc with a number
159                   # of implementations.
160                   Founded = datetime.date(1835, 9, 13),
161                   Opens = datetime.time(9, 0, 0),
162                   Admission = "0",
163                   )
164         box.memorize(SDZ)
165         # The object should get an ID automatically.
166         self.assertNotEqual(SDZ.ID, None)
167        
168         Biodome = Zoo(Name = u'Montr\xe9al Biod\xf4me',
169                       Founded = datetime.date(1992, 6, 19),
170                       Opens = datetime.time(9, 0, 0),
171                       Admission = "11.75",
172                       )
173         box.memorize(Biodome)
174        
175         seaworld = Zoo(Name = 'Sea_World', Admission = "60")
176         box.memorize(seaworld)
177        
178         # Animals
179         leopard = Animal(Species='Leopard', Lifespan=73.5)
180         self.assertEqual(leopard.PreviousZoos, None)
181         box.memorize(leopard)
182         leopard.add(WAP)
183         leopard.LastEscape = datetime.datetime(2004, 12, 21, 8, 15, 0)
184        
185         lion = Animal(Species='Lion', ZooID=WAP.ID)
186         box.memorize(lion)
187        
188         box.memorize(Animal(Species='Slug', Legs=1, Lifespan=.75))
189         tiger = Animal(Species='Tiger')
190         box.memorize(tiger)
191        
192         # Override Legs.default with itself just to make sure it works.
193         box.memorize(Animal(Species='Bear', Legs=4))
194         # Notice that ostrich.PreviousZoos is [], whereas leopard is None.
195         box.memorize(Animal(Species='Ostrich', Legs=2, PreviousZoos=[],
196                             Lifespan=103.2))
197         box.memorize(Animal(Species='Centipede', Legs=100))
198        
199         emp = Animal(Species='Emperor Penguin', Legs=2)
200         box.memorize(emp)
201         adelie = Animal(Species='Adelie Penguin', Legs=2)
202         box.memorize(adelie)
203        
204         seaworld.add(emp, adelie)
205        
206         millipede = Animal(Species='Millipede', Legs=1000000)
207         millipede.PreviousZoos = [WAP.ID]
208         box.memorize(millipede)
209        
210         SDZ.add(tiger, millipede)
211        
212         # Add a mother and child to test relationships
213         bai_yun = Animal(Species='Ape', Legs=2)
214         box.memorize(bai_yun)   # ID = 11
215         hua_mei = Animal(Species='Ape', Legs=2, MotherID=bai_yun.ID)
216         box.memorize(hua_mei)   # ID = 12
217        
218         # Exhibits
219         pe = Exhibit(Name = 'The Penguin Encounter',
220                      ZooID = seaworld.ID,
221                      Animals = [emp.ID, adelie.ID],
222                      PettingAllowed = True,
223                      Acreage = "3.21",
224                      )
225         box.memorize(pe)
226        
227         tr = Exhibit(Name = 'Tiger River',
228                      ZooID = SDZ.ID,
229                      Animals = [tiger.ID],
230                      PettingAllowed = False,
231                      Acreage = "4",
232                      )
233         box.memorize(tr)
234        
235         # Vets
236         cs = Vet(Name = 'Charles Schroeder', ZooID = SDZ.ID)
237         box.memorize(cs)
238         jm = Vet(Name = 'Jim McBain', ZooID = seaworld.ID)
239         box.memorize(jm)
240        
241         # Visits
242         for d in every13days:
243             box.memorize(Visit(VetID=cs.ID, AnimalID=tiger.ID, Date=d))
244         for d in every17days:
245             box.memorize(Visit(VetID=jm.ID, AnimalID=emp.ID, Date=d))
246        
247         box.flush_all()
248    
249     def test_3_Properties(self):
250         box = arena.new_sandbox()
251        
252         # Zoos
253         WAP = box.unit(Zoo, Name='Wild Animal Park')
254         self.assertNotEqual(WAP, None)
255         self.assertEqual(WAP.Founded, datetime.date(2000, 1, 1))
256         self.assertEqual(WAP.Opens, datetime.time(8, 15, 59))
257         # This should have been updated when leopard.LastEscape was set.
258         self.assertEqual(WAP.LastEscape,
259                          datetime.datetime(2004, 12, 21, 8, 15, 0))
260         self.assertEqual(str(WAP.Admission), "4.95")
261        
262         SDZ = box.unit(Zoo, Founded=datetime.date(1835, 9, 13))
263         self.assertNotEqual(SDZ, None)
264         self.assertEqual(SDZ.Founded, datetime.date(1835, 9, 13))
265         self.assertEqual(SDZ.Opens, datetime.time(9, 0, 0))
266         self.assertEqual(SDZ.LastEscape, None)
267         self.assertEqual(float(SDZ.Admission), 0)
268        
269         # Try a magic Sandbox recaller method
270         Biodome = box.Zoo(Name = u'Montr\xe9al Biod\xf4me')
271         self.assertNotEqual(Biodome, None)
272         self.assertEqual(Biodome.Name, u'Montr\xe9al Biod\xf4me')
273         self.assertEqual(Biodome.Founded, datetime.date(1992, 6, 19))
274         self.assertEqual(Biodome.Opens, datetime.time(9, 0, 0))
275         self.assertEqual(Biodome.LastEscape, None)
276         self.assertEqual(float(Biodome.Admission), 11.75)
277        
278         if fixedpoint:
279             seaworld = box.unit(Zoo, Admission = fixedpoint.FixedPoint(60))
280         else:
281             seaworld = box.unit(Zoo, Admission = float(60))
282         self.assertNotEqual(seaworld, None)
283         self.assertEqual(seaworld.Name, u'Sea_World')
284        
285         # Animals
286         leopard = box.unit(Animal, Species='Leopard')
287         self.assertEqual(leopard.Species, 'Leopard')
288         self.assertEqual(leopard.Legs, 4)
289         self.assertEqual(leopard.Lifespan, 73.5)
290         self.assertEqual(leopard.ZooID, WAP.ID)
291         self.assertEqual(leopard.PreviousZoos, None)
292         self.assertEqual(leopard.LastEscape,
293                          datetime.datetime(2004, 12, 21, 8, 15, 0))
294        
295         ostrich = box.unit(Animal, Species='Ostrich')
296         self.assertEqual(ostrich.Species, 'Ostrich')
297         self.assertEqual(ostrich.Legs, 2)
298         self.assertEqual(ostrich.ZooID, None)
299         self.assertEqual(ostrich.PreviousZoos, [])
300         self.assertEqual(ostrich.LastEscape, None)
301        
302         millipede = box.unit(Animal, Legs=1000000)
303         self.assertEqual(millipede.Species, 'Millipede')
304         self.assertEqual(millipede.Legs, 1000000)
305         self.assertEqual(millipede.ZooID, SDZ.ID)
306         self.assertEqual(millipede.PreviousZoos, [WAP.ID])
307         self.assertEqual(millipede.LastEscape, None)
308        
309         # Exhibits
310         exes = box.recall(Exhibit)
311         self.assertEqual(len(exes), 2)
312         if exes[0].Name == 'The Penguin Encounter':
313             pe = exes[0]
314             tr = exes[1]
315         else:
316             pe = exes[1]
317             tr = exes[0]
318         self.assertEqual(pe.ZooID, seaworld.ID)
319         self.assertEqual(len(pe.Animals), 2)
320         self.assertEqual(float(pe.Acreage), 3.21)
321         self.assertEqual(pe.PettingAllowed, True)
322        
323         self.assertEqual(tr.ZooID, SDZ.ID)
324         self.assertEqual(len(tr.Animals), 1)
325         self.assertEqual(float(tr.Acreage), 4)
326         self.assertEqual(tr.PettingAllowed, False)
327        
328         box.flush_all()
329    
330     def test_Expressions(self):
331         box = arena.new_sandbox()
332        
333         def matches(lam, cls=Animal):
334             # We flush_all to ensure a DB hit each time.
335             box.flush_all()
336             return len(box.recall(cls, logic.Expression(lam)))
337        
338         zoos = box.recall(Zoo)
339         self.assertEqual(zoos[0].dirty(), False)
340         self.assertEqual(len(zoos), 4)
341         self.assertEqual(matches(lambda x: True), 12)
342         self.assertEqual(matches(lambda x: x.Legs == 4), 4)
343         self.assertEqual(matches(lambda x: x.Legs == 2), 5)
344         self.assertEqual(matches(lambda x: x.Legs >= 2 and x.Legs < 20), 9)
345         self.assertEqual(matches(lambda x: x.Legs > 10), 2)
346         self.assertEqual(matches(lambda x: x.Lifespan > 70), 2)
347         self.assertEqual(matches(lambda x: x.Species.startswith('L')), 2)
348         self.assertEqual(matches(lambda x: x.Species.endswith('pede')), 2)
349         self.assertEqual(matches(lambda x: x.LastEscape != None), 1)
350         self.assertEqual(matches(lambda x: None == x.LastEscape), 11)
351        
352         # In operator (containedby)
353         self.assertEqual(matches(lambda x: 'pede' in x.Species), 2)
354         self.assertEqual(matches(lambda x: x.Species in ('Lion', 'Tiger', 'Bear')), 3)
355        
356         # Try In with cell references
357         class thing(object): pass
358         pet, pet2 = thing(), thing()
359         pet.Name, pet2.Name = 'Slug', 'Ostrich'
360         self.assertEqual(matches(lambda x: x.Species in (pet.Name, pet2.Name)), 2)
361        
362         # logic and other functions
363         self.assertEqual(matches(lambda x: dejavu.ieq(x.Species, 'slug')), 1)
364         self.assertEqual(matches(lambda x: dejavu.icontains(x.Species, 'PEDE')), 2)
365         self.assertEqual(matches(lambda x: dejavu.icontains(('Lion', 'Banana'), x.Species)), 1)
366         f = lambda x: dejavu.icontainedby(x.Species, ('Lion', 'Bear', 'Leopard'))
367         self.assertEqual(matches(f), 3)
368         name = 'Lion'
369         self.assertEqual(matches(lambda x: len(x.Species) == len(name)), 3)
370        
371         # This broke sometime in 2004. Rev 32 seems to have fixed it.
372         self.assertEqual(matches(lambda x: 'i' in x.Species), 7)
373        
374         # Test now(), today(), year()
375         self.assertEqual(matches(lambda x: x.Founded != None
376                                  and x.Founded < dejavu.today(), Zoo), 3)
377         self.assertEqual(matches(lambda x: x.LastEscape == dejavu.now()), 0)
378         self.assertEqual(matches(lambda x: dejavu.year(