root / elixir / trunk / tests / test_abstract.py @ 513

Revision 513, 6.0 kB (checked in by ged, 5 years ago)

- do not leak options_defaults from a subclass into a parent class
- do not initialize useless attributes for base and abstract classes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1"""
2test inheritance with abstract entities
3"""
4
5import re
6
7from elixir import *
8import elixir
9
10def camel_to_underscore(entity):
11    return re.sub(r'(.+?)([A-Z])+?', r'\1_\2', entity.__name__).lower()
12
13def setup():
14    metadata.bind = 'sqlite://'
15    elixir.options_defaults['shortnames'] = True
16
17class TestAbstractInheritance(object):
18    def teardown(self):
19        cleanup_all(True)
20
21    def test_abstract_alone(self):
22        class AbstractPerson(Entity):
23            using_options(abstract=True)
24
25            firstname = Field(String(30))
26            lastname = Field(String(30))
27
28        setup_all(True)
29
30        assert not hasattr(AbstractPerson, 'table')
31
32    def test_inheritance(self):
33        class AbstractPerson(Entity):
34            using_options(abstract=True)
35            using_options_defaults(tablename=camel_to_underscore)
36
37            firstname = Field(String(30))
38            lastname = Field(String(30))
39
40        class AbstractEmployee(AbstractPerson):
41            using_options(abstract=True)
42            using_options_defaults(identity=camel_to_underscore)
43
44            corporation = Field(String(30))
45
46        class ConcreteEmployee(AbstractEmployee):
47            service = Field(String(30))
48
49        class ConcreteCitizen(AbstractPerson):
50            country = Field(String(30))
51
52        setup_all(True)
53
54        assert not hasattr(AbstractPerson, 'table')
55        assert not hasattr(AbstractEmployee, 'table')
56        assert hasattr(ConcreteEmployee, 'table')
57        assert hasattr(ConcreteCitizen, 'table')
58        assert ConcreteEmployee.table.name == 'concrete_employee'
59        assert ConcreteCitizen.table.name == 'concrete_citizen'
60
61        assert 'firstname' in ConcreteEmployee.table.columns
62        assert 'lastname' in ConcreteEmployee.table.columns
63        assert 'corporation' in ConcreteEmployee.table.columns
64        assert 'service' in ConcreteEmployee.table.columns
65
66        assert 'firstname' in ConcreteCitizen.table.columns
67        assert 'lastname' in ConcreteCitizen.table.columns
68        assert 'corporation' not in ConcreteCitizen.table.columns
69        assert 'country' in ConcreteCitizen.table.columns
70        # test that the options_defaults do not leak into the parent base
71        assert ConcreteCitizen._descriptor.identity == 'concretecitizen'
72
73    def test_simple_relation(self):
74        class Page(Entity):
75            title = Field(String(30))
76            content = Field(String(30))
77            comments = OneToMany('Comment')
78
79        class AbstractAttachment(Entity):
80            using_options(abstract=True)
81
82            page = ManyToOne('Page')
83            is_spam = Field(Boolean())
84
85        class Comment(AbstractAttachment):
86            message = Field(String(100))
87
88        setup_all(True)
89
90        p1 = Page(title="My title", content="My content")
91        p1.comments.append(Comment(message='My first comment', is_spam=False))
92
93        assert p1.comments[0].page == p1
94        session.commit()
95
96    def test_simple_relation_abstract_wh_multiple_children(self):
97        class Page(Entity):
98            title = Field(String(30))
99            content = Field(String(30))
100            comments = OneToMany('Comment')
101            links = OneToMany('Link')
102
103        class AbstractAttachment(Entity):
104            using_options(abstract=True)
105
106            page = ManyToOne('Page')
107            is_spam = Field(Boolean())
108
109        class Link(AbstractAttachment):
110            url = Field(String(30))
111
112        class Comment(AbstractAttachment):
113            message = Field(String(100))
114
115        setup_all(True)
116
117        p1 = Page(title="My title", content="My content")
118        p1.comments.append(Comment(message='My first comment', is_spam=False))
119        p1.links.append(Link(url="My url", is_spam=True))
120
121        assert p1.comments[0].page == p1
122        session.commit()
123
124    def test_multiple_inheritance(self):
125        class AbstractDated(Entity):
126            using_options(abstract=True)
127            using_options_defaults(tablename=camel_to_underscore)
128
129            #TODO: add defaults
130            created_date = Field(DateTime)
131            modified_date = Field(DateTime)
132
133        class AbstractContact(Entity):
134            using_options(abstract=True)
135            using_options_defaults(identity=camel_to_underscore)
136
137            first_name = Field(Unicode(50))
138            last_name = Field(Unicode(50))
139
140        class DatedContact(AbstractContact, AbstractDated):
141            pass
142
143        setup_all(True)
144
145        assert 'created_date' in DatedContact.table.columns
146        assert 'modified_date' in DatedContact.table.columns
147        assert 'first_name' in DatedContact.table.columns
148        assert 'last_name' in DatedContact.table.columns
149        assert DatedContact._descriptor.identity == 'dated_contact'
150        assert DatedContact.table.name == 'dated_contact'
151
152        contact1 = DatedContact(first_name=u"Guido", last_name=u"van Rossum")
153        session.commit()
154
155    def test_mixed_inheritance(self):
156        class AbstractDated(Entity):
157            using_options(abstract=True)
158            using_options_defaults(tablename=camel_to_underscore)
159
160            #TODO: add defaults
161            created_date = Field(DateTime)
162            modified_date = Field(DateTime)
163
164        class AbstractContact(Entity):
165            using_options(abstract=True)
166            using_options_defaults(identity=camel_to_underscore)
167
168            first_name = Field(Unicode(50))
169            last_name = Field(Unicode(50))
170
171        class Contact(AbstractContact):
172            using_options(inheritance='multi')
173
174        class MixedDatedContact(AbstractDated, Contact):
175            using_options(inheritance='multi')
176
177        setup_all(True)
178
179        assert 'created_date' in MixedDatedContact.table.columns
180        assert 'modified_date' in MixedDatedContact.table.columns
181        assert MixedDatedContact._descriptor.identity == 'mixed_dated_contact'
182        assert MixedDatedContact.table.name == 'mixed_dated_contact'
183
184        contact1 = MixedDatedContact(first_name=u"Guido",
185                                     last_name=u"van Rossum")
186        session.commit()
187
Note: See TracBrowser for help on using the browser.