test: Check move / annotate commands with both synthetic and non-synthetic intervals in database

These tests are designed to check that `getIntervalsById()` will not
count the open interval at the end of the database twice.

See https://github.com/GothenburgBitFactory/timewarrior/pull/269/files#r368238522
This commit is contained in:
Shaun Ruffell 2020-01-18 15:29:35 -06:00 committed by lauft
parent 7b438830e2
commit 845ab2f805
2 changed files with 124 additions and 0 deletions

View file

@ -191,6 +191,48 @@ class TestAnnotate(TestCase):
self.assertEqual(len(j), 1)
self.assertClosedInterval(j[0], expectedAnnotation='bar "foo" bar')
def test_annotate_synthetic_and_nonsynthetic_intervals(self):
"""timew annotate should be able to work on both synthetic and non-synthetic intervals in the same invocation"""
now = datetime.now()
day_before = now - timedelta(days=1)
three_hours_before = now - timedelta(hours=3)
four_hours_before = now - timedelta(hours=4)
now_utc = now.utcnow()
three_hours_before_utc = now_utc - timedelta(hours=3)
four_hours_before_utc = now_utc - timedelta(hours=4)
five_hours_before_utc = now_utc - timedelta(hours=5)
self.t.configure_exclusions((four_hours_before.time(), three_hours_before.time()))
# First, we'll add a closed interval that is outside the exclusion.
self.t("track {:%Y-%m-%dT%H:%M:%S}Z - {:%Y-%m-%dT%H:%M:%S}Z foo".format(day_before, day_before + timedelta(hours=1)))
# Next create an open interval that crosses the exclusion. This will
# result in the creation of synthetic intervals
self.t("start {:%Y-%m-%dT%H:%M:%S}Z foo".format(five_hours_before_utc))
# Annotate one of the synthetic and the non-synthetic interval
self.t("annotate @3 @2 bar")
j = self.t.export()
self.assertEqual(len(j), 3)
self.assertClosedInterval(j[0],
expectedStart="{:%Y%m%dT%H%M%S}Z".format(day_before),
expectedEnd="{:%Y%m%dT%H%M%S}Z".format(day_before + timedelta(hours=1)),
expectedAnnotation="bar",
description="modified interval")
self.assertClosedInterval(j[1],
expectedStart="{:%Y%m%dT%H%M%S}Z".format(five_hours_before_utc),
expectedEnd="{:%Y%m%dT%H%M%S}Z".format(four_hours_before_utc),
expectedAnnotation="bar",
description="modified interval")
self.assertOpenInterval(j[2],
expectedStart="{:%Y%m%dT%H%M%S}Z".format(three_hours_before_utc),
expectedAnnotation="",
description="unmodified interval")
if __name__ == "__main__":
from simpletap import TAPTestRunner

View file

@ -186,6 +186,88 @@ class TestMove(TestCase):
expectedTags=[],
description="unmodified interval")
def test_move_synthetic_interval_into_exclusion(self):
"""timew move should work with both synthetic and non-synethic intervals in database"""
now = datetime.now()
three_hours_before = now - timedelta(hours=3)
four_hours_before = now - timedelta(hours=4)
now_utc = now.utcnow()
day_before = now_utc - timedelta(days=1)
three_hours_before_utc = now_utc - timedelta(hours=3)
four_hours_before_utc = now_utc - timedelta(hours=4)
five_hours_before_utc = now_utc - timedelta(hours=5)
self.t.configure_exclusions((four_hours_before.time(), three_hours_before.time()))
# Place a non-synthetic interval in the history
self.t("track {:%Y-%m-%dT%H:%M:%S}Z - {:%Y-%m-%dT%H:%M:%S}Z bar".format(day_before, day_before + timedelta(minutes=30)))
# Now create an open interval that crosses the exlusions added
# previously, which will result in synthetic intervals
self.t("start {:%Y-%m-%dT%H:%M:%S}Z foo".format(five_hours_before_utc))
j = self.t.export()
self.assertEqual(len(j), 3)
self.assertClosedInterval(j[0],
expectedStart=day_before,
expectedEnd=day_before + timedelta(minutes=30),
expectedTags=[],
description="unmodified interval")
self.assertClosedInterval(j[1],
expectedStart=five_hours_before_utc,
expectedEnd=four_hours_before_utc,
expectedTags=[],
description="unmodified interval")
self.assertOpenInterval(j[2],
expectedStart=three_hours_before_utc,
expectedTags=[],
description="unmodified interval")
# First move the non-synthetic one
self.t("move @3 {:%Y-%m-%dT%H:%M:%S}Z".format(day_before + timedelta(minutes=30)))
j = self.t.export()
self.assertEqual(len(j), 3)
self.assertClosedInterval(j[0],
expectedStart=day_before + timedelta(minutes=30),
expectedEnd=day_before + timedelta(hours=1),
expectedTags=[],
description="moved interval")
self.assertClosedInterval(j[1],
expectedStart=five_hours_before_utc,
expectedEnd=four_hours_before_utc,
expectedTags=[],
description="unmodified interval")
self.assertOpenInterval(j[2],
expectedStart=three_hours_before_utc,
expectedTags=[],
description="unmodified interval")
# Then move the synthetic one
self.t("move @2 {:%Y-%m-%dT%H:%M:%S}Z".format(five_hours_before_utc + timedelta(minutes=20)))
j = self.t.export()
self.assertEqual(len(j), 3)
self.assertClosedInterval(j[0],
expectedStart=day_before + timedelta(minutes=30),
expectedEnd=day_before + timedelta(hours=1),
expectedTags=[],
description="non-synthetic interval")
self.assertClosedInterval(j[1],
expectedStart=five_hours_before_utc + timedelta(minutes=20),
expectedEnd=four_hours_before_utc + timedelta(minutes=20),
expectedTags=[],
description="moved interval")
self.assertOpenInterval(j[2],
expectedStart=three_hours_before_utc,
expectedTags=[],
description="unmodified interval")
def test_move_interval_to_enclose_a_month_border(self):
"""Move an interval to enclose a month border"""
self.t("track 20180831T180000 - 20180831T230000 foo")