diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-06-16 12:09:45 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2011-06-16 12:09:45 -0400 |
| commit | e30d02c6259d5a2386fd836e27dee75e3a143bd2 (patch) | |
| tree | 30463f11d8df3d13e8b10499908f079b2f0f7bdd /examples | |
| parent | a59bff38dca6f2a42bb6e4b7d27da9833e61a9cb (diff) | |
| download | sqlalchemy-e30d02c6259d5a2386fd836e27dee75e3a143bd2.tar.gz | |
- Repaired the examples/versioning test runner
to not rely upon SQLAlchemy test libs,
nosetests must be run from within
examples/versioning to get around setup.cfg
breaking it.
- Tweak to examples/versioning to pick the
correct foreign key in a multi-level
inheritance situation.
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/versioning/__init__.py | 3 | ||||
| -rw-r--r-- | examples/versioning/_lib.py | 96 | ||||
| -rw-r--r-- | examples/versioning/history_meta.py | 2 | ||||
| -rw-r--r-- | examples/versioning/test_versioning.py | 10 |
4 files changed, 104 insertions, 7 deletions
diff --git a/examples/versioning/__init__.py b/examples/versioning/__init__.py index 72edcca53..61b8f13c6 100644 --- a/examples/versioning/__init__.py +++ b/examples/versioning/__init__.py @@ -8,7 +8,8 @@ represents historical versions of the target object. Usage is illustrated via a unit test module ``test_versioning.py``, which can be run via nose:: - nosetests -w examples/versioning/ + cd examples/versioning + nosetests -v A fragment of example usage, using declarative:: diff --git a/examples/versioning/_lib.py b/examples/versioning/_lib.py new file mode 100644 index 000000000..d5f2cb0b7 --- /dev/null +++ b/examples/versioning/_lib.py @@ -0,0 +1,96 @@ +"""copy of ComparableEntity and eq_() from test.lib. + +This is just to support running the example outside of +the SQLA testing environment which is no longer part of +SQLAlchemy as of 0.7. + +""" + +import sqlalchemy as sa +from sqlalchemy import exc as sa_exc + + +def eq_(a, b, msg=None): + """Assert a == b, with repr messaging on failure.""" + assert a == b, msg or "%r != %r" % (a, b) + +_repr_stack = set() +class BasicEntity(object): + def __init__(self, **kw): + for key, value in kw.iteritems(): + setattr(self, key, value) + + def __repr__(self): + if id(self) in _repr_stack: + return object.__repr__(self) + _repr_stack.add(id(self)) + try: + return "%s(%s)" % ( + (self.__class__.__name__), + ', '.join(["%s=%r" % (key, getattr(self, key)) + for key in sorted(self.__dict__.keys()) + if not key.startswith('_')])) + finally: + _repr_stack.remove(id(self)) + +_recursion_stack = set() +class ComparableEntity(BasicEntity): + def __hash__(self): + return hash(self.__class__) + + def __ne__(self, other): + return not self.__eq__(other) + + def __eq__(self, other): + """'Deep, sparse compare. + + Deeply compare two entities, following the non-None attributes of the + non-persisted object, if possible. + + """ + if other is self: + return True + elif not self.__class__ == other.__class__: + return False + + if id(self) in _recursion_stack: + return True + _recursion_stack.add(id(self)) + + try: + # pick the entity thats not SA persisted as the source + try: + self_key = sa.orm.attributes.instance_state(self).key + except sa.orm.exc.NO_STATE: + self_key = None + + if other is None: + a = self + b = other + elif self_key is not None: + a = other + b = self + else: + a = self + b = other + + for attr in a.__dict__.keys(): + if attr.startswith('_'): + continue + value = getattr(a, attr) + + try: + # handle lazy loader errors + battr = getattr(b, attr) + except (AttributeError, sa_exc.UnboundExecutionError): + return False + + if hasattr(value, '__iter__'): + if list(value) != list(battr): + return False + else: + if value is not None and value != battr: + return False + return True + finally: + _recursion_stack.remove(id(self)) diff --git a/examples/versioning/history_meta.py b/examples/versioning/history_meta.py index 2983a33e2..5f3820f68 100644 --- a/examples/versioning/history_meta.py +++ b/examples/versioning/history_meta.py @@ -35,7 +35,7 @@ def _history_mapper(local_mapper): col.unique = False if super_mapper and col_references_table(column, super_mapper.local_table): - super_fks.append((col.key, list(super_history_mapper.base_mapper.local_table.primary_key)[0])) + super_fks.append((col.key, list(super_history_mapper.local_table.primary_key)[0])) cols.append(col) diff --git a/examples/versioning/test_versioning.py b/examples/versioning/test_versioning.py index d2d270c43..5baf09530 100644 --- a/examples/versioning/test_versioning.py +++ b/examples/versioning/test_versioning.py @@ -1,16 +1,16 @@ +from unittest import TestCase from sqlalchemy.ext.declarative import declarative_base from history_meta import VersionedMeta, VersionedListener from sqlalchemy import create_engine, Column, Integer, String, ForeignKey from sqlalchemy.orm import clear_mappers, sessionmaker, deferred, relationship -from test.lib.testing import TestBase, eq_ -from test.lib.entities import ComparableEntity +from _lib import ComparableEntity, eq_ def setup(): global engine engine = create_engine('sqlite://', echo=True) -class TestVersioning(fixtures.TestBase): - def setup(self): +class TestVersioning(TestCase): + def setUp(self): global Base, Session, Versioned Base = declarative_base(bind=engine) class Versioned(object): @@ -18,7 +18,7 @@ class TestVersioning(fixtures.TestBase): _decl_class_registry = Base._decl_class_registry Session = sessionmaker(extension=VersionedListener()) - def teardown(self): + def tearDown(self): clear_mappers() Base.metadata.drop_all() |
