Esempio n. 1
0
    def test_archive(self):
        todolist = load_file_to_todolist("test/data/ArchiveCommandTest.txt")
        archive = TodoList([])

        command = ArchiveCommand(todolist, archive)
        command.execute()

        self.assertTrue(todolist.dirty)
        self.assertTrue(archive.dirty)
        self.assertEqual(todolist.print_todos(), "x Not complete\n(C) Active")
        self.assertEqual(archive.print_todos(), "x 2014-10-19 Complete\nx 2014-10-20 Another one complete")
Esempio n. 2
0
    def test_archive(self):
        todolist = load_file_to_todolist("test/data/ArchiveCommandTest.txt")
        archive = TodoList([])

        command = ArchiveCommand(todolist, archive)
        command.execute()

        self.assertTrue(todolist.is_dirty())
        self.assertTrue(archive.is_dirty())
        self.assertEqual(todolist.print_todos(), "x Not complete\n(C) Active")
        self.assertEqual(archive.print_todos(), "x 2014-10-19 Complete\nx 2014-10-20 Another one complete")
Esempio n. 3
0
class EditCommandTest(CommandTest):
    def setUp(self):
        super(EditCommandTest, self).setUp()
        todos = [
            "Foo id:1",
            "Bar p:1 @test",
            "Baz @test",
            u("Fo\u00f3B\u0105\u017a"),
        ]

        self.todolist = TodoList(todos)

    @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
    def test_edit1(self, mock_open_in_editor):
        """ Preserve dependencies after editing. """
        mock_open_in_editor.return_value = 0

        command = EditCommand(["1"], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.errors, "")
        self.assertEqual(
            self.todolist.print_todos(),
            u("Bar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a\nFoo id:1"))

    @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
    @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
    def test_edit2(self, mock_open_in_editor, mock_todos_from_temp):
        """ Edit some todo. """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [Todo('Lazy Cat')]

        command = EditCommand(["Bar"], self.todolist, self.out, self.error,
                              None)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.errors, "")
        self.assertEqual(
            self.todolist.print_todos(),
            u("Foo id:1\nBaz @test\nFo\u00f3B\u0105\u017a\nLazy Cat"))

    def test_edit3(self):
        """ Throw an error after invalid todo number given as argument. """
        command = EditCommand(["FooBar"], self.todolist, self.out, self.error,
                              None)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(self.errors, "Invalid todo number given.\n")

    def test_edit4(self):
        """ Throw an error with pointing invalid argument. """
        command = EditCommand(["Bar", "5"], self.todolist, self.out,
                              self.error, None)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(self.errors, "Invalid todo number given: 5.\n")

    @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
    @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
    def test_edit5(self, mock_open_in_editor, mock_todos_from_temp):
        """ Don't let to delete todos acidentally while editing. """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [Todo('Only one line')]

        command = EditCommand(["1", "Bar"], self.todolist, self.out,
                              self.error, None)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(
            self.errors,
            "Number of edited todos is not equal to number of supplied todo IDs.\n"
        )
        self.assertEqual(
            self.todolist.print_todos(),
            u("Foo id:1\nBar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a"))

    def test_edit6(self):
        """ Throw an error with invalid argument containing special characters. """
        command = EditCommand([u("Fo\u00d3B\u0105r"), "Bar"], self.todolist,
                              self.out, self.error, None)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(self.errors,
                         u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))

    @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
    @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
    def test_edit7(self, mock_open_in_editor, mock_todos_from_temp):
        """ Edit todo with special characters. """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [Todo('Lazy Cat')]

        command = EditCommand([u("Fo\u00f3B\u0105\u017a")], self.todolist,
                              self.out, self.error, None)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.errors, "")
        self.assertEqual(self.todolist.print_todos(),
                         u("Foo id:1\nBar p:1 @test\nBaz @test\nLazy Cat"))

    @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
    @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
    def test_edit_expr(self, mock_open_in_editor, mock_todos_from_temp):
        """ Edit todos matching expression. """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [
            Todo('Lazy Cat'), Todo('Lazy Dog')
        ]

        command = EditCommand(["-e", "@test"], self.todolist, self.out,
                              self.error, None)
        command.execute()

        expected = u("|  3| Lazy Cat\n|  4| Lazy Dog\n")

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.errors, "")
        self.assertEqual(self.output, expected)
        self.assertEqual(
            self.todolist.print_todos(),
            u("Foo id:1\nFo\u00f3B\u0105\u017a\nLazy Cat\nLazy Dog"))

    @mock.patch('topydo.commands.EditCommand.check_call')
    def test_edit_archive(self, mock_call):
        """ Edit archive file. """
        mock_call.return_value = 0

        editor = 'vi'
        os.environ['EDITOR'] = editor
        archive = config().archive()

        command = EditCommand(["-d"], self.todolist, self.out, self.error,
                              None)
        command.execute()

        self.assertEqual(self.errors, "")
        mock_call.assert_called_once_with([editor, archive])

    @mock.patch('topydo.commands.EditCommand.check_call')
    def test_edit_todotxt(self, mock_call):
        """ Edit todo file. """
        mock_call.return_value = 0

        editor = 'vi'
        os.environ['EDITOR'] = editor
        todotxt = config().todotxt()

        result = self.todolist.print_todos(
        )  # copy TodoList content *before* executing command

        command = EditCommand([], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertEqual(self.errors, "")
        self.assertEqual(self.todolist.print_todos(), result)
        mock_call.assert_called_once_with([editor, todotxt])
Esempio n. 4
0
class RevertCommandTest(CommandTest):
    def setUp(self):
        super().setUp()
        todos = [
            "Foo",
            "Bar",
            "Baz",
        ]

        self.todolist = TodoList(todos)
        self.today = date.today()

        self.tmp_name = str(uuid4().hex.upper()[0:6])

        archive_filename = tempfile.gettempdir() + os.sep + self.tmp_name + '_archive'
        todo_filename = tempfile.gettempdir() + os.sep + self.tmp_name + '_todo'

        config(p_overrides={('topydo', 'archive_filename'): archive_filename,
            ('topydo', 'filename'): todo_filename, ('topydo', 'backup_count'): '5'})

        self.archive_file = TodoFile(archive_filename)
        self.archive = TodoList([])

    def test_revert01(self):
        backup = ChangeSet(p_label=['do 1'])
        backup.add_todolist(self.todolist)
        backup.add_archive(self.archive)
        backup.timestamp = '1'
        command = DoCommand(["1"], self.todolist, self.out, self.error, None)
        command.execute()
        archive_command = ArchiveCommand(self.todolist, self.archive)
        archive_command.execute()
        self.archive_file.write(self.archive.print_todos())
        backup.save(self.todolist)

        self.assertEqual(self.archive.print_todos(), "x {} Foo".format(self.today))
        self.assertEqual(self.todolist.print_todos(), "Bar\nBaz")

        revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
        revert_command.execute()

        result = TodoList(self.archive_file.read()).print_todos()

        self.assertEqual(self.errors, "")
        self.assertTrue(self.output.endswith("Successfully reverted: do 1\n"))
        self.assertEqual(result, "")
        self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz")

    def test_revert02(self):
        backup = ChangeSet(self.todolist, self.archive, ['do 1'])
        backup.timestamp = '1'
        command1 = DoCommand(["1"], self.todolist, self.out, self.error, None)
        command1.execute()
        archive_command1 = ArchiveCommand(self.todolist, self.archive)
        archive_command1.execute()
        self.archive_file.write(self.archive.print_todos())
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['do Bar'])
        backup.timestamp = '2'
        command2 = DoCommand(["Bar"], self.todolist, self.out, self.error, None)
        command2.execute()
        archive_command2 = ArchiveCommand(self.todolist, self.archive)
        archive_command2.execute()
        self.archive_file.write(self.archive.print_todos())
        backup.save(self.todolist)

        self.assertEqual(self.archive.print_todos(), "x {t} Foo\nx {t} Bar".format(t=self.today))
        self.assertEqual(self.todolist.print_todos(), "Baz")

        revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
        revert_command.execute()

        result = TodoList(self.archive_file.read()).print_todos()

        self.assertEqual(self.errors, "")
        self.assertTrue(self.output.endswith("Successfully reverted: do Bar\n"))
        self.assertEqual(result, "x {} Foo".format(self.today))
        self.assertEqual(self.todolist.print_todos(), "Bar\nBaz")

    def test_revert03(self):
        """ Test behavior when no backup is found """
        command = RevertCommand([], self.todolist, self.out, self.error)
        command.execute()

        self.assertEqual(self.errors, "No backup was found for the current state of {}\n".format(config().todotxt()))

    def test_revert04(self):
        """ Test trimming of the backup_file """
        backup = ChangeSet(self.todolist, self.archive, ['add One'])
        backup.timestamp = '1'
        command1 = AddCommand(["One"], self.todolist, self.out, self.error, None)
        command1.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Two'])
        backup.timestamp = '2'
        command2 = AddCommand(["Two"], self.todolist, self.out, self.error, None)
        command2.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Three'])
        backup.timestamp = '3'
        command3 = AddCommand(["Three"], self.todolist, self.out, self.error, None)
        command3.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Four'])
        backup.timestamp = '4'
        command4 = AddCommand(["Four"], self.todolist, self.out, self.error, None)
        command4.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Five'])
        backup.timestamp = '5'
        command5 = AddCommand(["Five"], self.todolist, self.out, self.error, None)
        command5.execute()
        backup.save(self.todolist)

        result = len(ChangeSet().backup_dict.keys())
        self.assertEqual(result, 6)

        backup = ChangeSet(self.todolist, self.archive, ['add Six'])
        backup.timestamp = '6'
        command6 = AddCommand(["Six"], self.todolist, self.out, self.error, None)
        command6.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Seven'])
        backup.timestamp = '7'
        command7 = AddCommand(["Seven"], self.todolist, self.out, self.error, None)
        command7.execute()
        backup.save(self.todolist)

        result = len(ChangeSet().backup_dict.keys())
        self.assertEqual(result, 6)

        revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
        revert_command.execute()

        backup = ChangeSet()
        changesets = list(backup.backup_dict.keys())
        changesets.remove('index')
        index_timestamps = [change[0] for change in backup._get_index()]
        result = list(set(index_timestamps) - set(changesets))

        self.assertEqual(len(changesets), 4)
        self.assertEqual(result, [])
        self.assertEqual(self.errors, "")
        self.assertTrue(self.output.endswith("Successfully reverted: add Seven\n"))

    def test_revert05(self):
        """ Test for possible backup collisions """
        backup = ChangeSet(self.todolist, self.archive, ['add One'])
        backup.timestamp = '1'
        command1 = AddCommand(["One"], self.todolist, self.out, self.error, None)
        command1.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Two'])
        backup.timestamp = '2'
        command2 = AddCommand(["Two"], self.todolist, self.out, self.error, None)
        command2.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Three'])
        backup.timestamp = '3'
        command3 = AddCommand(["Three"], self.todolist, self.out, self.error, None)
        command3.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['delete Three'])
        backup.timestamp = '4'
        command4 = DeleteCommand(["Three"], self.todolist, self.out, self.error, None)
        command4.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Four'])
        backup.timestamp = '5'
        command4 = AddCommand(["Four"], self.todolist, self.out, self.error, None)
        command4.execute()
        backup.save(self.todolist)

        revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(self.output.endswith("Successfully reverted: add Four\n"))
        self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz\n{t} One\n{t} Two".format(t=self.today))

        revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(self.output.endswith("Successfully reverted: delete Three\n"))
        self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz\n{t} One\n{t} Two\n{t} Three".format(t=self.today))

        revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(self.output.endswith("Successfully reverted: add Three\n"))
        self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz\n{t} One\n{t} Two".format(t=self.today))

        revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(self.output.endswith("Successfully reverted: add Two\n"))
        self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz\n{t} One".format(t=self.today))

        revert_command = RevertCommand([], self.todolist, self.out, self.error, None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(self.output.endswith("Successfully reverted: add One\n"))
        self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz")

    def test_revert06(self):
        """ Test attempt of deletion with non-existing backup key"""
        backup = ChangeSet(self.todolist, self.archive, ['add One'])
        backup.timestamp = '1'
        command1 = AddCommand(["One"], self.todolist, self.out, self.error, None)
        command1.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Two'])
        backup.timestamp = '2'
        command2 = AddCommand(["Two"], self.todolist, self.out, self.error, None)
        command2.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Three'])
        backup.timestamp = '3'
        command3 = AddCommand(["Three"], self.todolist, self.out, self.error, None)
        command3.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['delete Three'])
        backup.timestamp = '4'
        command4 = DeleteCommand(["Three"], self.todolist, self.out, self.error, None)
        command4.execute()
        backup.save(self.todolist)

        backup = ChangeSet()
        backup.delete('Foo')

        changesets = list(backup.backup_dict.keys())
        changesets.remove('index')
        index_timestamps = [change[0] for change in backup._get_index()]
        result = list(set(index_timestamps) - set(changesets))

        self.assertEqual(len(changesets), 4)
        self.assertEqual(result, [])
        self.assertEqual(self.errors, "")

    def test_revert07(self):
        """ Test backup when no archive file is set """
        backup = ChangeSet(self.todolist, None, ['add One'])
        backup.timestamp = '1'
        command1 = AddCommand(["One"], self.todolist, self.out, self.error, None)
        command1.execute()
        backup.save(self.todolist)

        changesets = list(backup.backup_dict.keys())
        changesets.remove('index')

        self.assertEqual(len(changesets), 1)
        self.assertEqual(self.errors, "")

    def test_backup_config01(self):
        config(p_overrides={('topydo', 'backup_count'): '1'})

        self.assertEqual(config().backup_count(), 1)

    def test_backup_config02(self):
        config(p_overrides={('topydo', 'backup_count'): '0'})

        self.assertEqual(config().backup_count(), 0)

    def test_backup_config03(self):
        config(p_overrides={('topydo', 'backup_count'): '-88'})

        self.assertEqual(config().backup_count(), 0)

    def test_backup_config04(self):
        config(p_overrides={('topydo', 'backup_count'): 'foo'})

        self.assertEqual(config().backup_count(), 5)

    def test_revert_name(self):
        name = RevertCommand.name()

        self.assertEqual(name, 'revert')

    def test_help(self):
        command = RevertCommand(["help"], self.todolist, self.out, self.error)
        command.execute()

        self.assertEqual(self.output, "")
        self.assertEqual(self.errors, command.usage() + "\n\n" + command.help() + "\n")

    def tearDown(self):
        for filename in glob('/tmp/' + self.tmp_name + '*'):
            os.remove(filename)
