def testTitleFormater(self): dbutils.getOrCreateProject("x", interactive=False) dbutils.getOrCreateKeyword("key1", interactive=False) dbutils.getOrCreateKeyword("key2", interactive=False) task = dbutils.addTask("x", "t1", {}) taskWithKeywords = dbutils.addTask("x", "t2", {"key1": None, "key2": 12}) longTask = dbutils.addTask("x", "01234567890123456789", {}) longTask.description = "And it has a description" TEST_DATA = ( (task, 20, "t1"), (taskWithKeywords, 20, "t2 (key1, key2)"), (taskWithKeywords, 4, "t2 >"), (longTask, 10, longTask.title[:8] + ">*"), (longTask, len(longTask.title), longTask.title[:-2] + ">*"), (longTask, len(longTask.title) + 1, longTask.title + "*"), (longTask, 40, longTask.title.ljust(39) + "*"), ) for task, width, expected in TEST_DATA: with self.subTest(task=task, width=width): formater = TitleFormater(width) out = formater(task)[0] out = stripColor(out) expected = expected.ljust(width) self.assertEqual(out, expected)
def testTitleFormater(self): dbutils.getOrCreateProject("x", interactive=False) dbutils.getOrCreateKeyword("key1", interactive=False) dbutils.getOrCreateKeyword("key2", interactive=False) task = dbutils.addTask("x", "t1", {}) taskWithKeywords = dbutils.addTask("x", "t2", { "key1": None, "key2": 12 }) longTask = dbutils.addTask("x", "01234567890123456789", {}) longTask.description = "And it has a description" TEST_DATA = ( (task, 20, "t1"), (taskWithKeywords, 20, "t2 (key1, key2)"), (taskWithKeywords, 4, "t2 >"), (longTask, 10, longTask.title[:8] + ">*"), (longTask, len(longTask.title), longTask.title[:-2] + ">*"), (longTask, len(longTask.title) + 1, longTask.title + "*"), (longTask, 40, longTask.title.ljust(39) + "*"), ) for task, width, expected in TEST_DATA: with self.subTest(task=task, width=width): formater = TitleFormater(width, StubCryptoMgr()) out = formater(task)[0] out = stripColor(out) expected = expected.ljust(width) self.assertEqual(out, expected)
def testOnlyListTasks(self): prj = dbutils.getOrCreateProject("p1", interactive=False) t1 = dbutils.addTask("p1", "Task", {}) t2 = dbutils.addTask("p1", "Note", {NOTE_KEYWORD: None}) oldList = massedit.createEntriesForProject(prj) self.assertEqual(len(oldList), 1)
def testFullRendering(self): dbutils.getOrCreateProject("x", interactive=False) dbutils.getOrCreateKeyword("k1", interactive=False) dbutils.getOrCreateKeyword("k2", interactive=False) t1 = dbutils.addTask("x", "t1", {}) t2 = dbutils.addTask("x", "t2", {"k1": None, "k2": 12}) longTask = dbutils.addTask("x", "A longer task name", {}) longTask.description = "And it has a description" out = StringIO() renderer = TextListRenderer(out, termWidth=80, cryptoMgr=YokadiCryptoManager()) renderer.addTaskList("Foo", [t2, longTask]) self.assertEqual(renderer.maxTitleWidth, len(longTask.title) + 1) renderer.end() out = stripColor(out.getvalue()) expected = \ " Foo \n" \ + "ID│Title │U │S│Age │Due date\n" \ + "──┼───────────────────┼───┼─┼────────┼────────\n" \ + "2 │t2 (k1, k2) │0 │N│0m │ \n" \ + "3 │A longer task name*│0 │N│0m │ \n" self.assertMultiLineEqual(out, expected)
def testKList(self): t1 = dbutils.addTask("x", "t1", dict(k1=12, k2=None), interactive=False) t2 = dbutils.addTask("x", "t2", dict(k1=None, k3=None), interactive=False) lst = list(_listKeywords(self.session)) lst = [(name, list(ids)) for name, ids in lst] self.assertEqual(lst, [("k1", [t1.id, t2.id]), ("k2", [t1.id]), ("k3", [t2.id]), ])
def testTitleFormater(self): dbutils.getOrCreateProject("x", interactive=False) dbutils.getOrCreateKeyword("k1", interactive=False) dbutils.getOrCreateKeyword("k2", interactive=False) t1 = dbutils.addTask("x", "t1", {}) t2 = dbutils.addTask("x", "t2", {"k1": None, "k2": 12}) longerTask = dbutils.addTask("x", "A longer task name", {}) longerTask.description = "And it has a description" out = StringIO() renderer = TextListRenderer(out, termWidth=80, cryptoMgr=YokadiCryptoManager()) renderer.addTaskList("Foo", [t1]) self.assertEquals(renderer.maxTitleWidth, 5) renderer.end() expected = unicode(\ "%(CYAN)s Foo %(RESET)s\n" \ + "%(BOLD)sID|Title|U |S|Age |Due date%(RESET)s\n" \ + "--------------------------------\n" \ + "1 |t1 %(RESET)s|0 |N|0m | \n" \ ) % dict(CYAN=C.CYAN, RESET=C.RESET, BOLD=C.BOLD) testutils.multiLinesAssertEqual(self, out.getvalue(), expected) out = StringIO() renderer = TextListRenderer(out, termWidth=80, cryptoMgr=YokadiCryptoManager()) renderer.addTaskList("Foo", [t1, t2]) self.assertEquals(renderer.maxTitleWidth, 11) renderer.end() expected = unicode(\ "%(CYAN)s Foo %(RESET)s\n" \ + "%(BOLD)sID|Title |U |S|Age |Due date%(RESET)s\n" \ + "--------------------------------------\n" \ + "1 |t1 %(RESET)s|0 |N|0m | \n" \ + "2 |t2 (%(BOLD)sk1, k2)%(RESET)s|0 |N|0m | \n" \ ) % dict(CYAN=C.CYAN, RESET=C.RESET, BOLD=C.BOLD) testutils.multiLinesAssertEqual(self, out.getvalue(), expected) out = StringIO() renderer = TextListRenderer(out, termWidth=80, cryptoMgr=YokadiCryptoManager()) renderer.addTaskList("Foo", [t2, longerTask]) self.assertEquals(renderer.maxTitleWidth, len(longerTask.title) + 1) renderer.end() expected = unicode(\ "%(CYAN)s Foo %(RESET)s\n" \ + "%(BOLD)sID|Title |U |S|Age |Due date%(RESET)s\n" \ + "----------------------------------------------\n" \ + "2 |t2 (%(BOLD)sk1, k2) %(RESET)s|0 |N|0m | \n" \ + "3 |A longer task name%(RESET)s*|0 |N|0m | \n" \ ) % dict(CYAN=C.CYAN, RESET=C.RESET, BOLD=C.BOLD) testutils.multiLinesAssertEqual(self, out.getvalue(), expected)
def testApplyMEditChangesUnknownIds(self): prj = dbutils.getOrCreateProject("p1", interactive=False) t1 = dbutils.addTask("p1", "Foo", {}) t2 = dbutils.addTask("p1", "Bar", {}) oldList = massedit.createEntriesForProject(prj) newList = [ MEditEntry(t1.id, "new", t1.title, {}), MEditEntry(t2.id + 1, "new", t2.title, {}), ] self.assertRaises(YokadiException, massedit.applyChanges, prj, oldList, newList, interactive=False)
def testTitleFormater(self): dbutils.getOrCreateProject("x", interactive=False) dbutils.getOrCreateKeyword("k1", interactive=False) dbutils.getOrCreateKeyword("k2", interactive=False) t1 = dbutils.addTask("x", "t1", {}) t2 = dbutils.addTask("x", "t2", {"k1": None, "k2": 12}) longerTask = dbutils.addTask("x", "A longer task name", {}) longerTask.description = "And it has a description" out = StringIO() renderer = TextListRenderer(out, termWidth=80, cryptoMgr=YokadiCryptoManager()) renderer.addTaskList("Foo", [t1]) self.assertEqual(renderer.maxTitleWidth, 5) renderer.end() expected = str(\ "%(CYAN)s Foo %(RESET)s\n" \ + "%(BOLD)sID|Title|U |S|Age |Due date%(RESET)s\n" \ + "--------------------------------\n" \ + "1 |t1 %(RESET)s|0 |N|0m | \n" \ ) % dict(CYAN=C.CYAN, RESET=C.RESET, BOLD=C.BOLD) testutils.multiLinesAssertEqual(self, out.getvalue(), expected) out = StringIO() renderer = TextListRenderer(out, termWidth=80, cryptoMgr=YokadiCryptoManager()) renderer.addTaskList("Foo", [t1, t2]) self.assertEqual(renderer.maxTitleWidth, 11) renderer.end() expected = str(\ "%(CYAN)s Foo %(RESET)s\n" \ + "%(BOLD)sID|Title |U |S|Age |Due date%(RESET)s\n" \ + "--------------------------------------\n" \ + "1 |t1 %(RESET)s|0 |N|0m | \n" \ + "2 |t2 (%(BOLD)sk1, k2)%(RESET)s|0 |N|0m | \n" \ ) % dict(CYAN=C.CYAN, RESET=C.RESET, BOLD=C.BOLD) testutils.multiLinesAssertEqual(self, out.getvalue(), expected) out = StringIO() renderer = TextListRenderer(out, termWidth=80, cryptoMgr=YokadiCryptoManager()) renderer.addTaskList("Foo", [t2, longerTask]) self.assertEqual(renderer.maxTitleWidth, len(longerTask.title) + 1) renderer.end() expected = str(\ "%(CYAN)s Foo %(RESET)s\n" \ + "%(BOLD)sID|Title |U |S|Age |Due date%(RESET)s\n" \ + "----------------------------------------------\n" \ + "2 |t2 (%(BOLD)sk1, k2) %(RESET)s|0 |N|0m | \n" \ + "3 |A longer task name%(RESET)s*|0 |N|0m | \n" \ ) % dict(CYAN=C.CYAN, RESET=C.RESET, BOLD=C.BOLD) testutils.multiLinesAssertEqual(self, out.getvalue(), expected)
def testKEditMerge(self): t1 = dbutils.addTask("x", "t1", dict(k1=None, k2=None), interactive=False) t2 = dbutils.addTask("x", "t2", dict(k1=None), interactive=False) tui.addInputAnswers("k2", "y") self.cmd.do_k_edit("k1") kwDict = t1.getKeywordDict() self.assertTrue("k1" not in kwDict) self.assertTrue("k2" in kwDict) kwDict = t2.getKeywordDict() self.assertTrue("k1" not in kwDict) self.assertTrue("k2" in kwDict) self.assertRaises(YokadiException, dbutils.getKeywordFromName, "k1")
def testTitleMapping(self): tui.addInputAnswers("y") t1 = dbutils.addTask("x", "t1", {}) v1 = yical.createVTodoFromTask(t1) # Check id is here self.assertEqual(v1.get("summary")[-4:], " (%s)" % t1.id) # Title and id should not change with update origin_id = t1.id origin_title = t1.title yical.updateTaskFromVTodo(t1, v1) self.assertEqual(t1.id, origin_id) self.assertEqual(t1.title, origin_title) # Update vtodo summary and remove (id) or space before (id) info. # Only task title should be changed for new_summary in ("hello", "hello(%s)" % origin_id, "hello (%s)" % origin_id, "(%s)hello" % origin_id, " (%s)hello" % origin_id): v1["summary"] = new_summary yical.updateTaskFromVTodo(t1, v1) self.assertEqual(t1.id, origin_id) self.assertEqual(t1.title, "hello") # Update votod with fake id info. # Should be present in task title for new_summary in ("hello", "hello()", "hello(123456)", "hello (123456)"): v1["summary"] = new_summary yical.updateTaskFromVTodo(t1, v1) self.assertEqual(t1.id, origin_id) self.assertEqual(t1.title, new_summary)
def _processVTodo(self, vTodo): if vTodo["UID"] in self.newTask: # This is a recent new task but remote ical calendar tool is not # aware of new Yokadi UID. Update it here to avoid duplicate new tasks print "update UID to avoid duplicate task" vTodo["UID"] = TASK_UID % self.newTask[vTodo["UID"]] if vTodo["UID"].startswith(UID_PREFIX): # This is a yokadi Task. if vTodo["LAST-MODIFIED"].dt > vTodo["CREATED"].dt: # Task has been modified print "Modified task: %s" % vTodo["UID"] result = TASK_RE.match(vTodo["UID"]) if result: id = result.group(1) task = dbutils.getTaskFromId(id) print "Task found in yokadi db: %s" % task.title updateTaskFromVTodo(task, vTodo) else: raise YokadiException("Task %s does exist in yokadi db " % id) else: # This is a new task print "New task %s (%s)" % (vTodo["summary"], vTodo["UID"]) keywordDict = {} task = dbutils.addTask(INBOX_PROJECT, vTodo["summary"], keywordDict, interactive=False) # Keep record of new task origin UID to avoid duplicate # if user update it right after creation without reloading the # yokadi UID # TODO: add purge for old UID self.newTask[vTodo["UID"]] = task.id
def _t_add(self, cmd, line): """Code shared by t_add, bug_add and n_add.""" parser = self._parser_t_add(cmd) args = parser.parse_args(line) line = " ".join(args.cmd) if not line: raise BadUsageException("Missing parameters") projectName, title, keywordDict = parseutils.parseLine(line) projectName = self._realProjectName(projectName) if not title: raise BadUsageException("Missing title") if args.crypt: # Obfuscate line in history length = readline.get_current_history_length() if length > 0: # Ensure history is positive to avoid crash with bad readline setup readline.replace_history_item(length - 1, "%s %s " % (cmd, line.replace(title, "<...encrypted...>"))) # Encrypt title title = self.cryptoMgr.encrypt(title) task = dbutils.addTask(projectName, title, keywordDict) if not task: tui.reinjectInRawInput("%s %s" % (cmd, line)) return None self.lastTaskId = task.id if args.describe: self.do_t_describe(self.lastTaskId) return task
def _t_add(self, cmd, line): """Code shared by t_add, bug_add and n_add.""" parser = self._parser_t_add(cmd) args = parser.parse_args(line) line = " ".join(args.cmd) if not line: raise BadUsageException("Missing parameters") projectName, title, keywordDict = parseutils.parseLine(line) projectName = self._realProjectName(projectName) if not title: raise BadUsageException("Missing title") if args.crypt: # Obfuscate line in history length = readline.get_current_history_length() if length > 0: # Ensure history is positive to avoid crash with bad readline setup readline.replace_history_item( length - 1, "%s %s " % (cmd, line.replace(title, "<...encrypted...>"))) # Encrypt title title = self.cryptoMgr.encrypt(title) task = dbutils.addTask(projectName, title, keywordDict) if not task: tui.reinjectInRawInput(u"%s %s" % (cmd, line)) return None self.lastTaskId = task.id if args.describe: self.do_t_describe(self.lastTaskId) return task
def testKEditNoMerge(self): t1 = dbutils.addTask("x", "t1", dict(k1=12, k2=None), interactive=False) tui.addInputAnswers("newk1") self.cmd.do_k_edit("k1") kwDict = t1.getKeywordDict() self.assertTrue("k1" not in kwDict) self.assertEqual(kwDict.get("newk1"), 12) self.assertRaises(YokadiException, dbutils.getKeywordFromName, "k1")
def testKRemove(self): t1 = dbutils.addTask("x", "t1", dict(k1=12, k2=None), interactive=False) tui.addInputAnswers("y") self.cmd.do_k_remove("k1") kwDict = t1.getKeywordDict() self.assertFalse("k1" in kwDict) self.assertTrue("k2" in kwDict) taskKeyword = self.session.query(db.TaskKeyword).filter_by(taskId=t1.id).one() self.assertEqual(taskKeyword.keyword.name, "k2")
def testTfilter(self): t1 = dbutils.addTask("x", "t1", interactive=False) t2 = dbutils.addTask("x", "t2", keywordDict={"kw1": None, "kw2": 12}, interactive=False) t3 = dbutils.addTask("y", "t3", interactive=False) testData = [ ("@kw1", {"x": [t2]}), ("x", {"x": [t1, t2]}), ("x @kw1", {"x": [t2]}), ("none", {"x": [t1, t2], "y": [t3]}), ] for filter, expectedTaskDict in testData: self.cmd.do_t_filter(filter) renderer = testutils.TestRenderer() self.cmd.do_t_list("", renderer=renderer) self.assertEqual(renderer.taskDict, expectedTaskDict) self.assertRaises(YokadiException, self.cmd.do_t_filter, "")
def testSimpleFilter(self): t1 = dbutils.addTask("p1", "t1", interactive=False) t2 = dbutils.addTask("p1", "t2", keywordDict={"k1": None}, interactive=False) t3 = dbutils.addTask("p1", "t3", keywordDict={"k2": None}, interactive=False) t4 = dbutils.addTask("p1", "t4", keywordDict={"k1": None, "k2": None}, interactive=False) testData = [ (KeywordFilter("k1"), {t2, t4}), (KeywordFilter("k%"), {t2, t3, t4}), (KeywordFilter("k1", negative=True), {t1, t3}), (KeywordFilter("k%", negative=True), {t1}), ] for flt, expected in testData: query = self.session.query(db.Task) query = flt.apply(query) resultSet = {x.title for x in query} expectedSet = {x.title for x in expected} self.assertEqual(resultSet, expectedSet)
def testTfilter(self): t1 = dbutils.addTask("x", "t1", interactive=False) t2 = dbutils.addTask("x", "t2", keywordDict={"kw1": None, "kw2": 12}, interactive=False) t3 = dbutils.addTask("y", "t3", interactive=False) testData = [ ("@kw1", {"x": [t2]}), ("@kw1 @kw2", {"x": [t2]}), ("x", {"x": [t1, t2]}), ("x @kw1", {"x": [t2]}), ("none", {"x": [t1, t2], "y": [t3]}), ] for filter, expectedTaskDict in testData: self.cmd.do_t_filter(filter) renderer = testutils.TestRenderer() self.cmd.do_t_list("", renderer=renderer) self.assertEqual(renderer.taskDict.keys(), expectedTaskDict.keys()) for key in renderer.taskDict.keys(): self.assertEqual([x.title for x in renderer.taskDict[key]], [x.title for x in expectedTaskDict[key]]) self.assertRaises(YokadiException, self.cmd.do_t_filter, "")
def testGetTaskFromId(self): tui.addInputAnswers("y") t1 = dbutils.addTask("x", "t1", {}) task = dbutils.getTaskFromId(str(t1.id)) self.assertEqual(task, t1) task = dbutils.getTaskFromId(t1.id) self.assertEqual(task, t1) task = dbutils.getTaskFromId(t1.uuid) self.assertEqual(task, t1)
def testKEditCannotMerge(self): """ One can't merge keywords if they have different values """ t1 = dbutils.addTask("x", "t1", dict(k1=12, k2=None), interactive=False) tui.addInputAnswers("k2", "y") self.cmd.do_k_edit("k1") kwDict = t1.getKeywordDict() self.assertTrue("k1" in kwDict) self.assertTrue("k2" in kwDict) dbutils.getKeywordFromName("k1")
def testApplyMEditChanges(self): prj = dbutils.getOrCreateProject("p1", interactive=False) t1 = dbutils.addTask("p1", "Change text", {}) tui.addInputAnswers("y", "y") t2 = dbutils.addTask("p1", "Change keywords", {"k1": None, "k2": 1}) t3 = dbutils.addTask("p1", "Done", {}) t3.status = "started" self.session.merge(t3) t4 = dbutils.addTask("p1", "Deleted", {}) t5 = dbutils.addTask("p1", "Moved", {}) self.session.commit() deletedId = t4.id oldList = massedit.createEntriesForProject(prj) newList = [ MEditEntry(None, "new", u"Added", {}), MEditEntry(t1.id, "new", u"New text", {}), MEditEntry(t2.id, "new", u"Change keywords", { "k2": 2, "k3": None }), MEditEntry(t5.id, "new", u"Moved", {}), MEditEntry(t3.id, "done", u"Done", {}), ] massedit.applyChanges(prj, oldList, newList, interactive=False) self.session.commit() newTask = self.session.query(db.Task).filter_by(title=u"Added").one() self.assertEqual(t1.title, u"New text") self.assertEqual(t2.getKeywordDict(), {"k2": 2, "k3": None}) self.assertEqual(t3.status, "done") self.assertTrue(t3.doneDate) self.assertRaises(YokadiException, dbutils.getTaskFromId, deletedId) self.assertEqual(newTask.urgency, 5) self.assertEqual(t1.urgency, 4) self.assertEqual(t2.urgency, 3) self.assertEqual(t5.urgency, 2) self.assertEqual(t3.urgency, 1)
def testKRemove(self): t1 = dbutils.addTask("x", "t1", dict(k1=12, k2=None), interactive=False) tui.addInputAnswers("y") self.cmd.do_k_remove("k1") kwDict = t1.getKeywordDict() self.assertFalse("k1" in kwDict) self.assertTrue("k2" in kwDict) taskKeyword = self.session.query( db.TaskKeyword).filter_by(taskId=t1.id).one() self.assertEqual(taskKeyword.keyword.name, "k2")
def testEdit(self): task = dbutils.addTask("prj", "bug", interactive=False) kwDict = dict(_severity=1, _likelihood=2, _bug=3) task.setKeywordDict(kwDict) self.session.commit() tui.addInputAnswers("bug edited", "2", "4", "6") self.cmd.do_bug_edit(str(task.id)) task = dbutils.getTaskFromId(task.id) self.assertEqual(task.title, "bug edited") kwDict = task.getKeywordDict() self.assertEqual(kwDict, dict(_severity=2, _likelihood=4, _bug=6))
def testMerge(self): COUNT = 4 for x in range(COUNT): dbutils.addTask('p1', 'p1-t{}'.format(x), interactive=False) dbutils.addTask('p2', 'p2-t{}'.format(x), interactive=False) # Merge p1 into p2 tui.addInputAnswers("y") self.cmd.do_p_merge("p1 p2") # p2 should have both its tasks and all p1 tasks now project = self.session.query(Project).filter_by(name="p2").one() tasks = set([x.title for x in project.tasks]) expected = set() for x in range(COUNT): expected.add('p1-t{}'.format(x)) expected.add('p2-t{}'.format(x)) self.assertEqual(tasks, expected) # p1 should be gone testutils.assertQueryEmpty(self, self.session.query(Project).filter_by(name="p1"))
def testRemove(self): # Create project p1 with one associated task tui.addInputAnswers("y") self.cmd.do_p_add("p1") self.session.query(Project).one() task = dbutils.addTask("p1", "t1", interactive=False) taskId = task.id # Remove project, its task should be removed tui.addInputAnswers("y") self.cmd.do_p_remove("p1") self.assertEqual(list(self.session.query(Task).filter_by(id=taskId)), [])
def testFullRendering(self): dbutils.getOrCreateProject("x", interactive=False) dbutils.getOrCreateKeyword("k1", interactive=False) dbutils.getOrCreateKeyword("k2", interactive=False) dbutils.addTask("x", "t1", {}) t2 = dbutils.addTask("x", "t2", {"k1": None, "k2": 12}) longTask = dbutils.addTask("x", "A longer task name", {}) longTask.description = "And it has a description" out = StringIO() renderer = TextListRenderer(out, termWidth=80) renderer.addTaskList("Foo", [t2, longTask]) self.assertEqual(renderer.maxTitleWidth, len(longTask.title) + 1) renderer.end() out = stripColor(out.getvalue()) expected = \ " Foo \n" \ "ID│Title │U │S│Age │Due date\n" \ "──┼───────────────────┼───┼─┼────────┼────────\n" \ "2 │t2 (k1, k2) │0 │N│0m │ \n" \ "3 │A longer task name*│0 │N│0m │ \n" self.assertMultiLineEqual(out, expected)
def testRemove(self): # Create project p1 with one associated task tui.addInputAnswers("y") self.cmd.do_p_add("p1") project = self.session.query(Project).one() task = dbutils.addTask("p1", "t1", interactive=False) taskId = task.id # Remove project, its task should be removed tui.addInputAnswers("y") self.cmd.do_p_remove("p1") self.assertEqual(list(self.session.query(Task).filter_by(id=taskId)), [])
def testApplyMEditChanges(self): prj = dbutils.getOrCreateProject("p1", interactive=False) t1 = dbutils.addTask("p1", "Change text", {}) tui.addInputAnswers("y", "y") t2 = dbutils.addTask("p1", "Change keywords", {"k1": None, "k2": 1}) t3 = dbutils.addTask("p1", "Done", {}) t3.status = "started" self.session.merge(t3) t4 = dbutils.addTask("p1", "Deleted", {}) t5 = dbutils.addTask("p1", "Moved", {}) self.session.commit() deletedId = t4.id oldList = massedit.createEntriesForProject(prj) newList = [ MEditEntry(None, "new", u"Added", {}), MEditEntry(t1.id, "new", u"New text", {}), MEditEntry(t2.id, "new", u"Change keywords", {"k2": 2, "k3": None}), MEditEntry(t5.id, "new", u"Moved", {}), MEditEntry(t3.id, "done", u"Done", {}), ] massedit.applyChanges(prj, oldList, newList, interactive=False) self.session.commit() newTask = self.session.query(db.Task).filter_by(title=u"Added").one() self.assertEqual(t1.title, u"New text") self.assertEqual(t2.getKeywordDict(), {"k2": 2, "k3": None}) self.assertEqual(t3.status, "done") self.assertTrue(t3.doneDate) self.assertRaises(YokadiException, dbutils.getTaskFromId, deletedId) self.assertEqual(newTask.urgency, 5) self.assertEqual(t1.urgency, 4) self.assertEqual(t2.urgency, 3) self.assertEqual(t5.urgency, 2) self.assertEqual(t3.urgency, 1)
def testTaskLockManagerStaleLock(self): tui.addInputAnswers("y") t1 = dbutils.addTask("x", "t1", {}) taskLockManager = dbutils.TaskLockManager(t1) # Lock the task taskLockManager.acquire(pid=1, now=datetime(2014, 1, 1)) lock1 = taskLockManager._getLock() self.assertEqual(lock1.pid, 1) # Try to lock again, the stale lock should get reused taskLockManager.acquire(pid=2, now=datetime(2015, 1, 1)) lock2 = taskLockManager._getLock() self.assertEqual(lock1.id, lock2.id) self.assertEqual(lock2.pid, 2)
def testMerge(self): COUNT = 4 for x in range(COUNT): dbutils.addTask('p1', 'p1-t{}'.format(x), interactive=False) dbutils.addTask('p2', 'p2-t{}'.format(x), interactive=False) # Merge p1 into p2 tui.addInputAnswers("y") self.cmd.do_p_merge("p1 p2") # p2 should have both its tasks and all p1 tasks now project = self.session.query(Project).filter_by(name="p2").one() tasks = set([x.title for x in project.tasks]) expected = set() for x in range(COUNT): expected.add('p1-t{}'.format(x)) expected.add('p2-t{}'.format(x)) self.assertEqual(tasks, expected) # p1 should be gone testutils.assertQueryEmpty( self, self.session.query(Project).filter_by(name="p1"))
def testUrgencyMapping(self): tui.addInputAnswers("y") t1 = dbutils.addTask("x", "t1", {}) v1 = yical.createVTodoFromTask(t1) self.assertEqual(v1.get("priority"), None) # No priority t1.urgency = 45 v1 = yical.createVTodoFromTask(t1) self.assertEqual(v1.get("priority"), 2) yical.updateTaskFromVTodo(t1, v1) self.assertEqual(t1.urgency, 45) # Ensure urgency does change v1["priority"] = 4 yical.updateTaskFromVTodo(t1, v1) self.assertEqual(t1.urgency, 20) # Check urgency is updated
def testUrgencyMapping(self): tui.addInputAnswers("y") t1 = dbutils.addTask("x", "t1", {}) v1 = yical.createVTodoFromTask(t1) self.assertEquals(v1.get("priority"), None) # No priority t1.urgency = 45 v1 = yical.createVTodoFromTask(t1) self.assertEquals(v1.get("priority"), 2) yical.updateTaskFromVTodo(t1, v1) self.assertEquals(t1.urgency, 45) # Ensure urgency does change v1["priority"] = 4 yical.updateTaskFromVTodo(t1, v1) self.assertEquals(t1.urgency, 20) # Check urgency is updated
def testRemove(self): # Create project p1, with one project keyword and one associated task tui.addInputAnswers("y") self.cmd.do_p_add("p1 @kw") project = self.session.query(Project).one() task = dbutils.addTask("p1", "t1", interactive=False) taskId = task.id keyword = self.session.query(Keyword).filter_by(name="kw").one() self.assertEqual(keyword.projects, [project]) # Remove project, its task should be removed and the created keyword # should no longer be associated with any project tui.addInputAnswers("y") self.cmd.do_p_remove("p1") self.assertEqual(keyword.projects, []) self.assertEqual(list(self.session.query(Task).filter_by(id=taskId)), [])
def testKeywordMapping(self): tui.addInputAnswers("y") tui.addInputAnswers("y") tui.addInputAnswers("y") t1 = dbutils.addTask("x", "t1", {"k1": None, "k2": 123}) v1 = yical.createVTodoFromTask(t1) # Check categories are created categories = [str(c) for c in v1.get("categories")] categories.sort() self.assertEqual(categories, ["k1", "k2=123"]) # Check keywords are still here yical.updateTaskFromVTodo(t1, v1) keywords = list(t1.getKeywordDict().keys()) self.session.commit() keywords.sort() self.assertEqual(keywords, ["k1", "k2"]) self.assertEqual(t1.getKeywordDict()["k2"], 123) # Remove k2 category v1["categories"] = ["k1"] yical.updateTaskFromVTodo(t1, v1) self.session.commit() self.assertEqual(list(t1.getKeywordDict().keys()), [ "k1", ]) # Set k1 value v1["categories"] = [ "k1=456", ] yical.updateTaskFromVTodo(t1, v1) self.session.commit() self.assertEqual(t1.getKeywordDict()["k1"], 456) # Create a category v1["categories"] = ["k1", "k4=789"] yical.updateTaskFromVTodo(t1, v1) keywords = list(t1.getKeywordDict().keys()) keywords.sort() self.assertEqual(keywords, ["k1", "k4"]) self.assertEqual(t1.getKeywordDict()["k4"], 789)
def _t_add(self, cmd, line): """Code shared by t_add, bug_add and n_add.""" parser = self._parser_t_add(cmd) args = parser.parse_args(line) line = " ".join(args.cmd) if not line: raise BadUsageException("Missing parameters") projectName, title, keywordDict = parseutils.parseLine(line) projectName = self._realProjectName(projectName) if not title: raise BadUsageException("Missing title") task = dbutils.addTask(projectName, title, keywordDict) if not task: tui.reinjectInRawInput("%s %s" % (cmd, line)) return None self.lastTaskId = task.id if args.describe: self.do_t_describe(self.lastTaskId) return task
def testKeywordMapping(self): tui.addInputAnswers("y") tui.addInputAnswers("y") tui.addInputAnswers("y") t1 = dbutils.addTask("x", "t1", {"k1": None, "k2": 123}) v1 = yical.createVTodoFromTask(t1) # Check categories are created categories = [str(c) for c in v1.get("categories")] categories.sort() self.assertEqual(categories, ["k1", "k2=123"]) # Check keywords are still here yical.updateTaskFromVTodo(t1, v1) keywords = list(t1.getKeywordDict().keys()) self.session.commit() keywords.sort() self.assertEqual(keywords, ["k1", "k2"]) self.assertEqual(t1.getKeywordDict()["k2"], 123) # Remove k2 category v1["categories"] = ["k1"] yical.updateTaskFromVTodo(t1, v1) self.session.commit() self.assertEqual(list(t1.getKeywordDict().keys()), ["k1", ]) # Set k1 value v1["categories"] = ["k1=456", ] yical.updateTaskFromVTodo(t1, v1) self.session.commit() self.assertEqual(t1.getKeywordDict()["k1"], 456) # Create a category v1["categories"] = ["k1", "k4=789"] yical.updateTaskFromVTodo(t1, v1) keywords = list(t1.getKeywordDict().keys()) keywords.sort() self.assertEqual(keywords, ["k1", "k4"]) self.assertEqual(t1.getKeywordDict()["k4"], 789)
def testTaskDoneMapping(self): tui.addInputAnswers("y") t1 = dbutils.addTask("x", "t1", {}) v1 = yical.createVTodoFromTask(t1)
def main(): parser = ArgumentParser() parser.add_argument('db', metavar='<db>') args = parser.parse_args() dbname = args.db if os.path.exists(dbname): os.unlink(dbname) db.connectDatabase(dbname) db.setDefaultConfig() session = db.getSession() for name in PROJECTS: session.add(db.Project(name=name)) for name in KEYWORDS: dbutils.getOrCreateKeyword(name, interactive=False) dbutils.addTask("birthday", "Buy food", {"grocery": None}) dbutils.addTask("birthday", "Buy drinks", {"grocery": None}) dbutils.addTask("birthday", "Invite Bob", {"phone": None}) dbutils.addTask("birthday", "Invite Wendy", {"phone": None}) dbutils.addTask("birthday", "Bake a yummy cake") dbutils.addTask("birthday", "Decorate living-room") task = dbutils.addTask("home", "Fix leak in the roof") task.dueDate = ydateutils.parseHumaneDateTime("-2d") dbutils.addTask("home", "Buy AAA batteries for kid toys", {"grocery": None}) task = dbutils.addTask("home", "Bring the car to the garage") task.dueDate = ydateutils.parseHumaneDateTime("-1d") task.status = "done" task = dbutils.addTask("work", "Finish weekly report") task.dueDate = ydateutils.parseHumaneDateTime("+4d") task.description = """Include results from Acme department: http://acme.intranet/results. Don't forget to CC [email protected]. """ session.commit() return 0
def main(): parser = ArgumentParser() parser.add_argument('db', metavar='<db>') args = parser.parse_args() dbname = args.db if os.path.exists(dbname): os.unlink(dbname) db.connectDatabase(dbname) db.setDefaultConfig() for name in PROJECTS: db.Project(name=name) for name in KEYWORDS: db.Keyword(name=name) dbutils.addTask("birthday", "Buy food", {"grocery": None}) dbutils.addTask("birthday", "Buy drinks", {"grocery": None}) dbutils.addTask("birthday", "Invite Bob", {"phone": None}) dbutils.addTask("birthday", "Invite Wendy", {"phone": None}) dbutils.addTask("birthday", "Bake a yummy cake") dbutils.addTask("birthday", "Decorate living-room") task = dbutils.addTask("home", "Fix leak in the roof") task.dueDate = ydateutils.parseHumaneDateTime("-2d") dbutils.addTask("home", "Buy AAA batteries for kid toys", {"grocery": None}) task = dbutils.addTask("home", "Bring the car to the garage") task.dueDate = ydateutils.parseHumaneDateTime("-1d") task.status = "done" task = dbutils.addTask("work", "Finish weekly report") task.dueDate = ydateutils.parseHumaneDateTime("+4d") task.description = """Include results from Acme department: http://acme.intranet/results. Don't forget to CC [email protected]. """ return 0