Changeset 128
- Timestamp:
- 06/15/07 10:26:18 (6 years ago)
- Location:
- elixir/branches/autodelay
- Files:
-
- 11 modified
-
CHANGES (modified) (1 diff)
-
tests/test_autoload.py (modified) (3 diffs)
-
tests/test_hasfield.py (modified) (2 diffs)
-
tests/test_inherit.py (modified) (2 diffs)
-
tests/test_movies.py (modified) (2 diffs)
-
tests/test_multi.py (modified) (2 diffs)
-
tests/test_nestedclass.py (modified) (1 diff)
-
tests/test_oneway.py (modified) (1 diff)
-
tests/test_options.py (modified) (5 diffs)
-
tests/test_order_by.py (modified) (1 diff)
-
tests/test_selfref.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
elixir/branches/autodelay/CHANGES
r119 r128 9 9 - Made EntityMeta public, so that people can actually define their own base 10 10 class. 11 - Reworked/cleaned tests so that they don't leak stuff to other tests (both at 12 the method level and module level) anymore. Uses nosetest's module level 13 fixture. 11 14 - Fixed relationships to tables using a schema (Patch by Neil Blakey-Milner) 12 15 -
elixir/branches/autodelay/tests/test_autoload.py
r93 r128 3 3 """ 4 4 5 import sqlalchemy 6 from sqlalchemy import Table, Column, ForeignKey, BoundMetaData 7 from sqlalchemy.types import * 5 from sqlalchemy import Table, Column, ForeignKey, BoundMetaData, create_engine 8 6 from elixir import * 9 from elixir import metadata, objectstore10 7 import elixir 11 import datetime12 8 13 # First create the tables (it would be better to use an external db) 14 engine = sqlalchemy.create_engine('sqlite:///') 15 meta = BoundMetaData(engine) 9 def setup(): 10 # First create the tables (it would be better to use an external db) 11 engine = create_engine('sqlite:///') 12 meta = BoundMetaData(engine) 16 13 17 person_table = Table('person', meta, 18 Column('id', Integer, primary_key=True), 19 Column('father_id', Integer, ForeignKey('person.id')), 20 Column('name', Unicode(32))) 21 person_table.create() 14 person_table = Table('person', meta, 15 Column('id', Integer, primary_key=True), 16 Column('father_id', Integer, ForeignKey('person.id')), 17 Column('name', Unicode(32))) 22 18 23 animal_table = Table('animal', meta, 24 Column('id', Integer, primary_key=True), 25 Column('name', String(30)), 26 Column('color', String(15)), 27 Column('owner_id', Integer, ForeignKey('person.id')), 28 Column('feeder_id', Integer, ForeignKey('person.id'))) 29 animal_table.create() 19 animal_table = Table('animal', meta, 20 Column('id', Integer, primary_key=True), 21 Column('name', String(30)), 22 Column('color', String(15)), 23 Column('owner_id', Integer, ForeignKey('person.id')), 24 Column('feeder_id', Integer, ForeignKey('person.id'))) 30 25 31 category_table = Table('category', meta, 32 Column('name', String, primary_key=True)) 33 category_table.create() 26 category_table = Table('category', meta, 27 Column('name', String, primary_key=True)) 34 28 35 person_category_table = Table('person_category', meta, 36 Column('person_id', Integer, ForeignKey('person.id')), 37 Column('category_name', String, ForeignKey('category.name'))) 38 person_category_table.create() 29 person_category_table = Table('person_category', meta, 30 Column('person_id', Integer, ForeignKey('person.id')), 31 Column('category_name', String, ForeignKey('category.name'))) 39 32 40 person_person_table = Table('person_person', meta, 41 Column('person_id1', Integer, ForeignKey('person.id')), 42 Column('person_id2', Integer, ForeignKey('person.id'))) 43 person_person_table.create() 33 person_person_table = Table('person_person', meta, 34 Column('person_id1', Integer, ForeignKey('person.id')), 35 Column('person_id2', Integer, ForeignKey('person.id'))) 44 36 45 elixir.delay_setup = True 46 elixir.options_defaults.update(dict(autoload=True, shortnames=True)) 37 meta.create_all() 47 38 48 class Person(Entity): 49 belongs_to('father', of_kind='Person') 50 has_many('children', of_kind='Person') 51 has_many('pets', of_kind='Animal', inverse='owner') 52 has_many('animals', of_kind='Animal', inverse='feeder') 53 has_and_belongs_to_many('categories', of_kind='Category', 54 tablename='person_category') 55 has_and_belongs_to_many('appreciate', of_kind='Person', 56 tablename='person_person', 57 local_side='person_id1') 58 has_and_belongs_to_many('isappreciatedby', of_kind='Person', 59 tablename='person_person', 60 local_side='person_id2') 39 elixir.delay_setup = True 40 elixir.options_defaults.update(dict(autoload=True, shortnames=True)) 61 41 62 def __str__(self): 63 s = '%s\n' % self.name.encode('utf-8') 64 for pet in self.pets: 65 s += ' * pet: %s\n' % pet.name 66 return s 42 global Person, Animal, Category 43 44 class Person(Entity): 45 belongs_to('father', of_kind='Person') 46 has_many('children', of_kind='Person') 47 has_many('pets', of_kind='Animal', inverse='owner') 48 has_many('animals', of_kind='Animal', inverse='feeder') 49 has_and_belongs_to_many('categories', of_kind='Category', 50 tablename='person_category') 51 has_and_belongs_to_many('appreciate', of_kind='Person', 52 tablename='person_person', 53 local_side='person_id1') 54 has_and_belongs_to_many('isappreciatedby', of_kind='Person', 55 tablename='person_person', 56 local_side='person_id2') 57 58 def __str__(self): 59 s = '%s\n' % self.name.encode('utf-8') 60 for pet in self.pets: 61 s += ' * pet: %s\n' % pet.name 62 return s 67 63 68 64 69 class Animal(Entity):70 belongs_to('owner', of_kind='Person', colname='owner_id')71 belongs_to('feeder', of_kind='Person', colname='feeder_id')65 class Animal(Entity): 66 belongs_to('owner', of_kind='Person', colname='owner_id') 67 belongs_to('feeder', of_kind='Person', colname='feeder_id') 72 68 73 69 74 class Category(Entity):75 has_and_belongs_to_many('persons', of_kind='Person',76 tablename='person_category')70 class Category(Entity): 71 has_and_belongs_to_many('persons', of_kind='Person', 72 tablename='person_category') 77 73 78 elixir.delay_setup = False 79 elixir.options_defaults.update(dict(autoload=False, shortnames=False)) 74 elixir.delay_setup = False 75 elixir.options_defaults.update(dict(autoload=False, shortnames=False)) 76 77 metadata.connect(engine) 78 setup_all() 79 80 def teardown(): 81 cleanup_all() 80 82 81 83 #----------- … … 83 85 class TestAutoload(object): 84 86 def setup(self): 85 metadata.connect(engine) 86 setup_all() 87 87 create_all() 88 88 89 def teardown(self): 89 90 drop_all() 91 objectstore.clear() 90 92 91 93 def test_autoload(self): … … 169 171 170 172 if __name__ == '__main__': 173 setup() 174 171 175 test = TestAutoload() 172 176 test.setup() 177 test.test_autoload() 178 test.teardown() 179 180 test.setup() 181 test.test_autoload_selfref() 182 test.teardown() 183 184 test.setup() 185 test.test_autoload_has_and_belongs_to_many() 186 test.teardown() 187 188 test.setup() 173 189 test.test_autoload_has_and_belongs_to_many_selfref() 174 # test.test_autoload()175 190 test.teardown() 191 192 teardown() -
elixir/branches/autodelay/tests/test_hasfield.py
r47 r128 3 3 """ 4 4 5 import sqlalchemy 5 from sqlalchemy import create_engine 6 from elixir import * 6 7 7 from sqlalchemy.types import * 8 from elixir import * 8 def setup(): 9 global Person 10 11 class Person(Entity): 12 has_field('firstname', Unicode(30)) 13 has_field('surname', Unicode(30)) 14 15 def __str__(self): 16 return "<Person: %s %s>" % (self.firstname, self.surname) 17 18 engine = create_engine('sqlite:///') 19 metadata.connect(engine) 9 20 10 21 11 class Person(Entity): 12 has_field('firstname', Unicode(30)) 13 has_field('surname', Unicode(30)) 22 def teardown(): 23 cleanup_all() 14 24 15 def __str__(self):16 return "%s %s" % (self.firstname, self.surname)17 18 25 19 26 class TestHasField(object): 20 27 def setup(self): 21 engine = sqlalchemy.create_engine('sqlite:///')22 metadata.connect(engine)23 28 create_all() 24 29 25 30 def teardown(self): 26 cleanup_all() 31 drop_all() 32 objectstore.clear() 27 33 28 34 def test_hasfield(self): … … 41 47 42 48 if __name__ == '__main__': 49 setup() 43 50 test = TestHasField() 44 51 test.setup() 45 52 test.test_hasfield() 46 53 test.teardown() 54 teardown() -
elixir/branches/autodelay/tests/test_inherit.py
r92 r128 3 3 """ 4 4 5 import sqlalchemy 5 from sqlalchemy import create_engine 6 from elixir import * 6 7 7 from sqlalchemy.types import * 8 from elixir import * 8 def setup(): 9 global Person, PersonExtended 9 10 10 #import elixir 11 #elixir.delay_setup = True 11 class Person(Entity): 12 has_field('firstname', Unicode(30)) 13 has_field('surname', Unicode(30)) 14 belongs_to('sister', of_kind='Person') 12 15 13 class Person(Entity): 14 has_field('firstname', Unicode(30)) 15 has_field('surname', Unicode(30)) 16 belongs_to('sister', of_kind='Person') 16 @property 17 def name(self): 18 return "%s %s" % (self.firstname, self.surname) 17 19 18 @property 19 def name(self): 20 return "%s %s" % (self.firstname, self.surname) 20 def __str__(self): 21 sister = self.sister and self.sister.name or "unknown" 22 return "%s [%s]" % (self.name, sister) 23 24 class PersonExtended(Person): 25 has_field('age', Integer) 26 belongs_to('parent', of_kind='PersonExtended') 21 27 22 def __str__(self): 23 sister = self.sister and self.sister.name or "unknown" 24 return "%s [%s]" % (self.name, sister) 25 26 class PersonExtended(Person): 27 has_field('age', Integer) 28 belongs_to('parent', of_kind='PersonExtended') 28 using_options(inheritance='single') 29 29 30 using_options(inheritance='single') 30 def __str__(self): 31 parent = self.parent and self.parent.name or "unknown" 32 return "%s (%s) {%s}" % (super(PersonExtended, self).__str__(), 33 self.age, parent) 31 34 32 def __str__(self): 33 parent = self.parent and self.parent.name or "unknown" 34 return "%s (%s) {%s}" % (super(PersonExtended, self).__str__(), 35 self.age, parent) 35 engine = create_engine('sqlite:///') 36 metadata.connect(engine) 36 37 37 #elixir.delay_setup = False 38 39 def teardown(): 40 cleanup_all() 41 38 42 39 43 class TestInheritance(object): 40 44 def setup(self): 41 engine = sqlalchemy.create_engine('sqlite:///') 42 metadata.connect(engine) 43 setup_all() 45 create_all() 44 46 45 47 def teardown(self): 46 cleanup_all() 48 drop_all() 49 objectstore.clear() 47 50 48 51 def test_singletable_inheritance(self): 49 52 homer = PersonExtended(firstname="Homer", surname="Simpson", age=36) 50 53 # lisa needs to be a Person object, not a PersonExtended object because 51 # the sister relationship points to a Person, not a PersonExtende nd, so54 # the sister relationship points to a Person, not a PersonExtended, so 52 55 # bart's sister must be a Person. This is to comply with SQLAlchemy's 53 56 # policy to prevent loading relationships with unintended types, unless … … 72 75 73 76 if __name__ == '__main__': 77 setup() 74 78 test = TestInheritance() 75 79 test.setup() 76 80 test.test_singletable_inheritance() 77 81 test.teardown() 82 teardown() -
elixir/branches/autodelay/tests/test_movies.py
r50 r128 6 6 from elixir import * 7 7 8 class Director(Entity): 9 with_fields( 10 name = Field(Unicode(60)) 11 ) 12 13 has_many('movies', of_kind='Movie', inverse='director') 14 15 using_options(shortnames=True) 8 def setup(): 9 global Director, Movie, Actor, Media 10 11 class Director(Entity): 12 with_fields( 13 name = Field(Unicode(60)) 14 ) 15 16 has_many('movies', of_kind='Movie', inverse='director') 16 17 17 18 18 class Movie(Entity): 19 """ 20 simple movie class 21 """ 22 23 # columns 24 with_fields( 25 title = Field(Unicode(50)), 26 year = Field(Integer) 27 ) 28 29 # relationships 30 belongs_to('director', of_kind="Director", inverse='movies') 31 32 has_and_belongs_to_many('actors', of_kind="Actor", inverse='movies') 33 has_one('media', of_kind='Media', inverse='movie') 34 35 # options 36 using_options(tablename="movies_table") 19 class Movie(Entity): 20 """ 21 simple movie class 22 """ 23 24 # columns 25 with_fields( 26 title = Field(Unicode(50)), 27 year = Field(Integer) 28 ) 29 30 # relationships 31 belongs_to('director', of_kind="Director", inverse='movies') 32 33 has_and_belongs_to_many('actors', of_kind="Actor", inverse='movies') 34 has_one('media', of_kind='Media', inverse='movie') 37 35 38 36 39 class Actor(Entity):40 with_fields(41 name = Field(Unicode(60))42 )43 44 has_and_belongs_to_many('movies', of_kind="Movie", inverse="actors")37 class Actor(Entity): 38 with_fields( 39 name = Field(Unicode(60)) 40 ) 41 42 has_and_belongs_to_many('movies', of_kind="Movie", inverse="actors") 45 43 46 44 47 class Media(Entity): 48 with_fields( 49 number = Field(Integer, primary_key=True) 50 ) 51 52 belongs_to('movie', of_kind='Movie', inverse='media') 53 45 class Media(Entity): 46 with_fields( 47 number = Field(Integer, primary_key=True) 48 ) 49 50 belongs_to('movie', of_kind='Movie', inverse='media') 51 52 engine = create_engine('sqlite:///') 53 metadata.connect(engine) 54 55 def teardown(): 56 cleanup_all() 57 54 58 55 59 class TestMovies(object): 56 60 def setup(self): 57 engine = create_engine('sqlite:///')58 metadata.connect(engine)59 61 create_all() 60 62 61 63 def teardown(self): 62 cleanup_all() 64 drop_all() 65 objectstore.clear() 63 66 64 67 def test_bidirectional(self): … … 111 114 assert Actor.get_by(name="Sigourney Weaver") in Media.get_by(number=7).movie.actors 112 115 116 if __name__ == '__main__': 117 setup() 118 test = TestMovies() 119 test.setup() 120 test.test_bidirectional() 121 test.teardown() 122 teardown() -
elixir/branches/autodelay/tests/test_multi.py
r49 r128 4 4 5 5 import sqlalchemy 6 import datetime7 8 6 from elixir import * 9 7 … … 42 40 def teardown(self): 43 41 cleanup_all() 42 objectstore.clear() 44 43 45 44 def test_belongs_to_multi_ref(self): -
elixir/branches/autodelay/tests/test_nestedclass.py
r62 r128 1 1 from elixir import Entity, has_field, String 2 2 3 class Thing(Entity): 4 has_field('name', String(40)) 5 has_field('type', String(40)) 3 def setup(): 4 global Thing 5 6 class Thing(Entity): 7 has_field('name', String(40)) 8 has_field('type', String(40)) 9 10 class Stuff(Entity): 11 has_field('ping', String(32)) 12 has_field('pong', String(32)) 13 14 has_field('other', String(40)) 6 15 7 class Stuff(Entity):8 has_field('ping', String(32))9 has_field('pong', String(32))10 11 has_field('other', String(40))12 13 14 16 class TestNestedClass(object): 15 17 def test_nestedclass(self): 18 print "GLOBALS", globals().keys() 16 19 assert 'name' in Thing.table.columns.keys() 17 20 assert 'type' in Thing.table.columns.keys() -
elixir/branches/autodelay/tests/test_oneway.py
r50 r128 4 4 5 5 from sqlalchemy import create_engine 6 from elixir import *6 from elixir import * 7 7 8 class Person(Entity): 9 with_fields( 10 name = Field(Unicode(30)) 11 ) 8 def setup(): 9 global Person, Animal 12 10 13 class Animal(Entity): 14 with_fields( 15 name = Field(Unicode(30)), 16 nose_color = Field(Unicode(15)) 17 ) 18 19 belongs_to('owner', of_kind='Person') 11 class Person(Entity): 12 with_fields( 13 name = Field(Unicode(30)) 14 ) 20 15 16 class Animal(Entity): 17 with_fields( 18 name = Field(Unicode(30)), 19 nose_color = Field(Unicode(15)) 20 ) 21 22 belongs_to('owner', of_kind='Person') 23 24 engine = create_engine('sqlite:///') 25 metadata.connect(engine) 26 27 def teardown(): 28 cleanup_all() 21 29 22 30 class TestOneWay(object): 23 31 def setup(self): 24 engine = create_engine('sqlite:///')25 metadata.connect(engine)26 32 create_all() 27 33 28 34 def teardown(self): 29 cleanup_all() 35 drop_all() 36 objectstore.clear() 30 37 31 38 def test_oneway(self): -
elixir/branches/autodelay/tests/test_options.py
r96 r128 5 5 from sqlalchemy import create_engine, create_session, UniqueConstraint 6 6 from sqlalchemy.exceptions import SQLError, ConcurrentModificationError 7 from elixir import *7 from elixir import * 8 8 9 9 … … 12 12 engine = create_engine('sqlite:///') 13 13 metadata.connect(engine) 14 15 def teardown(self): 16 cleanup_all() 14 17 15 18 # this test is a rip-off SQLAlchemy's activemapper's update test … … 73 76 options_defaults['tablename'] = None 74 77 75 def teardown(self):76 cleanup_all()77 78 78 79 79 80 class TestTableOptions(object): 80 81 def setup(self): 81 global Person 82 engine = create_engine('sqlite:///') 83 metadata.connect(engine) 82 84 85 def teardown(self): 86 cleanup_all() 87 88 def test_table_options(self): 83 89 class Person(Entity): 84 90 has_field('firstname', Unicode(30)) … … 87 93 using_table_options(UniqueConstraint('firstname', 'surname')) 88 94 89 engine = create_engine('sqlite:///')90 metadata.connect(engine)91 95 create_all() 92 96 93 def test_table_options(self):94 97 homer = Person(firstname="Homer", surname='Simpson') 95 98 bart = Person(firstname="Bart", surname='Simpson') … … 107 110 assert raised 108 111 109 objectstore.clear()110 111 def teardown(self):112 cleanup_all()113 -
elixir/branches/autodelay/tests/test_order_by.py
r71 r128 4 4 5 5 from sqlalchemy import create_engine 6 from elixir import *6 from elixir import * 7 7 8 8 9 class Record(Entity): 10 has_field('title', Unicode(30)) 11 has_field('year', Integer) 12 belongs_to('artist', of_kind='Artist') 13 has_and_belongs_to_many('genres', of_kind='Genre') 9 def setup(): 10 global Record, Artist, Genre 11 12 class Record(Entity): 13 has_field('title', Unicode(100)) 14 has_field('year', Integer) 15 belongs_to('artist', of_kind='Artist') 16 has_and_belongs_to_many('genres', of_kind='Genre') 14 17 15 # order titles descending by year, then by title16 using_options(order_by=['-year', 'title'])18 # order titles descending by year, then by title 19 using_options(order_by=['-year', 'title']) 17 20 18 def __str__(self):19 return "%s - %s (%d)" % (self.artist.name, self.title, self.year)21 def __str__(self): 22 return "%s - %s (%d)" % (self.artist.name, self.title, self.year) 20 23 21 class Artist(Entity):22 has_field('name', Unicode(30))23 has_many('records', of_kind='Record', order_by=['year', '-title'])24 class Artist(Entity): 25 has_field('name', Unicode(30)) 26 has_many('records', of_kind='Record', order_by=['year', '-title']) 24 27 25 class Genre(Entity): 26 has_field('name', Unicode(30)) 27 has_and_belongs_to_many('records', of_kind='Record', 28 order_by='-title') 28 class Genre(Entity): 29 has_field('name', Unicode(30)) 30 has_and_belongs_to_many('records', of_kind='Record', 31 order_by='-title') 32 33 engine = create_engine('sqlite:///') 34 metadata.connect(engine) 35 create_all() 36 37 # insert some data 38 artist = Artist(name="Dream Theater") 39 genre = Genre(name="Progressive metal") 40 titles = ( 41 ("A Change Of Seasons", 1995), 42 ("Awake", 1994), 43 ("Falling Into Infinity", 1997), 44 ("Images & Words", 1992), 45 ("Metropolis Pt. 2: Scenes From A Memory", 1999), 46 ("Octavarium", 2005), 47 # 2005 is a mistake to make the test more interesting 48 ("Six Degrees Of Inner Turbulence", 2005), 49 ("Train Of Thought", 2003), 50 ("When Dream And Day Unite", 1989) 51 ) 29 52 53 for title, year in titles: 54 Record(title=title, artist=artist, year=year, genres=[genre]) 55 56 objectstore.flush() 57 objectstore.clear() 58 59 60 def teardown(): 61 cleanup_all() 62 63 30 64 class TestOrderBy(object): 31 def setup(self): 32 engine = create_engine('sqlite:///') 33 # engine.echo = True 34 metadata.connect(engine) 35 create_all() 36 37 artist = Artist(name="Dream Theater") 38 genre = Genre(name="Progressive metal") 39 titles = ( 40 ("A Change Of Seasons", 1995), 41 ("Awake", 1994), 42 ("Falling Into Infinity", 1997), 43 ("Images & Words", 1992), 44 ("Metropolis Pt. 2: Scenes From A Memory", 1999), 45 ("Octavarium", 2005), 46 # 2005 is a mistake to make the test more interesting 47 ("Six Degrees Of Inner Turbulence", 2005), 48 ("Train Of Thought", 2003), 49 ("When Dream And Day Unite", 1989) 50 ) 51 52 for title, year in titles: 53 Record(title=title, artist=artist, year=year, genres=[genre]) 54 55 objectstore.flush() 65 def teardown(self): 56 66 objectstore.clear() 57 58 def teardown(self):59 # we don't use cleanup_all because setup and teardown are called for60 # each test, and since the class is not redefined, it will not be61 # reinitialized so we can't kill it62 drop_all()63 67 64 68 def test_mapper_order_by(self): -
elixir/branches/autodelay/tests/test_selfref.py
r47 r128 81 81 def test_belongs_to_multiple_selfref(self): 82 82 # define a self-referential table with several relations 83 83 84 class TreeNode(Entity): 84 85 has_field('name', String(50), nullable=False)
