root / elixir / trunk / tests / test_autoload.py @ 268

Revision 268, 6.0 kB (checked in by ged, 6 years ago)

allow overriding primary_key columns on autoloaded entities (closes tickets
#20 and #22)

Line 
1"""
2test autoloaded entities
3"""
4
5from sqlalchemy import Table, Column, ForeignKey, MetaData
6from elixir import *
7import elixir
8
9def setup():
10    # First create the tables (it would be better to use an external db)
11    meta = MetaData('sqlite:///')
12
13    person_table = Table('person', meta,
14        Column('id', Integer, primary_key=True),
15        Column('father_id', Integer, ForeignKey('person.id')),
16        Column('name', Unicode(32)))
17
18    animal_table = Table('animal', meta,
19        Column('id', Integer, primary_key=True),
20        Column('name', String(30)),
21        Column('owner_id', Integer, ForeignKey('person.id')),
22        Column('feeder_id', Integer, ForeignKey('person.id')))
23
24    category_table = Table('category', meta,
25        Column('name', String, primary_key=True))
26
27    person_category_table = Table('person_category', meta,
28        Column('person_id', Integer, ForeignKey('person.id')),
29        Column('category_name', String, ForeignKey('category.name')))
30
31    person_person_table = Table('person_person', meta,
32        Column('person_id1', Integer, ForeignKey('person.id')),
33        Column('person_id2', Integer, ForeignKey('person.id')))
34
35    meta.create_all()
36
37    elixir.options_defaults.update(dict(autoload=True, shortnames=True))
38
39    global Person, Animal, Category
40
41    #TODO: split these into individual classes for each test. It's best to wait
42    # till we can define several classes in a method with reference between them
43    # without having to make them global.
44    class Person(Entity):
45        father = ManyToOne('Person')
46        children = OneToMany('Person')
47        pets = OneToMany('Animal', inverse='owner')
48        animals = OneToMany('Animal', inverse='feeder')
49        categories = ManyToMany('Category', 
50                                tablename='person_category')
51        appreciate = ManyToMany('Person',
52                                tablename='person_person',
53                                local_side='person_id1')
54        isappreciatedby = ManyToMany('Person',
55                                tablename='person_person',
56                                local_side='person_id2')
57
58    class Animal(Entity):
59        owner = ManyToOne('Person', colname='owner_id')
60        feeder = ManyToOne('Person', colname='feeder_id')
61
62
63    class Category(Entity):
64        persons = ManyToMany('Person', 
65                                tablename='person_category')
66
67    metadata.bind = meta.bind
68    setup_all()
69
70
71def teardown():
72    cleanup_all()
73    elixir.options_defaults.update(dict(autoload=False, shortnames=False))
74
75#-----------
76
77class TestAutoload(object):
78    def setup(self):
79        create_all()
80       
81    def teardown(self):
82        drop_all()
83        session.clear()
84   
85    def test_autoload(self):
86        snowball = Animal(name="Snowball II")
87        slh = Animal(name="Santa's Little Helper")
88        homer = Person(name="Homer", animals=[snowball, slh], pets=[slh])
89        lisa = Person(name="Lisa", pets=[snowball])
90       
91        session.flush()
92        session.clear()
93       
94        homer = Person.get_by(name="Homer")
95        lisa = Person.get_by(name="Lisa")
96        slh = Animal.get_by(name="Santa's Little Helper")
97       
98        assert len(homer.animals) == 2
99        assert homer == lisa.pets[0].feeder
100        assert homer == slh.owner
101
102    def test_autoload_selfref(self):
103        grampa = Person(name="Abe")
104        homer = Person(name="Homer")
105        bart = Person(name="Bart")
106        lisa = Person(name="Lisa")
107       
108        grampa.children.append(homer)
109        homer.children.append(bart)
110        lisa.father = homer
111       
112        session.flush()
113        session.clear()
114       
115        p = Person.get_by(name="Homer")
116       
117        assert p in p.father.children
118        assert p.father.name == "Abe"
119        assert p.father is Person.get_by(name="Abe")
120        assert p is Person.get_by(name="Lisa").father
121
122    def test_autoload_m2m(self):
123        stupid = Category(name="Stupid")
124        simpson = Category(name="Simpson")
125        old = Category(name="Old")
126
127        grampa = Person(name="Abe", categories=[simpson, old])
128        homer = Person(name="Homer", categories=[simpson, stupid])
129        bart = Person(name="Bart")
130        lisa = Person(name="Lisa")
131       
132        simpson.persons.extend([bart, lisa])
133       
134        session.flush()
135        session.clear()
136       
137        c = Category.get_by(name="Simpson")
138        grampa = Person.get_by(name="Abe")
139       
140        print "Persons in the '%s' category: %s." % (
141                c.name, 
142                ", ".join(p.name for p in c.persons))
143       
144        assert len(c.persons) == 4
145        assert c in grampa.categories
146
147    def test_autoload_m2m_selfref(self):
148        barney = Person(name="Barney")
149        homer = Person(name="Homer", appreciate=[barney])
150
151        session.flush()
152        session.clear()
153       
154        homer = Person.get_by(name="Homer")
155        barney = Person.get_by(name="Barney")
156
157        assert barney in homer.appreciate
158        assert homer in barney.isappreciatedby
159
160
161def setup_entity_raise(cls):
162    try:
163        setup_entities([cls])
164    except Exception, e:
165        pass
166    else:
167        assert False, "Exception did not occur setting up %s" % cls.__name__
168
169class TestAutoloadOverrideColumn(object):
170    def setup(self):
171        create_all()
172
173    def teardown(self):
174        drop_all()
175
176    def test_override_pk_fails(self):
177        class Person(Entity):
178            id = Field(Integer, primary_key=True)
179
180        setup_entity_raise(Person)
181
182    def test_override_non_pk_fails(self):
183        class Animal(Entity):
184            name = Field(Unicode(30))
185
186        setup_entity_raise(Animal)
187
188    def test_override_pk(self):
189        class Person(Entity):
190            using_options(allowcoloverride=True)
191
192            id = Field(Integer, primary_key=True)
193
194        setup_entities([Person])
195
196    def test_override_non_pk(self):
197        class Animal(Entity):
198            using_options(allowcoloverride=True)
199
200            name = Field(Unicode(30))
201
202        setup_entities([Animal])
203        assert isinstance(Animal.table.columns['name'].type, Unicode)
204
Note: See TracBrowser for help on using the browser.