Esempio n. 5
0
class DeleteCommandTest(CommandTest):
    def setUp(self):
        super().setUp()
        todos = [
            "Foo id:1",
            "Bar p:1",
            "a @test with due:2015-06-03",
            "a @test with +project",
        ]

        self.todolist = TodoList(todos)

    def test_del1(self):
        command = DeleteCommand(["1"], self.todolist, self.out, self.error,
                                _no_prompt)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.todolist.todo(1).source(), "Bar")
        self.assertEqual(self.output, "|  2| Bar p:1\nRemoved: Foo id:1\n")
        self.assertEqual(self.errors, "")

    def test_del1_regex(self):
        command = DeleteCommand(["Foo"], self.todolist, self.out, self.error,
                                _no_prompt)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.todolist.todo(1).source(), "Bar")
        self.assertEqual(self.output, "|  2| Bar p:1\nRemoved: Foo id:1\n")
        self.assertEqual(self.errors, "")

    def test_del2(self):
        command = DeleteCommand(["1"], self.todolist, self.out, self.error,
                                _yes_prompt)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.todolist.count(), 2)
        self.assertEqual(self.output,
                         "|  2| Bar p:1\nRemoved: Bar\nRemoved: Foo\n")
        self.assertEqual(self.errors, "")

    def test_del3(self):
        command = DeleteCommand(["-f", "1"], self.todolist, self.out,
                                self.error, _yes_prompt)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.todolist.count(), 3)  # force won't delete subtasks
        self.assertEqual(self.output, "|  2| Bar p:1\nRemoved: Foo id:1\n")
        self.assertEqual(self.errors, "")

    def test_del4(self):
        command = DeleteCommand(["--force", "1"], self.todolist, self.out,
                                self.error, _yes_prompt)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.todolist.count(), 3)  # force won't delete subtasks
        self.assertEqual(self.output, "|  2| Bar p:1\nRemoved: Foo id:1\n")
        self.assertEqual(self.errors, "")

    def test_del5(self):
        command = DeleteCommand(["2"], self.todolist, self.out, self.error)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.todolist.todo(1).source(), "Foo")
        self.assertEqual(self.output, "Removed: Bar p:1\nThe following todo item(s) became active:\n|  1| Foo\n")
        self.assertEqual(self.errors, "")

    def test_del7(self):
        command = DeleteCommand(["99"], self.todolist, self.out, self.error)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(self.output, "")
        self.assertEqual(self.errors, "Invalid todo number given.\n")

    def test_del8(self):
        command = DeleteCommand(["A"], self.todolist, self.out, self.error)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(self.output, "")
        self.assertEqual(self.errors, "Invalid todo number given.\n")

    def test_del9(self):
        """ Test deletion with textual IDs. """
        config("test/data/todolist-uid.conf")

        command = DeleteCommand(["8to"], self.todolist, self.out, self.error)
        command.execute()

        result = "Foo\na @test with due:2015-06-03\na @test with +project"

        self.assertEqual(self.todolist.print_todos(), result)
        self.assertRaises(InvalidTodoException, self.todolist.todo, 'b0n')

    def test_multi_del1(self):
        """ Test deletion of multiple items. """
        command = DeleteCommand(["1", "2"], self.todolist, self.out,
                                self.error, _no_prompt)
        command.execute()

        result = "a @test with due:2015-06-03\na @test with +project"

        self.assertEqual(self.todolist.count(), 2)
        self.assertEqual(self.todolist.print_todos(), result)

    def test_multi_del2(self):
        """ Test deletion of multiple items. """
        command = DeleteCommand(["1", "2"], self.todolist, self.out,
                                self.error, _yes_prompt)
        command.execute()

        result = "a @test with due:2015-06-03\na @test with +project"

        self.assertEqual(self.todolist.count(), 2)
        self.assertEqual(self.todolist.print_todos(), result)

    def test_multi_del3(self):
        """  Fail if any of supplied todo numbers is invalid. """
        command = DeleteCommand(["99", "2"], self.todolist, self.out,
                                self.error, _yes_prompt)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(self.output, "")
        self.assertEqual(self.errors, "Invalid todo number given: 99.\n")

    def test_multi_del4(self):
        """  Check output when all supplied todo numbers are invalid. """
        command = DeleteCommand(["99", "A"], self.todolist, self.out,
                                self.error, _yes_prompt)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(self.output, "")
        self.assertEqual(self.errors, "Invalid todo number given: 99.\nInvalid todo number given: A.\n")

    def test_multi_del5(self):
        """
        Throw an error with invalid argument containing special characters.
        """
        command = DeleteCommand([u"Fo\u00d3B\u0105r", "Bar"], self.todolist,
                                self.out, self.error, None)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(self.output, "")
        self.assertEqual(self.errors,
                         u"Invalid todo number given: Fo\u00d3B\u0105r.\n")

    def test_expr_del1(self):
        command = DeleteCommand(["-e", "@test"], self.todolist, self.out,
                                self.error, None)
        command.execute()

        result = "Removed: a @test with due:2015-06-03\nRemoved: a @test with +project\n"

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.todolist.count(), 2)
        self.assertEqual(self.output, result)
        self.assertEqual(self.errors, "")

    def test_expr_del2(self):
        command = DeleteCommand(["-e", "@test", "due:2015-06-03"],
                                self.todolist, self.out, self.error, None)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.output, "Removed: a @test with due:2015-06-03\n")
        self.assertEqual(self.errors, "")

    def test_expr_del3(self):
        command = DeleteCommand(["-e", "@test", "due:2015-06-03", "+project"],
                                self.todolist, self.out, self.error, None)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())

    def test_expr_del4(self):
        """ Remove only relevant todo items. """
        command = DeleteCommand(["-e", ""], self.todolist, self.out,
                                self.error, None)
        command.execute()

        result = "Foo"

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.todolist.count(), 1)
        self.assertEqual(self.todolist.print_todos(), result)

    def test_expr_del5(self):
        """ Force deleting unrelevant items with additional -x flag. """
        command = DeleteCommand(["-xe", ""], self.todolist, self.out,
                                self.error, _yes_prompt)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.todolist.count(), 0)

    def test_empty(self):
        command = DeleteCommand([], self.todolist, self.out, self.error)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertFalse(self.output)
        self.assertEqual(self.errors, command.usage() + "\n")

    def test_help(self):
        command = DeleteCommand(["help"], self.todolist, self.out, self.error)
        command.execute()

        self.assertEqual(self.output, "")
        self.assertEqual(self.errors,
                         command.usage() + "\n\n" + command.help() + "\n")
