Beispiel #1
0
    def setUp(self):
        self.vars = CommonVariables('test_variables.ini')
        mgr = DatabaseManager(self.vars)

        self.tasks = mgr.get_tasks_model()
        self.client = CliClient(mgr, MockFileManager())
        self.client.remove_all_tasks()
        self.date_generator = DateGenerator()

        self.june4 = Day(datetime.strptime("2021-06-04",
                                           self.vars.date_format))
        self.june7 = Day(datetime.strptime("2021-06-07",
                                           self.vars.date_format))
        self.june9 = Day(datetime.strptime("2021-06-09",
                                           self.vars.date_format))
Beispiel #2
0
    def test_complete_task(self):
        due_date_list = DateGenerator().get_due_dates("every sa")

        tasks = Tasks(self.db)
        tasks.clear_objects()
        tasks.add("Repetitive task", "current", "home", "every sa")
        task_list = tasks.get_object_list()

        self.assertTrue(len(due_date_list) == len(task_list))

        for task in task_list:
            task.complete()

        for task in task_list:
            self.assertTrue(task.is_completed())
Beispiel #3
0
 def __init__(self, database):
     super().__init__(database, Task())
     self.__calendar = Calendar()
     self.__vars = CommonVariables()
     self.__date_generator = DateGenerator()
