1import itertools
2
3from datetime import datetime
4from tests import BaseTestCase
5from parameterized import parameterized, param
6from dateparser.utils import (
7    find_date_separator, localize_timezone, apply_timezone,
8    apply_timezone_from_settings, registry
9)
10from pytz import UnknownTimeZoneError, utc
11from dateparser.conf import settings
12
13
14class TestUtils(BaseTestCase):
15    def setUp(self):
16        super(TestUtils, self).setUp()
17        self.date_format = None
18        self.result = None
19
20    def given_date_format(self, date_format):
21        self.date_format = date_format
22
23    def when_date_seperator_is_parsed(self):
24        self.result = find_date_separator(self.date_format)
25
26    def then_date_seperator_is(self, sep):
27        self.assertEqual(self.result, sep)
28
29    @staticmethod
30    def make_class_without_get_keys():
31        class SomeClass:
32            pass
33        some_class = SomeClass
34        return some_class
35
36    @parameterized.expand([
37        param(date_format=fmt.format(sep=sep), expected_sep=sep)
38        for (fmt, sep) in itertools.product(
39            ['%d{sep}%m{sep}%Y', '%d{sep}%m{sep}%Y %H:%M'],
40            ['/', '.', '-', ':'])
41    ])
42    def test_separator_extraction(self, date_format, expected_sep):
43        self.given_date_format(date_format)
44        self.when_date_seperator_is_parsed()
45        self.then_date_seperator_is(expected_sep)
46
47    @parameterized.expand([
48        param(datetime(2015, 12, 12), timezone='UTC', zone='UTC'),
49        param(datetime(2015, 12, 12), timezone='Asia/Karachi', zone='Asia/Karachi'),
50        param(datetime(2015, 12, 12, tzinfo=utc), timezone='UTC', zone='UTC'),
51    ])
52    def test_localize_timezone_function(self, date, timezone, zone):
53        tzaware_dt = localize_timezone(date, timezone)
54        self.assertEqual(tzaware_dt.tzinfo.zone, zone)
55
56    @parameterized.expand([
57        param(datetime(2015, 12, 12), timezone='UTB'),
58        param(datetime(2015, 12, 12), timezone='Asia/Karach'),
59    ])
60    def test_localize_timezone_function_raise_error(self, date, timezone):
61        self.assertRaises(UnknownTimeZoneError, localize_timezone, date, timezone)
62
63    @parameterized.expand([
64        param(datetime(2015, 12, 12), timezone='UTC+3', zone='UTC\+03:00'),
65    ])
66    def test_localize_timezone_function_exception(self, date, timezone, zone):
67        tzaware_dt = localize_timezone(date, timezone)
68        self.assertEqual(tzaware_dt.tzinfo._StaticTzInfo__name, zone)
69
70    @parameterized.expand([
71        param(datetime(2015, 12, 12, 10, 12), timezone='Asia/Karachi', expected=datetime(2015, 12, 12, 15, 12)),
72        param(datetime(2015, 12, 12, 10, 12), timezone='-0500', expected=datetime(2015, 12, 12, 5, 12)),
73    ])
74    def test_apply_timezone_function(self, date, timezone, expected):
75        result = apply_timezone(date, timezone)
76        result = result.replace(tzinfo=None)
77        self.assertEqual(expected, result)
78
79    @parameterized.expand([
80        param(datetime(2015, 12, 12, 10, 12), timezone='Asia/Karachi', expected=datetime(2015, 12, 12, 15, 12)),
81        param(datetime(2015, 12, 12, 10, 12), timezone='-0500', expected=datetime(2015, 12, 12, 5, 12)),
82    ])
83    def test_apply_timezone_from_settings_function(self, date, timezone, expected):
84        result = apply_timezone_from_settings(date, settings.replace(**{'TO_TIMEZONE': timezone, 'TIMEZONE': 'UTC'}))
85        self.assertEqual(expected, result)
86
87    @parameterized.expand([
88        param(datetime(2015, 12, 12, 10, 12),
89              expected=datetime(2015, 12, 12, 10, 12)),
90
91    ])
92    def test_apply_timezone_from_settings_function_none_settings(self, date, expected):
93        result = apply_timezone_from_settings(date, None)
94        self.assertEqual(expected, result)
95
96    @parameterized.expand([
97        param(datetime(2015, 12, 12, 10, 12),),
98        param(datetime(2015, 12, 12, 10, 12),),
99    ])
100    def test_apply_timezone_from_settings_function_should_return_tz(self, date):
101        result = apply_timezone_from_settings(date, settings.replace(**{'RETURN_AS_TIMEZONE_AWARE': True}))
102        self.assertTrue(bool(result.tzinfo))
103
104    def test_registry_when_get_keys_not_implemented(self):
105        cl = self.make_class_without_get_keys()
106        self.assertRaises(NotImplementedError, registry, cl)
107