1from datetime import datetime, timezone
2from itertools import product
3import unittest
4from unittest.mock import patch
5
6from Orange.data import Table
7
8from orangecontrib.timeseries import Timeseries
9from orangecontrib.timeseries.functions import timestamp, fromtimestamp
10
11
12class TestTimeseries(unittest.TestCase):
13    def test_create_time_variable(self):
14        table = Table("iris")
15        time_series = Timeseries.from_data_table(table)
16        id_1 = id(time_series.attributes)
17        time_series.time_variable = time_series.domain.attributes[0]
18        self.assertNotEqual(id_1, id(time_series.attributes))
19
20    def test_make_timeseries_from_continuous_var(self):
21        table = Table.from_url("http://file.biolab.si/datasets/slovenian-national-assembly-eng.tab")
22        time_series = Timeseries.make_timeseries_from_continuous_var(table,
23                                                                     'date of birth')
24        self.assertEqual(time_series.time_variable.name, 'date of birth')
25        self.assertTrue(time_series.time_variable in time_series.domain.metas)
26
27    def test_time_var_removed(self):
28        ts_with_tv = Timeseries.from_file('airpassengers')
29        # select columns without time variable
30        ts_without_tv = Timeseries.from_data_table(ts_with_tv[:,
31                                      ts_with_tv.domain.class_var])
32        self.assertTrue(ts_with_tv.time_variable)
33        # make sure the Timeseries without time variable in domain has
34        # time_variable set to None
35        self.assertIsNone(ts_without_tv.time_variable)
36
37
38class TestTimestamp(unittest.TestCase):
39    def test_timestamp(self):
40        local = datetime.now().astimezone().tzinfo
41
42        class T(datetime):
43            def timestamp(self):
44                nonlocal was_hit
45                was_hit = True
46                raise OverflowError
47
48        # test different years since 1900 was not a leap year, 2000 was
49        # test different timezones to account for naive and aware datetime
50        for y, tz in product([1890, 1991, 2004], [None, timezone.utc, local]):
51            was_hit = False
52            date = datetime(y, 5, 1, 19, 20, 21, 5, tzinfo=tz)
53            test_date = T(y, 5, 1, 19, 20, 21, 5, tzinfo=tz)
54
55            self.assertEqual(date.timestamp(), timestamp(test_date))
56            self.assertTrue(was_hit)
57
58    def test_fromtimestamp(self):
59        TS = -1234567890
60        expected = datetime.fromtimestamp(TS)
61
62        was_hit = False
63
64        class MockDatetime(datetime):
65            @classmethod
66            def fromtimestamp(cls, *args, **kwargs):
67                nonlocal was_hit
68                if was_hit:
69                    return super().fromtimestamp(*args, **kwargs)
70                was_hit = True
71                raise OSError
72
73        with patch('datetime.datetime', MockDatetime):
74            self.assertEqual(fromtimestamp(TS), expected)
75            self.assertTrue(was_hit)
76