aboutsummaryrefslogtreecommitdiffstats
path: root/tests/utils/test_time.py
blob: 7bde92506db4a782aef271234ec8f7827352d925 (plain) (blame)
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
import asyncio
from datetime import datetime, timezone
from unittest.mock import patch

import pytest
from dateutil.relativedelta import relativedelta

from bot.utils import time
from tests.helpers import AsyncMock


@pytest.mark.parametrize(
    ('delta', 'precision', 'max_units', 'expected'),
    (
        (relativedelta(days=2), 'seconds', 1, '2 days'),
        (relativedelta(days=2, hours=2), 'seconds', 2, '2 days and 2 hours'),
        (relativedelta(days=2, hours=2), 'seconds', 1, '2 days'),
        (relativedelta(days=2, hours=2), 'days', 2, '2 days'),

        # Does not abort for unknown units, as the unit name is checked
        # against the attribute of the relativedelta instance.
        (relativedelta(days=2, hours=2), 'elephants', 2, '2 days and 2 hours'),

        # Very high maximum units, but it only ever iterates over
        # each value the relativedelta might have.
        (relativedelta(days=2, hours=2), 'hours', 20, '2 days and 2 hours'),
    )
)
def test_humanize_delta(
        delta: relativedelta,
        precision: str,
        max_units: int,
        expected: str
):
    assert time.humanize_delta(delta, precision, max_units) == expected


@pytest.mark.parametrize('max_units', (-1, 0))
def test_humanize_delta_raises_for_invalid_max_units(max_units: int):
    with pytest.raises(ValueError, match='max_units must be positive'):
        time.humanize_delta(relativedelta(days=2, hours=2), 'hours', max_units)


@pytest.mark.parametrize(
    ('stamp', 'expected'),
    (
        ('Sun, 15 Sep 2019 12:00:00 GMT', datetime(2019, 9, 15, 12, 0, 0, tzinfo=timezone.utc)),
    )
)
def test_parse_rfc1123(stamp: str, expected: str):
    assert time.parse_rfc1123(stamp) == expected


@patch('asyncio.sleep', new_callable=AsyncMock)
def test_wait_until(sleep_patch):
    start = datetime(2019, 1, 1, 0, 0)
    then = datetime(2019, 1, 1, 0, 10)

    # No return value
    assert asyncio.run(time.wait_until(then, start)) is None

    sleep_patch.assert_called_once_with(10 * 60)


@pytest.mark.parametrize(
    ('date_from', 'date_to', 'parts', 'expected'),
    (
        (datetime(2019, 12, 12, 0, 1), datetime(2019, 12, 12, 12, 0, 5), 2, '11 hours, 59 minutes'),
        (datetime(2019, 12, 12, 0, 1), datetime(2019, 12, 12, 12, 0, 5), 1, '11 hours'),
        (datetime(2019, 12, 12, 0, 1), datetime(2019, 12, 12, 12, 0, 5), None, '11 hours, 59 minutes, 5 seconds'),
        (datetime(2019, 12, 12, 0, 0), datetime(2019, 12, 11, 23, 59), 2, '1 minute'),
        (datetime(2019, 11, 23, 20, 9), datetime(2019, 11, 30, 20, 15), 2, '1 week, 6 minutes'),
        (datetime(2019, 11, 23, 20, 9), datetime(2019, 4, 25, 20, 15), 2, '7 months, 2 weeks'),
        (datetime(2019, 11, 23, 20, 9), datetime(2019, 4, 25, 20, 15),
         None, '7 months, 2 weeks, 1 day, 23 hours, 54 minutes'),
        (datetime(2019, 11, 23, 20, 58), datetime(2019, 11, 23, 21, 3), 2, '5 minutes'),
        (datetime(2019, 11, 23, 23, 59), datetime(2019, 11, 24, 0, 0), 2, '1 minute'),
        (datetime(2019, 11, 23, 23, 59), datetime(2022, 11, 23, 23, 0), 2, '3 years, 3 months'),
        (datetime(2019, 11, 23, 23, 59), datetime(2019, 11, 23, 23, 49, 5), 2, '9 minutes, 55 seconds'),
    )
)
def test_get_duration(date_from: datetime, date_to: datetime, parts: int, expected: str):
    assert time.get_duration(date_from, date_to, parts) == expected


@pytest.mark.parametrize(
    ('expiry', 'date_from', 'parts', 'expected'),
    (
        ('2019-12-12T00:01:00Z', datetime(2019, 12, 12, 12, 0, 5), 2, '2019-12-12 00:01 (11 hours, 59 minutes)'),
        ('2019-12-12T00:01:00Z', datetime(2019, 12, 12, 12, 0, 5), 1, '2019-12-12 00:01 (11 hours)'),
        ('2019-12-12T00:01:00Z', datetime(2019, 12, 12, 12, 0, 5),
         None, '2019-12-12 00:01 (11 hours, 59 minutes, 5 seconds)'),
        ('2019-12-12T00:00:00Z', datetime(2019, 12, 11, 23, 59), 2, '2019-12-12 00:00 (1 minute)'),
        ('2019-11-23T20:09:00Z', datetime(2019, 11, 30, 20, 15), 2, '2019-11-23 20:09 (1 week, 6 minutes)'),
        ('2019-11-23T20:09:00Z', datetime(2019, 4, 25, 20, 15), 2, '2019-11-23 20:09 (7 months, 2 weeks)'),
        ('2019-11-23T20:09:00Z', datetime(2019, 4, 25, 20, 15), None,
         '2019-11-23 20:09 (7 months, 2 weeks, 1 day, 23 hours, 54 minutes)'),
        ('2019-11-23T20:58:00Z', datetime(2019, 11, 23, 21, 3), 2, '2019-11-23 20:58 (5 minutes)'),
        ('2019-11-23T23:59:00Z', datetime(2019, 11, 24, 0, 0), 2, '2019-11-23 23:59 (1 minute)'),
        ('2019-11-23T23:59:00Z', datetime(2022, 11, 23, 23, 0), 2, '2019-11-23 23:59 (3 years, 3 months)'),
        ('2019-11-23T23:59:00Z', datetime(2019, 11, 23, 23, 49, 5), 2, '2019-11-23 23:59 (9 minutes, 55 seconds)'),
        (None, datetime(2019, 11, 23, 23, 49, 5), 2, None),
    )
)
def test_get_duration_from_expiry(expiry: str, date_from: datetime, parts: int, expected: str):
    assert time.get_duration_from_expiry(expiry, date_from, parts) == expected