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_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")
class BackupSimulator(object): def __init__(self, p_todolist, p_archive, p_timestamp, p_label): self.backup = ChangeSet(p_todolist, p_archive, p_label) self.backup.timestamp = p_timestamp def save(self, p_todolist): self.backup.save(p_todolist)
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_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_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, "")
class CLIApplicationBase(object): """ Base class for a Command Line Interfaces (CLI) for topydo. Examples are the original CLI and the Prompt interface. Handles input/output of the various subcommands. """ def __init__(self): self.todolist = TodoList.TodoList([]) self.todofile = None self.do_archive = True self._post_archive_action = None self.backup = None @staticmethod def _usage(): usage() sys.exit(0) def _process_flags(self): args = sys.argv[1:] try: opts, args = getopt.getopt(args, MAIN_OPTS, MAIN_LONG_OPTS) except getopt.GetoptError as e: error(str(e)) sys.exit(1) alt_config_path = None overrides = {} for opt, value in opts: if opt == "-a": self.do_archive = False elif opt == "-c": alt_config_path = value elif opt == "-C": overrides[('topydo', 'force_colors')] = '1' overrides[('topydo', 'colors')] = value elif opt == "-t": overrides[('topydo', 'filename')] = value elif opt == "-d": overrides[('topydo', 'archive_filename')] = value elif opt in ("-v", "--version"): version() else: CLIApplicationBase._usage() if alt_config_path: config(alt_config_path, overrides) elif len(overrides): config(p_overrides=overrides) return args def _archive(self): """ Performs an archive action on the todolist. This means that all completed tasks are moved to the archive file (defaults to done.txt). """ archive, archive_file = _retrieve_archive() if self.backup: self.backup.add_archive(archive) if archive: command = ArchiveCommand(self.todolist, archive) command.execute() if archive.dirty: archive_file.write(archive.print_todos()) @staticmethod def is_read_only(p_command): """ Returns True when the given command class is read-only. """ read_only_commands = tuple( cmd for cmd in ('revert', ) + READ_ONLY_COMMANDS) return p_command.name() in read_only_commands def _backup(self, p_command, p_args=None, p_label=None): if config().backup_count( ) > 0 and p_command and not CLIApplicationBase.is_read_only(p_command): p_args = p_args if p_args else [] call = [p_command.name()] + p_args from topydo.lib.ChangeSet import ChangeSet label = p_label if p_label else call self.backup = ChangeSet(self.todolist, p_label=label) def _execute(self, p_command, p_args): """ Execute a subcommand with arguments. p_command is a class (not an object). """ self._backup(p_command, p_args) if p_command == None: usage() return False if p_command.name() != 'archive': command = p_command(p_args, self.todolist, output, error, input) if command.execute() != False: self._post_archive_action = command.execute_post_archive_actions return True else: self.todolist.dirty = True self.do_archive = True return True return False def _post_execute(self): """ Should be called when executing the user requested command has been completed. It will do some maintenance and write out the final result to the todo.txt file. """ if self.todolist.dirty: # do not archive when the value of the filename is an empty string # (i.e. explicitly left empty in the configuration if self.do_archive and config().archive(): self._archive() elif config().archive() and self.backup: archive = _retrieve_archive()[0] self.backup.add_archive(archive) try: self._post_archive_action() except TypeError: pass if config().keep_sorted(): from topydo.commands.SortCommand import SortCommand self._execute(SortCommand, []) if self.backup: self.backup.save(self.todolist) self.todofile.write(self.todolist.print_todos()) self.todolist.dirty = False self.backup = None def run(self): raise NotImplementedError
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_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"))
class CLIApplicationBase(object): """ Base class for a Command Line Interfaces (CLI) for topydo. Examples are the original CLI and the Prompt interface. Handles input/output of the various subcommands. """ def __init__(self): self.todolist = TodoList.TodoList([]) self.todofile = None self.do_archive = True self._post_archive_action = None self.backup = None @staticmethod def _usage(): usage() sys.exit(0) def _process_flags(self): args = sys.argv[1:] try: opts, args = getopt.getopt(args, MAIN_OPTS, MAIN_LONG_OPTS) except getopt.GetoptError as e: error(str(e)) sys.exit(1) alt_config_path = None overrides = {} for opt, value in opts: if opt == "-a": self.do_archive = False elif opt == "-c": alt_config_path = value elif opt == "-C": overrides[('topydo', 'force_colors')] = '1' overrides[('topydo', 'colors')] = value elif opt == "-t": overrides[('topydo', 'filename')] = value elif opt == "-d": overrides[('topydo', 'archive_filename')] = value elif opt in ("-v", "--version"): version() else: CLIApplicationBase._usage() if alt_config_path: config(alt_config_path, overrides) elif len(overrides): config(p_overrides=overrides) return args def _archive(self): """ Performs an archive action on the todolist. This means that all completed tasks are moved to the archive file (defaults to done.txt). """ archive, archive_file = _retrieve_archive() if self.backup: self.backup.add_archive(archive) if archive: from topydo.commands.ArchiveCommand import ArchiveCommand command = ArchiveCommand(self.todolist, archive) command.execute() if archive.dirty: archive_file.write(archive.print_todos()) @staticmethod def is_read_only(p_command): """ Returns True when the given command class is read-only. """ read_only_commands = tuple(cmd for cmd in ('revert', ) + READ_ONLY_COMMANDS) return p_command.name() in read_only_commands def _backup(self, p_command, p_args=None, p_label=None): if config().backup_count() > 0 and p_command and not CLIApplicationBase.is_read_only(p_command): p_args = p_args if p_args else [] call = [p_command.name()] + p_args from topydo.lib.ChangeSet import ChangeSet label = p_label if p_label else call self.backup = ChangeSet(self.todolist, p_label=label) def _execute(self, p_command, p_args): """ Execute a subcommand with arguments. p_command is a class (not an object). """ self._backup(p_command, p_args) command = p_command( p_args, self.todolist, output, error, input) if command.execute() != False: self._post_archive_action = command.execute_post_archive_actions return True return False def _post_execute(self): """ Should be called when executing the user requested command has been completed. It will do some maintenance and write out the final result to the todo.txt file. """ if self.todolist.dirty: # do not archive when the value of the filename is an empty string # (i.e. explicitly left empty in the configuration if self.do_archive and config().archive(): self._archive() elif config().archive() and self.backup: archive = _retrieve_archive()[0] self.backup.add_archive(archive) self._post_archive_action() if config().keep_sorted(): from topydo.commands.SortCommand import SortCommand self._execute(SortCommand, []) if self.backup: self.backup.save(self.todolist) self.todofile.write(self.todolist.print_todos()) self.todolist.dirty = False self.backup = None def run(self): raise NotImplementedError
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_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"))
class CLIApplicationBase(object): """ Base class for a Command Line Interfaces (CLI) for topydo. Examples are the original CLI and the Prompt interface. Handles input/output of the various subcommands. """ def __init__(self): self.todolist = TodoList.TodoList([]) self.todofile = None self.do_archive = True self.backup = None def _usage(self): usage() sys.exit(0) def _process_flags(self): args = sys.argv[1:] try: opts, args = getopt.getopt(args, MAIN_OPTS) except getopt.GetoptError as e: error(str(e)) sys.exit(1) alt_config_path = None overrides = {} for opt, value in opts: if opt == "-a": self.do_archive = False elif opt == "-c": alt_config_path = value elif opt == "-t": overrides[('topydo', 'filename')] = value elif opt == "-d": overrides[('topydo', 'archive_filename')] = value elif opt == "-v": version() else: self._usage() if alt_config_path: config(alt_config_path, overrides) elif len(overrides): config(p_overrides=overrides) return args def _archive(self): """ Performs an archive action on the todolist. This means that all completed tasks are moved to the archive file (defaults to done.txt). """ archive_file = TodoFile.TodoFile(config().archive()) archive = TodoListBase.TodoListBase(archive_file.read()) if self.backup: self.backup.add_archive(archive) if archive: from topydo.commands.ArchiveCommand import ArchiveCommand command = ArchiveCommand(self.todolist, archive) command.execute() if archive.is_dirty(): archive_file.write(archive.print_todos()) def _help(self, args): if args is None: pass # TODO else: pass # TODO def is_read_only(self, p_command): """ Returns True when the given command class is read-only. """ read_only_commands = tuple(cmd + 'Command' for cmd in ('Revert', ) + READ_ONLY_COMMANDS) return p_command.__module__.endswith(read_only_commands) def _execute(self, p_command, p_args): """ Execute a subcommand with arguments. p_command is a class (not an object). """ if config().backup_count() > 0 and p_command and not self.is_read_only(p_command): call = [p_command.__module__.lower()[16:-7]] + p_args # strip "topydo.commands" and "Command" from topydo.lib.ChangeSet import ChangeSet self.backup = ChangeSet(self.todolist, p_call=call) command = p_command( p_args, self.todolist, lambda o: write(sys.stdout, o), error, input) if command.execute() != False: return True return False def _post_execute(self): """ Should be called when executing the user requested command has been completed. It will do some maintenance and write out the final result to the todo.txt file. """ if self.todolist.is_dirty(): # do not archive when the value of the filename is an empty string # (i.e. explicitly left empty in the configuration if self.do_archive and config().archive(): self._archive() if config().keep_sorted(): from topydo.commands.SortCommand import SortCommand self._execute(SortCommand, []) if self.backup: self.backup.save(self.todolist) self.todofile.write(self.todolist.print_todos()) self.backup = None def run(self): raise NotImplementedError