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")
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")
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])
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)
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")
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")
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")
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])
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)
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)