def test_properties(self): test_file = os.path.join(self.test_dir, "recurring task.md") t = Task.from_file(test_file) self.assertListEqual([t.hold, t.done, t.ip, t.todo, t.abandoned], [False, False, True, False, False]) dtd = (t.due - datetime.datetime.now()).days + 1 self.assertEqual(dtd, t.days_till_due)
def from_files(cls, path: str, id: str, coerce_pid_mismatches=False): """ Generate a Project object from existing files. Args: path (str): The path of the project folder. Should already contain tasks and notes subdirs id (str): a single alphabetic character representing the project id. Must be unique coerce_pid_mismatches (bool): If True, will coerce existing tasks with mismatching project ids to match this project's id. Returns: Project object """ tasks = [] notes = [] path = os.path.abspath(path) tasks_dir = os.path.join(path, tasks_subdir) notes_dir = os.path.join(path, notes_subdir) inactive_dir = os.path.join(tasks_dir, inactive_subdir) for subdir in (notes_dir, inactive_dir): if not os.path.exists(subdir): os.makedirs(subdir, exist_ok=False) for taskdir in (tasks_dir, inactive_dir): for ft in os.listdir(taskdir): f_full = os.path.abspath(os.path.join(taskdir, ft)) if f_full.endswith(task_extension): try: t = Task.from_file(f_full) tasks.append(t) except DexcodeException: warnings.warn( f"File {f_full} has no dexcode. Please remove this file or make it into a task." ) for task in tasks: project_id = task.dexid[0] number_task_id = int(task.dexid[1:]) if project_id != id: warnings.warn( f"Task {task.dexid} does not have project id matching project {id}: {path}." ) if coerce_pid_mismatches: warnings.warn( f"Converting task {task.dexid} to project {id}!") task.set_dexid(f"{id}{number_task_id}") for fn in os.listdir(notes_dir): n_full = os.path.abspath(os.path.join(notes_dir, fn)) if n_full.endswith(note_extension): n = Note.from_file(n_full) notes.append(n) return cls(path, id, tasks, notes)
def test_set_status(self): fname = 'example task.md' test_file = os.path.join(self.test_dir, fname) # checking setting the same status t = Task.from_file(test_file) self.assertEqual(t.status, todo_str) t.set_status(todo_str) t = Task.from_file(test_file) self.assertEqual(t.status, todo_str) t = Task.from_file(test_file) t.set_status(ip_str) t = Task.from_file(test_file) self.assertEqual(t.status, ip_str) t = Task.from_file(test_file) t.set_status(hold_str) t = Task.from_file(test_file) self.assertEqual(t.status, hold_str) # moving it into an inactive state from an active state t = Task.from_file(test_file) t.set_status(done_str) expected_newpath = os.path.join( os.path.join(self.test_dir, inactive_subdir), fname) self.assertTrue(t.path == expected_newpath) # changing the inactive state t = Task.from_file(expected_newpath) self.assertEqual(t.status, done_str) t.set_status(abandoned_str) self.assertEqual(t.status, abandoned_str) t = Task.from_file(expected_newpath) self.assertEqual(t.status, abandoned_str) # Changing from inactive to active stae t.set_status(todo_str) self.assertEqual(t.status, todo_str) self.assertEqual(t.path, test_file) t = Task.from_file(test_file) self.assertEqual(t.status, todo_str)
def test_task_from_file(self): test_flle = os.path.join(self.test_dir, "example task.md") t = Task.from_file(test_flle) self.assertEqual(t.dexid, "b44") self.assertEqual(t.effort, 2) self.assertEqual(t.importance, 5) self.assertEqual(t.status, "todo") self.assertListEqual(t.flags, ["n"]) ref_time = datetime.datetime.strptime("2020-07-21", due_date_fmt) self.assertTrue(ref_time == t.due)
def test_rename(self): test_flle = os.path.join(self.test_dir, "example task.md") t = Task.from_file(test_flle) new_name = "renamed file" t.rename(new_name) self.assertTrue( os.path.exists( os.path.join(self.test_dir, f"{new_name}{task_extension}"))) self.assertFalse(os.path.exists(os.path.join(self.test_dir, test_flle))) self.assertEqual(t.name, new_name)
def test_flag_setting(self): test_file = os.path.join(self.test_dir, 'example task.md') t = Task.from_file(test_file) test_flag = "r22" self.assertTrue("n" in t.flags) self.assertTrue(test_flag not in t.flags) t.add_flag(test_flag) self.assertTrue(test_flag in t.flags) t.rm_flag(test_flag) self.assertTrue(test_flag not in t.flags)
def test_setters(self): test_file = os.path.join(self.test_dir, 'example task.md') t = Task.from_file(test_file) ny_2099 = datetime.datetime.strptime("2099-01-01", due_date_fmt) t.set_due(ny_2099) self.assertEqual(ny_2099, t.due) t = Task.from_file(test_file) self.assertEqual(ny_2099, t.due) t.set_importance(1) self.assertEqual(t.importance, 1) t = Task.from_file(test_file) self.assertEqual(t.importance, 1) t.set_effort(5) self.assertEqual(t.effort, 5) t = Task.from_file(test_file) self.assertEqual(t.effort, 5) t.set_dexid("f421") self.assertEqual(t.dexid, "f421") t = Task.from_file(test_file) self.assertEqual(t.dexid, "f421")
def test_recurrence(self): test_file_recurring = os.path.join(self.test_dir, "recurring task.md") t_recurring = Task.from_file(test_file_recurring) test_file_nonrecurring = os.path.join(self.test_dir, "example task.md") t_nonrecurring = Task.from_file(test_file_nonrecurring) recurrence, recurrence_time = t_recurring.recurrence self.assertTrue(recurrence) self.assertEqual(recurrence_time, 5) recurrence, recurrence_time = t_nonrecurring.recurrence self.assertFalse(recurrence) self.assertIsNone(recurrence_time) # Ensure due date is updated to the next due date when the recurring task is completed self.assertEqual( t_recurring.due, datetime.datetime.strptime("2020-07-25", due_date_fmt)) t_recurring.set_status(done_str) self.assertEqual( t_recurring.due, datetime.datetime.strptime("2020-07-30", due_date_fmt)) # completed recurring task should be set to todo, not done as it will never recur! self.assertEqual(t_recurring.status, todo_str) # Changing a recurring task from todo to done (i.e., updating the due) t_recurring.set_status(done_str) self.assertEqual(t_recurring.status, todo_str) print(t_recurring.due) self.assertEqual( t_recurring.due, datetime.datetime.strptime("2020-08-04", due_date_fmt)) self.assertEqual(t_recurring.path, test_file_recurring)
def test_setting_recurrence(self): test_file = os.path.join(self.test_dir, 'example task.md') t = Task.from_file(test_file) self.assertEqual((False, None), t.recurrence) t.add_flag("r10") self.assertEqual((True, 10), t.recurrence)