def executeCMD(model: UMLModel, command_history: CommandHistory, commandName: str, arguments: list) -> None: """Grabs the command and pushes it into the history if it is undoable Executes the command in the REPL, and prints out a success/error message depending on whether it was an appropriate command Params: - model - the current model to execute commands on - commandName - the name of the command - arguments - the possible argument(s) that came with the command """ # Ensure valid command if commandName not in CommandData.COMMANDS: print( f"{ERROR_COLOR}CommandError:{NORMAL_COLOR}", f"'{commandName}' is not a valid command\ntype 'help' for a list of valid commands" ) return # Find command usage matching args # and validate number of arguments command = None for usage in CommandData.COMMANDS[commandName]: # found usage matching num args if usage["num_arguments"] == len(arguments): # if the command class was provided if "command" in usage: command = usage["command"](model, usage["function"], arguments) # otherwise, assume it is not an undoable command else: command = CLICommand(model, usage["function"], arguments) break # matching usage not found else: print( f"{ERROR_COLOR}CommandError:{NORMAL_COLOR}", f"Incorrect usage of {commandName}\ntype 'help {commandName}' to see valid usages of {commandName}" ) return # save backup - for undoable commands if isinstance(command, UndoableCLICommand): command.saveBackup() # execute the command status, msg = command.execute() # Ensure command was successful if not status: print(f"{ERROR_COLOR}ERROR:{NORMAL_COLOR} {msg}") return # push undoable commands to the history if isinstance(command, UndoableCLICommand): # add to the list of history command_history.push(command) print(f"{SUCCESS_COLOR}SUCCESS:{NORMAL_COLOR} {msg}")
def test_executeCMD(self): model = UMLModel() command_history = CommandHistory(HISTORY_LIMIT) # Test1 : simple cmd executeCMD(model, command_history, "create_class", ["class1"]) # ensure model has the new class self.assertTrue("class1" in model.classes) # ensure command is in history self.assertTrue(len(command_history.history) == 1) # Test2 : invalid cmd captured = io.StringIO() sys.stdout = captured executeCMD(model, command_history, "not_a_command", []) # ensure error message was given self.assertEqual( captured.getvalue(), f"{ERROR_COLOR}CommandError:{NORMAL_COLOR} " f"'not_a_command' is not a valid command\ntype 'help' for a list of valid commands\n" ) # Test3 : invalid length of arguments captured = io.StringIO() sys.stdout = captured commandName = "create_field" executeCMD(model, command_history, commandName, ["name"]) # ensure error message was given self.assertEqual( captured.getvalue(), f"{ERROR_COLOR}CommandError:{NORMAL_COLOR} " f"Incorrect usage of {commandName}\ntype 'help {commandName}' to see valid usages of {commandName}\n" ) # Test4 : valid cmd with arguments that fail captured = io.StringIO() sys.stdout = captured executeCMD(model, command_history, "create_class", ["class1"]) # ensure error message was given self.assertTrue(captured.getvalue().startswith( f"{ERROR_COLOR}ERROR:{NORMAL_COLOR}")) # Test5 : non-undoable command captured = io.StringIO() sys.stdout = captured command_history = CommandHistory(HISTORY_LIMIT) executeCMD(model, command_history, "list_classes", []) # ensure success self.assertTrue(captured.getvalue().startswith( f"{SUCCESS_COLOR}SUCCESS:{NORMAL_COLOR}")) # ensure command was not added to history self.assertEqual(len(command_history.history), 0)
def test_complete_rename_class(self): model = UMLModel() model.create_class("class1") model.create_class("myclass") repl = REPL(model, CommandHistory(HISTORY_LIMIT)) # Test 1: Tab before classname classnames = repl.complete_rename_class("", "rename_class ", 0, 0) self.assertEqual(classnames, ["class1", "myclass"]) # Test 2: Tab in the middle of classname - only one match classnames = repl.complete_rename_class("cl", "rename_class cl", 0, 0) self.assertEqual(classnames, ["class1"]) # Test 3: Tab after classname classnames = repl.complete_rename_class("class1", "rename_class class1", 0, 0) self.assertEqual(classnames, ["class1"]) # Test 4: Tab before second classname classnames = repl.complete_rename_class("", "rename_class class1 ", 0, 0) self.assertEqual(classnames, []) # Test 5: Tab after second classname classnames = repl.complete_rename_class( "newclassname", "rename_class class1 newclassname", 0, 0) self.assertEqual(classnames, [])
def __init__(self, model=UMLModel(), command_history=CommandHistory(HISTORY_LIMIT)): cmd.Cmd.__init__(self) self.model = model # Keeps track of the commands that were performed self.command_history = command_history
def test_do_create_class(self): model = UMLModel() command_history = CommandHistory(HISTORY_LIMIT) repl = REPL(model, command_history) repl.do_create_class("class1") # ensure class was created self.assertTrue("class1" in model.classes)
def test_do_create_field(self): model = UMLModel() model.create_class("class1") command_history = CommandHistory(HISTORY_LIMIT) repl = REPL(model, command_history) repl.do_create_field("class1 private int age") # ensure field was created self.assertTrue(model.classes["class1"].field_index("age") != -1)
def test_complete_rename_parameter(self): model = UMLModel() model.create_class("class1") model.create_method("class1", "public", "int", "method1") model.create_parameter("class1", "method1", "int", "a") model.create_parameter("class1", "method1", "int", "b") model.create_parameter("class1", "method1", "int", "abba") model.create_method("class1", "public", "int", "method2") model.create_method("class1", "public", "int", "mymethod") model.create_class("myclass") repl = REPL(model, CommandHistory(HISTORY_LIMIT)) # Test 1: Tab before classname classnames = repl.complete_rename_parameter("", "rename_parameter ", 0, 0) self.assertEqual(classnames, ["class1", "myclass"]) # Test 2: Tab in the middle of classname - only one match classnames = repl.complete_rename_parameter("cl", "rename_parameter cl", 0, 0) self.assertEqual(classnames, ["class1"]) # Test 3: Tab before methodname classnames = repl.complete_rename_parameter( "", "rename_parameter class1 ", 0, 0) self.assertEqual(classnames, ["method1", "method2", "mymethod"]) # Test 4: Tab during methodname classnames = repl.complete_rename_parameter( "met", "rename_parameter class1 met", 0, 0) self.assertEqual(classnames, ["method1", "method2"]) # Test 5: Tab before old param name classnames = repl.complete_rename_parameter( "", "rename_parameter class1 method1 ", 0, 0) self.assertEqual(classnames, ["a", "b", "abba"]) # Test 6: Tab during old param name classnames = repl.complete_rename_parameter( "a", "rename_parameter class1 method1 a", 0, 0) self.assertEqual(classnames, ["a", "abba"]) # Test 7: Tab after old param name classnames = repl.complete_rename_parameter( "", "rename_parameter class1 method1 abba ", 0, 0) self.assertEqual(classnames, []) # Test 8: Tab after old param name classnames = repl.complete_rename_parameter( "iLikePie", "rename_parameter class1 method1 abba iLikePie", 0, 0) self.assertEqual(classnames, [])
def test_undo(self): model = UMLModel() command_history = CommandHistory(HISTORY_LIMIT) executeCMD(model, command_history, "create_class", ["class1"]) # ensure class was there previously self.assertTrue("class1" in model.classes) # Test 1: undo valid command undo(command_history, []) # ensure command was undone self.assertTrue(len(model.classes) == 0) self.assertTrue(len(command_history.history) == 0) self.assertTrue(len(command_history.future) == 1) # Test 2: nothing to undo captured = io.StringIO() sys.stdout = captured undo(command_history, []) self.assertEqual( captured.getvalue(), f"{ERROR_COLOR}ERROR:{NORMAL_COLOR} no command to undo\n")
def redo(command_history: CommandHistory, args: list): """redoes a command in the given command history and prints whether it was successful or not. the args parameter just checks to make sure no arguments were provided """ # Ensure no args if len(args) != 0: print(f"{ERROR_COLOR}CommandError:{NORMAL_COLOR}", f"Incorrect usage of redo\nredo does not take any arguments") return # get undone command command = command_history.pop_redo() # ensure there was a command if command == None: print(f"{ERROR_COLOR}ERROR:{NORMAL_COLOR} no command to redo") return # redo the command command.execute() print(f"{SUCCESS_COLOR}SUCCESS:{NORMAL_COLOR} command redone succesfully")