summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-02-29 17:47:59 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2012-02-29 17:47:59 -0500
commit0536c48dafb670d34fc96d26078b41ed6accf01f (patch)
treeb3109ed91ac61e5ddbe8c77c5a1e0bf3e08c0f51 /test
parentcd655cf0996de682365201a0184170256da6859b (diff)
downloadsqlalchemy-0536c48dafb670d34fc96d26078b41ed6accf01f.tar.gz
- expand the check to determine if a selectable column is embedded
in the corresponding selectable to take into account clones of the target column. fixes [ticket:2419] - have _make_proxy() copy out the _is_clone_of attribute on the new column so that even more corresponding_column() checks work as expected for cloned elements. - add a new test fixture so that mapped tests can be specified using declarative.
Diffstat (limited to 'test')
-rw-r--r--test/lib/fixtures.py43
-rw-r--r--test/orm/inheritance/test_assorted_poly.py67
-rw-r--r--test/sql/test_generative.py82
3 files changed, 185 insertions, 7 deletions
diff --git a/test/lib/fixtures.py b/test/lib/fixtures.py
index 6714107bd..03116fbc1 100644
--- a/test/lib/fixtures.py
+++ b/test/lib/fixtures.py
@@ -4,6 +4,7 @@ from test.lib.engines import drop_all_tables
import sys
import sqlalchemy as sa
from test.lib.entities import BasicEntity, ComparableEntity
+from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta
class TestBase(object):
# A sequence of database names to always run, regardless of the
@@ -228,8 +229,7 @@ class MappedTest(_ORMTest, TablesTest, testing.AssertsExecutionResults):
@classmethod
def teardown_class(cls):
- cls.classes.clear()
- _ORMTest.teardown_class()
+ cls._teardown_once_class()
cls._teardown_once_metadata_bind()
def setup(self):
@@ -243,6 +243,12 @@ class MappedTest(_ORMTest, TablesTest, testing.AssertsExecutionResults):
self._teardown_each_tables()
@classmethod
+ def _teardown_once_class(cls):
+ cls.classes.clear()
+ _ORMTest.teardown_class()
+
+
+ @classmethod
def _setup_once_classes(cls):
if cls.run_setup_classes == 'once':
cls._with_register_classes(cls.setup_classes)
@@ -269,6 +275,7 @@ class MappedTest(_ORMTest, TablesTest, testing.AssertsExecutionResults):
cls_registry[classname] = cls
return type.__init__(cls, classname, bases, dict_)
+
class _Base(object):
__metaclass__ = FindFixture
class Basic(BasicEntity, _Base):
@@ -294,3 +301,35 @@ class MappedTest(_ORMTest, TablesTest, testing.AssertsExecutionResults):
def setup_mappers(cls):
pass
+class DeclarativeMappedTest(MappedTest):
+ declarative_meta = None
+
+ @classmethod
+ def setup_class(cls):
+ if cls.declarative_meta is None:
+ cls.declarative_meta = sa.MetaData()
+
+ super(DeclarativeMappedTest, cls).setup_class()
+
+ @classmethod
+ def _teardown_once_class(cls):
+ if cls.declarative_meta.tables:
+ cls.declarative_meta.drop_all(testing.db)
+ super(DeclarativeMappedTest, cls)._teardown_once_class()
+
+ @classmethod
+ def _with_register_classes(cls, fn):
+ cls_registry = cls.classes
+ class FindFixtureDeclarative(DeclarativeMeta):
+ def __init__(cls, classname, bases, dict_):
+ cls_registry[classname] = cls
+ return DeclarativeMeta.__init__(
+ cls, classname, bases, dict_)
+ _DeclBase = declarative_base(metadata=cls.declarative_meta,
+ metaclass=FindFixtureDeclarative)
+ class DeclarativeBasic(BasicEntity):
+ pass
+ cls.DeclarativeBasic = _DeclBase
+ fn()
+ if cls.declarative_meta.tables:
+ cls.declarative_meta.create_all(testing.db)
diff --git a/test/orm/inheritance/test_assorted_poly.py b/test/orm/inheritance/test_assorted_poly.py
index 0a10071ea..4fa1034ad 100644
--- a/test/orm/inheritance/test_assorted_poly.py
+++ b/test/orm/inheritance/test_assorted_poly.py
@@ -1,5 +1,5 @@
-"""Very old inheritance-related tests.
-
+"""Miscellaneous inheritance-related tests, many very old.
+These are generally tests derived from specific user issues.
"""
@@ -1451,4 +1451,65 @@ class JoinedInhAdjacencyTest(fixtures.MappedTest):
}
)
assert Dude.supervisor.property.direction is MANYTOONE
- self._dude_roundtrip() \ No newline at end of file
+ self._dude_roundtrip()
+
+
+class Ticket2419Test(fixtures.DeclarativeMappedTest):
+ """Test [ticket:2419]'s test case."""
+
+ @classmethod
+ def setup_classes(cls):
+ Base = cls.DeclarativeBasic
+ class A(Base):
+ __tablename__ = "a"
+
+ id = Column(Integer, primary_key=True)
+
+ class B(Base):
+ __tablename__ = "b"
+
+ id = Column(Integer, primary_key=True)
+ ds = relationship("D")
+ es = relationship("E")
+
+ class C(A):
+ __tablename__ = "c"
+
+ id = Column(Integer, ForeignKey('a.id'), primary_key=True)
+ b_id = Column(Integer, ForeignKey('b.id'))
+ b = relationship("B", primaryjoin=b_id==B.id)
+
+ class D(Base):
+ __tablename__ = "d"
+
+ id = Column(Integer, primary_key=True)
+ b_id = Column(Integer, ForeignKey('b.id'))
+
+ class E(Base):
+ __tablename__ = 'e'
+ id = Column(Integer, primary_key=True)
+ b_id = Column(Integer, ForeignKey('b.id'))
+
+ def test_join_w_eager_w_any(self):
+ A, B, C, D, E = self.classes.A, self.classes.B, \
+ self.classes.C, self.classes.D, \
+ self.classes.E
+ s = Session(testing.db)
+
+ b = B(ds=[D()])
+ s.add_all([
+ C(
+ b=b
+ )
+
+ ])
+
+ s.commit()
+
+ q = s.query(B, B.ds.any(D.id==1)).options(joinedload_all("es"))
+ q = q.join(C, C.b_id==B.id)
+ q = q.limit(5)
+ eq_(
+ q.all(),
+ [(b, True)]
+ )
diff --git a/test/sql/test_generative.py b/test/sql/test_generative.py
index f9333dbf5..98e783ede 100644
--- a/test/sql/test_generative.py
+++ b/test/sql/test_generative.py
@@ -5,7 +5,7 @@ from test.lib import *
from sqlalchemy.sql.visitors import *
from sqlalchemy import util, exc
from sqlalchemy.sql import util as sql_util
-from test.lib.testing import eq_, assert_raises
+from test.lib.testing import eq_, ne_, assert_raises
class TraversalTest(fixtures.TestBase, AssertsExecutionResults):
"""test ClauseVisitor's traversal, particularly its
@@ -173,7 +173,7 @@ class ClauseTest(fixtures.TestBase, AssertsCompiledSQL):
@classmethod
def setup_class(cls):
- global t1, t2
+ global t1, t2, t3
t1 = table("table1",
column("col1"),
column("col2"),
@@ -184,6 +184,10 @@ class ClauseTest(fixtures.TestBase, AssertsCompiledSQL):
column("col2"),
column("col3"),
)
+ t3 = Table('table3', MetaData(),
+ Column('col1', Integer),
+ Column('col2', Integer)
+ )
def test_binary(self):
clause = t1.c.col2 == t2.c.col2
@@ -242,6 +246,80 @@ class ClauseTest(fixtures.TestBase, AssertsCompiledSQL):
str(f)
)
+ def test_aliased_cloned_column_adapt_inner(self):
+ clause = select([t1.c.col1, func.foo(t1.c.col2).label('foo')])
+
+ aliased1 = select([clause.c.col1, clause.c.foo])
+ aliased2 = clause
+ aliased2.c.col1, aliased2.c.foo
+ aliased3 = cloned_traverse(aliased2, {}, {})
+
+ # fixed by [ticket:2419]. the inside columns
+ # on aliased3 have _is_clone_of pointers to those of
+ # aliased2. corresponding_column checks these
+ # now.
+ adapter = sql_util.ColumnAdapter(aliased1)
+ f1 = select([
+ adapter.columns[c]
+ for c in aliased2._raw_columns
+ ])
+ f2 = select([
+ adapter.columns[c]
+ for c in aliased3._raw_columns
+ ])
+ eq_(
+ str(f1), str(f2)
+ )
+
+ def test_aliased_cloned_column_adapt_exported(self):
+ clause = select([t1.c.col1, func.foo(t1.c.col2).label('foo')])
+
+ aliased1 = select([clause.c.col1, clause.c.foo])
+ aliased2 = clause
+ aliased2.c.col1, aliased2.c.foo
+ aliased3 = cloned_traverse(aliased2, {}, {})
+
+ # also fixed by [ticket:2419]. When we look at the
+ # *outside* columns of aliased3, they previously did not
+ # have an _is_clone_of pointer. But we now modified _make_proxy
+ # to assign this.
+ adapter = sql_util.ColumnAdapter(aliased1)
+ f1 = select([
+ adapter.columns[c]
+ for c in aliased2.c
+ ])
+ f2 = select([
+ adapter.columns[c]
+ for c in aliased3.c
+ ])
+ eq_(
+ str(f1), str(f2)
+ )
+
+ def test_aliased_cloned_schema_column_adapt_exported(self):
+ clause = select([t3.c.col1, func.foo(t3.c.col2).label('foo')])
+
+ aliased1 = select([clause.c.col1, clause.c.foo])
+ aliased2 = clause
+ aliased2.c.col1, aliased2.c.foo
+ aliased3 = cloned_traverse(aliased2, {}, {})
+
+ # also fixed by [ticket:2419]. When we look at the
+ # *outside* columns of aliased3, they previously did not
+ # have an _is_clone_of pointer. But we now modified _make_proxy
+ # to assign this.
+ adapter = sql_util.ColumnAdapter(aliased1)
+ f1 = select([
+ adapter.columns[c]
+ for c in aliased2.c
+ ])
+ f2 = select([
+ adapter.columns[c]
+ for c in aliased3.c
+ ])
+ eq_(
+ str(f1), str(f2)
+ )
def test_text(self):
clause = text(