summaryrefslogtreecommitdiff
path: root/test/sql
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2019-10-17 13:09:24 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2019-10-20 20:49:03 -0400
commited553fffd65a063d6dbdb3770d1fa0124bd55e23 (patch)
tree59ab8a457b3ed82cb7647b7da1b94b4ce2a815e1 /test/sql
parent528782d1c356445f17cea857ef0974e074c51d60 (diff)
downloadsqlalchemy-ed553fffd65a063d6dbdb3770d1fa0124bd55e23.tar.gz
Implement facade for pytest parametrize, fixtures, classlevel
Add factilities to implement pytest.mark.parametrize and pytest.fixtures patterns, which largely resemble things we are already doing. Ensure a facade is used, so that the test suite remains independent of py.test, but also tailors the functions to the more limited scope in which we are using them. Additionally, create a class-based version that works from the same facade. Several old polymorphic tests as well as two of the sql test are refactored to use the new features. Change-Id: I6ef8af1dafff92534313016944d447f9439856cf References: #4896
Diffstat (limited to 'test/sql')
-rw-r--r--test/sql/test_operators.py315
-rw-r--r--test/sql/test_types.py433
2 files changed, 355 insertions, 393 deletions
diff --git a/test/sql/test_operators.py b/test/sql/test_operators.py
index 66fe18598..637f1f8a5 100644
--- a/test/sql/test_operators.py
+++ b/test/sql/test_operators.py
@@ -73,12 +73,41 @@ class LoopOperate(operators.ColumnOperators):
class DefaultColumnComparatorTest(fixtures.TestBase):
- def _do_scalar_test(self, operator, compare_to):
+ @testing.combinations((operators.desc_op, desc), (operators.asc_op, asc))
+ def test_scalar(self, operator, compare_to):
left = column("left")
assert left.comparator.operate(operator).compare(compare_to(left))
self._loop_test(operator)
- def _do_operate_test(self, operator, right=column("right")):
+ right_column = column("right")
+
+ @testing.combinations(
+ (operators.add, right_column),
+ (operators.is_, None),
+ (operators.isnot, None),
+ (operators.is_, null()),
+ (operators.is_, true()),
+ (operators.is_, false()),
+ (operators.eq, True),
+ (operators.ne, True),
+ (operators.is_distinct_from, True),
+ (operators.is_distinct_from, False),
+ (operators.is_distinct_from, None),
+ (operators.isnot_distinct_from, True),
+ (operators.is_, True),
+ (operators.isnot, True),
+ (operators.is_, False),
+ (operators.isnot, False),
+ (operators.like_op, right_column),
+ (operators.notlike_op, right_column),
+ (operators.ilike_op, right_column),
+ (operators.notilike_op, right_column),
+ (operators.is_, right_column),
+ (operators.isnot, right_column),
+ (operators.concat_op, right_column),
+ id_="ns",
+ )
+ def test_operate(self, operator, right):
left = column("left")
assert left.comparator.operate(operator, right).compare(
@@ -109,84 +138,13 @@ class DefaultColumnComparatorTest(fixtures.TestBase):
loop = LoopOperate()
is_(operator(loop, *arg), operator)
- def test_desc(self):
- self._do_scalar_test(operators.desc_op, desc)
-
- def test_asc(self):
- self._do_scalar_test(operators.asc_op, asc)
-
- def test_plus(self):
- self._do_operate_test(operators.add)
-
- def test_is_null(self):
- self._do_operate_test(operators.is_, None)
-
- def test_isnot_null(self):
- self._do_operate_test(operators.isnot, None)
-
- def test_is_null_const(self):
- self._do_operate_test(operators.is_, null())
-
- def test_is_true_const(self):
- self._do_operate_test(operators.is_, true())
-
- def test_is_false_const(self):
- self._do_operate_test(operators.is_, false())
-
- def test_equals_true(self):
- self._do_operate_test(operators.eq, True)
-
- def test_notequals_true(self):
- self._do_operate_test(operators.ne, True)
-
- def test_is_distinct_from_true(self):
- self._do_operate_test(operators.is_distinct_from, True)
-
- def test_is_distinct_from_false(self):
- self._do_operate_test(operators.is_distinct_from, False)
-
- def test_is_distinct_from_null(self):
- self._do_operate_test(operators.is_distinct_from, None)
-
- def test_isnot_distinct_from_true(self):
- self._do_operate_test(operators.isnot_distinct_from, True)
-
- def test_is_true(self):
- self._do_operate_test(operators.is_, True)
-
- def test_isnot_true(self):
- self._do_operate_test(operators.isnot, True)
-
- def test_is_false(self):
- self._do_operate_test(operators.is_, False)
-
- def test_isnot_false(self):
- self._do_operate_test(operators.isnot, False)
-
- def test_like(self):
- self._do_operate_test(operators.like_op)
-
- def test_notlike(self):
- self._do_operate_test(operators.notlike_op)
-
- def test_ilike(self):
- self._do_operate_test(operators.ilike_op)
-
- def test_notilike(self):
- self._do_operate_test(operators.notilike_op)
-
- def test_is(self):
- self._do_operate_test(operators.is_)
-
- def test_isnot(self):
- self._do_operate_test(operators.isnot)
-
def test_no_getitem(self):
assert_raises_message(
NotImplementedError,
"Operator 'getitem' is not supported on this expression",
- self._do_operate_test,
+ self.test_operate,
operators.getitem,
+ column("right"),
)
assert_raises_message(
NotImplementedError,
@@ -274,9 +232,6 @@ class DefaultColumnComparatorTest(fixtures.TestBase):
collate(left, right)
)
- def test_concat(self):
- self._do_operate_test(operators.concat_op)
-
def test_default_adapt(self):
class TypeOne(TypeEngine):
pass
@@ -329,7 +284,8 @@ class DefaultColumnComparatorTest(fixtures.TestBase):
class CustomUnaryOperatorTest(fixtures.TestBase, testing.AssertsCompiledSQL):
__dialect__ = "default"
- def _factorial_fixture(self):
+ @testing.fixture
+ def factorial(self):
class MyInteger(Integer):
class comparator_factory(Integer.Comparator):
def factorial(self):
@@ -355,24 +311,24 @@ class CustomUnaryOperatorTest(fixtures.TestBase, testing.AssertsCompiledSQL):
return MyInteger
- def test_factorial(self):
- col = column("somecol", self._factorial_fixture())
+ def test_factorial(self, factorial):
+ col = column("somecol", factorial())
self.assert_compile(col.factorial(), "somecol !")
- def test_double_factorial(self):
- col = column("somecol", self._factorial_fixture())
+ def test_double_factorial(self, factorial):
+ col = column("somecol", factorial())
self.assert_compile(col.factorial().factorial(), "somecol ! !")
- def test_factorial_prefix(self):
- col = column("somecol", self._factorial_fixture())
+ def test_factorial_prefix(self, factorial):
+ col = column("somecol", factorial())
self.assert_compile(col.factorial_prefix(), "!! somecol")
- def test_factorial_invert(self):
- col = column("somecol", self._factorial_fixture())
+ def test_factorial_invert(self, factorial):
+ col = column("somecol", factorial())
self.assert_compile(~col, "!!! somecol")
- def test_double_factorial_invert(self):
- col = column("somecol", self._factorial_fixture())
+ def test_double_factorial_invert(self, factorial):
+ col = column("somecol", factorial())
self.assert_compile(~(~col), "!!! (!!! somecol)")
def test_unary_no_ops(self):
@@ -1845,7 +1801,15 @@ class MathOperatorTest(fixtures.TestBase, testing.AssertsCompiledSQL):
table1 = table("mytable", column("myid", Integer))
- def _test_math_op(self, py_op, sql_op):
+ @testing.combinations(
+ ("add", operator.add, "+"),
+ ("mul", operator.mul, "*"),
+ ("sub", operator.sub, "-"),
+ ("div", operator.truediv if util.py3k else operator.div, "/"),
+ ("mod", operator.mod, "%"),
+ id_="iaa",
+ )
+ def test_math_op(self, py_op, sql_op):
for (lhs, rhs, res) in (
(5, self.table1.c.myid, ":myid_1 %s mytable.myid"),
(5, literal(5), ":param_1 %s :param_2"),
@@ -1862,24 +1826,6 @@ class MathOperatorTest(fixtures.TestBase, testing.AssertsCompiledSQL):
):
self.assert_compile(py_op(lhs, rhs), res % sql_op)
- def test_math_op_add(self):
- self._test_math_op(operator.add, "+")
-
- def test_math_op_mul(self):
- self._test_math_op(operator.mul, "*")
-
- def test_math_op_sub(self):
- self._test_math_op(operator.sub, "-")
-
- def test_math_op_div(self):
- if util.py3k:
- self._test_math_op(operator.truediv, "/")
- else:
- self._test_math_op(operator.div, "/")
-
- def test_math_op_mod(self):
- self._test_math_op(operator.mod, "%")
-
class ComparisonOperatorTest(fixtures.TestBase, testing.AssertsCompiledSQL):
__dialect__ = "default"
@@ -1898,7 +1844,16 @@ class ComparisonOperatorTest(fixtures.TestBase, testing.AssertsCompiledSQL):
clause = tuple_(1, 2, 3)
eq_(str(clause), str(util.pickle.loads(util.pickle.dumps(clause))))
- def _test_comparison_op(self, py_op, fwd_op, rev_op):
+ @testing.combinations(
+ (operator.lt, "<", ">"),
+ (operator.gt, ">", "<"),
+ (operator.eq, "=", "="),
+ (operator.ne, "!=", "!="),
+ (operator.le, "<=", ">="),
+ (operator.ge, ">=", "<="),
+ id_="naa",
+ )
+ def test_comparison_op(self, py_op, fwd_op, rev_op):
dt = datetime.datetime(2012, 5, 10, 15, 27, 18)
for (lhs, rhs, l_sql, r_sql) in (
("a", self.table1.c.myid, ":myid_1", "mytable.myid"),
@@ -1935,24 +1890,6 @@ class ComparisonOperatorTest(fixtures.TestBase, testing.AssertsCompiledSQL):
+ "'",
)
- def test_comparison_operators_lt(self):
- self._test_comparison_op(operator.lt, "<", ">"),
-
- def test_comparison_operators_gt(self):
- self._test_comparison_op(operator.gt, ">", "<")
-
- def test_comparison_operators_eq(self):
- self._test_comparison_op(operator.eq, "=", "=")
-
- def test_comparison_operators_ne(self):
- self._test_comparison_op(operator.ne, "!=", "!=")
-
- def test_comparison_operators_le(self):
- self._test_comparison_op(operator.le, "<=", ">=")
-
- def test_comparison_operators_ge(self):
- self._test_comparison_op(operator.ge, ">=", "<=")
-
class NonZeroTest(fixtures.TestBase):
def _raises(self, expr):
@@ -2690,38 +2627,39 @@ class CustomOpTest(fixtures.TestBase):
assert operators.is_comparison(op1)
assert not operators.is_comparison(op2)
- def test_return_types(self):
+ @testing.combinations(
+ (sqltypes.NULLTYPE,),
+ (Integer(),),
+ (ARRAY(String),),
+ (String(50),),
+ (Boolean(),),
+ (DateTime(),),
+ (sqltypes.JSON(),),
+ (postgresql.ARRAY(Integer),),
+ (sqltypes.Numeric(5, 2),),
+ id_="r",
+ )
+ def test_return_types(self, typ):
some_return_type = sqltypes.DECIMAL()
- for typ in [
- sqltypes.NULLTYPE,
- Integer(),
- ARRAY(String),
- String(50),
- Boolean(),
- DateTime(),
- sqltypes.JSON(),
- postgresql.ARRAY(Integer),
- sqltypes.Numeric(5, 2),
- ]:
- c = column("x", typ)
- expr = c.op("$", is_comparison=True)(None)
- is_(expr.type, sqltypes.BOOLEANTYPE)
+ c = column("x", typ)
+ expr = c.op("$", is_comparison=True)(None)
+ is_(expr.type, sqltypes.BOOLEANTYPE)
- c = column("x", typ)
- expr = c.bool_op("$")(None)
- is_(expr.type, sqltypes.BOOLEANTYPE)
+ c = column("x", typ)
+ expr = c.bool_op("$")(None)
+ is_(expr.type, sqltypes.BOOLEANTYPE)
- expr = c.op("$")(None)
- is_(expr.type, typ)
+ expr = c.op("$")(None)
+ is_(expr.type, typ)
- expr = c.op("$", return_type=some_return_type)(None)
- is_(expr.type, some_return_type)
+ expr = c.op("$", return_type=some_return_type)(None)
+ is_(expr.type, some_return_type)
- expr = c.op("$", is_comparison=True, return_type=some_return_type)(
- None
- )
- is_(expr.type, some_return_type)
+ expr = c.op("$", is_comparison=True, return_type=some_return_type)(
+ None
+ )
+ is_(expr.type, some_return_type)
class TupleTypingTest(fixtures.TestBase):
@@ -2756,7 +2694,8 @@ class TupleTypingTest(fixtures.TestBase):
class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
__dialect__ = "default"
- def _fixture(self):
+ @testing.fixture
+ def t_fixture(self):
m = MetaData()
t = Table(
@@ -2767,8 +2706,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
)
return t
- def test_any_array(self):
- t = self._fixture()
+ def test_any_array(self, t_fixture):
+ t = t_fixture
self.assert_compile(
5 == any_(t.c.arrval),
@@ -2776,8 +2715,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"param_1": 5},
)
- def test_any_array_method(self):
- t = self._fixture()
+ def test_any_array_method(self, t_fixture):
+ t = t_fixture
self.assert_compile(
5 == t.c.arrval.any_(),
@@ -2785,8 +2724,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"param_1": 5},
)
- def test_all_array(self):
- t = self._fixture()
+ def test_all_array(self, t_fixture):
+ t = t_fixture
self.assert_compile(
5 == all_(t.c.arrval),
@@ -2794,8 +2733,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"param_1": 5},
)
- def test_all_array_method(self):
- t = self._fixture()
+ def test_all_array_method(self, t_fixture):
+ t = t_fixture
self.assert_compile(
5 == t.c.arrval.all_(),
@@ -2803,8 +2742,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"param_1": 5},
)
- def test_any_comparator_array(self):
- t = self._fixture()
+ def test_any_comparator_array(self, t_fixture):
+ t = t_fixture
self.assert_compile(
5 > any_(t.c.arrval),
@@ -2812,8 +2751,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"param_1": 5},
)
- def test_all_comparator_array(self):
- t = self._fixture()
+ def test_all_comparator_array(self, t_fixture):
+ t = t_fixture
self.assert_compile(
5 > all_(t.c.arrval),
@@ -2821,8 +2760,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"param_1": 5},
)
- def test_any_comparator_array_wexpr(self):
- t = self._fixture()
+ def test_any_comparator_array_wexpr(self, t_fixture):
+ t = t_fixture
self.assert_compile(
t.c.data > any_(t.c.arrval),
@@ -2830,8 +2769,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={},
)
- def test_all_comparator_array_wexpr(self):
- t = self._fixture()
+ def test_all_comparator_array_wexpr(self, t_fixture):
+ t = t_fixture
self.assert_compile(
t.c.data > all_(t.c.arrval),
@@ -2839,8 +2778,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={},
)
- def test_illegal_ops(self):
- t = self._fixture()
+ def test_illegal_ops(self, t_fixture):
+ t = t_fixture
assert_raises_message(
exc.ArgumentError,
@@ -2856,8 +2795,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
t.c.data + all_(t.c.arrval), "tab1.data + ALL (tab1.arrval)"
)
- def test_any_array_comparator_accessor(self):
- t = self._fixture()
+ def test_any_array_comparator_accessor(self, t_fixture):
+ t = t_fixture
self.assert_compile(
t.c.arrval.any(5, operator.gt),
@@ -2865,8 +2804,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"param_1": 5},
)
- def test_all_array_comparator_accessor(self):
- t = self._fixture()
+ def test_all_array_comparator_accessor(self, t_fixture):
+ t = t_fixture
self.assert_compile(
t.c.arrval.all(5, operator.gt),
@@ -2874,8 +2813,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"param_1": 5},
)
- def test_any_array_expression(self):
- t = self._fixture()
+ def test_any_array_expression(self, t_fixture):
+ t = t_fixture
self.assert_compile(
5 == any_(t.c.arrval[5:6] + postgresql.array([3, 4])),
@@ -2891,8 +2830,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
dialect="postgresql",
)
- def test_all_array_expression(self):
- t = self._fixture()
+ def test_all_array_expression(self, t_fixture):
+ t = t_fixture
self.assert_compile(
5 == all_(t.c.arrval[5:6] + postgresql.array([3, 4])),
@@ -2908,8 +2847,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
dialect="postgresql",
)
- def test_any_subq(self):
- t = self._fixture()
+ def test_any_subq(self, t_fixture):
+ t = t_fixture
self.assert_compile(
5
@@ -2919,8 +2858,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"data_1": 10, "param_1": 5},
)
- def test_any_subq_method(self):
- t = self._fixture()
+ def test_any_subq_method(self, t_fixture):
+ t = t_fixture
self.assert_compile(
5
@@ -2933,8 +2872,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"data_1": 10, "param_1": 5},
)
- def test_all_subq(self):
- t = self._fixture()
+ def test_all_subq(self, t_fixture):
+ t = t_fixture
self.assert_compile(
5
@@ -2944,8 +2883,8 @@ class AnyAllTest(fixtures.TestBase, testing.AssertsCompiledSQL):
checkparams={"data_1": 10, "param_1": 5},
)
- def test_all_subq_method(self):
- t = self._fixture()
+ def test_all_subq_method(self, t_fixture):
+ t = t_fixture
self.assert_compile(
5
diff --git a/test/sql/test_types.py b/test/sql/test_types.py
index 7bf83b461..2ffdd83b7 100644
--- a/test/sql/test_types.py
+++ b/test/sql/test_types.py
@@ -5,6 +5,7 @@ import importlib
import operator
import os
+import sqlalchemy as sa
from sqlalchemy import and_
from sqlalchemy import ARRAY
from sqlalchemy import BigInteger
@@ -87,42 +88,83 @@ from sqlalchemy.testing.util import round_decimal
from sqlalchemy.util import OrderedDict
-class AdaptTest(fixtures.TestBase):
- def _all_dialect_modules(self):
- return [
- importlib.import_module("sqlalchemy.dialects.%s" % d)
- for d in dialects.__all__
- if not d.startswith("_")
- ]
+def _all_dialect_modules():
+ return [
+ importlib.import_module("sqlalchemy.dialects.%s" % d)
+ for d in dialects.__all__
+ if not d.startswith("_")
+ ]
- def _all_dialects(self):
- return [d.base.dialect() for d in self._all_dialect_modules()]
- def _types_for_mod(self, mod):
- for key in dir(mod):
- typ = getattr(mod, key)
- if not isinstance(typ, type) or not issubclass(
- typ, types.TypeEngine
- ):
- continue
- yield typ
+def _all_dialects():
+ return [d.base.dialect() for d in _all_dialect_modules()]
- def _all_types(self):
- for typ in self._types_for_mod(types):
- yield typ
- for dialect in self._all_dialect_modules():
- for typ in self._types_for_mod(dialect):
- yield typ
- def test_uppercase_importable(self):
- import sqlalchemy as sa
+def _types_for_mod(mod):
+ for key in dir(mod):
+ typ = getattr(mod, key)
+ if not isinstance(typ, type) or not issubclass(typ, types.TypeEngine):
+ continue
+ yield typ
- for typ in self._types_for_mod(types):
- if typ.__name__ == typ.__name__.upper():
- assert getattr(sa, typ.__name__) is typ
- assert typ.__name__ in types.__all__
- def test_uppercase_rendering(self):
+def _all_types(omit_special_types=False):
+ seen = set()
+ for typ in _types_for_mod(types):
+ if omit_special_types and typ in (
+ types.TypeDecorator,
+ types.TypeEngine,
+ types.Variant,
+ ):
+ continue
+
+ if typ in seen:
+ continue
+ seen.add(typ)
+ yield typ
+ for dialect in _all_dialect_modules():
+ for typ in _types_for_mod(dialect):
+ if typ in seen:
+ continue
+ seen.add(typ)
+ yield typ
+
+
+class AdaptTest(fixtures.TestBase):
+ @testing.combinations(((t,) for t in _types_for_mod(types)), id_="n")
+ def test_uppercase_importable(self, typ):
+ if typ.__name__ == typ.__name__.upper():
+ assert getattr(sa, typ.__name__) is typ
+ assert typ.__name__ in types.__all__
+
+ @testing.combinations(
+ ((d.name, d) for d in _all_dialects()), argnames="dialect", id_="ia"
+ )
+ @testing.combinations(
+ (REAL(), "REAL"),
+ (FLOAT(), "FLOAT"),
+ (NUMERIC(), "NUMERIC"),
+ (DECIMAL(), "DECIMAL"),
+ (INTEGER(), "INTEGER"),
+ (SMALLINT(), "SMALLINT"),
+ (TIMESTAMP(), ("TIMESTAMP", "TIMESTAMP WITHOUT TIME ZONE")),
+ (DATETIME(), "DATETIME"),
+ (DATE(), "DATE"),
+ (TIME(), ("TIME", "TIME WITHOUT TIME ZONE")),
+ (CLOB(), "CLOB"),
+ (VARCHAR(10), ("VARCHAR(10)", "VARCHAR(10 CHAR)")),
+ (
+ NVARCHAR(10),
+ ("NVARCHAR(10)", "NATIONAL VARCHAR(10)", "NVARCHAR2(10)"),
+ ),
+ (CHAR(), "CHAR"),
+ (NCHAR(), ("NCHAR", "NATIONAL CHAR")),
+ (BLOB(), ("BLOB", "BLOB SUB_TYPE 0")),
+ (BOOLEAN(), ("BOOLEAN", "BOOL", "INTEGER")),
+ argnames="type_, expected",
+ id_="ra",
+ )
+ def test_uppercase_rendering(self, dialect, type_, expected):
"""Test that uppercase types from types.py always render as their
type.
@@ -133,51 +175,48 @@ class AdaptTest(fixtures.TestBase):
"""
- for dialect in self._all_dialects():
- for type_, expected in (
- (REAL, "REAL"),
- (FLOAT, "FLOAT"),
- (NUMERIC, "NUMERIC"),
- (DECIMAL, "DECIMAL"),
- (INTEGER, "INTEGER"),
- (SMALLINT, "SMALLINT"),
- (TIMESTAMP, ("TIMESTAMP", "TIMESTAMP WITHOUT TIME ZONE")),
- (DATETIME, "DATETIME"),
- (DATE, "DATE"),
- (TIME, ("TIME", "TIME WITHOUT TIME ZONE")),
- (CLOB, "CLOB"),
- (VARCHAR(10), ("VARCHAR(10)", "VARCHAR(10 CHAR)")),
- (
- NVARCHAR(10),
- ("NVARCHAR(10)", "NATIONAL VARCHAR(10)", "NVARCHAR2(10)"),
- ),
- (CHAR, "CHAR"),
- (NCHAR, ("NCHAR", "NATIONAL CHAR")),
- (BLOB, ("BLOB", "BLOB SUB_TYPE 0")),
- (BOOLEAN, ("BOOLEAN", "BOOL", "INTEGER")),
- ):
- if isinstance(expected, str):
- expected = (expected,)
+ if isinstance(expected, str):
+ expected = (expected,)
- try:
- compiled = types.to_instance(type_).compile(
- dialect=dialect
- )
- except NotImplementedError:
- continue
+ try:
+ compiled = type_.compile(dialect=dialect)
+ except NotImplementedError:
+ return
- assert compiled in expected, (
- "%r matches none of %r for dialect %s"
- % (compiled, expected, dialect.name)
- )
+ assert compiled in expected, "%r matches none of %r for dialect %s" % (
+ compiled,
+ expected,
+ dialect.name,
+ )
- assert str(types.to_instance(type_)) in expected, (
- "default str() of type %r not expected, %r"
- % (type_, expected)
- )
+ assert (
+ str(types.to_instance(type_)) in expected
+ ), "default str() of type %r not expected, %r" % (type_, expected)
+
+ def _adaptions():
+ for typ in _all_types(omit_special_types=True):
+
+ # up adapt from LowerCase to UPPERCASE,
+ # as well as to all non-sqltypes
+ up_adaptions = [typ] + typ.__subclasses__()
+ yield "%s.%s" % (
+ typ.__module__,
+ typ.__name__,
+ ), False, typ, up_adaptions
+ for subcl in typ.__subclasses__():
+ if (
+ subcl is not typ
+ and typ is not TypeDecorator
+ and "sqlalchemy" in subcl.__module__
+ ):
+ yield "%s.%s" % (
+ subcl.__module__,
+ subcl.__name__,
+ ), True, subcl, [typ]
@testing.uses_deprecated(".*Binary.*")
- def test_adapt_method(self):
+ @testing.combinations(_adaptions(), id_="iaaa")
+ def test_adapt_method(self, is_down_adaption, typ, target_adaptions):
"""ensure all types have a working adapt() method,
which creates a distinct copy.
@@ -190,67 +229,44 @@ class AdaptTest(fixtures.TestBase):
"""
- def adaptions():
- for typ in self._all_types():
- # up adapt from LowerCase to UPPERCASE,
- # as well as to all non-sqltypes
- up_adaptions = [typ] + typ.__subclasses__()
- yield False, typ, up_adaptions
- for subcl in typ.__subclasses__():
- if (
- subcl is not typ
- and typ is not TypeDecorator
- and "sqlalchemy" in subcl.__module__
- ):
- yield True, subcl, [typ]
-
- for is_down_adaption, typ, target_adaptions in adaptions():
- if typ in (types.TypeDecorator, types.TypeEngine, types.Variant):
+ if issubclass(typ, ARRAY):
+ t1 = typ(String)
+ else:
+ t1 = typ()
+ for cls in target_adaptions:
+ if (is_down_adaption and issubclass(typ, sqltypes.Emulated)) or (
+ not is_down_adaption and issubclass(cls, sqltypes.Emulated)
+ ):
continue
- elif issubclass(typ, ARRAY):
- t1 = typ(String)
- else:
- t1 = typ()
- for cls in target_adaptions:
- if (
- is_down_adaption and issubclass(typ, sqltypes.Emulated)
- ) or (
- not is_down_adaption and issubclass(cls, sqltypes.Emulated)
- ):
- continue
- if cls.__module__.startswith("test"):
+ # print("ADAPT %s -> %s" % (t1.__class__, cls))
+ t2 = t1.adapt(cls)
+ assert t1 is not t2
+
+ if is_down_adaption:
+ t2, t1 = t1, t2
+
+ for k in t1.__dict__:
+ if k in (
+ "impl",
+ "_is_oracle_number",
+ "_create_events",
+ "create_constraint",
+ "inherit_schema",
+ "schema",
+ "metadata",
+ "name",
+ ):
continue
+ # assert each value was copied, or that
+ # the adapted type has a more specific
+ # value than the original (i.e. SQL Server
+ # applies precision=24 for REAL)
+ assert (
+ getattr(t2, k) == t1.__dict__[k] or t1.__dict__[k] is None
+ )
- # print("ADAPT %s -> %s" % (t1.__class__, cls))
- t2 = t1.adapt(cls)
- assert t1 is not t2
-
- if is_down_adaption:
- t2, t1 = t1, t2
-
- for k in t1.__dict__:
- if k in (
- "impl",
- "_is_oracle_number",
- "_create_events",
- "create_constraint",
- "inherit_schema",
- "schema",
- "metadata",
- "name",
- ):
- continue
- # assert each value was copied, or that
- # the adapted type has a more specific
- # value than the original (i.e. SQL Server
- # applies precision=24 for REAL)
- assert (
- getattr(t2, k) == t1.__dict__[k]
- or t1.__dict__[k] is None
- )
-
- eq_(t1.evaluates_none().should_evaluate_none, True)
+ eq_(t1.evaluates_none().should_evaluate_none, True)
def test_python_type(self):
eq_(types.Integer().python_type, int)
@@ -270,15 +286,13 @@ class AdaptTest(fixtures.TestBase):
)
@testing.uses_deprecated()
- def test_repr(self):
- for typ in self._all_types():
- if typ in (types.TypeDecorator, types.TypeEngine, types.Variant):
- continue
- elif issubclass(typ, ARRAY):
- t1 = typ(String)
- else:
- t1 = typ()
- repr(t1)
+ @testing.combinations(*[(t,) for t in _all_types(omit_special_types=True)])
+ def test_repr(self, typ):
+ if issubclass(typ, ARRAY):
+ t1 = typ(String)
+ else:
+ t1 = typ()
+ repr(t1)
def test_adapt_constructor_copy_override_kw(self):
"""test that adapt() can accept kw args that override
@@ -299,27 +313,30 @@ class AdaptTest(fixtures.TestBase):
class TypeAffinityTest(fixtures.TestBase):
- def test_type_affinity(self):
- for type_, affin in [
- (String(), String),
- (VARCHAR(), String),
- (Date(), Date),
- (LargeBinary(), types._Binary),
- ]:
- eq_(type_._type_affinity, affin)
-
- for t1, t2, comp in [
- (Integer(), SmallInteger(), True),
- (Integer(), String(), False),
- (Integer(), Integer(), True),
- (Text(), String(), True),
- (Text(), Unicode(), True),
- (LargeBinary(), Integer(), False),
- (LargeBinary(), PickleType(), True),
- (PickleType(), LargeBinary(), True),
- (PickleType(), PickleType(), True),
- ]:
- eq_(t1._compare_type_affinity(t2), comp, "%s %s" % (t1, t2))
+ @testing.combinations(
+ (String(), String),
+ (VARCHAR(), String),
+ (Date(), Date),
+ (LargeBinary(), types._Binary),
+ id_="rn",
+ )
+ def test_type_affinity(self, type_, affin):
+ eq_(type_._type_affinity, affin)
+
+ @testing.combinations(
+ (Integer(), SmallInteger(), True),
+ (Integer(), String(), False),
+ (Integer(), Integer(), True),
+ (Text(), String(), True),
+ (Text(), Unicode(), True),
+ (LargeBinary(), Integer(), False),
+ (LargeBinary(), PickleType(), True),
+ (PickleType(), LargeBinary(), True),
+ (PickleType(), PickleType(), True),
+ id_="rra",
+ )
+ def test_compare_type_affinity(self, t1, t2, comp):
+ eq_(t1._compare_type_affinity(t2), comp, "%s %s" % (t1, t2))
def test_decorator_doesnt_cache(self):
from sqlalchemy.dialects import postgresql
@@ -340,30 +357,32 @@ class TypeAffinityTest(fixtures.TestBase):
class PickleTypesTest(fixtures.TestBase):
- def test_pickle_types(self):
+ @testing.combinations(
+ ("Boo", Boolean()),
+ ("Str", String()),
+ ("Tex", Text()),
+ ("Uni", Unicode()),
+ ("Int", Integer()),
+ ("Sma", SmallInteger()),
+ ("Big", BigInteger()),
+ ("Num", Numeric()),
+ ("Flo", Float()),
+ ("Dat", DateTime()),
+ ("Dat", Date()),
+ ("Tim", Time()),
+ ("Lar", LargeBinary()),
+ ("Pic", PickleType()),
+ ("Int", Interval()),
+ id_="ar",
+ )
+ def test_pickle_types(self, name, type_):
+ column_type = Column(name, type_)
+ meta = MetaData()
+ Table("foo", meta, column_type)
+
for loads, dumps in picklers():
- column_types = [
- Column("Boo", Boolean()),
- Column("Str", String()),
- Column("Tex", Text()),
- Column("Uni", Unicode()),
- Column("Int", Integer()),
- Column("Sma", SmallInteger()),
- Column("Big", BigInteger()),
- Column("Num", Numeric()),
- Column("Flo", Float()),
- Column("Dat", DateTime()),
- Column("Dat", Date()),
- Column("Tim", Time()),
- Column("Lar", LargeBinary()),
- Column("Pic", PickleType()),
- Column("Int", Interval()),
- ]
- for column_type in column_types:
- meta = MetaData()
- Table("foo", meta, column_type)
- loads(dumps(column_type))
- loads(dumps(meta))
+ loads(dumps(column_type))
+ loads(dumps(meta))
class _UserDefinedTypeFixture(object):
@@ -2414,19 +2433,19 @@ class ExpressionTest(
expr = column("foo", CHAR) == "asdf"
eq_(expr.right.type.__class__, CHAR)
- def test_actual_literal_adapters(self):
- for data, expected in [
- (5, Integer),
- (2.65, Float),
- (True, Boolean),
- (decimal.Decimal("2.65"), Numeric),
- (datetime.date(2015, 7, 20), Date),
- (datetime.time(10, 15, 20), Time),
- (datetime.datetime(2015, 7, 20, 10, 15, 20), DateTime),
- (datetime.timedelta(seconds=5), Interval),
- (None, types.NullType),
- ]:
- is_(literal(data).type.__class__, expected)
+ @testing.combinations(
+ (5, Integer),
+ (2.65, Float),
+ (True, Boolean),
+ (decimal.Decimal("2.65"), Numeric),
+ (datetime.date(2015, 7, 20), Date),
+ (datetime.time(10, 15, 20), Time),
+ (datetime.datetime(2015, 7, 20, 10, 15, 20), DateTime),
+ (datetime.timedelta(seconds=5), Interval),
+ (None, types.NullType),
+ )
+ def test_actual_literal_adapters(self, data, expected):
+ is_(literal(data).type.__class__, expected)
def test_typedec_operator_adapt(self):
expr = test_table.c.bvalue + "hi"
@@ -2592,18 +2611,22 @@ class ExpressionTest(
expr = column("bar", types.Interval) * column("foo", types.Numeric)
eq_(expr.type._type_affinity, types.Interval)
- def test_numerics_coercion(self):
-
- for op in (operator.add, operator.mul, operator.truediv, operator.sub):
- for other in (Numeric(10, 2), Integer):
- expr = op(
- column("bar", types.Numeric(10, 2)), column("foo", other)
- )
- assert isinstance(expr.type, types.Numeric)
- expr = op(
- column("foo", other), column("bar", types.Numeric(10, 2))
- )
- assert isinstance(expr.type, types.Numeric)
+ @testing.combinations(
+ (operator.add,),
+ (operator.mul,),
+ (operator.truediv,),
+ (operator.sub,),
+ argnames="op",
+ id_="n",
+ )
+ @testing.combinations(
+ (Numeric(10, 2),), (Integer(),), argnames="other", id_="r"
+ )
+ def test_numerics_coercion(self, op, other):
+ expr = op(column("bar", types.Numeric(10, 2)), column("foo", other))
+ assert isinstance(expr.type, types.Numeric)
+ expr = op(column("foo", other), column("bar", types.Numeric(10, 2)))
+ assert isinstance(expr.type, types.Numeric)
def test_asdecimal_int_to_numeric(self):
expr = column("a", Integer) * column("b", Numeric(asdecimal=False))