Beispiel #4
0
class Tasks(Model):
    """
    Main entry point for querying and managing local tasks.
    """
    logger = AppLogger("tasks").get_logger()

    def __init__(self, database):
        super().__init__(database, Task())
        self.__calendar = Calendar()
        self.__vars = CommonVariables()
        self.__date_generator = DateGenerator()

    def add(self, text, label, project, date_expression) -> List[Task]:
        assert type(text) and type(label) and type(project)\
               and type(date_expression) is str
        task_list = list()
        if self.__date_generator.validate_input(date_expression):
            for due_date in self.__date_generator.get_due_dates(
                    date_expression):
                task = Task(text)
                task.label = label
                task.project = project
                task.date_expression = date_expression
                task.due_date = due_date
                self.append(task)
                task_list.append(task)
        else:
            raise AttributeError(
                f"Provided date expression {date_expression} is invalid")

        return task_list

    def append(self, obj: Task):
        assert isinstance(obj, Task)
        return self.append_object(obj)

    def contains_due_date_range(self, task, min_date_string, max_date_string):
        assert isinstance(task, Task)
        assert type(min_date_string) and type(max_date_string) is str

        min_day = Day(
            datetime.strptime(min_date_string, self.__vars.date_format))
        max_day = Day(
            datetime.strptime(max_date_string, self.__vars.date_format))
        if len(task.due_date.date_string) > 0:
            day = Day(
                datetime.strptime(task.due_date.date_string,
                                  self.__vars.date_format))

            if min_day.to_date_time() < day.to_date_time(
            ) < max_day.to_date_time():
                return task

    def get_task(self, func) -> Task:
        for task in self.get_object_list():
            if func(task) is not None:
                self.logger.debug(
                    f"Retrieved task by index: {task.index}, text: {task.text}"
                )
                return task

    def get_task_list(self):
        return sorted(self.get_object_list(),
                      key=lambda task: task.due_date.date_string)

    def get_tasks_containing_text(self, value) -> List[Task]:
        """
        Selects all tasks that with a text value that contain the provided value
        :param value:
        :return: list of Task
        """
        assert type(value) is str
        return [
            task for task in self.get_task_list()
            if str(value).lower() in str(task.text).lower()
        ]

    def get_tasks_matching_text(self, value) -> List[Task]:
        """
        Selects all tasks with a text value that matches the provided value
        :param value:
        :return:
        """
        assert type(value) is str
        return [
            task for task in self.get_task_list()
            if str(value.lower() == str(task.text).lower())
        ]

    def get_task_by_index(self, index: int) -> Task:
        assert type(index) is int
        return self.get_task(lambda task: task
                             if task.index == index else None)

    def get_task_by_external_id(self, external_id: int) -> Task:
        assert type(external_id) is str
        return self.get_task(lambda task: task
                             if task.external_id == external_id else None)

    def get_task_by_id(self, task_id: str) -> Task:
        assert type(task_id) is str
        return self.get_task(lambda task: task
                             if task.unique_id == task_id else None)

    def get_task_by_name(self, task_name: str) -> Task:
        assert type(task_name) is str
        return self.get_task(lambda task: task
                             if task.text == task_name else None)

    def get_tasks_by_date(self, date_expression: str) -> List[Task]:
        assert type(date_expression) is str
        task_list = list()
        for due_date in self.__date_generator.get_due_dates(date_expression):
            for task in self.get_task_list():
                if task.due_date.date_string == due_date.date_string:
                    task_list.append(task)
        return task_list

    def get_tasks_within_date_range(self, min_date_string: str,
                                    max_date_string: str) -> List[Task]:
        assert type(min_date_string) is str
        assert type(max_date_string) is str
        return [
            task
            for task in self.get_task_list() if self.contains_due_date_range(
                task, min_date_string, max_date_string)
        ]

    def get_tasks_by_status(self, is_completed: bool) -> List[Task]:
        assert type(is_completed) is bool

        if is_completed:
            return [
                task for task in self.get_task_list() if task.is_completed()
            ]
        else:
            return [
                task for task in self.get_task_list()
                if not task.is_completed()
            ]

    def get_tasks_by_project(self, project: str) -> List[Task]:
        assert type(project) is str
        return self.get_list_by_type("project", project)

    def get_tasks_by_label(self, label: str) -> List[Task]:
        assert type(label) is str
        return self.get_list_by_type("label", label)

    def get_filtered_list(self) -> List[Task]:
        return [task for task in self.get_task_list() if not task.deleted]

    def delete(self, task_id: str) -> Task:
        assert type(task_id) is str

        task = self.get_task_by_id(task_id)
        if task is not None:
            task.deleted = True
            self.replace_object(task.index, task)
            return task
        else:
            raise TaskKeyError()

    def undelete(self, task_id: str) -> Task:
        assert type(task_id) is str

        task = self.get_task_by_id(task_id)
        if task is not None:
            task.deleted = False
            self.replace_object(task.index, task)
            return task
        else:
            raise TaskKeyError()

    def complete(self, task_id: str) -> Task:
        assert type(task_id) is str

        task = self.get_task_by_id(task_id)
        if task is not None:
            task.complete()
            self.replace_object(task.index, task)
            return task
        else:
            raise TaskKeyError()

    def reset(self, task_id: str) -> Task:
        """
        Resets the due date to today on the selected task
        :param task_id:
        :return:
        """
        assert type(task_id) is str

        task = self.get_task_by_id(task_id)
        if task is not None:
            due_date = DueDate()
            due_date.completed = False
            due_date.date_string = Today().to_date_string()
            task.due_date = due_date
            self.replace_object(task.index, task)
            return task
        else:
            raise TaskKeyError()

    def replace(self, local_task: Task, remote_task: Task) -> Task:
        assert isinstance(remote_task, Task)
        assert isinstance(local_task, Task)

        remote_task.index = local_task.index
        remote_task.unique_id = local_task.unique_id
        remote_task.due_date = local_task.due_date

        self.replace_object(local_task.index, remote_task)
        self.logger.debug(
            f"Replaced local_task: {dict(local_task)} with remote_task: {dict(remote_task)}"
        )
        return remote_task

    def edit(self, index: int, text: str, label: str, project: str,
             date_expression: str) -> Task:

        task = self.get_task_by_index(index)
        if task is not None:
            task.text = text
            task.project = project
            task.label = label

            due_date = self.__date_generator.get_due_date(date_expression)
            if due_date is not None:
                task.date_expression = date_expression
                task.due_date.date_string = due_date.date_string

            self.replace_object(task.index, task)
            return task
        else:
            raise TaskKeyError()

    def reschedule(self, today) -> None:
        assert type(today) is Today or Day
        task_list = self.get_task_list()
        for task in task_list:
            if self.__calendar.is_past(
                    task.due_date, today
            ) and task.due_date.completed is False and task.deleted is False:
                task.due_date.date_string = today.to_date_string()
        self.update_objects(task_list)

    def get_list_by_type(self,
                         parameter_name: str,
                         value: str,
                         task_list=None) -> list:
        """
        Returns list of tasks when a task parameter (ie. project, text, label) matches
        a single value.
        :param parameter_name:
        :param value:
        :param task_list:
        :return:
        """
        assert type(parameter_name) is str
        assert type(value) is str

        if task_list is None:
            task_list = self.get_task_list()
        else:
            assert type(task_list) is list

        return list(
            filter(lambda t: getattr(t, parameter_name) == value, task_list))

    def __sort(self, parameter_name: str) -> list:
        assert type(parameter_name) is str
        return [
            t for t in sorted(self.get_task_list(),
                              key=lambda t: getattr(t, parameter_name))
        ]

    def get_label_list(self) -> List[str]:
        return self.unique("label", self.get_task_list())

    def get_project_list(self) -> List[str]:
        return self.unique("project", self.get_task_list())

    def get_due_date_list(self) -> List[str]:
        return list(
            set([task.due_date.date_string for task in self.get_task_list()]))

    @staticmethod
    def unique(parameter_name: str, task_list: list) -> List[str]:
        assert type(parameter_name) is str
        assert type(task_list) is list
        unique_set = set([getattr(task, parameter_name) for task in task_list])
        return sorted(list(unique_set))

    def clear(self):
        self.clear_objects()
