mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-30 04:24:38 -04:00
20cdc64588
become an externally usable package but still remains within the main sqlalchemy parent package. in this system, we use kind of an ugly hack to get the noseplugin imported outside of the "sqlalchemy" package, while still making it available within sqlalchemy for usage by third party libraries.
128 lines
3.7 KiB
Python
128 lines
3.7 KiB
Python
from sqlalchemy.orm import descriptor_props, aliased
|
|
from sqlalchemy.orm.interfaces import PropComparator
|
|
from sqlalchemy.orm.properties import ColumnProperty
|
|
from sqlalchemy.sql import column
|
|
from sqlalchemy import Column, Integer, func, String
|
|
from sqlalchemy.ext.declarative import declarative_base
|
|
from sqlalchemy.util import partial
|
|
from sqlalchemy.testing import fixtures
|
|
from sqlalchemy.testing import eq_
|
|
|
|
class TestDescriptor(descriptor_props.DescriptorProperty):
|
|
def __init__(self, cls, key, descriptor=None, doc=None,
|
|
comparator_factory = None):
|
|
self.parent = cls.__mapper__
|
|
self.key = key
|
|
self.doc = doc
|
|
self.descriptor = descriptor
|
|
if comparator_factory:
|
|
self._comparator_factory = partial(comparator_factory, self)
|
|
else:
|
|
self._comparator_factory = lambda mapper: None
|
|
|
|
class DescriptorInstrumentationTest(fixtures.ORMTest):
|
|
def _fixture(self):
|
|
Base = declarative_base()
|
|
|
|
class Foo(Base):
|
|
__tablename__ = 'foo'
|
|
id = Column(Integer, primary_key=True)
|
|
|
|
return Foo
|
|
|
|
def test_fixture(self):
|
|
Foo = self._fixture()
|
|
|
|
d = TestDescriptor(Foo, 'foo')
|
|
d.instrument_class(Foo.__mapper__)
|
|
|
|
assert Foo.foo
|
|
|
|
def test_property_wrapped_classlevel(self):
|
|
Foo = self._fixture()
|
|
prop = property(lambda self:None)
|
|
Foo.foo = prop
|
|
|
|
d = TestDescriptor(Foo, 'foo')
|
|
d.instrument_class(Foo.__mapper__)
|
|
|
|
assert Foo().foo is None
|
|
assert Foo.foo is not prop
|
|
|
|
def test_property_subclass_wrapped_classlevel(self):
|
|
Foo = self._fixture()
|
|
|
|
class myprop(property):
|
|
attr = 'bar'
|
|
|
|
def method1(self):
|
|
return "method1"
|
|
|
|
prop = myprop(lambda self:None)
|
|
Foo.foo = prop
|
|
|
|
d = TestDescriptor(Foo, 'foo')
|
|
d.instrument_class(Foo.__mapper__)
|
|
|
|
assert Foo().foo is None
|
|
assert Foo.foo is not prop
|
|
assert Foo.foo.attr == 'bar'
|
|
assert Foo.foo.method1() == 'method1'
|
|
|
|
def test_comparator(self):
|
|
class Comparator(PropComparator):
|
|
__hash__ = None
|
|
|
|
attr = 'bar'
|
|
|
|
def method1(self):
|
|
return "method1"
|
|
|
|
def method2(self, other):
|
|
return "method2"
|
|
|
|
def __getitem__(self, key):
|
|
return 'value'
|
|
|
|
def __eq__(self, other):
|
|
return column('foo') == func.upper(other)
|
|
|
|
Foo = self._fixture()
|
|
d = TestDescriptor(Foo, 'foo', comparator_factory=Comparator)
|
|
d.instrument_class(Foo.__mapper__)
|
|
eq_(Foo.foo.method1(), "method1")
|
|
eq_(Foo.foo.method2('x'), "method2")
|
|
assert Foo.foo.attr == 'bar'
|
|
assert Foo.foo['bar'] == 'value'
|
|
eq_(
|
|
(Foo.foo == 'bar').__str__(),
|
|
"foo = upper(:upper_1)"
|
|
)
|
|
|
|
|
|
def test_aliased_comparator(self):
|
|
class Comparator(ColumnProperty.Comparator):
|
|
__hash__ = None
|
|
def __eq__(self, other):
|
|
return func.foobar(self.__clause_element__()) ==\
|
|
func.foobar(other)
|
|
|
|
Foo = self._fixture()
|
|
Foo._name = Column('name', String)
|
|
|
|
def comparator_factory(self, mapper):
|
|
prop = mapper._props['_name']
|
|
return Comparator(prop, mapper)
|
|
|
|
d = TestDescriptor(Foo, 'foo', comparator_factory=comparator_factory)
|
|
d.instrument_class(Foo.__mapper__)
|
|
|
|
eq_(
|
|
str(Foo.foo == 'ed'),
|
|
"foobar(foo.name) = foobar(:foobar_1)"
|
|
)
|
|
eq_(
|
|
str(aliased(Foo).foo == 'ed'),
|
|
"foobar(foo_1.name) = foobar(:foobar_1)"
|
|
)
|