Esempio n. 6
0
class EditCommandTest(CommandTest):
    def setUp(self):
        super().setUp()
        todos = [
            "Foo id:1",
            "Bar p:1 @test",
            "Baz @test",
            u"Fo\u00f3B\u0105\u017a",
        ]

        self.todolist = TodoList(todos)

    @mock.patch('topydo.commands.EditCommand._is_edited')
    @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
    @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
    def test_edit01(self, mock_open_in_editor, mock_todos_from_temp, mock_is_edited):
        """ Preserve dependencies after editing. """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [Todo('Foo id:1')]
        mock_is_edited.return_value = True

        command = EditCommand(["1"], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertEqual(self.errors, "")
        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.todolist.print_todos(), u"Bar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a\nFoo id:1")

    @mock.patch('topydo.commands.EditCommand._is_edited')
    @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
    @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
    def test_edit02(self, mock_open_in_editor, mock_todos_from_temp, mock_is_edited):
        """ Edit some todo. """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [Todo('Lazy Cat')]
        mock_is_edited.return_value = True

        command = EditCommand(["Bar"], self.todolist, self.out, self.error,
                              None)
        command.execute()

        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.errors, "")
        self.assertEqual(self.todolist.print_todos(), u"Foo id:1\nBaz @test\nFo\u00f3B\u0105\u017a\nLazy Cat")

    def test_edit03(self):
        """ Throw an error after invalid todo number given as argument. """
        command = EditCommand(["FooBar"], self.todolist, self.out, self.error,
                              None)
        command.execute()

        self.assertFalse(self.todolist.dirty)
        self.assertEqual(self.errors, "Invalid todo number given.\n")

    def test_edit04(self):
        """ Throw an error with pointing invalid argument. """
        command = EditCommand(["Bar", "5"], self.todolist, self.out,
                              self.error, None)
        command.execute()

        self.assertFalse(self.todolist.dirty)
        self.assertEqual(self.errors, "Invalid todo number given: 5.\n")

    def test_edit05(self):
        """
        Throw an error with invalid argument containing special characters.
        """
        command = EditCommand([u"Fo\u00d3B\u0105r", "Bar"], self.todolist,
                              self.out, self.error, None)
        command.execute()

        self.assertFalse(self.todolist.dirty)
        self.assertEqual(self.errors,
                         u"Invalid todo number given: Fo\u00d3B\u0105r.\n")

    @mock.patch('topydo.commands.EditCommand._is_edited')
    @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
    @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
    def test_edit06(self, mock_open_in_editor, mock_todos_from_temp, mock_is_edited):
        """ Edit todo with special characters. """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [Todo('Lazy Cat')]
        mock_is_edited.return_value = True

        command = EditCommand([u"Fo\u00f3B\u0105\u017a"], self.todolist,
                              self.out, self.error, None)
        command.execute()

        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.errors, "")
        self.assertEqual(self.todolist.print_todos(),
                         u"Foo id:1\nBar p:1 @test\nBaz @test\nLazy Cat")

    @mock.patch('topydo.commands.EditCommand._is_edited')
    @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
    @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
    def test_edit07(self, mock_open_in_editor, mock_todos_from_temp, mock_is_edited):
        """ Don't perform write if tempfile is unchanged """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [Todo('Only one line')]
        mock_is_edited.return_value = False

        command = EditCommand(["1", "Bar"], self.todolist, self.out,
                              self.error, None)
        command.execute()

        self.assertFalse(self.todolist.dirty)
        self.assertEqual(self.errors, "Editing aborted. Nothing to do.\n")
        self.assertEqual(self.todolist.print_todos(), u"Foo id:1\nBar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a")

    @mock.patch('topydo.commands.EditCommand._is_edited')
    @mock.patch('topydo.commands.EditCommand.EditCommand._todos_from_temp')
    @mock.patch('topydo.commands.EditCommand.EditCommand._open_in_editor')
    def test_edit_expr(self, mock_open_in_editor, mock_todos_from_temp, mock_is_edited):
        """ Edit todos matching expression. """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [Todo('Lazy Cat'),
                                             Todo('Lazy Dog')]
        mock_is_edited.return_value = True

        command = EditCommand(["-e", "@test"], self.todolist, self.out,
                              self.error, None)
        command.execute()

        expected = u"|  3| Lazy Cat\n|  4| Lazy Dog\n"

        self.assertEqual(self.errors, "")
        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.output, expected)
        self.assertEqual(self.todolist.print_todos(), u"Foo id:1\nFo\u00f3B\u0105\u017a\nLazy Cat\nLazy Dog")

    @mock.patch.dict(os.environ, {'EDITOR': 'vi'})
    @mock.patch('topydo.commands.EditCommand.check_call')
    def test_edit_archive(self, mock_call):
        """ Edit archive file. """
        mock_call.return_value = 0

        archive = config().archive()

        command = EditCommand(["-d"], self.todolist, self.out, self.error,
                              None)
        command.execute()

        self.assertEqual(self.errors, "")
        mock_call.assert_called_once_with(['vi', archive])

    @mock.patch.dict(os.environ, {'EDITOR': 'vi'})
    @mock.patch('topydo.commands.EditCommand.check_call')
    def test_edit_todotxt(self, mock_call):
        """ Edit todo file. """
        mock_call.return_value = 0

        todotxt = config().todotxt()

        result = self.todolist.print_todos()  # copy TodoList content *before* executing command

        command = EditCommand([], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertEqual(self.errors, "")
        self.assertEqual(self.todolist.print_todos(), result)
        mock_call.assert_called_once_with(['vi', todotxt])

    @mock.patch.dict(os.environ, {'EDITOR': 'vi'})
    @mock.patch.dict(os.environ, {'TOPYDO_EDITOR': 'nano'})
    @mock.patch('topydo.commands.EditCommand.check_call')
    def test_edit_editor1(self, mock_call):
        """ $TOPYDO_EDITOR overrides $EDITOR """
        mock_call.return_value = 0

        todotxt = config().todotxt()

        command = EditCommand([], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertEqual(self.errors, "")
        mock_call.assert_called_once_with(['nano', todotxt])

    @mock.patch.dict(os.environ, {'EDITOR': 'vi'})
    @mock.patch.dict(os.environ, {'TOPYDO_EDITOR': 'nano'})
    @mock.patch('topydo.commands.EditCommand.check_call')
    def test_edit_editor2(self, mock_call):
        """ $TOPYDO_EDITOR overrides $EDITOR """
        mock_call.return_value = 0

        todotxt = config().todotxt()

        command = EditCommand([], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertEqual(self.errors, "")
        mock_call.assert_called_once_with(['nano', todotxt])

    @mock.patch.dict(os.environ, {'EDITOR': 'vi'})
    @mock.patch.dict(os.environ, {'TOPYDO_EDITOR': 'nano'})
    @mock.patch('topydo.commands.EditCommand.check_call')
    def test_edit_editor3(self, mock_call):
        """ Editor on commandline overrides $TOPYDO_EDITOR """
        mock_call.return_value = 0

        command = EditCommand(["-E", "foo"], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertEqual(self.errors, "")
        mock_call.assert_called_once_with(['foo', config().todotxt()])

    @mock.patch.dict(os.environ, {'EDITOR': 'vi'})
    @mock.patch.dict(os.environ, {'TOPYDO_EDITOR': 'nano'})
    @mock.patch('topydo.commands.EditCommand.check_call')
    def test_edit_editor4(self, mock_call):
        """ Editor in configuration file is overridden by $TOPYDO_EDITOR """
        mock_call.return_value = 0

        config(p_overrides={('edit', 'editor'): 'foo'})

        command = EditCommand([], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertEqual(self.errors, "")
        mock_call.assert_called_once_with(['nano', config().todotxt()])

    @mock.patch.dict(os.environ, {'EDITOR': 'vi'})
    @mock.patch('topydo.commands.EditCommand.check_call')
    def test_edit_editor5(self, mock_call):
        """ Editor in configuration file overrides $EDITOR """
        mock_call.return_value = 0

        config(p_overrides={('edit', 'editor'): 'foo'})

        command = EditCommand([], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertEqual(self.errors, "")
        mock_call.assert_called_once_with(['foo', config().todotxt()])

    @mock.patch.dict(os.environ, {'EDITOR': ''})
    @mock.patch('topydo.commands.EditCommand.check_call')
    def test_edit_editor6(self, mock_call):
        """ Ultimate fallback is vi """
        mock_call.return_value = 0

        command = EditCommand([], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertEqual(self.errors, "")
        mock_call.assert_called_once_with(['vi', config().todotxt()])

    def test_edit_name(self):
        name = EditCommand.name()

        self.assertEqual(name, 'edit')

    def test_help(self):
        command = EditCommand(["help"], self.todolist, self.out, self.error,
                              None)
        command.execute()

        self.assertEqual(self.output, "")
        self.assertEqual(self.errors,
                         command.usage() + "\n\n" + command.help() + "\n")
Esempio n. 7
0
class DeleteCommandTest(CommandTest):
    def setUp(self):
        super().setUp()
        todos = [
            "Foo id:1",
            "Bar p:1",
            "a @test with due:2015-06-03",
            "a @test with +project",
        ]

        self.todolist = TodoList(todos)

    def test_del1(self):
        command = DeleteCommand(["1"], self.todolist, self.out, self.error,
                                _no_prompt)
        command.execute()
        command.execute_post_archive_actions()

        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.todolist.todo(1).source(), "Bar")
        self.assertEqual(self.output, "|  2| Bar p:1\nRemoved: Foo id:1\n")
        self.assertEqual(self.errors, "")

    def test_del1_regex(self):
        command = DeleteCommand(["Foo"], self.todolist, self.out, self.error,
                                _no_prompt)
        command.execute()
        command.execute_post_archive_actions()

        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.todolist.todo(1).source(), "Bar")
        self.assertEqual(self.output, "|  2| Bar p:1\nRemoved: Foo id:1\n")
        self.assertEqual(self.errors, "")

    def test_del2(self):
        command = DeleteCommand(["1"], self.todolist, self.out, self.error,
                                _yes_prompt)
        command.execute()
        command.execute_post_archive_actions()

        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.todolist.count(), 2)
        self.assertEqual(self.output,
                         "|  2| Bar p:1\nRemoved: Bar\nRemoved: Foo\n")
        self.assertEqual(self.errors, "")

    def test_del3(self):
        command = DeleteCommand(["-f", "1"], self.todolist, self.out,
                                self.error, _yes_prompt)
        command.execute()
        command.execute_post_archive_actions()

        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.todolist.count(),
                         3)  # force won't delete subtasks
        self.assertEqual(self.output, "|  2| Bar p:1\nRemoved: Foo id:1\n")
        self.assertEqual(self.errors, "")

    def test_del4(self):
        command = DeleteCommand(["--force", "1"], self.todolist, self.out,
                                self.error, _yes_prompt)
        command.execute()
        command.execute_post_archive_actions()

        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.todolist.count(),
                         3)  # force won't delete subtasks
        self.assertEqual(self.output, "|  2| Bar p:1\nRemoved: Foo id:1\n")
        self.assertEqual(self.errors, "")

    def test_del5(self):
        command = DeleteCommand(["2"], self.todolist, self.out, self.error)
        command.execute()
        command.execute_post_archive_actions()

        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.todolist.todo(1).source(), "Foo")
        self.assertEqual(
            self.output,
            "Removed: Bar p:1\nThe following todo item(s) became active:\n|  1| Foo\n"
        )
        self.assertEqual(self.errors, "")

    def test_del7(self):
        command = DeleteCommand(["99"], self.todolist, self.out, self.error)
        command.execute()
        command.execute_post_archive_actions()

        self.assertFalse(self.todolist.dirty)
        self.assertEqual(self.output, "")
        self.assertEqual(self.errors, "Invalid todo number given.\n")

    def test_del8(self):
        command = DeleteCommand(["A"], self.todolist, self.out, self.error)
        command.execute()
        command.execute_post_archive_actions()

        self.assertFalse(self.todolist.dirty)
        self.assertEqual(self.output, "")
        self.assertEqual(self.errors, "Invalid todo number given.\n")

    def test_del9(self):
        """ Test deletion with textual IDs. """
        config("test/data/todolist-uid.conf")

        command = DeleteCommand(["8to"], self.todolist, self.out, self.error)
        command.execute()
        command.execute_post_archive_actions()

        result = "Foo\na @test with due:2015-06-03\na @test with +project"

        self.assertEqual(self.todolist.print_todos(), result)
        self.assertRaises(InvalidTodoException, self.todolist.todo, 'b0n')

    def test_multi_del1(self):
        """ Test deletion of multiple items. """
        command = DeleteCommand(["1", "2"], self.todolist, self.out,
                                self.error, _no_prompt)
        command.execute()
        command.execute_post_archive_actions()

        result = "a @test with due:2015-06-03\na @test with +project"

        self.assertEqual(self.todolist.count(), 2)
        self.assertEqual(self.todolist.print_todos(), result)

    def test_multi_del2(self):
        """ Test deletion of multiple items. """
        command = DeleteCommand(["1", "2"], self.todolist, self.out,
                                self.error, _yes_prompt)
        command.execute()
        command.execute_post_archive_actions()

        result = "a @test with due:2015-06-03\na @test with +project"

        self.assertEqual(self.todolist.count(), 2)
        self.assertEqual(self.todolist.print_todos(), result)

    def test_multi_del3(self):
        """  Fail if any of supplied todo numbers is invalid. """
        command = DeleteCommand(["99", "2"], self.todolist, self.out,
                                self.error, _yes_prompt)
        command.execute()
        command.execute_post_archive_actions()

        self.assertFalse(self.todolist.dirty)
        self.assertEqual(self.output, "")
        self.assertEqual(self.errors, "Invalid todo number given: 99.\n")

    def test_multi_del4(self):
        """  Check output when all supplied todo numbers are invalid. """
        command = DeleteCommand(["99", "A"], self.todolist, self.out,
                                self.error, _yes_prompt)
        command.execute()
        command.execute_post_archive_actions()

        self.assertFalse(self.todolist.dirty)
        self.assertEqual(self.output, "")
        self.assertEqual(
            self.errors,
            "Invalid todo number given: 99.\nInvalid todo number given: A.\n")

    def test_multi_del5(self):
        """
        Throw an error with invalid argument containing special characters.
        """
        command = DeleteCommand([u"Fo\u00d3B\u0105r", "Bar"], self.todolist,
                                self.out, self.error, None)
        command.execute()
        command.execute_post_archive_actions()

        self.assertFalse(self.todolist.dirty)
        self.assertEqual(self.output, "")
        self.assertEqual(self.errors,
                         u"Invalid todo number given: Fo\u00d3B\u0105r.\n")

    def test_expr_del1(self):
        command = DeleteCommand(["-e", "@test"], self.todolist, self.out,
                                self.error, None)
        command.execute()
        command.execute_post_archive_actions()

        result = "Removed: a @test with due:2015-06-03\nRemoved: a @test with +project\n"

        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.todolist.count(), 2)
        self.assertEqual(self.output, result)
        self.assertEqual(self.errors, "")

    def test_expr_del2(self):
        command = DeleteCommand(["-e", "@test", "due:2015-06-03"],
                                self.todolist, self.out, self.error, None)
        command.execute()
        command.execute_post_archive_actions()

        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.output, "Removed: a @test with due:2015-06-03\n")
        self.assertEqual(self.errors, "")

    def test_expr_del3(self):
        command = DeleteCommand(["-e", "@test", "due:2015-06-03", "+project"],
                                self.todolist, self.out, self.error, None)
        command.execute()
        command.execute_post_archive_actions()

        self.assertFalse(self.todolist.dirty)

    def test_expr_del4(self):
        """ Remove only relevant todo items. """
        command = DeleteCommand(["-e", ""], self.todolist, self.out,
                                self.error, None)
        command.execute()
        command.execute_post_archive_actions()

        result = "Foo"

        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.todolist.count(), 1)
        self.assertEqual(self.todolist.print_todos(), result)

    def test_expr_del5(self):
        """ Force deleting unrelevant items with additional -x flag. """
        command = DeleteCommand(["-xe", ""], self.todolist, self.out,
                                self.error, _yes_prompt)
        command.execute()
        command.execute_post_archive_actions()

        self.assertTrue(self.todolist.dirty)
        self.assertEqual(self.todolist.count(), 0)

    def test_empty(self):
        command = DeleteCommand([], self.todolist, self.out, self.error)
        command.execute()
        command.execute_post_archive_actions()

        self.assertFalse(self.todolist.dirty)
        self.assertFalse(self.output)
        self.assertEqual(self.errors, command.usage() + "\n")

    def test_delete_name(self):
        name = DeleteCommand.name()

        self.assertEqual(name, 'delete')

    def test_help(self):
        command = DeleteCommand(["help"], self.todolist, self.out, self.error)
        command.execute()
        command.execute_post_archive_actions()

        self.assertEqual(self.output, "")
        self.assertEqual(self.errors,
                         command.usage() + "\n\n" + command.help() + "\n")
