def testCreateFromTW(self): """ Test import of new taskwarrior tasks in egt """ import taskw tw = taskw.TaskWarrior(marshal=True, config_filename=self.taskrc) new_task = tw.task_add("new task", ["tag", "testtag1"], project="testprj") tw.task_add("new parent task", project="testprj", depends=[new_task["uuid"]]) tw = None self.write_project([ "body line1", "body line2", ]) proj = Project(self.projectfile, statedir=self.workdir.name) proj.body.force_load_tw(config_filename=self.taskrc) proj.load() self.assertEqual(len(proj.body.content), 2) self.assertEqual(len(proj.body.tasks), 0) proj.body.sync_tasks() self.assertEqual(len(proj.body.content), 5) self.assertEqual(len(proj.body.tasks), 2) task = proj.body.tasks[0] self.assertIsNotNone(task.task) self.assertFalse(task.is_new) self.assertIsNotNone(task.id) self.assertEqual(task.task["description"], "new task") self.assertEqual(task.task["tags"], ["tag", "testtag1"]) self.assertEqual(task.task["project"], "testprj") with io.StringIO() as out: proj.body.print(out) body_lines = out.getvalue().splitlines() self.assertEqual(len(body_lines), 5) self.assertRegex(body_lines[0], r"^t\d+ \[[^]]+\] new task \+tag$") self.assertRegex(body_lines[1], r"^t\d+ \[[^]]+\] new parent task depends:1$") self.assertEqual(body_lines[2], "") self.assertEqual(body_lines[3], "body line1") self.assertEqual(body_lines[4], "body line2") with open(os.path.join(self.workdir.name, "project-testprj.json"), "rt") as fd: state = json.load(fd) tasks = state["tasks"] ids = tasks["ids"] self.assertEqual(len(ids), 2) self.assertEqual(ids[str(task.task["id"])], str(task.task["uuid"]))
def testCreateFromEgt(self): """ Test creation of new taskwarrior tasks from a project file """ self.write_project([ "body line1", "t new parent task", " t new taskwarrior task +tag", "body line3", ]) proj = Project(self.projectfile, statedir=self.workdir.name) proj.body.force_load_tw(config_filename=self.taskrc) proj.load() self.assertEqual(len(proj.body.content), 4) self.assertEqual(len(proj.body.tasks), 2) self.assertEqual(proj.body.tasks[0], proj.body.content[1]) self.assertEqual(proj.body.tasks[1], proj.body.content[2]) task = proj.body.tasks[1] self.assertEqual(task.indent, " ") self.assertIsNone(task.task) self.assertTrue(task.is_new) self.assertIsNone(task.id) self.assertEqual(task.desc, "new taskwarrior task") self.assertEqual(task.tags, {"tag"}) self.assertFalse(task.is_orphan) proj.body.sync_tasks() self.assertIsNotNone(task.task) self.assertFalse(task.is_new) self.assertIsNotNone(task.id) self.assertEqual(task.task["description"], "new taskwarrior task") self.assertEqual(task.task["tags"], ["tag", "testtag1", "testtag2"]) self.assertEqual(task.task["project"], "testprj") with io.StringIO() as out: proj.body.print(out) body_lines = out.getvalue().splitlines() self.assertEqual(len(body_lines), 4) self.assertEqual(body_lines[0], "body line1") self.assertRegex(body_lines[1], r"^t\d+ \[[^]]+\] new parent task$") self.assertRegex(body_lines[2], r"^ t\d+ \[[^]]+\] new taskwarrior task \+tag$") self.assertEqual(body_lines[3], "body line3") with open(os.path.join(self.workdir.name, "project-testprj.json"), "rt") as fd: state = json.load(fd) tasks = state["tasks"] ids = tasks["ids"] self.assertEqual(len(ids), 2) self.assertEqual(ids[str(task.task["id"])], str(task.task["uuid"]))
def testEmpty(self): with open(self.projectfile, "wt") as fd: print("Name: testprj", file=fd) print("", file=fd) proj = Project(self.projectfile, statedir=self.workdir.name) proj.load() self.assertEqual(len(proj.log._entries), 0) out = io.StringIO() proj.log.print(file=out, today=datetime.date(2018, 6, 1)) self.assertEqual(out.getvalue(), "2018\n")
def archive(self, text, today=datetime.date(2019, 2, 1)): with open(self.projectfile, "wt") as fd: if isinstance(text, str): fd.write(text) else: for line in text: print(line, file=fd) proj = Project(self.projectfile, statedir=self.workdir.name) proj.load() proj.meta.set("Name", "test") proj.meta.set("Archive-Dir", self.workdir.name) with open(self.reportfile, "wt") as fd: return proj, proj.archive(cutoff=today.replace(day=1), report_fd=fd)
def testParseFrench(self): """ Test creation of new taskwarrior tasks from a project file """ self.write_project([ "2015", "15 mars: 9:00-12:00", " - tested things", "16 mars:", " - implemented day logs", ], lang="fr") proj = Project(self.projectfile, statedir=self.workdir.name) proj.body.force_load_tw(config_filename=self.taskrc) proj.load() from egtlib.log import Timebase, Entry self.assertEqual(len(proj.log._entries), 3) self.assertIsInstance(proj.log._entries[0], Timebase) self.assertIsInstance(proj.log._entries[1], Entry) self.assertIsInstance(proj.log._entries[2], Entry) self.assertEqual(proj.log._entries[0].dt, datetime.datetime(2015, 1, 1)) entry = proj.log._entries[1] self.assertEqual(entry.begin, datetime.datetime(2015, 3, 15, 9)) self.assertEqual(entry.until, datetime.datetime(2015, 3, 15, 12)) self.assertEqual(entry.head, "15 mars: 9:00-12:00") self.assertEqual(entry.body, [" - tested things"]) self.assertEqual(entry.fullday, False) entry = proj.log._entries[2] self.assertEqual(entry.begin, datetime.datetime(2015, 3, 16, 0)) self.assertEqual(entry.until, datetime.datetime(2015, 3, 17, 0)) self.assertEqual(entry.head, "16 mars:") self.assertEqual(entry.body, [" - implemented day logs"]) self.assertEqual(entry.fullday, True) with io.StringIO() as out: proj.log.print(out, today=datetime.date(2015, 6, 1)) body_lines = out.getvalue().splitlines() self.assertEqual(len(body_lines), 5) self.assertEqual(body_lines[0], "2015") self.assertEqual(body_lines[1], "15 mars: 9:00-12:00 3h") self.assertEqual(body_lines[2], " - tested things") self.assertEqual(body_lines[3], "16 mars:") self.assertEqual(body_lines[4], " - implemented day logs")
def testWriteNewYear(self): # TODO: mock year as 2016 self.write_project([ "2015", "15 march: 9:00-12:00", " - tested things", ]) proj = Project(self.projectfile, statedir=self.workdir.name) proj.load() self.assertEqual(len(proj.log._entries), 2) out = io.StringIO() proj.log.print(file=out, today=datetime.date(2016, 6, 1)) self.assertEqual( out.getvalue(), "2015\n" "15 march: 9:00-12:00 3h\n" " - tested things\n" "2016\n")
def testTags(self): """ Test creation of new taskwarrior tasks from a project file """ self.write_project([ "2015", "15 march: 9:00-12:00 3h +tag1 +tag2", " - tested things", "16 march: +tag2", " - implemented day logs", ]) proj = Project(self.projectfile, statedir=self.workdir.name) proj.load() self.assertEqual(proj.log._entries[1].tags, ["tag1", "tag2"]) self.assertEqual(proj.log._entries[2].tags, ["tag2"]) with io.StringIO() as out: proj.log.print(out, today=datetime.date(2015, 6, 1)) body_lines = out.getvalue().splitlines() self.assertEqual(len(body_lines), 5) self.assertEqual(body_lines[0], "2015") self.assertEqual(body_lines[1], "15 march: 9:00-12:00 3h +tag1 +tag2") self.assertEqual(body_lines[2], " - tested things") self.assertEqual(body_lines[3], "16 march: +tag2") self.assertEqual(body_lines[4], " - implemented day logs") proj.log._entries[1].tags.append("tag3") with io.StringIO() as out: proj.log.print(out, today=datetime.date(2015, 6, 1)) body_lines = out.getvalue().splitlines() self.assertEqual(len(body_lines), 5) self.assertEqual(body_lines[0], "2015") self.assertEqual(body_lines[1], "15 march: 9:00-12:00 3h +tag1 +tag2 +tag3") self.assertEqual(body_lines[2], " - tested things") self.assertEqual(body_lines[3], "16 march: +tag2") self.assertEqual(body_lines[4], " - implemented day logs")
def testCreateFromEgtWithAttributes(self): """ Test creation of new taskwarrior tasks with attributes from a project file """ datedata = datetime.datetime(2031, 1, 2, 0, 0, tzinfo=tzlocal()) test_attributes = [ ("due", "2031-01-02", datedata), ("wait", "2031-01-02", datedata), ("start", "2031-01-02", datedata), ("end", "2031-01-02", datedata), ("until", "2031-01-02", datedata), ("scheduled", "2031-01-02", datedata), ("priority", "H", "H"), ("due", "2030-12-26+week", datedata), ] for key, value, data in test_attributes: attr = "{}:{}".format(key, value) with self.subTest(config=attr): self.write_project([ "body line1", "t new test task " + attr, "body line3", ]) proj = Project(self.projectfile, statedir=self.workdir.name) proj.body.force_load_tw(config_filename=self.taskrc) proj.load() task = proj.body.tasks[0] self.assertIsNone(task.task) self.assertTrue(task.is_new) self.assertIsNone(task.id) self.assertEqual(task.desc, "new test task") self.assertEqual(task.attributes, {key: value}) proj.body.sync_tasks() self.assertIsNotNone(task.task) self.assertFalse(task.is_new) self.assertIsNotNone(task.id) self.assertEqual(task.task["description"], "new test task") self.assertEqual(task.task[key], data)
def testWritePartial(self): self.write_project([ "2015", "15 march: 9:00-12:00", " - tested things", "16 march:", " - implemented day logs", ]) proj = Project(self.projectfile, statedir=self.workdir.name) proj.load() proj.log._entries.pop(0) self.assertEqual(len(proj.log._entries), 2) out = io.StringIO() proj.log.print(file=out, today=datetime.date(2015, 6, 1)) self.assertEqual( out.getvalue(), "2015\n" "15 march: 9:00-12:00 3h\n" " - tested things\n" "16 march:\n" " - implemented day logs\n")
def testCreateFromEgtWithAttributes(self): """ Test creation of new taskwarrior tasks with attributes from a project file """ datedata = datetime.datetime(2031, 1, 2, 0, 0, tzinfo=tzlocal()) test_attributes = [("due", "2031-01-02", datedata), ("wait", "2031-01-02", datedata), ("start", "2031-01-02", datedata), ("end", "2031-01-02", datedata), ("until", "2031-01-02", datedata), ("scheduled", "2031-01-02", datedata), ("priority", "H", "H"), ("due", "2030-12-26+week", datedata), ] for key, value, data in test_attributes: attr = "{}:{}".format(key, value) with self.subTest(config=attr): self.write_project([ "body line1", "t new test task "+attr, "body line3", ]) proj = Project(self.projectfile, statedir=self.workdir.name) proj.body.force_load_tw(config_filename=self.taskrc) proj.load() task = proj.body.tasks[0] self.assertIsNone(task.task) self.assertTrue(task.is_new) self.assertIsNone(task.id) self.assertEqual(task.desc, "new test task") self.assertEqual(task.attributes, {key: value}) proj.body.sync_tasks() self.assertIsNotNone(task.task) self.assertFalse(task.is_new) self.assertIsNotNone(task.id) self.assertEqual(task.task["description"], "new test task") self.assertEqual(task.task[key], data)
def annotate(self, text, today=datetime.date(2019, 2, 1)): with open(self.projectfile, "wt") as fd: if isinstance(text, str): fd.write(text) else: for line in text: print(line, file=fd) proj = Project(self.projectfile, statedir=self.workdir.name) proj.body.force_load_tw(config_filename=self.taskrc) proj.load() proj.annotate(today=today) with io.StringIO() as fd: proj.print(fd, today=today) return fd.getvalue()
def testSyncDone(self): """ Test handling of tasks present both in taskwarrior and in egt, when a task is marked done on taskwarrior """ import taskw tw = taskw.TaskWarrior(marshal=True, config_filename=self.taskrc) new_task = tw.task_add("task", ["tag", "testtag1"], project="testprj") egt_id = new_task["id"] + 10 # Add the task to egt's state using a different number than taskwarrior # has with open(os.path.join(self.workdir.name, "project-testprj.json"), "wt") as fd: json.dump({ "tasks": { "ids": { egt_id: str(new_task["uuid"]), } } }, fd, indent=1) self.write_project([ "body line1", " t{} foo the bar".format(egt_id), "body line3", ]) # Mark the task as done tw.task_done(uuid=new_task["uuid"]) tw = None # Load the project and see proj = Project(self.projectfile, statedir=self.workdir.name) proj.body.force_load_tw(config_filename=self.taskrc) proj.load() self.assertEqual(len(proj.body.content), 3) self.assertEqual(len(proj.body.tasks), 1) self.assertEqual(proj.body.tasks[0], proj.body.content[1]) task = proj.body.tasks[0] self.assertEqual(task.indent, " ") self.assertIsNone(task.task) self.assertFalse(task.is_new) self.assertEqual(task.id, egt_id) self.assertEqual(task.desc, "foo the bar") self.assertEqual(task.tags, set()) self.assertFalse(task.is_orphan) proj.body.sync_tasks() self.assertEqual(len(proj.body.tasks), 1) self.assertEqual(task, proj.body.tasks[0]) self.assertIsNotNone(task.task) self.assertFalse(task.is_new) self.assertIsNone(task.id) self.assertEqual(task.task["description"], "task") self.assertEqual(task.task["tags"], ["tag", "testtag1"]) self.assertEqual(task.task["project"], "testprj") with io.StringIO() as out: proj.body.print(out) body_lines = out.getvalue().splitlines() self.assertEqual(len(body_lines), 3) self.assertEqual(body_lines[0], "body line1") self.assertRegex(body_lines[1], r"^ - \[[^]]+\] task \+tag$") self.assertEqual(body_lines[2], "body line3") with open(os.path.join(self.workdir.name, "project-testprj.json"), "rt") as fd: state = json.load(fd) tasks = state["tasks"] ids = tasks["ids"] self.assertEqual(len(ids), 0)
def test_mixed_langs(self): lines = [ "2015", "9:00-", " - tested things", "+", " - implemented day logs", ] self.write_project(lines + ["15 march:", " - localized"]) proj_default = Project(self.projectfile, statedir=self.workdir.name) proj_default.load() self.assertEqual(proj_default.log._entries[3].begin, datetime.datetime(2015, 3, 15, 0, 0, 0)) self.write_project(lines + ["15 marzo:", " - localized"], lang="it") proj_it = Project(self.projectfile, statedir=self.workdir.name) proj_it.load() self.assertEqual(proj_it.log._entries[3].begin, datetime.datetime(2015, 3, 15, 0, 0, 0)) self.write_project(lines + ["15 mars:", " - localized"], lang="fr") proj_fr = Project(self.projectfile, statedir=self.workdir.name) proj_fr.load() self.assertEqual(proj_fr.log._entries[3].begin, datetime.datetime(2015, 3, 15, 0, 0, 0)) self.write_project(lines + ["15 march:", " - localized"]) proj_default1 = Project(self.projectfile, statedir=self.workdir.name) proj_default1.load() self.assertEqual(proj_default1.log._entries[3].begin, datetime.datetime(2015, 3, 15, 0, 0, 0)) proj_default.log.sync(today=datetime.date(2016, 6, 1)) proj_it.log.sync(today=datetime.date(2016, 6, 1)) proj_fr.log.sync(today=datetime.date(2016, 6, 1)) with io.StringIO() as out: proj_default.log.print(out, today=datetime.date(2015, 6, 1)) body_lines = out.getvalue().splitlines() self.assertEqual(body_lines, [ "2015", "01 June: 09:00-", " - tested things", "01 June:", " - implemented day logs", "15 march:", " - localized", ]) with io.StringIO() as out: proj_it.log.print(out, today=datetime.date(2015, 6, 1)) body_lines = out.getvalue().splitlines() self.assertEqual(body_lines, [ "2015", "01 giugno: 09:00-", " - tested things", "01 giugno:", " - implemented day logs", "15 marzo:", " - localized", ]) with io.StringIO() as out: proj_fr.log.print(out, today=datetime.date(2015, 6, 1)) body_lines = out.getvalue().splitlines() self.assertEqual(body_lines, [ "2015", "01 juin: 09:00-", " - tested things", "01 juin:", " - implemented day logs", "15 mars:", " - localized", ])
def testParseNewRequest(self): """ Test creation of new taskwarrior tasks from a project file """ self.write_project([ "2015", "15 march: 9:00-12:00", " - tested things", "8:00", " - new entry", "+", " - new day entry", ]) proj = Project(self.projectfile, statedir=self.workdir.name) proj.body.force_load_tw(config_filename=self.taskrc) proj.load() from egtlib.log import Timebase, Entry, Command self.assertEqual(len(proj.log._entries), 4) self.assertIsInstance(proj.log._entries[0], Timebase) self.assertIsInstance(proj.log._entries[1], Entry) self.assertIsInstance(proj.log._entries[2], Command) self.assertIsInstance(proj.log._entries[3], Command) self.assertEqual(proj.log._entries[0].dt, datetime.datetime(2015, 1, 1)) self.assertEqual(proj.log._entries[1].begin, datetime.datetime(2015, 3, 15, 9)) self.assertEqual(proj.log._entries[1].until, datetime.datetime(2015, 3, 15, 12)) self.assertEqual(proj.log._entries[1].head, "15 march: 9:00-12:00") self.assertEqual(proj.log._entries[1].body, [" - tested things"]) new_entry_dt2 = datetime.datetime.combine(datetime.datetime.today(), datetime.time(8, 0, 0)) self.assertEqual(proj.log._entries[2].start, datetime.time(8, 0)) self.assertEqual(proj.log._entries[2].head, "8:00") self.assertEqual(proj.log._entries[2].body, [" - new entry"]) new_entry_dt3 = datetime.datetime.combine(datetime.datetime.today(), datetime.time(0)) self.assertEqual(proj.log._entries[3].start, None) self.assertEqual(proj.log._entries[3].head, "+") self.assertEqual(proj.log._entries[3].body, [" - new day entry"]) proj.log.sync() self.assertEqual(len(proj.log._entries), 4) self.assertIsInstance(proj.log._entries[0], Timebase) self.assertIsInstance(proj.log._entries[1], Entry) self.assertIsInstance(proj.log._entries[2], Entry) self.assertIsInstance(proj.log._entries[3], Entry) self.assertEqual(proj.log._entries[0].dt, datetime.datetime(2015, 1, 1)) self.assertEqual(proj.log._entries[1].begin, datetime.datetime(2015, 3, 15, 9)) self.assertEqual(proj.log._entries[1].until, datetime.datetime(2015, 3, 15, 12)) self.assertEqual(proj.log._entries[1].head, "15 march: 9:00-12:00") self.assertEqual(proj.log._entries[1].body, [" - tested things"]) new_entry_dt2 = datetime.datetime.combine(datetime.datetime.today(), datetime.time(8, 0, 0)) self.assertEqual(proj.log._entries[2].begin, new_entry_dt2) self.assertEqual(proj.log._entries[2].until, None) self.assertEqual(proj.log._entries[2].head, new_entry_dt2.strftime("%d %B: %H:%M-")) self.assertEqual(proj.log._entries[2].body, [" - new entry"]) self.assertEqual(proj.log._entries[2].fullday, False) new_entry_dt3 = datetime.datetime.combine(datetime.datetime.today(), datetime.time(0)) self.assertEqual(proj.log._entries[3].begin, new_entry_dt3) self.assertEqual(proj.log._entries[3].until, new_entry_dt3 + datetime.timedelta(days=1)) self.assertEqual(proj.log._entries[3].head, new_entry_dt3.strftime("%d %B:")) self.assertEqual(proj.log._entries[3].body, [" - new day entry"]) self.assertEqual(proj.log._entries[3].fullday, True) with io.StringIO() as out: proj.log.print(out) body_lines = out.getvalue().splitlines() self.assertEqual(len(body_lines), 7) self.assertEqual(body_lines[0], "2015") self.assertEqual(body_lines[1], "15 march: 9:00-12:00 3h") self.assertEqual(body_lines[2], " - tested things") self.assertEqual(body_lines[3], new_entry_dt2.strftime("%d %B: %H:%M-")) self.assertEqual(body_lines[4], " - new entry") self.assertEqual(body_lines[5], new_entry_dt3.strftime("%d %B:")) self.assertEqual(body_lines[6], " - new day entry")
def testSyncDone(self): """ Test handling of tasks present both in taskwarrior and in egt, when a task is marked done on taskwarrior """ import taskw tw = taskw.TaskWarrior(marshal=True, config_filename=self.taskrc) new_task = tw.task_add("task", ["tag", "testtag1"], project="testprj") egt_id = new_task["id"] + 10 # Add the task to egt's state using a different number than taskwarrior # has with open(os.path.join(self.workdir.name, "project-testprj.json"), "wt") as fd: json.dump({"tasks": { "ids": { egt_id: str(new_task["uuid"]), } }}, fd, indent=1) self.write_project([ "body line1", " t{} foo the bar".format(egt_id), "body line3", ]) # Mark the task as done tw.task_done(uuid=new_task["uuid"]) tw = None # Load the project and see proj = Project(self.projectfile, statedir=self.workdir.name) proj.body.force_load_tw(config_filename=self.taskrc) proj.load() self.assertEqual(len(proj.body.content), 3) self.assertEqual(len(proj.body.tasks), 1) self.assertEqual(proj.body.tasks[0], proj.body.content[1]) task = proj.body.tasks[0] self.assertEqual(task.indent, " ") self.assertIsNone(task.task) self.assertFalse(task.is_new) self.assertEqual(task.id, egt_id) self.assertEqual(task.desc, "foo the bar") self.assertEqual(task.tags, set()) self.assertFalse(task.is_orphan) proj.body.sync_tasks() self.assertEqual(len(proj.body.tasks), 1) self.assertEqual(task, proj.body.tasks[0]) self.assertIsNotNone(task.task) self.assertFalse(task.is_new) self.assertIsNone(task.id) self.assertEqual(task.task["description"], "task") self.assertEqual(task.task["tags"], ["tag", "testtag1"]) self.assertEqual(task.task["project"], "testprj") with io.StringIO() as out: proj.body.print(out) body_lines = out.getvalue().splitlines() self.assertEqual(len(body_lines), 3) self.assertEqual(body_lines[0], "body line1") self.assertRegex(body_lines[1], r"^ - \[[^]]+\] task \+tag$") self.assertEqual(body_lines[2], "body line3") with open(os.path.join(self.workdir.name, "project-testprj.json"), "rt") as fd: state = json.load(fd) tasks = state["tasks"] ids = tasks["ids"] self.assertEqual(len(ids), 0)