File: test_timezone.py

package info (click to toggle)
python-sqlalchemy-utils 0.41.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,252 kB
  • sloc: python: 13,566; makefile: 141
file content (122 lines) | stat: -rw-r--r-- 3,603 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import pytest
import pytz
import sqlalchemy as sa
from dateutil.zoneinfo import get_zonefile_instance, tzfile

try:
    import zoneinfo
except ImportError:
    from backports import zoneinfo

from sqlalchemy_utils.compat import _select_args
from sqlalchemy_utils.types import timezone, TimezoneType


@pytest.fixture
def Visitor(Base):
    class Visitor(Base):
        __tablename__ = 'visitor'
        id = sa.Column(sa.Integer, primary_key=True)
        timezone_dateutil = sa.Column(
            timezone.TimezoneType(backend='dateutil')
        )
        timezone_pytz = sa.Column(
            timezone.TimezoneType(backend='pytz')
        )
        timezone_zoneinfo = sa.Column(
            timezone.TimezoneType(backend='zoneinfo')
        )

        def __repr__(self):
            return 'Visitor(%r)' % self.id
    return Visitor


@pytest.fixture
def init_models(Visitor):
    pass


class TestTimezoneType:
    def test_parameter_processing(self, session, Visitor):
        visitor = Visitor(
            timezone_dateutil='America/Los_Angeles',
            timezone_pytz='America/Los_Angeles',
            timezone_zoneinfo='America/Los_Angeles'
        )

        session.add(visitor)
        session.commit()

        visitor_dateutil = session.query(Visitor).filter_by(
            timezone_dateutil='America/Los_Angeles'
        ).first()
        visitor_pytz = session.query(Visitor).filter_by(
            timezone_pytz='America/Los_Angeles'
        ).first()
        visitor_zoneinfo = session.query(Visitor).filter_by(
            timezone_zoneinfo='America/Los_Angeles'
        ).first()

        assert visitor_dateutil is not None
        assert visitor_pytz is not None
        assert visitor_zoneinfo is not None

    def test_compilation(self, Visitor, session):
        query = sa.select(*_select_args(Visitor.timezone_pytz))
        # the type should be cacheable and not throw exception
        session.execute(query)


TIMEZONE_BACKENDS = ['dateutil', 'pytz', 'zoneinfo']


def test_can_coerce_pytz_DstTzInfo():
    tzcol = TimezoneType(backend='pytz')
    tz = pytz.timezone('America/New_York')
    assert isinstance(tz, pytz.tzfile.DstTzInfo)
    assert tzcol._coerce(tz) is tz


def test_can_coerce_pytz_StaticTzInfo():
    tzcol = TimezoneType(backend='pytz')
    tz = pytz.timezone('Pacific/Truk')
    assert tzcol._coerce(tz) is tz


@pytest.mark.parametrize('zone', pytz.all_timezones)
def test_can_coerce_string_for_pytz_zone(zone):
    tzcol = TimezoneType(backend='pytz')
    assert tzcol._coerce(zone).zone == zone


@pytest.mark.parametrize('zone', get_zonefile_instance().zones.keys())
def test_can_coerce_string_for_dateutil_zone(zone):
    tzcol = TimezoneType(backend='dateutil')
    assert isinstance(tzcol._coerce(zone), tzfile)


@pytest.mark.parametrize('zone', zoneinfo.available_timezones())
def test_can_coerce_string_for_zoneinfo_zone(zone):
    tzcol = TimezoneType(backend='zoneinfo')
    assert str(tzcol._coerce(zone)) == zone


@pytest.mark.parametrize('backend', TIMEZONE_BACKENDS)
def test_can_coerce_and_raise_UnknownTimeZoneError_or_ValueError(backend):
    tzcol = TimezoneType(backend=backend)
    exceptions = (
        ValueError,
        pytz.exceptions.UnknownTimeZoneError,
        zoneinfo.ZoneInfoNotFoundError
    )
    with pytest.raises(exceptions):
        tzcol._coerce('SolarSystem/Mars')
    with pytest.raises(exceptions):
        tzcol._coerce('')


@pytest.mark.parametrize('backend', TIMEZONE_BACKENDS)
def test_can_coerce_None(backend):
    tzcol = TimezoneType(backend=backend)
    assert tzcol._coerce(None) is None