Example #1
0
 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)
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
 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)
Example #5
0
 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)
Example #6
0
    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)
Example #7
0
    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")
Example #8
0
    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)
Example #9
0
 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)