summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-04-23 12:03:54 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2012-04-23 12:03:54 -0400
commit54017d9de202ed67072a352ce2f6dbfd74bf48f3 (patch)
treea632045bd8a5e7d5932d69d5f436bc27f1b9788d /test
parent8f35f7a803c67f4ab0620686592a021a24e4b331 (diff)
parentf7bb3b17e6df09caa56c20c722364fc52edf7afc (diff)
downloadsqlalchemy-54017d9de202ed67072a352ce2f6dbfd74bf48f3.tar.gz
merge patch for [ticket:2208]. This still needs documentation.
Diffstat (limited to 'test')
-rw-r--r--test/base/test_inspect.py62
-rw-r--r--test/engine/test_reflection.py29
-rw-r--r--test/orm/_fixtures.py45
-rw-r--r--test/orm/test_backref_mutations.py4
-rw-r--r--test/orm/test_inspect.py290
-rw-r--r--test/orm/test_mapper.py8
-rw-r--r--test/orm/test_query.py40
-rw-r--r--test/orm/test_session.py2
8 files changed, 413 insertions, 67 deletions
diff --git a/test/base/test_inspect.py b/test/base/test_inspect.py
new file mode 100644
index 000000000..b95b7d8c5
--- /dev/null
+++ b/test/base/test_inspect.py
@@ -0,0 +1,62 @@
+"""test the inspection registry system."""
+
+from test.lib.testing import eq_, assert_raises
+from sqlalchemy import exc, util
+from sqlalchemy import inspection, inspect
+from test.lib import fixtures
+
+class TestFixture(object):
+ pass
+
+class TestEvents(fixtures.TestBase):
+ """Test class- and instance-level event registration."""
+
+ def tearDown(self):
+ for type_ in list(inspection._registrars):
+ if issubclass(type_, TestFixture):
+ del inspection._registrars[type_]
+
+ def test_def_insp(self):
+ class SomeFoo(TestFixture):
+ pass
+
+ @inspection._inspects(SomeFoo)
+ def insp_somefoo(subject):
+ return {"insp":subject}
+
+ somefoo = SomeFoo()
+ insp = inspect(somefoo)
+ assert insp["insp"] is somefoo
+
+ def test_class_insp(self):
+ class SomeFoo(TestFixture):
+ pass
+
+ @inspection._inspects(SomeFoo)
+ class SomeFooInspect(object):
+ def __init__(self, target):
+ self.target = target
+
+ somefoo = SomeFoo()
+ insp = inspect(somefoo)
+ assert isinstance(insp, SomeFooInspect)
+ assert insp.target is somefoo
+
+ def test_hierarchy_insp(self):
+ class SomeFoo(TestFixture):
+ pass
+
+ class SomeSubFoo(SomeFoo):
+ pass
+
+ @inspection._inspects(SomeFoo)
+ def insp_somefoo(subject):
+ return 1
+
+ @inspection._inspects(SomeSubFoo)
+ def insp_somesubfoo(subject):
+ return 2
+
+ somefoo = SomeFoo()
+ eq_(inspect(SomeFoo()), 1)
+ eq_(inspect(SomeSubFoo()), 2)
diff --git a/test/engine/test_reflection.py b/test/engine/test_reflection.py
index f385a0fa2..e59849d98 100644
--- a/test/engine/test_reflection.py
+++ b/test/engine/test_reflection.py
@@ -1,8 +1,7 @@
from test.lib.testing import eq_, assert_raises, assert_raises_message
import StringIO, unicodedata
from sqlalchemy import types as sql_types
-from sqlalchemy import schema, events, event
-from sqlalchemy.engine.reflection import Inspector
+from sqlalchemy import schema, events, event, inspect
from sqlalchemy import MetaData, Integer, String
from test.lib.schema import Table, Column
import sqlalchemy as sa
@@ -10,8 +9,6 @@ from test.lib import ComparesTables, \
testing, engines, AssertsCompiledSQL
from test.lib import fixtures
-create_inspector = Inspector.from_engine
-
metadata, users = None, None
class ReflectionTest(fixtures.TestBase, ComparesTables):
@@ -773,7 +770,7 @@ class ReflectionTest(fixtures.TestBase, ComparesTables):
def test_inspector_conn_closing(self):
m1 = MetaData()
c = testing.db.connect()
- i = Inspector.from_engine(testing.db)
+ i = inspect(testing.db)
assert not c.closed
@testing.provide_metadata
@@ -1050,7 +1047,7 @@ class UnicodeReflectionTest(fixtures.TestBase):
@testing.requires.unicode_connections
def test_get_names(self):
- inspector = Inspector.from_engine(self.bind)
+ inspector = inspect(self.bind)
names = dict(
(tname, (cname, ixname)) for tname, cname, ixname in self.names
)
@@ -1362,18 +1359,18 @@ class ComponentReflectionTest(fixtures.TestBase):
@testing.requires.schemas
def test_get_schema_names(self):
- insp = Inspector(testing.db)
+ insp = inspect(testing.db)
self.assert_('test_schema' in insp.get_schema_names())
def test_dialect_initialize(self):
engine = engines.testing_engine()
assert not hasattr(engine.dialect, 'default_schema_name')
- insp = Inspector(engine)
+ insp = inspect(engine)
assert hasattr(engine.dialect, 'default_schema_name')
def test_get_default_schema_name(self):
- insp = Inspector(testing.db)
+ insp = inspect(testing.db)
eq_(insp.default_schema_name, testing.db.dialect.default_schema_name)
@testing.provide_metadata
@@ -1384,7 +1381,7 @@ class ComponentReflectionTest(fixtures.TestBase):
meta.create_all()
_create_views(meta.bind, schema)
try:
- insp = Inspector(meta.bind)
+ insp = inspect(meta.bind)
if table_type == 'view':
table_names = insp.get_view_names(schema)
table_names.sort()
@@ -1428,7 +1425,7 @@ class ComponentReflectionTest(fixtures.TestBase):
_create_views(meta.bind, schema)
table_names = ['users_v', 'email_addresses_v']
try:
- insp = Inspector(meta.bind)
+ insp = inspect(meta.bind)
for table_name, table in zip(table_names, (users,
addresses)):
schema_name = schema
@@ -1490,7 +1487,7 @@ class ComponentReflectionTest(fixtures.TestBase):
meta = self.metadata
users, addresses, dingalings = createTables(meta, schema)
meta.create_all()
- insp = Inspector(meta.bind)
+ insp = inspect(meta.bind)
users_pkeys = insp.get_primary_keys(users.name,
schema=schema)
eq_(users_pkeys, ['user_id'])
@@ -1517,7 +1514,7 @@ class ComponentReflectionTest(fixtures.TestBase):
meta = self.metadata
users, addresses, dingalings = createTables(meta, schema)
meta.create_all()
- insp = Inspector(meta.bind)
+ insp = inspect(meta.bind)
expected_schema = schema
# users
users_fkeys = insp.get_foreign_keys(users.name,
@@ -1561,7 +1558,7 @@ class ComponentReflectionTest(fixtures.TestBase):
createIndexes(meta.bind, schema)
# The database may decide to create indexes for foreign keys, etc.
# so there may be more indexes than expected.
- insp = Inspector(meta.bind)
+ insp = inspect(meta.bind)
indexes = insp.get_indexes('users', schema=schema)
expected_indexes = [
{'unique': False,
@@ -1590,7 +1587,7 @@ class ComponentReflectionTest(fixtures.TestBase):
view_name1 = 'users_v'
view_name2 = 'email_addresses_v'
try:
- insp = Inspector(meta.bind)
+ insp = inspect(meta.bind)
v1 = insp.get_view_definition(view_name1, schema=schema)
self.assert_(v1)
v2 = insp.get_view_definition(view_name2, schema=schema)
@@ -1613,7 +1610,7 @@ class ComponentReflectionTest(fixtures.TestBase):
meta = self.metadata
users, addresses, dingalings = createTables(meta, schema)
meta.create_all()
- insp = create_inspector(meta.bind)
+ insp = inspect(meta.bind)
oid = insp.get_table_oid(table_name, schema)
self.assert_(isinstance(oid, (int, long)))
diff --git a/test/orm/_fixtures.py b/test/orm/_fixtures.py
index 5def54e3a..7431a3a83 100644
--- a/test/orm/_fixtures.py
+++ b/test/orm/_fixtures.py
@@ -2,7 +2,8 @@ from sqlalchemy import MetaData, Integer, String, ForeignKey
from sqlalchemy import util
from test.lib.schema import Table
from test.lib.schema import Column
-from sqlalchemy.orm import attributes
+from sqlalchemy.orm import attributes, mapper, relationship, \
+ backref, configure_mappers
from test.lib import fixtures
__all__ = ()
@@ -49,6 +50,48 @@ class FixtureTest(fixtures.MappedTest):
pass
@classmethod
+ def _setup_stock_mapping(cls):
+ Node, composite_pk_table, users, Keyword, items, Dingaling, \
+ order_items, item_keywords, Item, User, dingalings, \
+ Address, keywords, CompositePk, nodes, Order, orders, \
+ addresses = cls.classes.Node, \
+ cls.tables.composite_pk_table, cls.tables.users, \
+ cls.classes.Keyword, cls.tables.items, \
+ cls.classes.Dingaling, cls.tables.order_items, \
+ cls.tables.item_keywords, cls.classes.Item, \
+ cls.classes.User, cls.tables.dingalings, \
+ cls.classes.Address, cls.tables.keywords, \
+ cls.classes.CompositePk, cls.tables.nodes, \
+ cls.classes.Order, cls.tables.orders, cls.tables.addresses
+
+ mapper(User, users, properties={
+ 'addresses':relationship(Address, backref='user', order_by=addresses.c.id),
+ 'orders':relationship(Order, backref='user', order_by=orders.c.id), # o2m, m2o
+ })
+ mapper(Address, addresses, properties={
+ 'dingaling':relationship(Dingaling, uselist=False, backref="address") #o2o
+ })
+ mapper(Dingaling, dingalings)
+ mapper(Order, orders, properties={
+ 'items':relationship(Item, secondary=order_items, order_by=items.c.id), #m2m
+ 'address':relationship(Address), # m2o
+ })
+ mapper(Item, items, properties={
+ 'keywords':relationship(Keyword, secondary=item_keywords) #m2m
+ })
+ mapper(Keyword, keywords)
+
+ mapper(Node, nodes, properties={
+ 'children':relationship(Node,
+ backref=backref('parent', remote_side=[nodes.c.id])
+ )
+ })
+
+ mapper(CompositePk, composite_pk_table)
+
+ configure_mappers()
+
+ @classmethod
def define_tables(cls, metadata):
Table('users', metadata,
Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
diff --git a/test/orm/test_backref_mutations.py b/test/orm/test_backref_mutations.py
index c633cb8ee..b3214984f 100644
--- a/test/orm/test_backref_mutations.py
+++ b/test/orm/test_backref_mutations.py
@@ -551,7 +551,7 @@ class M2MCollectionMoveTest(_fixtures.FixtureTest):
# list is still here.
eq_(
set(attributes.instance_state(i1).
- pending['keywords'].added_items),
+ _pending_mutations['keywords'].added_items),
set([k2])
)
# because autoflush is off, k2 is still
@@ -564,7 +564,7 @@ class M2MCollectionMoveTest(_fixtures.FixtureTest):
# the pending collection was removed
assert 'keywords' not in attributes.\
instance_state(i1).\
- pending
+ _pending_mutations
def test_duplicate_adds(self):
Item, Keyword = (self.classes.Item, self.classes.Keyword)
diff --git a/test/orm/test_inspect.py b/test/orm/test_inspect.py
new file mode 100644
index 000000000..9973c31c2
--- /dev/null
+++ b/test/orm/test_inspect.py
@@ -0,0 +1,290 @@
+"""test the inspection registry system."""
+
+from test.lib.testing import eq_, assert_raises, is_
+from sqlalchemy import exc, util
+from sqlalchemy import inspect
+from test.orm import _fixtures
+from sqlalchemy.orm import class_mapper, synonym, Session
+from sqlalchemy.orm.attributes import instance_state, NO_VALUE
+from test.lib import testing
+
+class TestORMInspection(_fixtures.FixtureTest):
+ @classmethod
+ def setup_mappers(cls):
+ cls._setup_stock_mapping()
+ inspect(cls.classes.User).add_property(
+ "name_syn",synonym("name")
+ )
+
+ def test_class_mapper(self):
+ User = self.classes.User
+
+ assert inspect(User) is class_mapper(User)
+
+ def test_instance_state(self):
+ User = self.classes.User
+ u1 = User()
+
+ assert inspect(u1) is instance_state(u1)
+
+ def test_column_collection_iterate(self):
+ User = self.classes.User
+ user_table = self.tables.users
+ insp = inspect(User)
+ eq_(
+ list(insp.columns),
+ [user_table.c.id, user_table.c.name]
+ )
+ is_(
+ insp.columns.id, user_table.c.id
+ )
+
+ def test_primary_key(self):
+ User = self.classes.User
+ user_table = self.tables.users
+ insp = inspect(User)
+ eq_(insp.primary_key,
+ (user_table.c.id,)
+ )
+
+ def test_local_table(self):
+ User = self.classes.User
+ user_table = self.tables.users
+ insp = inspect(User)
+ is_(insp.local_table, user_table)
+
+ def test_property(self):
+ User = self.classes.User
+ user_table = self.tables.users
+ insp = inspect(User)
+ is_(insp.attr.id, class_mapper(User).get_property('id'))
+
+ def test_col_property(self):
+ User = self.classes.User
+ user_table = self.tables.users
+ insp = inspect(User)
+ id_prop = insp.attr.id
+
+ eq_(id_prop.columns, [user_table.c.id])
+ is_(id_prop.expression, user_table.c.id)
+
+ assert not hasattr(id_prop, 'mapper')
+
+ def test_attr_keys(self):
+ User = self.classes.User
+ insp = inspect(User)
+ eq_(
+ set(insp.attr.keys()),
+ set(['addresses', 'orders', 'id', 'name', 'name_syn'])
+ )
+
+ def test_col_filter(self):
+ User = self.classes.User
+ insp = inspect(User)
+ eq_(
+ list(insp.column_attrs),
+ [insp.get_property('id'), insp.get_property('name')]
+ )
+ eq_(
+ insp.column_attrs.keys(),
+ ['id', 'name']
+ )
+ is_(
+ insp.column_attrs.id,
+ User.id.property
+ )
+
+ def test_synonym_filter(self):
+ User = self.classes.User
+ syn = inspect(User).synonyms
+
+ eq_(
+ list(syn.keys()), ['name_syn']
+ )
+ is_(syn.name_syn, User.name_syn.original_property)
+ eq_(dict(syn), {
+ "name_syn":User.name_syn.original_property
+ })
+
+ def test_relationship_filter(self):
+ User = self.classes.User
+ rel = inspect(User).relationships
+
+ eq_(
+ rel.addresses,
+ User.addresses.property
+ )
+ eq_(
+ set(rel.keys()),
+ set(['orders', 'addresses'])
+ )
+
+ def test_insp_prop(self):
+ User = self.classes.User
+ prop = inspect(User.addresses)
+ is_(prop, User.addresses.property)
+
+ def test_rel_accessors(self):
+ User = self.classes.User
+ Address = self.classes.Address
+ prop = inspect(User.addresses)
+ is_(prop.parent, class_mapper(User))
+ is_(prop.mapper, class_mapper(Address))
+
+ assert not hasattr(prop, 'columns')
+ assert not hasattr(prop, 'expression')
+
+ def test_instance_state(self):
+ User = self.classes.User
+ u1 = User()
+ insp = inspect(u1)
+ is_(insp, instance_state(u1))
+
+ def test_instance_state_attr(self):
+ User = self.classes.User
+ u1 = User(name='ed')
+ insp = inspect(u1)
+
+ eq_(
+ set(insp.attr.keys()),
+ set(['id', 'name', 'name_syn', 'addresses', 'orders'])
+ )
+ eq_(
+ insp.attr.name.value,
+ 'ed'
+ )
+ eq_(
+ insp.attr.name.loaded_value,
+ 'ed'
+ )
+
+ def test_instance_state_attr_passive_value_scalar(self):
+ User = self.classes.User
+ u1 = User(name='ed')
+ insp = inspect(u1)
+ # value was not set, NO_VALUE
+ eq_(
+ insp.attr.id.loaded_value,
+ NO_VALUE
+ )
+ # regular accessor sets it
+ eq_(
+ insp.attr.id.value,
+ None
+ )
+ # now the None is there
+ eq_(
+ insp.attr.id.loaded_value,
+ None
+ )
+
+ def test_instance_state_attr_passive_value_collection(self):
+ User = self.classes.User
+ u1 = User(name='ed')
+ insp = inspect(u1)
+ # value was not set, NO_VALUE
+ eq_(
+ insp.attr.addresses.loaded_value,
+ NO_VALUE
+ )
+ # regular accessor sets it
+ eq_(
+ insp.attr.addresses.value,
+ []
+ )
+ # now the None is there
+ eq_(
+ insp.attr.addresses.loaded_value,
+ []
+ )
+
+ def test_instance_state_attr_hist(self):
+ User = self.classes.User
+ u1 = User(name='ed')
+ insp = inspect(u1)
+ hist = insp.attr.addresses.history
+ eq_(
+ hist.unchanged, None
+ )
+ u1.addresses
+ hist = insp.attr.addresses.history
+ eq_(
+ hist.unchanged, []
+ )
+
+ def test_instance_state_ident_transient(self):
+ User = self.classes.User
+ u1 = User(name='ed')
+ insp = inspect(u1)
+ is_(insp.identity, None)
+
+ def test_instance_state_ident_persistent(self):
+ User = self.classes.User
+ u1 = User(name='ed')
+ s = Session(testing.db)
+ s.add(u1)
+ s.flush()
+ insp = inspect(u1)
+ eq_(insp.identity, (u1.id,))
+ is_(s.query(User).get(insp.identity), u1)
+
+ def test_identity_key(self):
+ User = self.classes.User
+ u1 = User(name='ed')
+ s = Session(testing.db)
+ s.add(u1)
+ s.flush()
+ insp = inspect(u1)
+ eq_(
+ insp.identity_key,
+ (User, (11, ))
+ )
+
+ def test_persistence_states(self):
+ User = self.classes.User
+ u1 = User(name='ed')
+ insp = inspect(u1)
+
+ eq_(
+ (insp.transient, insp.pending,
+ insp.persistent, insp.detached),
+ (True, False, False, False)
+ )
+ s = Session(testing.db)
+ s.add(u1)
+
+ eq_(
+ (insp.transient, insp.pending,
+ insp.persistent, insp.detached),
+ (False, True, False, False)
+ )
+
+ s.flush()
+ eq_(
+ (insp.transient, insp.pending,
+ insp.persistent, insp.detached),
+ (False, False, True, False)
+ )
+ s.expunge(u1)
+ eq_(
+ (insp.transient, insp.pending,
+ insp.persistent, insp.detached),
+ (False, False, False, True)
+ )
+
+ def test_session_accessor(self):
+ User = self.classes.User
+ u1 = User(name='ed')
+ insp = inspect(u1)
+
+ is_(insp.session, None)
+ s = Session()
+ s.add(u1)
+ is_(insp.session, s)
+
+ def test_object_accessor(self):
+ User = self.classes.User
+ u1 = User(name='ed')
+ insp = inspect(u1)
+ is_(insp.object, u1)
+
diff --git a/test/orm/test_mapper.py b/test/orm/test_mapper.py
index 4478e5d80..78a1c29a4 100644
--- a/test/orm/test_mapper.py
+++ b/test/orm/test_mapper.py
@@ -87,14 +87,6 @@ class MapperTest(_fixtures.FixtureTest, AssertsCompiledSQL):
- def test_prop_accessor(self):
- users, User = self.tables.users, self.classes.User
-
- mapper(User, users)
- assert_raises(NotImplementedError,
- getattr, sa.orm.class_mapper(User), 'properties')
-
-
def test_friendly_attribute_str_on_uncompiled_boom(self):
User, users = self.classes.User, self.tables.users
diff --git a/test/orm/test_query.py b/test/orm/test_query.py
index 1b57299f0..6e945aa72 100644
--- a/test/orm/test_query.py
+++ b/test/orm/test_query.py
@@ -29,45 +29,7 @@ class QueryTest(_fixtures.FixtureTest):
@classmethod
def setup_mappers(cls):
- Node, composite_pk_table, users, Keyword, items, Dingaling, \
- order_items, item_keywords, Item, User, dingalings, \
- Address, keywords, CompositePk, nodes, Order, orders, \
- addresses = cls.classes.Node, \
- cls.tables.composite_pk_table, cls.tables.users, \
- cls.classes.Keyword, cls.tables.items, \
- cls.classes.Dingaling, cls.tables.order_items, \
- cls.tables.item_keywords, cls.classes.Item, \
- cls.classes.User, cls.tables.dingalings, \
- cls.classes.Address, cls.tables.keywords, \
- cls.classes.CompositePk, cls.tables.nodes, \
- cls.classes.Order, cls.tables.orders, cls.tables.addresses
-
- mapper(User, users, properties={
- 'addresses':relationship(Address, backref='user', order_by=addresses.c.id),
- 'orders':relationship(Order, backref='user', order_by=orders.c.id), # o2m, m2o
- })
- mapper(Address, addresses, properties={
- 'dingaling':relationship(Dingaling, uselist=False, backref="address") #o2o
- })
- mapper(Dingaling, dingalings)
- mapper(Order, orders, properties={
- 'items':relationship(Item, secondary=order_items, order_by=items.c.id), #m2m
- 'address':relationship(Address), # m2o
- })
- mapper(Item, items, properties={
- 'keywords':relationship(Keyword, secondary=item_keywords) #m2m
- })
- mapper(Keyword, keywords)
-
- mapper(Node, nodes, properties={
- 'children':relationship(Node,
- backref=backref('parent', remote_side=[nodes.c.id])
- )
- })
-
- mapper(CompositePk, composite_pk_table)
-
- configure_mappers()
+ cls._setup_stock_mapping()
class MiscTest(QueryTest):
run_create_tables = None
diff --git a/test/orm/test_session.py b/test/orm/test_session.py
index 79852c7a4..a82606b2b 100644
--- a/test/orm/test_session.py
+++ b/test/orm/test_session.py
@@ -1158,7 +1158,7 @@ class DisposedStates(fixtures.MappedTest):
for obj in objs:
state = attributes.instance_state(obj)
sess.identity_map.discard(state)
- state.dispose()
+ state._dispose()
def _test_session(self, **kwargs):
global sess