summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJason Kirtland <jek@discorporate.us>2008-01-21 23:19:39 +0000
committerJason Kirtland <jek@discorporate.us>2008-01-21 23:19:39 +0000
commit412c80dd6c5d6b940e86e7e142aa1fdd6ee4466d (patch)
tree2a5bfa8185dd888d52b31bfb26ada56c7db89139 /test
parent08bbc3dfd84234c3cd691e43ff17ed36e2396d76 (diff)
downloadsqlalchemy-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.py4
-rw-r--r--test/ext/alltests.py8
-rw-r--r--test/orm/collection.py20
-rw-r--r--test/profiling/compiler.py6
-rw-r--r--test/sql/testtypes.py9
-rw-r--r--test/testlib/compat.py57
-rw-r--r--test/testlib/profiling.py2
-rw-r--r--test/testlib/testing.py31
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.