diff options
| author | Jason Kirtland <jek@discorporate.us> | 2008-01-21 23:19:39 +0000 |
|---|---|---|
| committer | Jason Kirtland <jek@discorporate.us> | 2008-01-21 23:19:39 +0000 |
| commit | 412c80dd6c5d6b940e86e7e142aa1fdd6ee4466d (patch) | |
| tree | 2a5bfa8185dd888d52b31bfb26ada56c7db89139 /test | |
| parent | 08bbc3dfd84234c3cd691e43ff17ed36e2396d76 (diff) | |
| download | sqlalchemy-412c80dd6c5d6b940e86e7e142aa1fdd6ee4466d.tar.gz | |
- 2.3 fixup, part two: 100% passing for sqlite
- added 2.4-style binops to util.Set on 2.3
- OrderedSets pickle on 2.3
- more lib/sqlalchemy set vs Set corrections
- fixed InstrumentedSet.discard for 2.3
- set, sorted compatibility for test suite
- added testing.fails_if decorator
Diffstat (limited to 'test')
| -rw-r--r-- | test/base/utils.py | 4 | ||||
| -rw-r--r-- | test/ext/alltests.py | 8 | ||||
| -rw-r--r-- | test/orm/collection.py | 20 | ||||
| -rw-r--r-- | test/profiling/compiler.py | 6 | ||||
| -rw-r--r-- | test/sql/testtypes.py | 9 | ||||
| -rw-r--r-- | test/testlib/compat.py | 57 | ||||
| -rw-r--r-- | test/testlib/profiling.py | 2 | ||||
| -rw-r--r-- | test/testlib/testing.py | 31 |
8 files changed, 119 insertions, 18 deletions
diff --git a/test/base/utils.py b/test/base/utils.py index 61e2b95a8..5a034e0b0 100644 --- a/test/base/utils.py +++ b/test/base/utils.py @@ -138,8 +138,8 @@ class HashEqOverride(object): class IdentitySetTest(unittest.TestCase): def assert_eq(self, identityset, expected_iterable): - found = sorted(list(identityset)) - expected = sorted(expected_iterable) + expected = sorted([id(o) for o in expected_iterable]) + found = sorted([id(o) for o in identityset]) self.assertEquals(found, expected) def test_init(self): diff --git a/test/ext/alltests.py b/test/ext/alltests.py index 7639cd71e..6f74e3dbc 100644 --- a/test/ext/alltests.py +++ b/test/ext/alltests.py @@ -1,12 +1,16 @@ import testenv; testenv.configure_for_tests() -import unittest, doctest +import doctest, sys, unittest def suite(): unittest_modules = ['ext.activemapper', 'ext.assignmapper', 'ext.orderinglist', 'ext.associationproxy'] - doctest_modules = ['sqlalchemy.ext.sqlsoup'] + + if sys.version_info >= (2, 4): + doctest_modules = ['sqlalchemy.ext.sqlsoup'] + else: + doctest_modules = [] alltests = unittest.TestSuite() for name in unittest_modules: diff --git a/test/orm/collection.py b/test/orm/collection.py index 7addb8687..d67ec980c 100644 --- a/test/orm/collection.py +++ b/test/orm/collection.py @@ -1,4 +1,6 @@ import testenv; testenv.configure_for_tests() +import sys +from operator import and_ from sqlalchemy import * import sqlalchemy.exceptions as exceptions from sqlalchemy.orm import create_session, mapper, relation, \ @@ -6,9 +8,14 @@ from sqlalchemy.orm import create_session, mapper, relation, \ import sqlalchemy.orm.collections as collections from sqlalchemy.orm.collections import collection from sqlalchemy import util -from operator import and_ from testlib import * +try: + py_set = __builtins__.set +except AttributeError: + import sets + py_set = sets.Set + class Canary(interfaces.AttributeExtension): def __init__(self): self.data = set() @@ -703,7 +710,7 @@ class CollectionsTest(PersistTest): def test_set_emulates(self): class SetIsh(object): - __emulates__ = set + __emulates__ = py_set def __init__(self): self.data = set() def add(self, item): @@ -839,10 +846,11 @@ class CollectionsTest(PersistTest): control.update(d) assert_eq() - kw = dict([(ee.a, ee) for ee in [e, creator()]]) - direct.update(**kw) - control.update(**kw) - assert_eq() + if sys.version_info >= (2, 4): + kw = dict([(ee.a, ee) for ee in [e, creator()]]) + direct.update(**kw) + control.update(**kw) + assert_eq() def _test_dict_bulk(self, typecallable, creator=dictable_entity): class Foo(object): diff --git a/test/profiling/compiler.py b/test/profiling/compiler.py index 58533f700..330271a1c 100644 --- a/test/profiling/compiler.py +++ b/test/profiling/compiler.py @@ -15,16 +15,16 @@ class CompileTest(AssertMixin): Column('c1', Integer, primary_key=True), Column('c2', String(30))) - @profiling.profiled('ctest_insert', call_range=(40, 50), always=True) + @profiling.function_call_count(42, {'2.3': 44}) def test_insert(self): t1.insert().compile() - @profiling.profiled('ctest_update', call_range=(40, 50), always=True) + @profiling.function_call_count(42, {'2.3': 47}) def test_update(self): t1.update().compile() # TODO: this is alittle high - @profiling.profiled('ctest_select', call_range=(110, 140), always=True) + @profiling.function_call_count(125, versions={'2.3': 180}) def test_select(self): s = select([t1], t1.c.c2==t2.c.c1) s.compile() diff --git a/test/sql/testtypes.py b/test/sql/testtypes.py index fdb6f3cc2..4d9780155 100644 --- a/test/sql/testtypes.py +++ b/test/sql/testtypes.py @@ -690,6 +690,14 @@ class StringTest(AssertMixin): finally: bar.drop() +def _missing_decimal(): + """Python implementation supports decimals""" + try: + import decimal + return False + except ImportError: + return True + class NumericTest(AssertMixin): def setUpAll(self): global numeric_table, metadata @@ -709,6 +717,7 @@ class NumericTest(AssertMixin): def tearDown(self): numeric_table.delete().execute() + @testing.fails_if(_missing_decimal) def test_decimal(self): from decimal import Decimal numeric_table.insert().execute(numericcol=3.5, floatcol=5.6, ncasdec=12.4, fcasdec=15.75) diff --git a/test/testlib/compat.py b/test/testlib/compat.py index 590bf50f4..8d2b35d4a 100644 --- a/test/testlib/compat.py +++ b/test/testlib/compat.py @@ -1,17 +1,66 @@ -import new +import itertools, new __all__ = 'set', 'sorted', '_function_named' try: set = set except NameError: - from sets import Set as set + import sets + + # keep this in sync with sqlalchemy.util.Set + # can't just import it in testlib because of coverage, load order, etc. + class set(sets.Set): + def _binary_sanity_check(self, other): + pass + + def issubset(self, iterable): + other = type(self)(iterable) + return sets.Set.issubset(self, other) + def __le__(self, other): + sets.Set._binary_sanity_check(self, other) + return sets.Set.__le__(self, other) + def issuperset(self, iterable): + other = type(self)(iterable) + return sets.Set.issuperset(self, other) + def __ge__(self, other): + sets.Set._binary_sanity_check(self, other) + return sets.Set.__ge__(self, other) + + # lt and gt still require a BaseSet + def __lt__(self, other): + sets.Set._binary_sanity_check(self, other) + return sets.Set.__lt__(self, other) + def __gt__(self, other): + sets.Set._binary_sanity_check(self, other) + return sets.Set.__gt__(self, other) + + def __ior__(self, other): + if not isinstance(other, sets.BaseSet): + return NotImplemented + return sets.Set.__ior__(self, other) + def __iand__(self, other): + if not isinstance(other, sets.BaseSet): + return NotImplemented + return sets.Set.__iand__(self, other) + def __ixor__(self, other): + if not isinstance(other, sets.BaseSet): + return NotImplemented + return sets.Set.__ixor__(self, other) + def __isub__(self, other): + if not isinstance(other, sets.BaseSet): + return NotImplemented + return sets.Set.__isub__(self, other) try: sorted = sorted except NameError: - def sorted(iterable): - return list(iterable).sort() + def sorted(iterable, cmp=None): + l = list(iterable) + if cmp: + l.sort(cmp) + else: + l.sort() + return l def _function_named(fn, newname): try: diff --git a/test/testlib/profiling.py b/test/testlib/profiling.py index 8867d0169..9e2b6ed87 100644 --- a/test/testlib/profiling.py +++ b/test/testlib/profiling.py @@ -143,7 +143,7 @@ def function_call_count(count=None, versions={}, variance=0.05): raise AssertionError( "Function call count %s not within %s%% " "of expected %s. (Python version %s)" % ( - calls, variance, count, py_version)) + calls, (variance * 100), count, py_version)) return result finally: if os.path.exists(filename): diff --git a/test/testlib/testing.py b/test/testlib/testing.py index b05795efd..8b64ce7db 100644 --- a/test/testlib/testing.py +++ b/test/testlib/testing.py @@ -25,6 +25,37 @@ _ops = { '<': operator.lt, # sugar ('testing.db'); set here by config() at runtime db = None +def fails_if(callable_): + """Mark a test as expected to fail if callable_ returns True. + + If the callable returns false, the test is run and reported as normal. + However if the callable returns true, the test is expected to fail and the + unit test logic is inverted: if the test fails, a success is reported. If + the test succeeds, a failure is reported. + """ + + docstring = getattr(callable_, '__doc__', callable_.__name__) + description = docstring.split('\n')[0] + + def decorate(fn): + fn_name = fn.__name__ + def maybe(*args, **kw): + if not callable_(): + return fn(*args, **kw) + else: + try: + fn(*args, **kw) + except Exception, ex: + print ("'%s' failed as expected (condition: %s): %s " % ( + fn_name, description, str(ex))) + return True + else: + raise AssertionError( + "Unexpected success for '%s' (condition: %s)" % + (fn_name, description)) + return _function_named(maybe, fn_name) + return decorate + def fails_on(*dbs): """Mark a test as expected to fail on one or more database implementations. |
