mirror of
https://github.com/janeczku/calibre-web
synced 2024-09-18 10:19:47 +00:00
394 lines
11 KiB
Python
394 lines
11 KiB
Python
# coding: utf-8
|
||
|
||
from .. import fixtures, config
|
||
from ..assertions import eq_
|
||
from ..config import requirements
|
||
from sqlalchemy import Integer, Unicode, UnicodeText, select
|
||
from sqlalchemy import Date, DateTime, Time, MetaData, String, \
|
||
Text, Numeric, Float
|
||
from ..schema import Table, Column
|
||
from ... import testing
|
||
import decimal
|
||
import datetime
|
||
|
||
|
||
class _UnicodeFixture(object):
|
||
__requires__ = 'unicode_data',
|
||
|
||
data = u"Alors vous imaginez ma surprise, au lever du jour, "\
|
||
u"quand une drôle de petite voix m’a réveillé. Elle "\
|
||
u"disait: « S’il vous plaît… dessine-moi un mouton! »"
|
||
|
||
@classmethod
|
||
def define_tables(cls, metadata):
|
||
Table('unicode_table', metadata,
|
||
Column('id', Integer, primary_key=True,
|
||
test_needs_autoincrement=True),
|
||
Column('unicode_data', cls.datatype),
|
||
)
|
||
|
||
def test_round_trip(self):
|
||
unicode_table = self.tables.unicode_table
|
||
|
||
config.db.execute(
|
||
unicode_table.insert(),
|
||
{
|
||
'unicode_data': self.data,
|
||
}
|
||
)
|
||
|
||
row = config.db.execute(
|
||
select([
|
||
unicode_table.c.unicode_data,
|
||
])
|
||
).first()
|
||
|
||
eq_(
|
||
row,
|
||
(self.data, )
|
||
)
|
||
assert isinstance(row[0], unicode)
|
||
|
||
def test_round_trip_executemany(self):
|
||
unicode_table = self.tables.unicode_table
|
||
|
||
config.db.execute(
|
||
unicode_table.insert(),
|
||
[
|
||
{
|
||
'unicode_data': self.data,
|
||
}
|
||
for i in xrange(3)
|
||
]
|
||
)
|
||
|
||
rows = config.db.execute(
|
||
select([
|
||
unicode_table.c.unicode_data,
|
||
])
|
||
).fetchall()
|
||
eq_(
|
||
rows,
|
||
[(self.data, ) for i in xrange(3)]
|
||
)
|
||
for row in rows:
|
||
assert isinstance(row[0], unicode)
|
||
|
||
def _test_empty_strings(self):
|
||
unicode_table = self.tables.unicode_table
|
||
|
||
config.db.execute(
|
||
unicode_table.insert(),
|
||
{"unicode_data": u''}
|
||
)
|
||
row = config.db.execute(
|
||
select([unicode_table.c.unicode_data])
|
||
).first()
|
||
eq_(row, (u'',))
|
||
|
||
|
||
class UnicodeVarcharTest(_UnicodeFixture, fixtures.TablesTest):
|
||
__requires__ = 'unicode_data',
|
||
|
||
datatype = Unicode(255)
|
||
|
||
@requirements.empty_strings_varchar
|
||
def test_empty_strings_varchar(self):
|
||
self._test_empty_strings()
|
||
|
||
|
||
class UnicodeTextTest(_UnicodeFixture, fixtures.TablesTest):
|
||
__requires__ = 'unicode_data', 'text_type'
|
||
|
||
datatype = UnicodeText()
|
||
|
||
@requirements.empty_strings_text
|
||
def test_empty_strings_text(self):
|
||
self._test_empty_strings()
|
||
|
||
class TextTest(fixtures.TablesTest):
|
||
@classmethod
|
||
def define_tables(cls, metadata):
|
||
Table('text_table', metadata,
|
||
Column('id', Integer, primary_key=True,
|
||
test_needs_autoincrement=True),
|
||
Column('text_data', Text),
|
||
)
|
||
|
||
def test_text_roundtrip(self):
|
||
text_table = self.tables.text_table
|
||
|
||
config.db.execute(
|
||
text_table.insert(),
|
||
{"text_data": 'some text'}
|
||
)
|
||
row = config.db.execute(
|
||
select([text_table.c.text_data])
|
||
).first()
|
||
eq_(row, ('some text',))
|
||
|
||
def test_text_empty_strings(self):
|
||
text_table = self.tables.text_table
|
||
|
||
config.db.execute(
|
||
text_table.insert(),
|
||
{"text_data": ''}
|
||
)
|
||
row = config.db.execute(
|
||
select([text_table.c.text_data])
|
||
).first()
|
||
eq_(row, ('',))
|
||
|
||
|
||
class StringTest(fixtures.TestBase):
|
||
@requirements.unbounded_varchar
|
||
def test_nolength_string(self):
|
||
metadata = MetaData()
|
||
foo = Table('foo', metadata,
|
||
Column('one', String)
|
||
)
|
||
|
||
foo.create(config.db)
|
||
foo.drop(config.db)
|
||
|
||
|
||
class _DateFixture(object):
|
||
compare = None
|
||
|
||
@classmethod
|
||
def define_tables(cls, metadata):
|
||
Table('date_table', metadata,
|
||
Column('id', Integer, primary_key=True,
|
||
test_needs_autoincrement=True),
|
||
Column('date_data', cls.datatype),
|
||
)
|
||
|
||
def test_round_trip(self):
|
||
date_table = self.tables.date_table
|
||
|
||
config.db.execute(
|
||
date_table.insert(),
|
||
{'date_data': self.data}
|
||
)
|
||
|
||
row = config.db.execute(
|
||
select([
|
||
date_table.c.date_data,
|
||
])
|
||
).first()
|
||
|
||
compare = self.compare or self.data
|
||
eq_(row,
|
||
(compare, ))
|
||
assert isinstance(row[0], type(compare))
|
||
|
||
def test_null(self):
|
||
date_table = self.tables.date_table
|
||
|
||
config.db.execute(
|
||
date_table.insert(),
|
||
{'date_data': None}
|
||
)
|
||
|
||
row = config.db.execute(
|
||
select([
|
||
date_table.c.date_data,
|
||
])
|
||
).first()
|
||
eq_(row, (None,))
|
||
|
||
|
||
class DateTimeTest(_DateFixture, fixtures.TablesTest):
|
||
__requires__ = 'datetime',
|
||
datatype = DateTime
|
||
data = datetime.datetime(2012, 10, 15, 12, 57, 18)
|
||
|
||
|
||
class DateTimeMicrosecondsTest(_DateFixture, fixtures.TablesTest):
|
||
__requires__ = 'datetime_microseconds',
|
||
datatype = DateTime
|
||
data = datetime.datetime(2012, 10, 15, 12, 57, 18, 396)
|
||
|
||
|
||
class TimeTest(_DateFixture, fixtures.TablesTest):
|
||
__requires__ = 'time',
|
||
datatype = Time
|
||
data = datetime.time(12, 57, 18)
|
||
|
||
|
||
class TimeMicrosecondsTest(_DateFixture, fixtures.TablesTest):
|
||
__requires__ = 'time_microseconds',
|
||
datatype = Time
|
||
data = datetime.time(12, 57, 18, 396)
|
||
|
||
|
||
class DateTest(_DateFixture, fixtures.TablesTest):
|
||
__requires__ = 'date',
|
||
datatype = Date
|
||
data = datetime.date(2012, 10, 15)
|
||
|
||
|
||
class DateTimeCoercedToDateTimeTest(_DateFixture, fixtures.TablesTest):
|
||
__requires__ = 'date',
|
||
datatype = Date
|
||
data = datetime.datetime(2012, 10, 15, 12, 57, 18)
|
||
compare = datetime.date(2012, 10, 15)
|
||
|
||
|
||
class DateTimeHistoricTest(_DateFixture, fixtures.TablesTest):
|
||
__requires__ = 'datetime_historic',
|
||
datatype = DateTime
|
||
data = datetime.datetime(1850, 11, 10, 11, 52, 35)
|
||
|
||
|
||
class DateHistoricTest(_DateFixture, fixtures.TablesTest):
|
||
__requires__ = 'date_historic',
|
||
datatype = Date
|
||
data = datetime.date(1727, 4, 1)
|
||
|
||
class NumericTest(fixtures.TestBase):
|
||
|
||
@testing.emits_warning(r".*does \*not\* support Decimal objects natively")
|
||
@testing.provide_metadata
|
||
def _do_test(self, type_, input_, output, filter_=None, check_scale=False):
|
||
metadata = self.metadata
|
||
t = Table('t', metadata, Column('x', type_))
|
||
t.create()
|
||
t.insert().execute([{'x':x} for x in input_])
|
||
|
||
result = set([row[0] for row in t.select().execute()])
|
||
output = set(output)
|
||
if filter_:
|
||
result = set(filter_(x) for x in result)
|
||
output = set(filter_(x) for x in output)
|
||
eq_(result, output)
|
||
if check_scale:
|
||
eq_(
|
||
[str(x) for x in result],
|
||
[str(x) for x in output],
|
||
)
|
||
|
||
def test_numeric_as_decimal(self):
|
||
self._do_test(
|
||
Numeric(precision=8, scale=4),
|
||
[15.7563, decimal.Decimal("15.7563"), None],
|
||
[decimal.Decimal("15.7563"), None],
|
||
)
|
||
|
||
def test_numeric_as_float(self):
|
||
self._do_test(
|
||
Numeric(precision=8, scale=4, asdecimal=False),
|
||
[15.7563, decimal.Decimal("15.7563"), None],
|
||
[15.7563, None],
|
||
)
|
||
|
||
def test_float_as_decimal(self):
|
||
self._do_test(
|
||
Float(precision=8, asdecimal=True),
|
||
[15.7563, decimal.Decimal("15.7563"), None],
|
||
[decimal.Decimal("15.7563"), None],
|
||
)
|
||
|
||
def test_float_as_float(self):
|
||
self._do_test(
|
||
Float(precision=8),
|
||
[15.7563, decimal.Decimal("15.7563")],
|
||
[15.7563],
|
||
filter_=lambda n: n is not None and round(n, 5) or None
|
||
)
|
||
|
||
@testing.requires.precision_numerics_general
|
||
def test_precision_decimal(self):
|
||
numbers = set([
|
||
decimal.Decimal("54.234246451650"),
|
||
decimal.Decimal("0.004354"),
|
||
decimal.Decimal("900.0"),
|
||
])
|
||
|
||
self._do_test(
|
||
Numeric(precision=18, scale=12),
|
||
numbers,
|
||
numbers,
|
||
)
|
||
|
||
@testing.requires.precision_numerics_enotation_large
|
||
def test_enotation_decimal(self):
|
||
"""test exceedingly small decimals.
|
||
|
||
Decimal reports values with E notation when the exponent
|
||
is greater than 6.
|
||
|
||
"""
|
||
|
||
numbers = set([
|
||
decimal.Decimal('1E-2'),
|
||
decimal.Decimal('1E-3'),
|
||
decimal.Decimal('1E-4'),
|
||
decimal.Decimal('1E-5'),
|
||
decimal.Decimal('1E-6'),
|
||
decimal.Decimal('1E-7'),
|
||
decimal.Decimal('1E-8'),
|
||
decimal.Decimal("0.01000005940696"),
|
||
decimal.Decimal("0.00000005940696"),
|
||
decimal.Decimal("0.00000000000696"),
|
||
decimal.Decimal("0.70000000000696"),
|
||
decimal.Decimal("696E-12"),
|
||
])
|
||
self._do_test(
|
||
Numeric(precision=18, scale=14),
|
||
numbers,
|
||
numbers
|
||
)
|
||
|
||
@testing.requires.precision_numerics_enotation_large
|
||
def test_enotation_decimal_large(self):
|
||
"""test exceedingly large decimals.
|
||
|
||
"""
|
||
|
||
numbers = set([
|
||
decimal.Decimal('4E+8'),
|
||
decimal.Decimal("5748E+15"),
|
||
decimal.Decimal('1.521E+15'),
|
||
decimal.Decimal('00000000000000.1E+12'),
|
||
])
|
||
self._do_test(
|
||
Numeric(precision=25, scale=2),
|
||
numbers,
|
||
numbers
|
||
)
|
||
|
||
@testing.requires.precision_numerics_many_significant_digits
|
||
def test_many_significant_digits(self):
|
||
numbers = set([
|
||
decimal.Decimal("31943874831932418390.01"),
|
||
decimal.Decimal("319438950232418390.273596"),
|
||
decimal.Decimal("87673.594069654243"),
|
||
])
|
||
self._do_test(
|
||
Numeric(precision=38, scale=12),
|
||
numbers,
|
||
numbers
|
||
)
|
||
|
||
@testing.requires.precision_numerics_retains_significant_digits
|
||
def test_numeric_no_decimal(self):
|
||
numbers = set([
|
||
decimal.Decimal("1.000")
|
||
])
|
||
self._do_test(
|
||
Numeric(precision=5, scale=3),
|
||
numbers,
|
||
numbers,
|
||
check_scale=True
|
||
)
|
||
|
||
|
||
|
||
__all__ = ('UnicodeVarcharTest', 'UnicodeTextTest',
|
||
'DateTest', 'DateTimeTest', 'TextTest',
|
||
'NumericTest',
|
||
'DateTimeHistoricTest', 'DateTimeCoercedToDateTimeTest',
|
||
'TimeMicrosecondsTest', 'TimeTest', 'DateTimeMicrosecondsTest',
|
||
'DateHistoricTest', 'StringTest')
|