Skip to content

Commit

Permalink
Second attempt at fixing timezone test issues
Browse files Browse the repository at this point in the history
This is a followup to #10. It turns out that `freezegun` does not yet
support `dateutil`'s `tzlocal`, which is used by `timew-report`
[here]. [This comment] on the `freezegun` repository provides a context
manager solution that can be used for now. This change properly fixes #6.

[here]: https://github.com/lauft/timew-report/blob/c972357a44640c7a5f803d79fc77ca597e1b22f0/timewreport/interval.py#L49
[This comment]: https://github.com/lauft/timew-report/blob/c972357a44640c7a5f803d79fc77ca597e1b22f0/timewreport/interval.py#L49
  • Loading branch information
jonafato committed Sep 22, 2021
1 parent c09d339 commit 8baacf6
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 61 deletions.
1 change: 0 additions & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ timew-report = "<1.3"

[dev-packages]
pytest = "*"
pytest-freezegun = "*"

[requires]
python_version = "3.6"
34 changes: 1 addition & 33 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 45 additions & 26 deletions tests/test_invoice.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import contextlib
import os
import time
import unittest
from datetime import datetime, timedelta, timezone
from random import randint
Expand All @@ -11,6 +14,21 @@
from billwarrior.invoice import Invoice, ItemCategory, LineItem


@contextlib.contextmanager
def mock_tz(new_tz):
old_tz = os.environ.get('TZ')
os.environ['TZ'] = new_tz
time.tzset()
try:
yield
finally:
if old_tz is not None:
os.environ['TZ'] = old_tz
else:
del os.environ['TZ']
time.tzset()


class BillWarriorConfigFake(BillWarriorConfig):
def __init__(self):
pass
Expand Down Expand Up @@ -57,28 +75,28 @@ def test_creates_different_categories_from_interval_tags_and_mapping(self):
self.assertEqual(str(expected_a), str(items[0]))
self.assertEqual(str(expected_b), str(items[1]))

@pytest.mark.freeze_time(tz_offset=2)
def test_groups_intervals_of_same_category(self):
same_day = datetime.today()
a, b, c = (
tests.give_interval(same_day, tags=["on-site", "coding"]),
tests.give_interval(same_day, tags=["coding", "off-site"]),
tests.give_interval(tags=["coding", "cafe"]),
)
with mock_tz('UTC'):
same_day = datetime.today()
a, b, c = (
tests.give_interval(same_day, tags=["on-site", "coding"]),
tests.give_interval(same_day, tags=["coding", "off-site"]),
tests.give_interval(tags=["coding", "cafe"]),
)

billw_config = BillWarriorConfigFake.build({"coding": "Consulting & Research"})
billw_config = BillWarriorConfigFake.build({"coding": "Consulting & Research"})

invoice = Invoice([a, b, c], billw_config)
items = invoice.items()
invoice = Invoice([a, b, c], billw_config)
items = invoice.items()

expected = ItemCategory(
"Consulting & Research",
{same_day.date(): [a, b], c.get_date().date(): [c]},
0.0,
)
expected = ItemCategory(
"Consulting & Research",
{same_day.date(): [a, b], c.get_date().date(): [c]},
0.0,
)

self.assertEqual(len(items), 1) # one category
self.assertEqual(str(items[0]), str(expected))
self.assertEqual(len(items), 1) # one category
self.assertEqual(str(items[0]), str(expected))

def test_raises_exception_when_interval_sorts_into_more_than_one_category(self):
a, b = (
Expand Down Expand Up @@ -228,17 +246,18 @@ def test_items_omitted_when_unit_price_is_negative(self):
self.assertEqual(str(category), "")

def test_line_items_should_be_populated_with_entries_per_day(self):
a_day = datetime.today()
entries = [
[tests.give_interval(a_day + timedelta(days=1))],
[tests.give_interval(a_day + timedelta(days=2))],
[tests.give_interval(a_day + timedelta(days=3))],
]
intervals_by_day = {entry[0].get_date().date(): entry for entry in entries}
with mock_tz('UTC'):
a_day = datetime.today()
entries = [
[tests.give_interval(a_day + timedelta(days=1))],
[tests.give_interval(a_day + timedelta(days=2))],
[tests.give_interval(a_day + timedelta(days=3))],
]
intervals_by_day = {entry[0].get_date().date(): entry for entry in entries}

category = ItemCategory("arbitray category", intervals_by_day, 0.0)
category = ItemCategory("arbitray category", intervals_by_day, 0.0)

self.assertEqual(len(category.line_items), len(entries))
self.assertEqual(len(category.line_items), len(entries))

def test_line_items_should_be_sorted_by_date(self):
entries = [
Expand Down
1 change: 0 additions & 1 deletion tests/testsupport.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,3 @@ def give_interval(day=None, tags=[]):
end = start + timedelta(0, randint(60 * 5, 60 * 60 * 2)) # up to 2h

return TimeWarriorInterval(start.strftime(DT_FORMAT), end.strftime(DT_FORMAT), tags)

0 comments on commit 8baacf6

Please sign in to comment.