summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/testing
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-03-13 18:54:56 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2014-03-13 18:54:56 -0400
commit8433a48fabbb77bfc99434fc915b9a5ccd427f43 (patch)
treefb76f91a906d9964f2bffda8a76870a6003038dd /lib/sqlalchemy/testing
parent36792434c74dea43a0f10f5fe1cc45c4206f01ee (diff)
downloadsqlalchemy-8433a48fabbb77bfc99434fc915b9a5ccd427f43.tar.gz
- add more support for suite tests, moving some tests from test_query out to suite
and adding some more requirements
Diffstat (limited to 'lib/sqlalchemy/testing')
-rw-r--r--lib/sqlalchemy/testing/exclusions.py2
-rw-r--r--lib/sqlalchemy/testing/requirements.py34
-rw-r--r--lib/sqlalchemy/testing/suite/test_results.py155
3 files changed, 185 insertions, 6 deletions
diff --git a/lib/sqlalchemy/testing/exclusions.py b/lib/sqlalchemy/testing/exclusions.py
index bcd593708..00bb69cbc 100644
--- a/lib/sqlalchemy/testing/exclusions.py
+++ b/lib/sqlalchemy/testing/exclusions.py
@@ -318,6 +318,8 @@ def open():
def closed():
return skip_if(BooleanPredicate(True, "marked as skip"))
+def fails():
+ return fails_if(BooleanPredicate(True, "expected to fail"))
@decorator
def future(fn, *arg):
diff --git a/lib/sqlalchemy/testing/requirements.py b/lib/sqlalchemy/testing/requirements.py
index 5dd2435d7..8591e7a16 100644
--- a/lib/sqlalchemy/testing/requirements.py
+++ b/lib/sqlalchemy/testing/requirements.py
@@ -174,6 +174,13 @@ class SuiteRequirements(Requirements):
)
@property
+ def duplicate_names_in_cursor_description(self):
+ """target platform supports a SELECT statement that has
+ the same name repeated more than once in the columns list."""
+
+ return exclusions.open()
+
+ @property
def denormalized_names(self):
"""Target database must have 'denormalized', i.e.
UPPERCASE as case insensitive names."""
@@ -514,6 +521,33 @@ class SuiteRequirements(Requirements):
return exclusions.closed()
@property
+ def percent_schema_names(self):
+ """target backend supports weird identifiers with percent signs
+ in them, e.g. 'some % column'.
+
+ this is a very weird use case but often has problems because of
+ DBAPIs that use python formatting. It's not a critical use
+ case either.
+
+ """
+ return exclusions.closed()
+
+ @property
+ def order_by_label_with_expression(self):
+ """target backend supports ORDER BY a column label within an
+ expression.
+
+ Basically this::
+
+ select data as foo from test order by foo || 'bar'
+
+ Lots of databases including Postgresql don't support this,
+ so this is off by default.
+
+ """
+ return exclusions.closed()
+
+ @property
def unicode_connections(self):
"""Target driver must support non-ASCII characters being passed at all."""
return exclusions.open()
diff --git a/lib/sqlalchemy/testing/suite/test_results.py b/lib/sqlalchemy/testing/suite/test_results.py
index b0265f7b5..ceb7e7828 100644
--- a/lib/sqlalchemy/testing/suite/test_results.py
+++ b/lib/sqlalchemy/testing/suite/test_results.py
@@ -4,8 +4,8 @@ from .. import exclusions
from ..assertions import eq_
from .. import engines
-from sqlalchemy import Integer, String, select, util
-
+from sqlalchemy import Integer, String, select, util, sql, DateTime
+import datetime
from ..schema import Table, Column
@@ -18,15 +18,26 @@ class RowFetchTest(fixtures.TablesTest):
Column('id', Integer, primary_key=True),
Column('data', String(50))
)
+ Table('has_dates', metadata,
+ Column('id', Integer, primary_key=True),
+ Column('today', DateTime)
+ )
@classmethod
def insert_data(cls):
config.db.execute(
cls.tables.plain_pk.insert(),
[
- {"id":1, "data":"d1"},
- {"id":2, "data":"d2"},
- {"id":3, "data":"d3"},
+ {"id": 1, "data": "d1"},
+ {"id": 2, "data": "d2"},
+ {"id": 3, "data": "d3"},
+ ]
+ )
+
+ config.db.execute(
+ cls.tables.has_dates.insert(),
+ [
+ {"id": 1, "today": datetime.datetime(2006, 5, 12, 12, 0, 0)}
]
)
@@ -67,4 +78,136 @@ class RowFetchTest(fixtures.TablesTest):
)
eq_(
row[self.tables.plain_pk.c.data], "d1"
- ) \ No newline at end of file
+ )
+
+ @requirements.duplicate_names_in_cursor_description
+ def test_row_with_dupe_names(self):
+ result = config.db.execute(
+ select([self.tables.plain_pk.c.data,
+ self.tables.plain_pk.c.data.label('data')]).\
+ order_by(self.tables.plain_pk.c.id)
+ )
+ row = result.first()
+ eq_(result.keys(), ['data', 'data'])
+ eq_(row, ('d1', 'd1'))
+
+
+ def test_row_w_scalar_select(self):
+ datetable = self.tables.has_dates
+ s = select([datetable.alias('x').c.today]).as_scalar()
+ s2 = select([datetable.c.id, s.label('somelabel')])
+ row = config.db.execute(s2).first()
+
+ eq_(row['somelabel'], datetime.datetime(2006, 5, 12, 12, 0, 0))
+
+
+class PercentSchemaNamesTest(fixtures.TablesTest):
+ """tests using percent signs, spaces in table and column names.
+
+ This is a very fringe use case, doesn't work for MySQL
+ or Postgresql. the requirement, "percent_schema_names",
+ is marked "skip" by default.
+
+ """
+
+ __requires__ = ('percent_schema_names', )
+
+ __multiple__ = True
+
+ @classmethod
+ def define_tables(cls, metadata):
+ cls.tables.percent_table = Table('percent%table', metadata,
+ Column("percent%", Integer),
+ Column("spaces % more spaces", Integer),
+ )
+ cls.tables.lightweight_percent_table = sql.table('percent%table',
+ sql.column("percent%"),
+ sql.column("spaces % more spaces"),
+ )
+
+ def test_single_roundtrip(self):
+ percent_table = self.tables.percent_table
+ for params in [
+ {'percent%': 5, 'spaces % more spaces': 12},
+ {'percent%': 7, 'spaces % more spaces': 11},
+ {'percent%': 9, 'spaces % more spaces': 10},
+ {'percent%': 11, 'spaces % more spaces': 9}
+ ]:
+ config.db.execute(percent_table.insert(), params)
+ self._assert_table()
+
+ def test_executemany_roundtrip(self):
+ percent_table = self.tables.percent_table
+ config.db.execute(
+ percent_table.insert(),
+ {'percent%': 5, 'spaces % more spaces': 12}
+ )
+ config.db.execute(
+ percent_table.insert(),
+ [{'percent%': 7, 'spaces % more spaces': 11},
+ {'percent%': 9, 'spaces % more spaces': 10},
+ {'percent%': 11, 'spaces % more spaces': 9}]
+ )
+ self._assert_table()
+
+ def _assert_table(self):
+ percent_table = self.tables.percent_table
+ lightweight_percent_table = self.tables.lightweight_percent_table
+
+ for table in (
+ percent_table,
+ percent_table.alias(),
+ lightweight_percent_table,
+ lightweight_percent_table.alias()):
+ eq_(
+ list(
+ config.db.execute(
+ table.select().order_by(table.c['percent%'])
+ )
+ ),
+ [
+ (5, 12),
+ (7, 11),
+ (9, 10),
+ (11, 9)
+ ]
+ )
+
+ eq_(
+ list(
+ config.db.execute(
+ table.select().
+ where(table.c['spaces % more spaces'].in_([9, 10])).
+ order_by(table.c['percent%']),
+ )
+ ),
+ [
+ (9, 10),
+ (11, 9)
+ ]
+ )
+
+ row = config.db.execute(table.select().\
+ order_by(table.c['percent%'])).first()
+ eq_(row['percent%'], 5)
+ eq_(row['spaces % more spaces'], 12)
+
+ eq_(row[table.c['percent%']], 5)
+ eq_(row[table.c['spaces % more spaces']], 12)
+
+ config.db.execute(
+ percent_table.update().values(
+ {percent_table.c['spaces % more spaces']: 15}
+ )
+ )
+
+ eq_(
+ list(
+ config.db.execute(
+ percent_table.\
+ select().\
+ order_by(percent_table.c['percent%'])
+ )
+ ),
+ [(5, 15), (7, 15), (9, 15), (11, 15)]
+ )