Beispiel #5
0
    def __init__(self, db_manager):
        assert isinstance(db_manager, DatabaseManager)

        self.tasks = db_manager.get_tasks_model()
        self.__date_generator = DateGenerator()
        self.__variables = CommonVariables()
Beispiel #6
0
class Client:
    """
    Base client facade that that provides access to all the application features. It integrates the import/export, tasks,
    snapshot, common variables, and date generator classes. It also makes it possible to support additional clients.
    Currently only the console client is supported, but a rest api could also extend this class.
    """
    logger = AppLogger("client").get_logger()

    def __init__(self, db_manager):
        assert isinstance(db_manager, DatabaseManager)

        self.tasks = db_manager.get_tasks_model()
        self.__date_generator = DateGenerator()
        self.__variables = CommonVariables()

    @abstractmethod
    def display_tasks(self, task_list: list):
        pass

    @abstractmethod
    def display_snapshots(self, snapshots: Snapshots, **kwargs):
        pass

    @abstractmethod
    def display_invalid_index_error(self, index: int):
        pass

    def edit_task(self, index: int, text: str, label: str, project: str,
                  date_expression: str) -> List[Task]:
        """
        Edits an existing task by replacing string values. None are allowed
        and handled by the Task object.
        :param index: integer starting at 0
        :param text: text string describing the task
        :param label: label name of the task
        :param project: project name of the task
        :param date_expression: Must be one of [today, tomorrow, m-s, every *, month / day, etc].
        :return: Task
        """
        assert type(index) is int
        assert type(text) is str
        assert type(project) is str
        assert type(label) is str
        assert type(date_expression) is str

        try:
            if self.__date_generator.validate_input(date_expression) is False:
                self.logger.info(
                    f"Provided due date {date_expression} is invalid")
            else:
                task = self.tasks.edit(index, text, label, project,
                                       date_expression)
                return self.display_tasks([task])
        except TaskKeyError:
            self.display_invalid_index_error(index)

    def get_task(self, task_index: int) -> List[Task]:
        task = self.tasks.get_task_by_index(int(task_index))
        return self.display_tasks([task])

    def filter_tasks_by_today(self) -> List[Task]:
        date_string = Today().to_date_string()
        task_list = self.tasks.get_tasks_by_date(date_string)
        return self.display_tasks(task_list)

    def filter_tasks_by_due_date(self, date_string: str) -> List[Task]:
        task_list = self.tasks.get_tasks_by_date(date_string)
        return self.display_tasks(task_list)

    def filter_tasks_by_due_date_range(self, min_date: str,
                                       max_date: str) -> List[Task]:
        task_list = self.tasks.get_tasks_within_date_range(min_date, max_date)
        return self.display_tasks(task_list)

    def filter_tasks_by_status(self, status: str) -> List[Task]:
        assert status in ["incomplete", "complete"]
        if status == "incomplete":
            task_list = self.tasks.get_tasks_by_status(is_completed=False)
        else:
            task_list = self.tasks.get_tasks_by_status(is_completed=True)
        return self.display_tasks(task_list)

    def filter_tasks_by_project(self, project: str) -> List[Task]:
        assert type(project) is str
        task_list = self.tasks.get_tasks_by_project(project)
        return self.display_tasks(task_list)

    def filter_tasks_by_label(self, label: str) -> List[Task]:
        assert type(label) is str
        task_list = self.tasks.get_tasks_by_label(label)
        return self.display_tasks(task_list)

    def filter_tasks_by_text(self, text: str) -> List[Task]:
        assert type(text) is str
        task_list = self.tasks.get_tasks_containing_text(text)
        return self.display_tasks(task_list)

    def group_tasks_by_project(self) -> List[Task]:
        task_list = list()
        for project in self.get_unique_project_list():
            for task in self.tasks.get_tasks_by_project(project):
                task_list.append(task)
        return self.display_tasks(task_list)

    def group_tasks_by_due_date(self) -> List[Task]:
        task_list = list()
        for due_date_string in self.__get_unique_due_date_list():
            for task in self.tasks.get_tasks_by_date(due_date_string):
                task_list.append(task)
        return self.display_tasks(task_list)

    def group_tasks_by_label(self) -> List[Task]:
        task_list = list()
        for label in self.get_unique_label_list():
            for task in self.tasks.get_tasks_by_label(label):
                task_list.append(task)
        return self.display_tasks(task_list)

    def get_unique_label_list(self) -> List[str]:
        """Returns a list of labels from the tasks."""
        return self.tasks.get_label_list()

    def get_unique_project_list(self) -> List[str]:
        """Returns list of project names from the tasks. """
        return self.tasks.get_project_list()

    def __get_unique_due_date_list(self) -> List[str]:
        """Returns list of due_date strings from the tasks."""
        return self.tasks.get_due_date_list()

    def count_all_tasks(self, **kwargs) -> List[Snapshot]:
        snapshots = Snapshots(self.tasks)
        snapshots.count_all_tasks()
        return self.display_snapshots(snapshots, **kwargs)

    def count_tasks_by_due_date_range(self, min_date: str, max_date: str,
                                      **kwargs) -> List[Snapshot]:
        assert type(min_date) and type(max_date) is str

        snapshots = Snapshots(self.tasks)
        snapshots.count_tasks_by_due_date_range(min_date, max_date)
        return self.display_snapshots(snapshots, **kwargs)

    def count_tasks_by_due_date(self, due_date: str,
                                **kwargs) -> List[Snapshot]:
        assert type(due_date) is str

        snapshots = Snapshots(self.tasks)
        snapshots.count_tasks_by_due_date(due_date)
        return self.display_snapshots(snapshots, **kwargs)

    def count_tasks_by_project(self, project_name: str,
                               **kwargs) -> List[Snapshot]:
        assert type(project_name) is str

        snapshots = Snapshots(self.tasks)
        snapshots.count_tasks_by_project(project_name)
        return self.display_snapshots(snapshots, **kwargs)

    def reschedule_tasks(self, today=Today()):
        self.tasks.reschedule(today)

    def remove_all_tasks(self):
        self.tasks.clear()

    def set_default_variables(self, **kwargs):
        """
        Sets the defaults variables to the variables.ini file.
        :param variable_dict: Contains key value pairs matching the
        properties in Variables class
        :return: None
        """
        assert type(kwargs) is dict

        for key, value in kwargs.items():
            if hasattr(self.__variables, key):
                setattr(self.__variables, key, value)

    @staticmethod
    def get_duration(start_datetime):
        """
        Gets a formatted time string using the provided datetime object
        :param start_datetime:
        :return: time string
        """
        end_datetime = datetime.now()
        total_seconds = (end_datetime - start_datetime).total_seconds()
        hours, remainder = divmod(total_seconds, 3600)
        minutes, seconds = divmod(remainder, 60)
        return '{:02}m:{:02}s'.format(int(minutes), int(seconds))

    @staticmethod
    def get_variables_list():
        return dict(CommonVariables()).items()
