def test_DateTime(): d1 = DateTime('2018-12-01') assert DateTime.from_db('2018-12-01 00:00:00') == d1 assert DateTime.fromtimestamp(d1.epoch()) == d1 assert DateTime.strptime('2018/12/01', '%Y/%m/%d') == d1 ts1 = timedelta(seconds=1) assert d1 + 1 == d1 + ts1 == DateTime('2018-12-01 00:00:01') assert d1 - 1 == d1 - ts1 == DateTime('2018-11-30 23:59:59') assert d1 != Date('2018-12-01') assert_eq(d1, DateTime('2018-12-01')) assert d1 != date(2018, 12, 1) assert_eq(d1, datetime(2018, 12, 1)) assert_gt(d1, Date('2018-11-30')) assert_gt(d1, DateTime('2018-11-30 23:59:59')) assert_gt(d1, date(2018, 11, 30)) assert_gt(d1, datetime(2018, 11, 30, 23, 59, 59)) assert {d1: d1}[DateTime('2018-12-01')] == d1 assert str(d1) == '2018-12-01 00:00:00' assert d1.add(months=1, day=2) == DateTime('2019-01-02') assert d1.date() == Date('2018-12-01') assert d1.day == 1 assert d1.month == 12 assert d1.weekday() == date(2018, 12, 1).weekday() assert d1.year == 2018 d2 = d1 - 2 assert d2.hour == 23 assert d2.minute == 59 assert d2.second == 58 assert d2.tzinfo is None # == TZ assert DateTime('2018-12-01 00:00:00Z').tzinfo.utcoffset(None).seconds == 0 assert DateTime('2018-12-01').is_valid() assert DateTime('2018-12-01 00').is_valid() assert DateTime('2018-12-01 00:00:00').is_valid() assert DateTime('2018-12-01 00:00:00Z').is_valid() assert DateTime('2018-12-01 00:00:00+0900').is_valid() assert DateTime('2018-12-01 00:00:00+09:00').is_valid() assert not DateTime('2018/12/01T00:00:00').is_valid() assert Util.json_dumps([d1]) == '["2018-12-01 00:00:00"]' assert DateTime.from_db('2018-12-01 00:00:00').date() == \ Date('2018-12-01') assert DateTime.from_db('2018-12-01 00:00:00.000123').microsecond == 123
def test_validate_range(): es = Errors() assert es.clear().validate(None, 3, range=(3, 3)) assert not es assert not es.clear().validate(None, 2, range=(3, 4)) assert es.get(None) == [errors.TOO_LITTLE(3)] assert not es.clear().validate(None, 4, range=(2, 3)) assert es.get(None) == [errors.TOO_GREAT(3)] t = DateTime('2018-03-23 11:30:00') e = t.epoch() assert es.validate(None, t, range=(e, e)) assert es.validate(None, t, range=(t, t)) assert not es.clear().validate(None, t - 1, range=(t, None)) assert es.get(None) == [errors.TOO_EARLY('2018-03-23 11:30')] assert not es.clear().validate(None, t, range=(e + 1, None)) assert es.get(None) == [errors.TOO_EARLY('2018-03-23 11:30:01')] assert not es.clear().validate(None, t + 1, range=(None, e)) assert es.get(None) == [errors.TOO_LATE('2018-03-23 11:30')] assert not es.clear().validate(None, t, range=(None, t - 1)) assert es.get(None) == [errors.TOO_LATE('2018-03-23 11:29:59')] d = Date('2018-03-23') e = d.epoch() assert es.validate(None, d, range=(e, e)) assert es.validate(None, d, range=(d, d)) assert not es.clear().validate(None, d, range=(e + 1, None)) assert es.get(None) == [errors.TOO_EARLY('2018-03-24')] assert not es.clear().validate(None, d, range=(d + 1, None)) assert es.get(None) == [errors.TOO_EARLY('2018-03-24')] assert not es.clear().validate(None, d, range=(None, e - 1)) assert es.get(None) == [errors.TOO_LATE('2018-03-22')] assert not es.clear().validate(None, d, range=(None, d - 1)) assert es.get(None) == [errors.TOO_LATE('2018-03-22')]
def test_Util_str2val(): s2v = Util.str2val assert s2v(False, bool) is False assert s2v(True, bool) is True assert s2v(0, bool) is False assert s2v(1, bool) is True assert s2v(2, bool) == 2 assert s2v('', bool) is None assert s2v('0', bool) is False assert s2v('1', bool) is True assert s2v('2', bool) == '2' assert s2v(10, int) == 10 assert s2v(0.1, int) == 0.1 assert s2v('', int) is None assert s2v('10', int) == 10 assert s2v('-1', int) == -1 assert s2v('0.1', int) == '0.1' assert s2v('a', int) == 'a' assert s2v('1,000', int) == '1,000' assert s2v('1,000', int, False) == 1000 d = Date('2019-01-31') assert s2v('', Date) is None assert s2v(d, Date) == d assert s2v('2019-01-31', Date) == d assert s2v('2019-01-32', Date) == '2019-01-32' dt = DateTime('2019-01-31 01:23:00') assert s2v('', DateTime) is None assert s2v(dt, DateTime) == dt assert s2v('2019-01-31 01:23:00', DateTime) == dt assert s2v('2019-01-31 01:23', DateTime) == '2019-01-31 01:23' assert s2v('2019-01-31 01:23', DateTime, None) == dt assert s2v('2019-01-31 01:23:60', DateTime) == '2019-01-31 01:23:60' with pytest.raises(KeyError): s2v(1, list)
def test_BELONGS_TO(): class Base(model.Model): DB = database.Database() class Foo(Base): DB_TABLE = 'foos' id = INT(auto_increment=True, primary_key=True) class Bar(Base): DB_TABLE = 'bars' id = INT(auto_increment=True, primary_key=True) foo_id = BELONGS_TO(Foo) assert '%r' % Bar.id == 'Bar.id' assert '%r' % Bar.foo_id == 'Bar.foo_id' bar = Bar() assert bar.foo_id is None assert bar.__dict__ == {} assert 'foo_id' not in bar foo = bar.foo = instantiate(Foo, id=10) assert bar.__dict__ == {'foo': foo, 'foo_id': 10} assert 'foo_id' in bar assert bar.foo_id == 10 assert bar.foo is foo foo.id = 11 assert bar.__dict__ == {'foo': foo, 'foo_id': 10} assert bar.foo_id == 10 assert bar.is_changed(txn={}) == {'foo_id': 10} assert bar.__dict__ == {'foo': foo, 'foo_id': 10} bar.foo_id = 11 assert bar.__dict__ == {'foo': foo, 'foo_id': 11} assert bar.foo_id == 11 assert bar.foo is foo bar.foo_id = 12 assert bar.__dict__ == {'foo_id': 12} assert 'foo' not in bar.__dict__ assert bar.foo_id == 12 bar = Bar() assert bar.foo_id is None foo = bar.foo = Foo() foo.id = 13 assert bar.foo_id == 13 assert bar.__dict__ == {'foo': foo} bar = Bar() assert not bar.is_valid() assert 'foo_id' not in bar bar = Bar() foo = bar.foo = Foo() assert bar.__dict__ == {'foo': foo} assert 'foo_id' not in bar assert bar.is_valid() del bar.__dict__['foo'] assert not bar.is_valid() del bar.__dict__['errors'] bar.foo = None assert bar.__dict__ == {'foo': None, 'foo_id': None} assert not bar.is_valid() bar.foo_id = 'abc' assert bar.foo is None assert not bar.is_valid() assert Bar.foo_id.db_type() == 'INT' class DatePk(Base): DB_TABLE = 'date_pks' id = DATE(primary_key=True) class StrPk(Base): DB_TABLE = 'str_pks' id = VARCHAR(primary_key=True) class Foo(Base): DB_TABLE = 'foos' id = SERIAL() date_pk_id = BELONGS_TO(DatePk) str_pk_id = BELONGS_TO(StrPk) assert Foo.ddl_sqls() == [ 'CREATE TABLE foos (\n' ' id SERIAL PRIMARY KEY,\n' ' date_pk_id DATE NOT NULL,\n' ' str_pk_id VARCHAR(255) NOT NULL,\n' ' FOREIGN KEY (date_pk_id) REFERENCES date_pks (id),\n' ' FOREIGN KEY (str_pk_id) REFERENCES str_pks (id)\n' ')', 'CREATE INDEX foos_date_pk_id ON foos (date_pk_id)', 'CREATE INDEX foos_str_pk_id ON foos (str_pk_id)' ] foo = Foo().set_items(date_pk_id='2020-01-27', str_pk_id='aaa') assert foo.date_pk_id == Date('2020-01-27') assert foo.is_valid()
def test_types(): class Base(model.Model): DB = database.Database() class Foo(Base): DB_TABLE = 'foos' c1 = INT() c2 = BOOL() c3 = DATE() c4 = DATETIME() c5 = VARCHAR() c6 = VARCHAR(null=True, blank=False) c7 = TEXT(null=True, validate=dict(re=r'\Ax')) c8 = BLOB(null=True) assert type(Foo.c7.validate['re']) is SRE_Pattern foo = Foo() assert not foo.is_valid() assert foo.errors == { 'c1': [errors.BLANK], 'c2': [errors.BLANK], 'c3': [errors.BLANK], 'c4': [errors.BLANK], 'c5': [errors.BLANK], } foo['c1'] = 'a' foo['c2'] = 'a' foo['c3'] = 'a' foo['c4'] = 'a' foo['c5'] = "\x00" foo['c7'] = "x\x00" foo['c8'] = "\x00" assert foo.c8 == b"\0" assert not foo.is_valid() assert foo.errors == { 'c1': [errors.BAD_FORMAT], 'c2': [errors.BAD_FORMAT], 'c3': [errors.BAD_FORMAT], 'c4': [errors.BAD_FORMAT], 'c5': [errors.BAD_CHARS("'\\x00'")], 'c7': [errors.BAD_CHARS("'\\x00'")], } foo['c1'] = '2147483648' foo['c2'] = '2' foo['c3'] = '2000-00-00' foo['c4'] = '2000-00-00 00:00:00' foo['c5'] = "\n" foo['c6'] = "\r" foo['c7'] = "x\r" foo['c8'] = "\n" assert foo.c8 == b"\n" assert not foo.is_valid() assert foo.errors == { 'c1': [errors.TOO_GREAT(2147483647)], 'c2': [errors.BAD_FORMAT], 'c3': [errors.BAD_FORMAT], 'c4': [errors.BAD_FORMAT], 'c5': [errors.BAD_CHARS('[LF]')], 'c6': [errors.BAD_CHARS('[CR]')], 'c7': [errors.BAD_CHARS('[CR]')], } foo['c1'] = '-2147483648' foo['c2'] = '0' foo['c3'] = '2000-01-01' foo['c4'] = '2000-01-01 00:00:00' foo['c5'] = " " foo['c6'] = '' foo['c7'] = "x\n" assert foo.is_valid() assert foo.errors == {} foo['c1'] = '' assert foo.c1 is None foo['c1'] = '-12' assert foo.c1 == -12 foo['c1'] = 'a' assert foo.c1 == 'a' foo['c1'] = 123 assert foo.c1 == 123 foo['c2'] = '' assert foo.c2 is None foo['c2'] = '1' assert foo.c2 is True foo['c2'] = '0' assert foo.c2 is False foo['c2'] = 'T' assert foo.c2 == 'T' foo['c2'] = True assert foo.c2 is True foo['c3'] = '' assert foo.c3 is None foo['c3'] = '2000-01-01' assert foo.c3 == Date('2000-01-01') foo['c3'] = '2000-02-30' assert foo.c3 == '2000-02-30' foo['c4'] = '' assert foo.c4 is None dt = DateTime('2000-01-01 00:00:00') foo['c4'] = '2000-01-01' assert foo.c4 == dt foo['c4'] = '2000-01-01 00' assert foo.c4 == dt foo['c4'] = '2000-01-01 00:00' assert foo.c4 == dt foo['c4'] = '2000-01-01 00:00:00' assert foo.c4 == dt foo['c4'] = '2000-02-30 00:00:00' assert foo.c4 == '2000-02-30 00:00:00' foo['c5'] = foo['c6'] = '' assert foo.c5 == '' assert foo.c6 is None assert type(NOW(foo)) is DateTime assert type(TODAY(foo)) is Date
def test_find(): Base, User, Foo, Bar, Baz = models() with pytest.raises(TypeError): Baz.find(1) with pytest.raises(TypeError): Bar.find(1, 2) with pytest.raises(TypeError): Bar.find(SQL('1')) with pytest.raises(RecordNotFound): Bar.find(None) with pytest.raises(RecordNotFound): Bar.find('2019-02-31') class Baz(Base): DB_TABLE = 'bazs' id = DATE(primary_key=True) name = VARCHAR() baz = Baz(id=Date('2019-01-01'), name='?') Base.DB.find_cache = {(Baz.DB_TABLE, baz.id): baz} assert Baz.find('2019-01-01') is baz Base.DB.find_cache = None with pytest.raises(TypeError): Bar.find(IN(1, 2, 3)) with pytest.raises(NotImplementedError): Baz.find_by(id=IN(1, 2, 3)) fc = Base.DB.find_cache = {} dt1 = Date('2019-01-01') Base.DB.execute = r2csr(id=dt1) Baz.where().select('id').peek() assert not fc Base.DB.execute = r2csr(id=dt1, name='A') baz1 = Baz.where().select('*').peek() assert baz1.name == 'A' assert fc == {('bazs', dt1): baz1} assert Baz.find_by(id='2019-01-01') is baz1 assert Baz.find_by(name='A') is not baz1 dt2 = Date('2019-01-02') baz1.id += 1 args = [] Base.DB.execute = lambda *a: args.append(a) or 1 assert baz1.update() == 1 assert args == [( 'UPDATE bazs t1 SET id = %s WHERE id = %s', (Date('2019-01-02'), Date('2019-01-01')), int)] assert fc == {('bazs', dt2): baz1} assert Baz.find_by(id='2019-01-02') is baz1 assert baz1.delete() == 1 assert fc == {}
def test_Date_compat(): d0 = date(2019, 12, 4) d1 = Date('2019-12-04') assert d1 == d0 assert d0 == d1 assert str(d1) == str(d0) == '2019-12-04' assert isinstance(d1, Date) assert not isinstance(d1, DateTime) assert isinstance(d1, date) assert not isinstance(d1, datetime) assert len({d0, d1}) == 1 with pytest.raises(AttributeError) as e: d1.xxx assert e.value.args == ("'Date' object has no attribute 'xxx'", ) with pytest.raises(AttributeError) as e: d1.yyy = 100 assert e.value.args == ("'Date' object has no attribute 'yyy'", ) d2 = Date('2019-12-06') dt0 = datetime(2019, 12, 4) dt2 = DateTime('2019-12-04 00:00:02') for x in ( (d0, d0, dict(seconds=0)), (d2, d0, dict(days=2)), (dt0, d0, None), (dt2, d0, None), (d0, d2, dict(days=-2)), (d2, d2, dict(seconds=0)), (dt0, d2, None), (dt2, d2, None), (d0, dt0, None), (d2, dt0, None), (dt0, dt0, dict(seconds=0)), (dt2, dt0, dict(seconds=2)), (d0, dt2, None), (d2, dt2, None), (dt0, dt2, dict(days=-1, seconds=86398)), (dt2, dt2, dict(seconds=0)), ): # print(x) if x[2] is None: with pytest.raises(TypeError) as e: x[0] - x[1] assert e.value.args[0].startswith('unsupported operand') else: assert (x[0] - x[1]) == timedelta(**x[2]) assert d1.ctime() == d0.ctime() == 'Wed Dec 4 00:00:00 2019' for m in (date.ctime, Date.ctime): with pytest.raises(TypeError): m() assert d1.day == d0.day == 4 assert '%r' % Date.fromordinal(737397) == \ '%r' % d1.fromordinal(737397) == "Date('2019-12-04')" assert '%r' % date.fromordinal(737397) == \ '%r' % d0.fromordinal(737397) == 'datetime.date(2019, 12, 4)' e1 = d1.epoch() assert '%r' % Date.fromtimestamp(e1) == \ '%r' % d1.fromtimestamp(e1) == "Date('2019-12-04')" assert '%r' % date.fromtimestamp(e1) == \ '%r' % d0.fromtimestamp(e1) == 'datetime.date(2019, 12, 4)' assert d1.isocalendar() == d0.isocalendar() == (2019, 49, 3) for m in (Date.isocalendar, date.isocalendar): with pytest.raises(TypeError): m() assert d1.isoformat() == d0.isoformat() == '2019-12-04' for m in (Date.isoformat, date.isoformat): with pytest.raises(TypeError): m() assert d1.isoweekday() == d0.isoweekday() == 3 for m in (Date.isoweekday, date.isoweekday): with pytest.raises(TypeError): m() assert '%r' % [d1.min, d1.max] == \ "[Date('0001-01-01'), Date('9999-12-31')]" assert '%r' % [d0.min, d0.max] == \ '[datetime.date(1, 1, 1), datetime.date(9999, 12, 31)]' assert d1.min == d0.min assert d0.max == d1.max assert d1.month == d0.month == 12 assert '%r' % d1.replace(day=5) == "Date('2019-12-05')" assert '%r' % d0.replace(day=5) == 'datetime.date(2019, 12, 5)' for m in (Date.replace, date.replace): with pytest.raises(TypeError): m(day=5) assert d1.resolution == d0.resolution assert d1.strftime('%F') == d0.strftime('%F') == '2019-12-04' for m in (Date.strftime, date.strftime): with pytest.raises(TypeError): m('%F') assert d1.timetuple() == d0.timetuple() for m in (Date.timetuple, date.timetuple): with pytest.raises(TypeError): m() assert Date.today() == d1.today() == date.today() == d0.today() assert d1.toordinal() == d0.toordinal() == 737397 for m in (Date.toordinal, date.toordinal): with pytest.raises(TypeError): m() assert d1.weekday() == d0.weekday() == 2 for m in (Date.weekday, date.weekday): with pytest.raises(TypeError): m() assert d1.year == d0.year == 2019 dt = DateTime.from_db('2020-02-01 00:00:00.000001') assert str(dt + 1) == '2020-02-01 00:00:01.000001' dt = DateTime.from_db('2020-02-01 00:00:00.1') assert str(dt + 1) == '2020-02-01 00:00:01.100000'
def test_Date(): d1 = Date('2018-12-01') assert Date.from_db('2018-12-01') == d1 assert Date.fromtimestamp(d1.epoch()) == d1 # assert Date.strptime('2018/12/01', '%Y/%m/%d') == d1 assert d1 + 1 == d1 + timedelta(days=1) == Date('2018-12-02') assert d1 - 1 == d1 - timedelta(days=1) == Date('2018-11-30') assert_eq(d1, Date('2018-12-01')) assert d1 != DateTime('2018-12-01') assert_eq(d1, date(2018, 12, 1)) assert d1 != datetime(2018, 12, 1) assert_gt(d1, Date('2018-11-30')) assert_gt(d1, DateTime('2018-11-30 23:59:59')) assert_gt(d1, date(2018, 11, 30)) assert_gt(d1, datetime(2018, 11, 30, 23, 59, 59)) assert {d1: d1}[Date('2018-12-01')] == d1 assert str(d1) == '2018-12-01' assert d1.add(months=1, day=2) == Date('2019-01-02') assert d1.datetime() == DateTime('2018-12-01') assert d1.day == 1 assert d1.month == 12 assert d1.weekday() == date(2018, 12, 1).weekday() assert d1.year == 2018 assert Date('2018-12-01').is_valid() assert not Date('2018/12/01').is_valid() assert Util.json_dumps([d1]) == '["2018-12-01"]' assert Date.from_db('2018-12-01').datetime() == \ DateTime('2018-12-01 00:00:00')