Esempio n. 8
0
class EditCommandTest(CommandTest):
    def setUp(self):
        super(EditCommandTest, self).setUp()
        todos = ["Foo id:1", "Bar p:1 @test", "Baz @test", u("Fo\u00f3B\u0105\u017a")]

        self.todolist = TodoList(todos)

    @mock.patch("topydo.commands.EditCommand.EditCommand._open_in_editor")
    def test_edit1(self, mock_open_in_editor):
        """ Preserve dependencies after editing. """
        mock_open_in_editor.return_value = 0

        command = EditCommand(["1"], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.errors, "")
        self.assertEqual(self.todolist.print_todos(), u("Bar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a\nFoo id:1"))

    @mock.patch("topydo.commands.EditCommand.EditCommand._todos_from_temp")
    @mock.patch("topydo.commands.EditCommand.EditCommand._open_in_editor")
    def test_edit2(self, mock_open_in_editor, mock_todos_from_temp):
        """ Edit some todo. """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [Todo("Lazy Cat")]

        command = EditCommand(["Bar"], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.errors, "")
        self.assertEqual(self.todolist.print_todos(), u("Foo id:1\nBaz @test\nFo\u00f3B\u0105\u017a\nLazy Cat"))

    def test_edit3(self):
        """ Throw an error after invalid todo number given as argument. """
        command = EditCommand(["FooBar"], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(self.errors, "Invalid todo number given.\n")

    def test_edit4(self):
        """ Throw an error with pointing invalid argument. """
        command = EditCommand(["Bar", "5"], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(self.errors, "Invalid todo number given: 5.\n")

    @mock.patch("topydo.commands.EditCommand.EditCommand._todos_from_temp")
    @mock.patch("topydo.commands.EditCommand.EditCommand._open_in_editor")
    def test_edit5(self, mock_open_in_editor, mock_todos_from_temp):
        """ Don't let to delete todos acidentally while editing. """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [Todo("Only one line")]

        command = EditCommand(["1", "Bar"], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(self.errors, "Number of edited todos is not equal to number of supplied todo IDs.\n")
        self.assertEqual(self.todolist.print_todos(), u("Foo id:1\nBar p:1 @test\nBaz @test\nFo\u00f3B\u0105\u017a"))

    def test_edit6(self):
        """ Throw an error with invalid argument containing special characters. """
        command = EditCommand([u("Fo\u00d3B\u0105r"), "Bar"], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertFalse(self.todolist.is_dirty())
        self.assertEqual(self.errors, u("Invalid todo number given: Fo\u00d3B\u0105r.\n"))

    @mock.patch("topydo.commands.EditCommand.EditCommand._todos_from_temp")
    @mock.patch("topydo.commands.EditCommand.EditCommand._open_in_editor")
    def test_edit7(self, mock_open_in_editor, mock_todos_from_temp):
        """ Edit todo with special characters. """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [Todo("Lazy Cat")]

        command = EditCommand([u("Fo\u00f3B\u0105\u017a")], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.errors, "")
        self.assertEqual(self.todolist.print_todos(), u("Foo id:1\nBar p:1 @test\nBaz @test\nLazy Cat"))

    @mock.patch("topydo.commands.EditCommand.EditCommand._todos_from_temp")
    @mock.patch("topydo.commands.EditCommand.EditCommand._open_in_editor")
    def test_edit_expr(self, mock_open_in_editor, mock_todos_from_temp):
        """ Edit todos matching expression. """
        mock_open_in_editor.return_value = 0
        mock_todos_from_temp.return_value = [Todo("Lazy Cat"), Todo("Lazy Dog")]

        command = EditCommand(["-e", "@test"], self.todolist, self.out, self.error, None)
        command.execute()

        expected = u("|  3| Lazy Cat\n|  4| Lazy Dog\n")

        self.assertTrue(self.todolist.is_dirty())
        self.assertEqual(self.errors, "")
        self.assertEqual(self.output, expected)
        self.assertEqual(self.todolist.print_todos(), u("Foo id:1\nFo\u00f3B\u0105\u017a\nLazy Cat\nLazy Dog"))

    @mock.patch("topydo.commands.EditCommand.check_call")
    def test_edit_archive(self, mock_call):
        """ Edit archive file. """
        mock_call.return_value = 0

        editor = "vi"
        os.environ["EDITOR"] = editor
        archive = config().archive()

        command = EditCommand(["-d"], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertEqual(self.errors, "")
        mock_call.assert_called_once_with([editor, archive])

    @mock.patch("topydo.commands.EditCommand.check_call")
    def test_edit_todotxt(self, mock_call):
        """ Edit todo file. """
        mock_call.return_value = 0

        editor = "vi"
        os.environ["EDITOR"] = editor
        todotxt = config().todotxt()

        result = self.todolist.print_todos()  # copy TodoList content *before* executing command

        command = EditCommand([], self.todolist, self.out, self.error, None)
        command.execute()

        self.assertEqual(self.errors, "")
        self.assertEqual(self.todolist.print_todos(), result)
        mock_call.assert_called_once_with([editor, todotxt])
Esempio n. 9
0
class RevertCommandTest(CommandTest):
    def setUp(self):
        super().setUp()
        todos = [
            "Foo",
            "Bar",
            "Baz",
        ]

        self.todolist = TodoList(todos)
        self.today = date.today()

        self.tmp_name = str(uuid4().hex.upper()[0:6])

        archive_filename = tempfile.gettempdir(
        ) + os.sep + self.tmp_name + '_archive'
        todo_filename = tempfile.gettempdir(
        ) + os.sep + self.tmp_name + '_todo'

        config(
            p_overrides={
                ('topydo', 'archive_filename'): archive_filename,
                ('topydo', 'filename'): todo_filename,
                ('topydo', 'backup_count'): '5'
            })

        self.archive_file = TodoFile(archive_filename)
        self.archive = TodoList([])

    def test_revert01(self):
        backup = BackupSimulator(self.todolist, self.archive, '1', ['do 1'])
        command_executer(DoCommand, ["1"], self.todolist, self.archive,
                         self.out, self.error, None)
        self.archive_file.write(self.archive.print_todos())
        backup.save(self.todolist)

        self.assertEqual(self.archive.print_todos(),
                         "x {} Foo".format(self.today))
        self.assertEqual(self.todolist.print_todos(), "Bar\nBaz")

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()

        result = TodoList(self.archive_file.read()).print_todos()

        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Reverted to state before: do 1\n"))
        self.assertEqual(result, "")
        self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz")

    def test_revert02(self):
        backup = BackupSimulator(self.todolist, self.archive, '1', ['do 1'])
        command_executer(DoCommand, ["1"], self.todolist, self.archive,
                         self.out, self.error, None)
        self.archive_file.write(self.archive.print_todos())
        backup.save(self.todolist)

        # Use add_todolist and add_archive to also cover them
        backup = ChangeSet(p_label=['do Bar'])
        backup.add_todolist(self.todolist)
        backup.add_archive(self.archive)
        backup.timestamp = '2'
        command_executer(DoCommand, ["Bar"], self.todolist, self.archive,
                         self.out, self.error, None)
        self.archive_file.write(self.archive.print_todos())
        backup.save(self.todolist)

        self.assertEqual(self.archive.print_todos(),
                         "x {t} Foo\nx {t} Bar".format(t=self.today))
        self.assertEqual(self.todolist.print_todos(), "Baz")

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()

        result = TodoList(self.archive_file.read()).print_todos()

        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Reverted to state before: do Bar\n"))
        self.assertEqual(result, "x {} Foo".format(self.today))
        self.assertEqual(self.todolist.print_todos(), "Bar\nBaz")

    def test_revert03(self):
        """ Test behavior when no backup is found """
        command = RevertCommand([], self.todolist, self.out, self.error)
        command.execute()

        self.assertEqual(
            self.errors,
            "No backup was found for the current state of {}\n".format(
                config().todotxt()))

    @mock.patch('topydo.lib.Config._Config.archive')
    def test_revert04(self, mock_archive):
        """ Test trimming of the backup_file """
        mock_archive.return_value = ''  # test for empty archive setting
        backup = BackupSimulator(self.todolist, self.archive, '1', ['add One'])
        command_executer(AddCommand, ["One"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '2', ['add Two'])
        command_executer(AddCommand, ["Two"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '3',
                                 ['add Three'])
        command_executer(AddCommand, ["Three"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '4',
                                 ['add Four'])
        command_executer(AddCommand, ["Four"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '5',
                                 ['add Five'])
        command_executer(AddCommand, ["Five"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        result = len(ChangeSet().backup_dict.keys())
        self.assertEqual(result, 6)

        backup = BackupSimulator(self.todolist, self.archive, '6', ['add Six'])
        command_executer(AddCommand, ["Six"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '7',
                                 ['add Seven'])
        command_executer(AddCommand, ["Seven"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        result = len(ChangeSet().backup_dict.keys())
        self.assertEqual(result, 6)

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()

        backup = ChangeSet()
        changesets = list(backup.backup_dict.keys())
        changesets.remove('index')
        index_timestamps = [change[0] for change in backup._get_index()]
        result = list(set(index_timestamps) - set(changesets))

        self.assertEqual(len(changesets), 4)
        self.assertEqual(result, [])
        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Reverted to state before: add Seven\n"))

    def test_revert05(self):
        """ Test for possible backup collisions """
        backup = BackupSimulator(self.todolist, self.archive, '1', ['add One'])
        command_executer(AddCommand, ["One"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '2', ['add Two'])
        command_executer(AddCommand, ["Two"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '3',
                                 ['add Three'])
        command_executer(AddCommand, ["Three"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '4',
                                 ['delete Three'])
        command_executer(DeleteCommand, ["Three"], self.todolist, None,
                         self.out, self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '5',
                                 ['add Four'])
        command_executer(AddCommand, ["Four"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Reverted to state before: add Four\n"))
        self.assertEqual(
            self.todolist.print_todos(),
            "Foo\nBar\nBaz\n{t} One\n{t} Two".format(t=self.today))

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Reverted to state before: delete Three\n"))
        self.assertEqual(
            self.todolist.print_todos(),
            "Foo\nBar\nBaz\n{t} One\n{t} Two\n{t} Three".format(t=self.today))

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Reverted to state before: add Three\n"))
        self.assertEqual(
            self.todolist.print_todos(),
            "Foo\nBar\nBaz\n{t} One\n{t} Two".format(t=self.today))

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Reverted to state before: add Two\n"))
        self.assertEqual(self.todolist.print_todos(),
                         "Foo\nBar\nBaz\n{t} One".format(t=self.today))

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Reverted to state before: add One\n"))
        self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz")

    def test_revert06(self):
        """ Test attempt of deletion with non-existing backup key"""
        backup = BackupSimulator(self.todolist, self.archive, '1', ['add One'])
        command_executer(AddCommand, ["One"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '2', ['add Two'])
        command_executer(AddCommand, ["Two"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '3',
                                 ['add Three'])
        command_executer(AddCommand, ["Three"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '4',
                                 ['delete Three'])
        command_executer(DeleteCommand, ["Three"], self.todolist, None,
                         self.out, self.error, None)
        backup.save(self.todolist)

        backup = ChangeSet()
        backup.delete('Foo')

        changesets = list(backup.backup_dict.keys())
        changesets.remove('index')
        index_timestamps = [change[0] for change in backup._get_index()]
        result = list(set(index_timestamps) - set(changesets))

        self.assertEqual(len(changesets), 4)
        self.assertEqual(result, [])
        self.assertEqual(self.errors, "")

    def test_revert07(self):
        """ Test backup when no archive file is set """
        backup = ChangeSet(self.todolist, None, ['add One'])
        backup.timestamp = '1'
        command_executer(AddCommand, ["One"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        changesets = list(backup.backup_dict.keys())
        changesets.remove('index')

        self.assertEqual(len(changesets), 1)
        self.assertEqual(self.errors, "")

    def test_revert_ls(self):
        backup = BackupSimulator(self.todolist, self.archive, '1', ['add One'])
        command_executer(AddCommand, ["One"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '2', ['add Two'])
        command_executer(AddCommand, ["Two"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '3',
                                 ['add Three'])
        command_executer(AddCommand, ["Three"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '4',
                                 ['delete Three'])
        command_executer(DeleteCommand, ["Three"], self.todolist, None,
                         self.out, self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '5',
                                 ['add Four'])
        command_executer(AddCommand, ["Four"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        command_executer(RevertCommand, ['ls'], self.todolist, None, self.out,
                         self.error, None)

        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("""  1| 1970-01-01 00:00:05 | add Four
  2| 1970-01-01 00:00:04 | delete Three
  3| 1970-01-01 00:00:03 | add Three
  4| 1970-01-01 00:00:02 | add Two
  5| 1970-01-01 00:00:01 | add One\n"""))

    def test_revert_08(self):
        backup = BackupSimulator(self.todolist, self.archive, '1', ['add One'])
        command_executer(AddCommand, ["One"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '2', ['add Two'])
        command_executer(AddCommand, ["Two"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '3',
                                 ['add Three'])
        command_executer(AddCommand, ["Three"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '4',
                                 ['delete Three'])
        command_executer(DeleteCommand, ["Three"], self.todolist, None,
                         self.out, self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '5',
                                 ['add Four'])
        command_executer(AddCommand, ["Four"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        command_executer(RevertCommand, ['3'], self.todolist, None, self.out,
                         self.error, None)

        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Reverted to state before: add Three\n"))
        self.assertEqual(self.todolist.print_todos(),
                         "Foo\nBar\nBaz\n2015-11-06 One\n2015-11-06 Two")

    def test_revert_invalid(self):
        """ Test invalid input for revert. """
        command_executer(RevertCommand, ["foo"], self.todolist, None, self.out,
                         self.error, None)
        command_executer(RevertCommand, ["ls", "foo"], self.todolist, None,
                         self.out, self.error, None)
        command_executer(RevertCommand, ["1", "foo"], self.todolist, None,
                         self.out, self.error, None)
        usage_text = RevertCommand([], self.todolist).usage() + '\n'
        self.assertEqual(self.errors, usage_text * 3)

    def test_revert_out_of_range(self):
        command_executer(RevertCommand, ["158"], self.todolist, None, self.out,
                         self.error, None)
        self.assertEqual(self.errors, "Specified index is out range\n")

    def test_revert_no_todolist(self):
        """ Test attempt of revert with todolist missing """
        backup = BackupSimulator(self.todolist, self.archive, '1', ['add One'])
        command_executer(AddCommand, ["One"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '2', ['add Two'])
        command_executer(AddCommand, ["Two"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '3',
                                 ['add Three'])
        command_executer(AddCommand, ["Three"], self.todolist, None, self.out,
                         self.error, None)
        backup.save(self.todolist)

        backup = BackupSimulator(self.todolist, self.archive, '4',
                                 ['delete Three'])
        command_executer(DeleteCommand, ["Three"], self.todolist, None,
                         self.out, self.error, None)
        backup.save(self.todolist)

        command_executer(RevertCommand, ['1'], None, None, self.out,
                         self.error, None)

        result = len(ChangeSet().backup_dict.keys())
        self.assertEqual(result, 4)

    def test_backup_config01(self):
        config(p_overrides={('topydo', 'backup_count'): '1'})

        self.assertEqual(config().backup_count(), 1)

    def test_backup_config02(self):
        config(p_overrides={('topydo', 'backup_count'): '0'})

        self.assertEqual(config().backup_count(), 0)

    def test_backup_config03(self):
        config(p_overrides={('topydo', 'backup_count'): '-88'})

        self.assertEqual(config().backup_count(), 0)

    def test_backup_config04(self):
        config(p_overrides={('topydo', 'backup_count'): 'foo'})

        self.assertEqual(config().backup_count(), 5)

    def test_revert_name(self):
        name = RevertCommand.name()

        self.assertEqual(name, 'revert')

    def test_help(self):
        command = RevertCommand(["help"], self.todolist, self.out, self.error)
        command.execute()

        self.assertEqual(self.output, "")
        self.assertEqual(self.errors,
                         command.usage() + "\n\n" + command.help() + "\n")

    def tearDown(self):
        for filename in glob('/tmp/' + self.tmp_name + '*'):
            os.remove(filename)
Esempio n. 10
0
class RevertCommandTest(CommandTest):
    def setUp(self):
        super().setUp()
        todos = [
            "Foo",
            "Bar",
            "Baz",
        ]

        self.todolist = TodoList(todos)
        self.today = date.today()

        self.tmp_name = str(uuid4().hex.upper()[0:6])

        archive_filename = tempfile.gettempdir(
        ) + os.sep + self.tmp_name + '_archive'
        todo_filename = tempfile.gettempdir(
        ) + os.sep + self.tmp_name + '_todo'

        config(
            p_overrides={
                ('topydo', 'archive_filename'): archive_filename,
                ('topydo', 'filename'): todo_filename,
                ('topydo', 'backup_count'): '5'
            })

        self.archive_file = TodoFile(archive_filename)
        self.archive = TodoList([])

    def test_revert01(self):
        backup = ChangeSet(p_label=['do 1'])
        backup.add_todolist(self.todolist)
        backup.add_archive(self.archive)
        backup.timestamp = '1'
        command = DoCommand(["1"], self.todolist, self.out, self.error, None)
        command.execute()
        archive_command = ArchiveCommand(self.todolist, self.archive)
        archive_command.execute()
        self.archive_file.write(self.archive.print_todos())
        backup.save(self.todolist)

        self.assertEqual(self.archive.print_todos(),
                         "x {} Foo".format(self.today))
        self.assertEqual(self.todolist.print_todos(), "Bar\nBaz")

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()

        result = TodoList(self.archive_file.read()).print_todos()

        self.assertEqual(self.errors, "")
        self.assertTrue(self.output.endswith("Successfully reverted: do 1\n"))
        self.assertEqual(result, "")
        self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz")

    def test_revert02(self):
        backup = ChangeSet(self.todolist, self.archive, ['do 1'])
        backup.timestamp = '1'
        command1 = DoCommand(["1"], self.todolist, self.out, self.error, None)
        command1.execute()
        archive_command1 = ArchiveCommand(self.todolist, self.archive)
        archive_command1.execute()
        self.archive_file.write(self.archive.print_todos())
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['do Bar'])
        backup.timestamp = '2'
        command2 = DoCommand(["Bar"], self.todolist, self.out, self.error,
                             None)
        command2.execute()
        archive_command2 = ArchiveCommand(self.todolist, self.archive)
        archive_command2.execute()
        self.archive_file.write(self.archive.print_todos())
        backup.save(self.todolist)

        self.assertEqual(self.archive.print_todos(),
                         "x {t} Foo\nx {t} Bar".format(t=self.today))
        self.assertEqual(self.todolist.print_todos(), "Baz")

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()

        result = TodoList(self.archive_file.read()).print_todos()

        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Successfully reverted: do Bar\n"))
        self.assertEqual(result, "x {} Foo".format(self.today))
        self.assertEqual(self.todolist.print_todos(), "Bar\nBaz")

    def test_revert03(self):
        """ Test behavior when no backup is found """
        command = RevertCommand([], self.todolist, self.out, self.error)
        command.execute()

        self.assertEqual(
            self.errors,
            "No backup was found for the current state of {}\n".format(
                config().todotxt()))

    def test_revert04(self):
        """ Test trimming of the backup_file """
        backup = ChangeSet(self.todolist, self.archive, ['add One'])
        backup.timestamp = '1'
        command1 = AddCommand(["One"], self.todolist, self.out, self.error,
                              None)
        command1.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Two'])
        backup.timestamp = '2'
        command2 = AddCommand(["Two"], self.todolist, self.out, self.error,
                              None)
        command2.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Three'])
        backup.timestamp = '3'
        command3 = AddCommand(["Three"], self.todolist, self.out, self.error,
                              None)
        command3.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Four'])
        backup.timestamp = '4'
        command4 = AddCommand(["Four"], self.todolist, self.out, self.error,
                              None)
        command4.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Five'])
        backup.timestamp = '5'
        command5 = AddCommand(["Five"], self.todolist, self.out, self.error,
                              None)
        command5.execute()
        backup.save(self.todolist)

        result = len(ChangeSet().backup_dict.keys())
        self.assertEqual(result, 6)

        backup = ChangeSet(self.todolist, self.archive, ['add Six'])
        backup.timestamp = '6'
        command6 = AddCommand(["Six"], self.todolist, self.out, self.error,
                              None)
        command6.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Seven'])
        backup.timestamp = '7'
        command7 = AddCommand(["Seven"], self.todolist, self.out, self.error,
                              None)
        command7.execute()
        backup.save(self.todolist)

        result = len(ChangeSet().backup_dict.keys())
        self.assertEqual(result, 6)

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()

        backup = ChangeSet()
        changesets = list(backup.backup_dict.keys())
        changesets.remove('index')
        index_timestamps = [change[0] for change in backup._get_index()]
        result = list(set(index_timestamps) - set(changesets))

        self.assertEqual(len(changesets), 4)
        self.assertEqual(result, [])
        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Successfully reverted: add Seven\n"))

    def test_revert05(self):
        """ Test for possible backup collisions """
        backup = ChangeSet(self.todolist, self.archive, ['add One'])
        backup.timestamp = '1'
        command1 = AddCommand(["One"], self.todolist, self.out, self.error,
                              None)
        command1.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Two'])
        backup.timestamp = '2'
        command2 = AddCommand(["Two"], self.todolist, self.out, self.error,
                              None)
        command2.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Three'])
        backup.timestamp = '3'
        command3 = AddCommand(["Three"], self.todolist, self.out, self.error,
                              None)
        command3.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['delete Three'])
        backup.timestamp = '4'
        command4 = DeleteCommand(["Three"], self.todolist, self.out,
                                 self.error, None)
        command4.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Four'])
        backup.timestamp = '5'
        command4 = AddCommand(["Four"], self.todolist, self.out, self.error,
                              None)
        command4.execute()
        backup.save(self.todolist)

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Successfully reverted: add Four\n"))
        self.assertEqual(
            self.todolist.print_todos(),
            "Foo\nBar\nBaz\n{t} One\n{t} Two".format(t=self.today))

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Successfully reverted: delete Three\n"))
        self.assertEqual(
            self.todolist.print_todos(),
            "Foo\nBar\nBaz\n{t} One\n{t} Two\n{t} Three".format(t=self.today))

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Successfully reverted: add Three\n"))
        self.assertEqual(
            self.todolist.print_todos(),
            "Foo\nBar\nBaz\n{t} One\n{t} Two".format(t=self.today))

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Successfully reverted: add Two\n"))
        self.assertEqual(self.todolist.print_todos(),
                         "Foo\nBar\nBaz\n{t} One".format(t=self.today))

        revert_command = RevertCommand([], self.todolist, self.out, self.error,
                                       None)
        revert_command.execute()
        self.assertEqual(self.errors, "")
        self.assertTrue(
            self.output.endswith("Successfully reverted: add One\n"))
        self.assertEqual(self.todolist.print_todos(), "Foo\nBar\nBaz")

    def test_revert06(self):
        """ Test attempt of deletion with non-existing backup key"""
        backup = ChangeSet(self.todolist, self.archive, ['add One'])
        backup.timestamp = '1'
        command1 = AddCommand(["One"], self.todolist, self.out, self.error,
                              None)
        command1.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Two'])
        backup.timestamp = '2'
        command2 = AddCommand(["Two"], self.todolist, self.out, self.error,
                              None)
        command2.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['add Three'])
        backup.timestamp = '3'
        command3 = AddCommand(["Three"], self.todolist, self.out, self.error,
                              None)
        command3.execute()
        backup.save(self.todolist)

        backup = ChangeSet(self.todolist, self.archive, ['delete Three'])
        backup.timestamp = '4'
        command4 = DeleteCommand(["Three"], self.todolist, self.out,
                                 self.error, None)
        command4.execute()
        backup.save(self.todolist)

        backup = ChangeSet()
        backup.delete('Foo')

        changesets = list(backup.backup_dict.keys())
        changesets.remove('index')
        index_timestamps = [change[0] for change in backup._get_index()]
        result = list(set(index_timestamps) - set(changesets))

        self.assertEqual(len(changesets), 4)
        self.assertEqual(result, [])
        self.assertEqual(self.errors, "")

    def test_revert07(self):
        """ Test backup when no archive file is set """
        backup = ChangeSet(self.todolist, None, ['add One'])
        backup.timestamp = '1'
        command1 = AddCommand(["One"], self.todolist, self.out, self.error,
                              None)
        command1.execute()
        backup.save(self.todolist)

        changesets = list(backup.backup_dict.keys())
        changesets.remove('index')

        self.assertEqual(len(changesets), 1)
        self.assertEqual(self.errors, "")

    def test_backup_config01(self):
        config(p_overrides={('topydo', 'backup_count'): '1'})

        self.assertEqual(config().backup_count(), 1)

    def test_backup_config02(self):
        config(p_overrides={('topydo', 'backup_count'): '0'})

        self.assertEqual(config().backup_count(), 0)

    def test_backup_config03(self):
        config(p_overrides={('topydo', 'backup_count'): '-88'})

        self.assertEqual(config().backup_count(), 0)

    def test_backup_config04(self):
        config(p_overrides={('topydo', 'backup_count'): 'foo'})

        self.assertEqual(config().backup_count(), 5)

    def test_revert_name(self):
        name = RevertCommand.name()

        self.assertEqual(name, 'revert')

    def test_help(self):
        command = RevertCommand(["help"], self.todolist, self.out, self.error)
        command.execute()

        self.assertEqual(self.output, "")
        self.assertEqual(self.errors,
                         command.usage() + "\n\n" + command.help() + "\n")

    def tearDown(self):
        for filename in glob('/tmp/' + self.tmp_name + '*'):
            os.remove(filename)