Beispiel #7
0
class TestCliClient(unittest.TestCase):
    def setUp(self):
        self.vars = CommonVariables('test_variables.ini')
        mgr = DatabaseManager(self.vars)

        self.tasks = mgr.get_tasks_model()
        self.client = CliClient(mgr, MockFileManager())
        self.client.remove_all_tasks()
        self.date_generator = DateGenerator()

        self.june4 = Day(datetime.strptime("2021-06-04",
                                           self.vars.date_format))
        self.june7 = Day(datetime.strptime("2021-06-07",
                                           self.vars.date_format))
        self.june9 = Day(datetime.strptime("2021-06-09",
                                           self.vars.date_format))

    def tearDown(self):
        self.client.remove_all_tasks()

    def test_add_task(self):
        self.client.add_task("Clean garage", "", "home", "empty")
        self.client.list_all_tasks()
        row_count = len(self.client.task_table.get_table().rows)
        self.assertTrue(row_count == 1)

    def test_list_all_tasks(self):
        self.client.add_task("Clean car", "@waiting_on", "home", "today")
        self.client.add_task("Clean bathroom", "", "home", "tomorrow")
        self.client.add_task("Book flight to New York", "@at_computer", "work",
                             "m")
        self.client.add_task("Repair deck", "@waiting_on", "home", "sa")
        self.client.add_task("Call friend for birthday", "@call", "home", "m")
        self.client.add_task("Paint picture", "@idea", "home", "sa")
        self.client.add_task("Build puzzle with family", "@idea", "home", "su")
        self.client.add_task("Schedule meeting with SW team", "@meeting",
                             "work", "m")
        self.client.add_task("Create facebook 2.0 app", "@idea", "", "empty")
        rows = self.client.list_all_tasks()
        self.assertTrue(len(rows) == 9)

    def test_list_tasks_by_label(self):
        self.client.add_task("Clean car", "@waiting_on", "home", "today")
        self.client.add_task("Clean bathroom", "", "home", "tomorrow")
        self.client.add_task("Book flight to New York", "@at_computer", "work",
                             "m")
        self.client.add_task("Repair deck", "@waiting_on", "home", "sa")
        self.client.add_task("Call friend for birthday", "@call", "home", "m")
        self.client.add_task("Paint picture", "@idea", "home", "sa")
        self.client.add_task("Build puzzle with family", "@idea", "home", "su")
        self.client.add_task("Schedule meeting with SW team", "@meeting",
                             "work", "m")
        self.client.add_task("Create facebook 2.0 app", "@idea", "", "empty")
        rows = self.client.group_tasks_by_label()
        self.assertTrue(len(rows) == 9)

    def test_list_tasks_by_project(self):
        self.client.add_task("Clean car", "@waiting_on", "home", "today")
        self.client.add_task("Clean bathroom", "", "home", "tomorrow")
        self.client.add_task("Book flight to New York", "@at_computer", "work",
                             "m")
        self.client.add_task("Repair deck", "@waiting_on", "home", "sa")
        self.client.add_task("Call friend for birthday", "@call", "home", "m")
        self.client.add_task("Paint picture", "@idea", "home", "sa")
        self.client.add_task("Build puzzle with family", "@idea", "home", "su")
        self.client.add_task("Schedule meeting with SW team", "@meeting",
                             "work", "m")
        self.client.add_task("Create facebook 2.0 app", "@idea", "", "empty")
        rows = self.client.group_tasks_by_project()
        self.assertTrue(len(rows) == 9)

    def test_encoding_decoding_date_string(self):
        now = datetime.now()
        date_string = now.strftime("%m-%d-%Y")
        date_object = datetime.strptime(date_string, "%m-%d-%Y")
        self.assertIsInstance(date_object, datetime)

    def test_edit_task_using_all_fields(self):
        self.client.add_task("Clean car", "deprecated", "home", "today")
        task_list = self.client.edit_task(1, "text_value", "current", "work",
                                          "apr 14")
        self.assertTrue(len(task_list) == 1)
        task = task_list[0]
        self.assertEqual(task.text, 'text_value')
        self.assertEqual(task.label, "current")
        self.assertEqual(task.deleted, False)
        self.assertEqual(task.priority, 1)
        self.assertEqual(task.project, 'work')
        self.assertEqual(task.date_expression, 'apr 14')
        self.assertEqual(task.due_date.date_string, '2021-04-14')
        self.assertEqual(task.due_date.completed, False)

    def test_today(self):
        self.client.add_task("task1", "home", "home", "empty")
        self.client.add_task("task2", "home", "home", "today")
        rows = self.client.filter_tasks_by_today()
        self.assertTrue(len(list(rows)) == 1)

    def test_delete(self):
        self.client.add_task("Clean car", "@waiting_on", "home", "today")
        self.client.add_task("Clean bathroom", "", "home", "tomorrow")
        task_list = self.client.delete_tasks((
            1,
            2,
        ))
        self.assertTrue(len(task_list) == 2)
        self.assertTrue(task_list[0].deleted)
        self.assertTrue(task_list[1].deleted)

    def test_complete(self):
        due_dates = self.date_generator.get_due_dates("every m")
        task_list = self.client.add_task("task1", "home", "home", "every m")
        for task in task_list:
            self.client.complete_tasks((task.index, ))

        rows = self.client.list_all_tasks()
        self.assertTrue(len(due_dates) == len(rows))

        done_list = [row.due_date.completed for row in rows]
        self.assertIsNotNone(done_list)
        self.assertTrue("False" not in done_list)

    def test_count_all_tasks(self):
        self.tasks.add("task1", "label1", "project1", "today")
        snapshot_list = self.client.count_all_tasks(**{"page": 1})
        self.assertIsNotNone(snapshot_list)
        self.assertTrue(len(snapshot_list) == 1)

    def test_count_by_date(self):
        self.tasks.add("task1", "label1", "project1", "today")
        date_string = Today().to_date_string()
        snapshot_list = self.client.count_tasks_by_due_date(
            date_string, **{"page": 1})
        self.assertTrue(len(snapshot_list) == 1)
        snapshot = snapshot_list[0]
        self.assertTrue(snapshot.count == 1)

    def test_count_by_due_date_range(self):
        june4_date_string = self.june4.to_date_string()
        june9_date_string = self.june9.to_date_string()
        self.tasks.add("task1", "current", "work", june4_date_string)
        self.tasks.add("task2", "current", "work", self.june7.to_date_string())
        self.tasks.add("task3", "current", "work", june9_date_string)
        snapshot_list = self.client.count_tasks_by_due_date_range(
            june4_date_string, june9_date_string, **{"page": 1})
        self.assertTrue(len(snapshot_list) == 1)

    def test_count_by_project(self):
        date_string = Today().to_date_string()
        self.tasks.add("task1", "current", "work", date_string)
        self.tasks.add("task2", "current", "work", date_string)
        self.tasks.add("task3", "current", "work", date_string)
        snapshot_list = self.client.count_tasks_by_project(
            "work", **{"page": 1})
        self.assertTrue(len(snapshot_list) == 1)
        snapshot = snapshot_list[0]
        self.assertTrue(snapshot.count == 3)

    def test_count_by_project_with_incorrect_value(self):
        self.tasks.add("task1", "current", "work", "today")
        snapshot_list = self.client.count_tasks_by_project(
            "work2", **{"page": 1})
        self.assertTrue(len(snapshot_list) == 0)
