def should_recognize_isodate_without_msecs(self): task = TaskWarrior(Config(separator='__')) task.config.taskfile.write_text(six.text_type('\n'.join([ '{0}\tfoo'.format(datetime.datetime(2021, 12, 31, 8, 0, 0).isoformat().split('.', 1)[0]), '{0}\tbar'.format(datetime.datetime(2021, 12, 31, 8, 10, 0).isoformat()), '{0}'.format(datetime.datetime(2021, 12, 31, 8, 30, 0).isoformat()), ]) + '\n')) self.assertEqual([_.title for _ in task.get_history()], ['foo', 'bar', None])
def should_resume_stopped_task(self): task = TaskWarrior() self.assertFalse(task.start()) self.assertIsNone(task.get_current_task()) task.start('foo') task.stop() self.assertTrue(task.start()) self.assertEqual(task.get_current_task(), 'foo')
def should_try_to_guess_separator_for_line(self): task = TaskWarrior(Config(separator='__')) task.config.taskfile.write_text(six.text_type('\n'.join([ '{0}__foo'.format(datetime.datetime(2021, 12, 31, 8, 0, 0).isoformat()), '{0}\tbar with space'.format(datetime.datetime(2021, 12, 31, 8, 10, 0).isoformat()), '{0} baz with space'.format(datetime.datetime(2021, 12, 31, 8, 20, 0).isoformat()), '{0}'.format(datetime.datetime(2021, 12, 31, 8, 30, 0).isoformat()), ]) + '\n')) self.assertEqual([_.title for _ in task.get_history()], ['foo', 'bar with space', 'baz with space', None])
def should_stop_task(self): task = TaskWarrior() self.assertIsNone(task.get_current_task()) task.start('foo') self.assertEqual(task.get_current_task(), 'foo') task.stop() self.assertIsNone(task.get_current_task())
def should_use_custom_separator_for_entry_tuple(self): task = TaskWarrior(Config(separator='__')) task.start('foo') task.start('bar') self.assertTrue('__foo' in task.config.taskfile.read_text()) task.stop() self.assertEqual([_.title for _ in task.get_history()], ['foo', 'bar', None])
def should_fix_task_history(self, subprocess_call): task = TaskWarrior() self.assertTrue(task.fix_history()) subprocess_call.assert_has_calls([ mock.call([os.environ.get('EDITOR', 'vi'), str(task.config.taskfile)]), ])
def should_rewrite_task_history_with_fill_value(self): task = TaskWarrior(Config(separator='__')) task.start('foo', now=datetime.datetime(2021, 12, 31, 8, 0, 0)) task.start('bar', now=datetime.datetime(2021, 12, 31, 8, 1, 0)) task.stop(now=datetime.datetime(2021, 12, 31, 8, 2, 0)) task.start(now=datetime.datetime(2021, 12, 31, 8, 3, 0)) task.start('foo', now=datetime.datetime(2021, 12, 31, 8, 4, 0)) task.rewrite_history( datetime.datetime(2021, 12, 31, 8, 2, 0), datetime.datetime(2021, 12, 31, 8, 3, 0), ['foo'], fill_value='baz' ) self.assertEqual([_.title for _ in task.get_history()], [ 'foo', 'bar', 'foo', 'baz', 'foo', ])
def should_rewrite_task_history_automatically(self): task = TaskWarrior(Config(separator='__')) task.start('foo', now=datetime.datetime(2021, 12, 31, 8, 0, 0)) task.start('bar', now=datetime.datetime(2021, 12, 31, 8, 1, 0)) task.stop(now=datetime.datetime(2021, 12, 31, 8, 2, 0)) task.start(now=datetime.datetime(2021, 12, 31, 8, 3, 0)) task.start('foo', now=datetime.datetime(2021, 12, 31, 8, 4, 0)) with self.assertRaises(RuntimeError): task.rewrite_history( datetime.datetime(2021, 12, 31, 8, 2, 0), datetime.datetime(2021, 12, 31, 8, 3, 0), ['baz', 'baz', 'excessive'], ) with self.assertRaises(RuntimeError): task.rewrite_history( datetime.datetime(2021, 12, 31, 8, 2, 0), datetime.datetime(2021, 12, 31, 8, 3, 0), ['not enough values'], ) task.rewrite_history( datetime.datetime(2021, 12, 31, 8, 2, 0), datetime.datetime(2021, 12, 31, 8, 3, 0), ['baz', 'baz'], ) self.assertEqual([_.title for _ in task.get_history()], [ 'foo', 'bar', 'baz', 'baz', 'foo', ]) task.rewrite_history( datetime.datetime(2021, 12, 31, 8, 2, 0), datetime.datetime(2021, 12, 31, 8, 3, 0), ['foo', None], ) self.assertEqual([_.title for _ in task.get_history()], [ 'foo', 'bar', 'foo', None, 'foo', ])
def should_accumulate_stats(self): task = TaskWarrior() task.start('foo', now=datetime.datetime(2021, 12, 31, 8, 0, 0)) task.start('bar', now=datetime.datetime(2021, 12, 31, 8, 2, 0)) task.stop(now=datetime.datetime(2021, 12, 31, 8, 5, 0)) task.start(now=datetime.datetime(2021, 12, 31, 8, 7, 0)) task.start('foo', now=datetime.datetime(2021, 12, 31, 8, 8, 0)) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.accumulate_stats( stop_datetime=datetime.datetime(2021, 12, 31, 8, 30, 0), )], [ (4, 'bar'), (24, 'foo'), ]) task.rewrite_history( datetime.datetime(2021, 12, 31, 8, 5, 0), datetime.datetime(2021, 12, 31, 8, 7, 0), ['bar', 'bar'] ) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.accumulate_stats( stop_datetime=datetime.datetime(2021, 12, 31, 8, 30, 0), )], [ (6, 'bar'), (24, 'foo'), ]) task.start('foo', now=datetime.datetime(2021, 12, 31, 8, 10, 0)) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.accumulate_stats( stop_datetime=datetime.datetime(2021, 12, 31, 8, 30, 0), )], [ (6, 'bar'), (24, 'foo'), ])
def should_squeeze_consequent_break_events(self): task = TaskWarrior() task.start('foo', now=datetime.datetime(2020, 12, 31, 8, 0, 0)) task.start('foo', now=datetime.datetime(2020, 12, 31, 8, 1, 0)) task.stop(now=datetime.datetime(2020, 12, 31, 8, 2, 0)) task.start(now=datetime.datetime(2020, 12, 31, 8, 3, 0)) task.stop(now=datetime.datetime(2020, 12, 31, 8, 4, 0)) task.start(now=datetime.datetime(2020, 12, 31, 8, 5, 0)) task.start('bar', now=datetime.datetime(2020, 12, 31, 8, 6, 0)) self.assertEqual([(_.title, _.datetime.time()) for _ in task.filter_history( squeeze_breaks=True, )], [ ('foo', datetime.time(8, 0)), ('foo', datetime.time(8, 1)), (None, datetime.time(8, 2)), ('foo', datetime.time(8, 5)), ('bar', datetime.time(8, 6)), ]) task = TaskWarrior() task.config.taskfile.write_bytes(b'') task.start('foo', now=datetime.datetime(2020, 12, 31, 8, 0, 0)) task.start('foo', now=datetime.datetime(2020, 12, 31, 8, 1, 0)) task.stop(now=datetime.datetime(2020, 12, 31, 8, 2, 0)) task.start(now=datetime.datetime(2020, 12, 31, 8, 3, 0)) task.stop(now=datetime.datetime(2020, 12, 31, 8, 4, 0)) task.start(now=datetime.datetime(2020, 12, 31, 8, 5, 0)) task.start('bar', now=datetime.datetime(2020, 12, 31, 8, 6, 0)) self.assertEqual([(_.title, _.datetime.time()) for _ in task.filter_history( squeeze_breaks=True, only_breaks=True, )], [ (None, datetime.time(8, 2)), ('foo', datetime.time(8, 5)), ]) task = TaskWarrior() task.config.taskfile.write_bytes(b'') task.start('foo', now=datetime.datetime(2020, 12, 31, 8, 0, 0)) task.start('foo', now=datetime.datetime(2020, 12, 31, 8, 1, 0)) task.stop(now=datetime.datetime(2020, 12, 31, 8, 2, 0)) task.start(now=datetime.datetime(2020, 12, 31, 8, 3, 0)) task.stop(now=datetime.datetime(2020, 12, 31, 8, 4, 0)) task.start(now=datetime.datetime(2020, 12, 31, 8, 5, 0)) self.assertEqual([(_.title, _.datetime.time()) for _ in task.filter_history( squeeze_breaks=True, only_breaks=True, )], [ (None, datetime.time(8, 2)), ('foo', datetime.time(8, 5)), ]) task = TaskWarrior() task.config.taskfile.write_bytes(b'') task.start('foo', now=datetime.datetime(2020, 12, 31, 8, 0, 0)) task.start('foo', now=datetime.datetime(2020, 12, 31, 8, 1, 0)) task.stop(now=datetime.datetime(2020, 12, 31, 8, 2, 0)) task.start(now=datetime.datetime(2020, 12, 31, 8, 3, 0)) task.stop(now=datetime.datetime(2020, 12, 31, 8, 4, 0)) self.assertEqual([(_.title, _.datetime.time()) for _ in task.filter_history( squeeze_breaks=True, only_breaks=True, )], [ (None, datetime.time(8, 2)), ('foo', datetime.time(8, 3)), ])
def should_collect_entries_to_passed_stats(self): task = TaskWarrior() task.start('foo', now=datetime.datetime(2021, 12, 31, 8, 0, 0)) task.start('bar', now=datetime.datetime(2021, 12, 31, 8, 2, 0)) task.stop(now=datetime.datetime(2021, 12, 31, 8, 5, 0)) task.start(now=datetime.datetime(2021, 12, 31, 8, 7, 0)) task.start('foo', now=datetime.datetime(2021, 12, 31, 8, 8, 0)) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.get_stats( stop_datetime=datetime.datetime(2021, 12, 31, 8, 30, 0), )], [ (2, 'foo'), (3, 'bar'), (1, 'bar'), (22, 'foo'), ]) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.get_stats( start_datetime=datetime.datetime(2021, 12, 31, 7, 30, 0), stop_datetime=datetime.datetime(2021, 12, 31, 8, 30, 0), )], [ (2, 'foo'), (3, 'bar'), (1, 'bar'), (22, 'foo'), ]) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.get_stats( start_datetime=datetime.datetime(2021, 12, 31, 8, 1, 0), stop_datetime=datetime.datetime(2021, 12, 31, 8, 30, 0), )], [ (1, 'foo'), (3, 'bar'), (1, 'bar'), (22, 'foo'), ]) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.get_stats( start_datetime=datetime.datetime(2021, 12, 31, 8, 1, 0), stop_datetime=datetime.datetime(2021, 12, 31, 8, 6, 0), )], [ (1, 'foo'), (3, 'bar'), ]) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.get_stats( start_datetime=datetime.datetime(2021, 12, 31, 8, 1, 0), stop_datetime=datetime.datetime(2021, 12, 31, 8, 4, 0), )], [ (1, 'foo'), (2, 'bar'), ]) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.get_stats( start_datetime=datetime.datetime(2021, 12, 31, 8, 2, 0), stop_datetime=datetime.datetime(2021, 12, 31, 8, 4, 0), )], [ (2, 'bar'), ]) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.get_stats( start_datetime=datetime.datetime(2021, 12, 31, 8, 3, 0), stop_datetime=datetime.datetime(2021, 12, 31, 8, 4, 0), )], [ (1, 'bar'), ]) task.stop(now=datetime.datetime(2021, 12, 31, 8, 10, 0)) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.get_stats( stop_datetime=datetime.datetime(2021, 12, 31, 8, 30, 0), )], [ (2, 'foo'), (3, 'bar'), (1, 'bar'), (2, 'foo'), ])
def should_use_custom_aliases_for_stop_and_resume(self): task = TaskWarrior(Config( resume_alias='UNLOCK', stop_alias='LOCK', )) task.config.taskfile.write_text(six.text_type('\n'.join([ '{0} foo'.format(datetime.datetime(2021, 12, 31, 8, 0, 0).isoformat()), '{0} LOCK'.format(datetime.datetime(2021, 12, 31, 8, 10, 0).isoformat()), '{0} UNLOCK'.format(datetime.datetime(2021, 12, 31, 8, 30, 0).isoformat()), ]) + '\n')) history = list(task.get_history()) self.assertEqual(len(history), 3) self.assertFalse(history[0].is_resume) self.assertFalse(history[0].is_stop) self.assertFalse(history[1].is_resume) self.assertTrue(history[1].is_stop) self.assertTrue(history[2].is_resume) self.assertFalse(history[2].is_stop) self.assertEqual(task.get_current_task(), 'foo') task.config.taskfile.write_text(six.text_type('\n'.join([ '{0} foo'.format(datetime.datetime(2021, 12, 31, 8, 0, 0).isoformat()), '{0} LOCK'.format(datetime.datetime(2021, 12, 31, 8, 10, 0).isoformat()), '{0} UNLOCK'.format(datetime.datetime(2021, 12, 31, 8, 30, 0).isoformat()), '{0}'.format(datetime.datetime(2021, 12, 31, 8, 0, 0).isoformat()), '{0} foo'.format(datetime.datetime(2021, 12, 31, 8, 0, 0).isoformat()), ]) + '\n')) history = list(task.get_history()) self.assertEqual(len(history), 5) self.assertFalse(history[0].is_resume) self.assertFalse(history[0].is_stop) self.assertFalse(history[1].is_resume) self.assertTrue(history[1].is_stop) self.assertTrue(history[2].is_resume) self.assertFalse(history[2].is_stop) self.assertFalse(history[3].is_resume) self.assertTrue(history[3].is_stop) self.assertTrue(history[4].is_resume) self.assertFalse(history[4].is_stop) self.assertEqual(task.get_current_task(), 'foo') task.config.taskfile.write_text(six.text_type('\n'.join([ '{0} foo'.format(datetime.datetime(2021, 12, 31, 8, 0, 0).isoformat()), '{0} LOCK'.format(datetime.datetime(2021, 12, 31, 8, 10, 0).isoformat()), '{0} UNLOCK'.format(datetime.datetime(2021, 12, 31, 8, 30, 0).isoformat()), '{0} bar'.format(datetime.datetime(2021, 12, 31, 8, 40, 0).isoformat()), '{0} foo'.format(datetime.datetime(2021, 12, 31, 8, 50, 0).isoformat()), ]) + '\n')) history = list(task.get_history()) self.assertEqual(len(history), 5) self.assertFalse(history[0].is_resume) self.assertFalse(history[0].is_stop) self.assertFalse(history[1].is_resume) self.assertTrue(history[1].is_stop) self.assertIsNone(history[1].title) self.assertTrue(history[2].is_resume) self.assertFalse(history[2].is_stop) self.assertEqual(history[2].title, 'foo') self.assertFalse(history[3].is_resume) self.assertFalse(history[3].is_stop) self.assertEqual(history[3].title, 'bar') self.assertFalse(history[4].is_resume) self.assertFalse(history[4].is_stop) self.assertEqual(history[4].title, 'foo') self.assertEqual(task.get_current_task(), 'foo')
def should_not_consider_consequent_tasks_as_resume(self): task = TaskWarrior() task.start('foo') task.start('foo') task.stop() task.start() task.stop() task.start('foo') history = list(task.get_history()) self.assertFalse(history[0].is_resume) self.assertFalse(history[1].is_resume) self.assertTrue(history[2].is_stop) self.assertTrue(history[3].is_resume) self.assertTrue(history[4].is_stop) self.assertTrue(history[5].is_resume)
def should_list_task_history(self): task = TaskWarrior() task.start('foo') task.start('bar') task.stop() self.assertEqual([_.title for _ in task.get_history()], ['foo', 'bar', None])
def should_squeeze_consequent_stats(self): task = TaskWarrior() task.start('foo', now=datetime.datetime(2021, 12, 31, 8, 0, 0)) task.start('bar', now=datetime.datetime(2021, 12, 31, 8, 2, 0)) task.stop(now=datetime.datetime(2021, 12, 31, 8, 5, 0)) task.start(now=datetime.datetime(2021, 12, 31, 8, 7, 0)) task.start('foo', now=datetime.datetime(2021, 12, 31, 8, 8, 0)) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.get_stats( stop_datetime=datetime.datetime(2021, 12, 31, 8, 30, 0), squeeze=True, )], [ (2, 'foo'), (3, 'bar'), (1, 'bar'), (22, 'foo'), ]) task.rewrite_history( datetime.datetime(2021, 12, 31, 8, 5, 0), datetime.datetime(2021, 12, 31, 8, 7, 0), ['bar', 'bar'] ) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.get_stats( stop_datetime=datetime.datetime(2021, 12, 31, 8, 30, 0), squeeze=True, )], [ (2, 'foo'), (6, 'bar'), (22, 'foo'), ]) task.start('foo', now=datetime.datetime(2021, 12, 31, 8, 10, 0)) self.assertEqual([(_.passed.total_seconds()/60, _.title) for _ in task.get_stats( stop_datetime=datetime.datetime(2021, 12, 31, 8, 30, 0), squeeze=True, )], [ (2, 'foo'), (6, 'bar'), (22, 'foo'), ])
def should_filter_task_history_by_datetime(self): task = TaskWarrior() task.start('foo', now=datetime.datetime(2020, 12, 31, 8, 0, 0)) task.start('bar', now=datetime.datetime(2020, 12, 31, 8, 20, 0)) task.stop(now=datetime.datetime(2020, 12, 31, 8, 45, 0)) task.start('baz', now=datetime.datetime(2020, 12, 31, 9, 40, 0)) task.stop(now=datetime.datetime(2020, 12, 31, 10, 20, 0)) task.start(now=datetime.datetime(2020, 12, 31, 12, 1, 0)) self.assertEqual([(_.title, _.datetime.time()) for _ in task.filter_history( start_datetime=datetime.datetime(2020, 12, 31, 8, 10, 0), stop_datetime=datetime.datetime(2020, 12, 31, 11, 10, 0), )], [ ('bar', datetime.time(8, 20)), (None, datetime.time(8, 45)), ('baz', datetime.time(9, 40)), (None, datetime.time(10, 20)), ])
def should_filter_out_duplicated_stop_resume_events(self): task = TaskWarrior() task.start('foo', now=datetime.datetime(2020, 12, 31, 8, 0, 0)) task.start('foo', now=datetime.datetime(2020, 12, 31, 8, 1, 0)) task.stop(now=datetime.datetime(2020, 12, 31, 8, 2, 0)) task.stop(now=datetime.datetime(2020, 12, 31, 8, 2, 5)) task.start(now=datetime.datetime(2020, 12, 31, 8, 3, 0)) task.start(now=datetime.datetime(2020, 12, 31, 8, 3, 5)) task.stop(now=datetime.datetime(2020, 12, 31, 8, 4, 0)) task.start('bar', now=datetime.datetime(2020, 12, 31, 8, 5, 0)) task.start('bar', now=datetime.datetime(2020, 12, 31, 8, 5, 3)) self.assertEqual([(_.title, _.datetime.time()) for _ in task.filter_history( )], [ ('foo', datetime.time(8, 0)), ('foo', datetime.time(8, 1)), (None, datetime.time(8, 2)), ('foo', datetime.time(8, 3)), ('foo', datetime.time(8, 3, 5)), (None, datetime.time(8, 4)), ('bar', datetime.time(8, 5)), ('bar', datetime.time(8, 5, 3)), ])