class TestDateGenerator(unittest.TestCase):
    def match_date(self, current_date_string, date_expression,
                   expected_date_string):
        current_date_time = datetime.strptime(current_date_string,
                                              CommonVariables().date_format)
        self.date_generator.current_day = Day(current_date_time)
        due_date_list = self.date_generator.get_due_dates(date_expression)
        return due_date_list[0].date_string == expected_date_string

    def get_date_count(self, current_date_string, date_expression):
        current_date_time = datetime.strptime(current_date_string,
                                              CommonVariables().date_format)
        self.date_generator.current_day = Day(current_date_time)
        due_date_list = self.date_generator.get_due_dates(date_expression)
        return len(due_date_list)

    def setUp(self):
        self.today = Today()
        self.vars = CommonVariables()
        self.date_generator = DateGenerator()
        self.march1 = datetime.strptime('2019-03-01', self.vars.date_format)

    def tearDown(self):
        pass

    def test_pad_number(self):
        current_date_time = datetime.strptime('2019-03-12',
                                              self.vars.date_format)
        day = Day(current_date_time)
        date_list = day.to_date_list()
        self.assertListEqual(date_list, ['2019-03-12'])

    def test_get_date_when_in_same_week(self):
        self.assertTrue(self.match_date('2019-03-12', 'w', '2019-03-13'))

    def test_get_date_when_in_next_week(self):
        self.assertTrue(self.match_date('2019-03-12', 'm', '2019-03-18'))

    def test_get_date_when_in_next_month(self):
        self.assertTrue(self.match_date('2019-03-29', 'tu', '2019-04-02'))

    def test_get_date_when_today(self):
        self.assertTrue(
            self.match_date(self.today.to_date_string(), 'today',
                            self.today.to_date_string()))

    def test_get_date_when_tomorrow(self):
        self.assertTrue(self.match_date('2019-03-29', 'tomorrow',
                                        '2019-03-30'))

    def test_get_date_when_next_week(self):
        self.assertTrue(
            self.match_date('2019-03-17', 'next week', '2019-03-18'))
        self.assertTrue(
            self.match_date('2019-03-18', 'next week', '2019-03-25'))
        self.assertTrue(
            self.match_date('2019-03-29', 'next week', '2019-04-01'))

    def test_get_date_when_next_month(self):
        self.assertTrue(
            self.match_date('2019-07-02', 'next month', '2019-08-01'))
        self.assertTrue(
            self.match_date('2019-12-02', 'next month', '2020-01-01'))

    def test_get_date_when_every_day(self):
        self.date_generator.current_day = Day(self.march1)
        due_date_list = self.date_generator.get_due_dates("every day")
        self.assertTrue(len(due_date_list) == 62)

    def test_get_date_count_when_every_weekday(self):
        self.vars.recurring_month_limit = 2
        day_count = self.get_date_count('2019-03-01', 'every weekday')
        self.assertTrue(day_count == 44)

    def test_get_date_when_every_weekday(self):
        self.vars.recurring_month_limit = 2
        self.date_generator.current_day = Day(self.march1)
        due_date_list = self.date_generator.get_due_dates("every weekday")
        self.assertTrue(len(due_date_list) == 44)
        self.assertTrue(due_date_list[0].date_string == "2019-03-01")
        self.assertTrue(due_date_list[1].date_string == "2019-03-04")
        self.assertTrue(due_date_list[2].date_string == "2019-03-05")
        self.assertTrue(due_date_list[3].date_string == "2019-03-06")
        self.assertTrue(due_date_list[4].date_string == "2019-03-07")

    def test_get_date_when_every_sunday(self):
        self.vars.recurring_month_limit = 2
        self.assertTrue(self.get_date_count('2019-03-01', 'every su') == 9)

    def test_get_date_when_every_monday(self):
        self.vars.recurring_month_limit = 2
        self.assertTrue(self.get_date_count('2019-03-01', 'every m') == 9)

    def test_get_date_when_every_tuesday(self):
        self.vars.recurring_month_limit = 2
        self.assertTrue(self.get_date_count('2019-03-01', 'every tu') == 9)

    def test_get_date_when_every_wednesday(self):
        self.vars.recurring_month_limit = 2
        self.assertTrue(self.get_date_count('2019-03-01', 'every w') == 9)

    def test_get_date_when_every_thursday(self):
        self.vars.recurring_month_limit = 2
        self.assertTrue(self.get_date_count('2019-03-01', 'every th') == 8)

    def test_get_date_when_every_friday(self):
        self.vars.recurring_month_limit = 2
        day_count = self.get_date_count('2019-03-01', 'every f')
        self.assertTrue(day_count == 9)

    def test_get_date_when_every_saturday(self):
        self.vars.recurring_month_limit = 2
        self.assertTrue(self.get_date_count('2019-03-01', 'every sa') == 9)

    def test_short_date(self):
        due_date_list = self.date_generator.get_due_dates("apr 14")
        self.assertTrue(len(due_date_list) == 1)
        self.assertTrue(due_date_list[0].date_string == '2021-04-14')

    def test_validate_input(self):
        self.assertTrue(self.date_generator.validate_input("every weekday"))
        self.assertTrue(self.date_generator.validate_input("every tu"))
        self.assertTrue(self.date_generator.validate_input("m"))
        self.assertTrue(self.date_generator.validate_input("today"))
        self.assertFalse(self.date_generator.validate_input("every"))
        self.assertFalse(self.date_generator.validate_input("24"))
        self.assertFalse(self.date_generator.validate_input("monday"))
        self.assertTrue(self.date_generator.validate_input("apr 21"))
        self.assertFalse(self.date_generator.validate_input("apr"))

    def test_empty_date_handler(self):
        due_date_list = self.date_generator.get_due_dates("empty")
        self.assertTrue(len(due_date_list) == 1)
        due_date = due_date_list[0]
        self.assertEqual(due_date.date_string, "")
        self.assertFalse(due_date.completed)

    def test_year_month_date_handler(self):
        due_date_list = self.date_generator.get_due_dates("2019-03-019")
        self.assertTrue(len(due_date_list) == 1)
        self.assertFalse(due_date_list[0].completed)

        due_date_list = self.date_generator.get_due_dates("2019-03-01")
        self.assertTrue(len(due_date_list) == 1)
        self.assertFalse(due_date_list[0].completed)
        self.assertTrue(due_date_list[0].date_string == "2019-03-01")

    def test_get_due_date(self):
        due_date = self.date_generator.get_due_date("this week")
        self.assertTrue(len(due_date.date_string) == 0)
        due_date = self.date_generator.get_due_date("sep 24")
        self.assertIn("09-24", due_date.date_string)
 def setUp(self):
     self.today = Today()
     self.vars = CommonVariables()
     self.date_generator = DateGenerator()
     self.march1 = datetime.strptime('2019-03-01', self.vars.date_format)