def test_execute(self): # create model model_name = "myModel" model = UMLModel() model.save_model(model_name + ".json", directory=os.getcwd() + "/") class_data = { "filename": model_name + ".json", "directory": os.getcwd() + "/", "class_name": "class1", "field_visibilities": ["private", "private"], "field_types": ["string", "int"], "field_names": ["name", "age"], "method_visibilities": ["public"], "method_types": ["string"], "method_names": ["getName"], "parameter_method_index": [], "parameter_types": [], "parameter_names": [] } cmd = CreateClassGUICommand(model, class_data) cmd.saveBackup() status, msg = cmd.execute() # ensure it passed self.assertTrue(status) # ensure components are in model self.assertTrue("class1" in model.classes) self.assertTrue(len(model.classes["class1"].fields) == 2)
def test_create_relationship(self): model = UMLModel() model.create_class("c1") model.create_class("c2") # Ensure relationship is created model.create_relationship("composition", "c1", "c2") self.assertTrue(model.classes["c1"].has_relationship("c2")) self.assertTrue(model.classes["c2"].has_relationship("c1")) status, msg = model.create_relationship("invalidRealType", "c5", "c2") self.assertFalse(status) self.assertEqual(msg, "'invalidRealType' is not a valid relationship type.") # Ensure we get correct output when class 1 doesn't exist status, msg = model.create_relationship("realization", "c5", "c2") self.assertFalse(status) self.assertEqual(msg, "'c5' does not exist") # Ensure we get correct output when class 2 doesn't exist status, msg = model.create_relationship("realization", "c1", "c5") self.assertFalse(status) self.assertEqual(msg, "'c5' does not exist") # Ensure already existing rel status, msg = model.create_relationship("composition","c2","c1") # ensure it failed self.assertFalse(status) self.assertEqual(msg, "Relationship between 'c2' and 'c1' already exists.")
def test_delete_relationship(self): model = UMLModel() model.create_class("c1") model.create_class("c2") model.create_relationship("realization", "c1", "c2") # Ensure we get correct output when class 1 doesn't exist status, msg = model.delete_relationship("c7","c2") self.assertFalse(status) self.assertEqual(msg, "c7 does not exist") # Ensure we get correct output when class 2 doesn't exist status, msg = model.delete_relationship("c1","c5") self.assertFalse(status) self.assertEqual(msg, "c5 does not exist") # Ensure relationship is deleted status, msg = model.delete_relationship("c1","c2") self.assertEqual(len(model.classes["c1"].relationships), 0) self.assertEqual(len(model.classes["c2"].relationships), 0) # Ensure we get correct output after relationship has been deleted self.assertTrue(status) self.assertEqual(msg, "Relationship between c1 and c2 has been deleted") # Ensure we get correct output if we try to delete relationship that doesn't exist status, msg = model.delete_relationship("c1","c2") self.assertFalse(status) self.assertEqual(msg, "Relationship between c1 and c2 does not exist.")
def test_delete_class(self): model = UMLModel() model.create_class("class1") model.create_class("class2") # create relationship between classes model.create_relationship("composition", "class1", "class2") # Ensure relationship is created self.assertTrue(model.classes["class1"].has_relationship("class2")) self.assertTrue(model.classes["class2"].has_relationship("class1")) # Ensure deleted model.delete_class("class1") # assert dictionary key was removed self.assertTrue("class1" not in model.classes) # Ensure relationship was removed after deletion of class1 status, msg = model.list_relationships("class2") self.assertTrue(status) self.assertEqual(msg, "Class 'class2' has no relationships") # Ensure no errors when class DNE status, msg = model.delete_class("class1") # ensure it failed self.assertFalse(status) self.assertEqual(msg, "class1 does not exist.")
def editRelationshipForm(model_name): # ensure model name exists if model_name not in getModelNames(): flash(f"Model '{model_name}' does not exist", "error") return redirect(url_for('models')) # Ensure there was a POST request if request.method != "POST": # send error message as a flash message flash("Nothing sent in POST", "error") return redirect(url_for('dashboard', model_name=model_name)) # load model model = UMLModel() model.load_model(model_name + ".json", directory=DATA_FOLDER) # ensure class1 exists if request.form.get('class_name1') not in model.classes: return f"Class '{request.form.get('class_name1')}' does not exist" # ensure class2 exists if request.form.get('class_name2') not in model.classes: return f"Class '{request.form.get('class_name2')}' does not exist" # grab class data data = {} data["classes"] = model.get_data() # add current relationships data data["relationship_type"] = request.form.get('relationship_type') data["class_name1"] = request.form.get('class_name1') data["class_name2"] = request.form.get('class_name2') # Build modal form inputs return render_template("editRelationshipForm.html", data=data)
def createModel(): # Ensure there was a POST request if request.method != "POST": # send error message as a flash message flash("Nothing sent in POST", "error") return redirect(url_for('models')) model_name:str = request.form.get("model_name") # Ensure new model name does not already exist if model_name in getModelNames(): flash(f"Model '{request.form.get('model_name')}' already exists", "error") return redirect(url_for('models')) # reject empty model names if model_name.strip() == "": flash(f"Model name cannot be empty", "error") return redirect(url_for('models')) # create new empty model file model = UMLModel() model.save_model(model_name + ".json", directory=DATA_FOLDER) flash(f"Model '{model_name}' created successfully", "success") return redirect(url_for("models"))
def editForm(model_name): # ensure model name exists if model_name not in getModelNames(): flash(f"Model '{model_name}' does not exist", "error") return redirect(url_for('models')) # Ensure there was a POST request if request.method != "POST": # send error message as a flash message flash("Nothing sent in POST", "error") return redirect(url_for('dashboard', model_name=model_name)) # load model model = UMLModel() model.load_model(model_name + ".json", directory=DATA_FOLDER) # ensure class exists if request.form.get('class_name') not in model.classes: return f"Class '{request.form.get('class_name')}' does not exist" # grab class data data = model.classes[request.form.get('class_name')].get_raw_data() # index methods for parameter matching for class_name in data: i = 0 for methodi in range(len(data["methods"])): data["methods"][methodi]["index"] = i i+=1 # Build modal form inputs return render_template("modalForm.html", data=data)
def dashboard(model_name): # ensure model name exists if model_name not in getModelNames(): flash(f"Model '{model_name}' does not exist", "error") return redirect(url_for('models')) # Get current model model = UMLModel() status, msg = model.load_model(model_name + ".json", directory=DATA_FOLDER) if not status: flash(msg, "error") return render_template("dashboard.html", data={}) # Setup template data data = { "model_name" : model_name, "classes" : [] } # add each class i = 0 for class_name in model.classes: data["classes"] += [model.classes[class_name].get_raw_data()] # Give class its index data["classes"][i]["index"] = i+1 data["classes"][i]["json"] = json.dumps(model.classes[class_name].get_raw_data()) i += 1 return render_template("dashboard.html", data=data)
def saveCardPosition(model_name): # ensure model name exists if model_name not in getModelNames(): flash(f"Model '{model_name}' does not exist", "error") return redirect(url_for('models')) # Ensure there was a POST request if request.method != "POST": # send error message as a flash message flash("Nothing sent in POST", "error") return redirect(url_for('dashboard', model_name=model_name)) # load model model = UMLModel() model.load_model(model_name + ".json", directory=DATA_FOLDER) # Grab the position data from the POST request class_data = { "filename" : model_name + ".json", "directory" : DATA_FOLDER, "class_name" : request.form['class_name'], "x" : request.form['x'], "y": request.form['y'], "zindex": request.form['zindex'] } # create command command = SetClassPositonGUICommand(UMLModel(), class_data) # save backup command.saveBackup() # execute command response = command.execute() # ensure response - this occurs if someone forgot to return a status from a command if not response: print(f"ERROR: Command did not give a status") # send error message as a flash message flash("Command did not give a status; This is most likely due to a bug", "error") return redirect(url_for('dashboard', model_name=model_name)) status, msg = response # command was not successful if not status: # command failed print(f"ERROR: {msg}") # send error message as a flash message flash(msg, "error") return redirect(url_for('dashboard', model_name=model_name)) # add to history command_history.push(command) # send success message as a flash message print(f"SUCCESS: {msg}") flash(msg, "success") return redirect(url_for('dashboard', model_name=model_name))
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_create_class(self): model = UMLModel() # Ensure class is created model.create_class("class1") self.assertEqual(model.classes["class1"].name, "class1") # Ensure duplicate class is not created status, msg = model.create_class("class1") self.assertFalse(status) self.assertEqual(msg, "class1 already exists.")
def test_execute(self): # create model model_name = "myModel" model = UMLModel() model.create_class("class1") model.create_class("class2") model.create_relationship("composition", "class1", "class2") model.save_model(model_name + ".json", directory=os.getcwd() + "/") class_data = { "filename": model_name + ".json", "directory": os.getcwd() + "/", "class_name1": "class1", "class_name2": "class2" } cmd = DeleteRelationshipGUICommand(model, class_data) cmd.saveBackup() status, msg = cmd.execute() # ensure it passed self.assertTrue(status) # ensure relationship was deleted self.assertTrue(len(model.classes["class1"].relationships) == 0) self.assertTrue(len(model.classes["class2"].relationships) == 0) # ensure it fails when invalid cmd = DeleteRelationshipGUICommand(model, class_data) cmd.saveBackup() status, msg = cmd.execute() self.assertFalse(status)
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_delete_field(self): model = UMLModel() model.create_class("class1") model.create_field("class1", "public", "void", "a1") testClass = model.classes["class1"] # Ensure we get correct output when class doesn't exist status, msg = model.delete_field("class5", "a1") self.assertFalse(status) self.assertEqual(msg, "class5 does not exist") # Ensure we get correct output when field we wish to remove doesn't exist status, msg = model.delete_field("class1", "a3") self.assertFalse(status) self.assertEqual(msg, "a3 is not a field of class1") # Ensure field is deleted model.delete_field("class1", "a1") self.assertFalse(testClass.has_field("a1"))
def test_delete_method(self): model = UMLModel() model.create_class("class1") model.create_method("class1", "public", "void", "add") testClass = model.classes["class1"] # Ensure we get correct output when class doesn't exist status, msg = model.delete_method("class4", "add") self.assertFalse(status) self.assertEqual(msg, "'class4' does not exist") # Ensure we get correct output when the method we wish to delete doesn't exist status, msg = model.delete_method("class1", "subtract") self.assertFalse(status) self.assertEqual(msg, "'subtract' does not exist in 'class1'") # Ensure method is deleted model.delete_method("class1", "add") self.assertFalse(testClass.has_method("add"))
def test_prompt_exit(self): # Test 1: fully exit exits = False try: # give 'no' response for prompt_exit to grab and exit sys.stdin = io.StringIO("no\n") prompt_exit(UMLModel()) except SystemExit: exits = True # make sure it exited self.assertTrue(exits) # Test 2: cancel exit exits = False try: # give 'cancel' response for prompt_exit sys.stdin = io.StringIO("cancel\n") status, msg = prompt_exit(UMLModel()) except SystemExit: exits = True # make sure it didnt exit self.assertFalse(exits) self.assertEqual(msg, "Exit aborted") # Test 3: save model model1 = UMLModel() model1.create_class("class1") model1.create_class("class2") exits = False captured = io.StringIO() try: # give 'yes' response for prompt_exit to grab and exit sys.stdin = io.StringIO("yes\ntest_prompt_exit.json\n") prompt_exit(model1, os.getcwd() + "/code/data/") except SystemExit: exits = True # make sure it exited self.assertTrue(exits) # make sure it saved model2 = UMLModel() model2.load_model("test_prompt_exit.json", os.getcwd() + "/code/data/") self.assertEqual(model1.classes.keys(), model2.classes.keys())
def editRelationship(model_name): # ensure model name exists if model_name not in getModelNames(): flash(f"Model '{model_name}' does not exist", "error") return redirect(url_for('models')) # Ensure there was a POST request if request.method != "POST": # send error message as a flash message flash("Nothing sent in POST", "error") return redirect(url_for('dashboard', model_name=model_name)) # build data for command data = { "filename" : model_name + ".json", "directory" : DATA_FOLDER, "old_relationship_type" : request.form.get('old_relationship_type'), "old_class_name1" : request.form.get('old_class_name1'), "old_class_name2" : request.form.get('old_class_name2'), "relationship_type" : request.form.get('relationship_type'), "class_name1" : request.form.get('class_name1'), "class_name2" : request.form.get('class_name2') } # create command command = EditRelationshipGUICommand(UMLModel(), data) # save backup command.saveBackup() # execute command response = command.execute() # ensure response - this occurs if someone forgot to return a status from a command if not response: print(f"ERROR: Command did not give a status") # send error message as a flash message flash("Command did not give a status; This is most likely due to a bug", "error") return redirect(url_for('dashboard', model_name=model_name)) status, msg = response # command was not successful if not status: # command failed print(f"ERROR: {msg}") # send error message as a flash message flash(msg, "error") return redirect(url_for('dashboard', model_name=model_name)) # add to history command_history.push(command) # send success message as a flash message print(f"SUCCESS: {msg}") flash(msg, "success") return redirect(url_for('dashboard', model_name=model_name))
def deleteClass(model_name): # ensure model name exists if model_name not in getModelNames(): flash(f"Model '{model_name}' does not exist", "error") return redirect(url_for('models')) # Ensure method was post if request.method != 'POST': # send error message as a flash message flash("Nothing sent in POST", "error") return redirect(url_for('dashboard', model_name=model_name)) # Print out what is being deleted print (f"Deleting class '{request.form.get('class_name')}' from the model") # Grab the data from the POST request class_data = { "filename" : model_name + ".json", "directory" : DATA_FOLDER, "class_name" : request.form.get('class_name') } # create command command = DeleteClassGUICommand(UMLModel(), class_data) # save backup command.saveBackup() # execute command response = command.execute() # ensure response if not response: print(f"ERROR: Command did not give a status") # send error message as a flash message flash("Command did not give a status; This is most likely due to a bug", "error") return redirect(url_for('dashboard', model_name=model_name)) status, msg = response # command was not successful if not status: # command failed print(f"ERROR: {msg}") # send error message as a flash message flash(msg, "error") return redirect(url_for('dashboard', model_name=model_name)) # add to history command_history.push(command) # send success message as a flash message print(f"SUCCESS: {msg}") flash(msg, "success") return redirect(url_for('dashboard', model_name=model_name))
def prompt_exit(model: UMLModel, directory=MODEL_DIRECTORY) -> Tuple[bool, str]: """Initiates the exit prompt Prompts user if they want to save before quitting If user types 'yes': - User is prompted for a filename to save to - Model is saved - Program exits If user types 'no': - program exits without saving If user types 'cancel': - model is not saved - returns from this function Params: - model (UMLModel) - the model to visibilityally save """ response = "" # Prompt user until we get a valid answer while response != "yes" and response != "no" and response != "cancel": print("Do you want to save current working project? (yes/no/cancel)") response = input().lower() # if user wants to save project, call the save_model function to save working project if response == "yes": print("Please enter the filename.") filename = input() model.save_model(filename, directory) elif response == "cancel": return (True, "Exit aborted") elif response == "no": print("Goodbye!") exit()
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 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_execute(self): # create model model_name = "myModel" model = UMLModel() model.create_class("class1") model.create_class("class2") model.create_relationship("composition", "class1", "class2") model.save_model(model_name + ".json", directory=os.getcwd() + "/") class_data = { "filename": model_name + ".json", "directory": os.getcwd() + "/", "old_relationship_type": "composition", "old_class_name1": "class1", "old_class_name2": "class2", "relationship_type": "inheritance", "class_name1": "class1", "class_name2": "class2" } cmd = EditRelationshipGUICommand(model, class_data) cmd.saveBackup() status, msg = cmd.execute() # ensure it passed self.assertTrue(status) # relationship exists self.assertTrue(len(model.classes["class1"].relationships) == 1) self.assertTrue(len(model.classes["class2"].relationships) == 1) self.assertEqual(model.classes["class1"].relationships[0].type, RelationshipType.INHERITANCE) self.assertEqual(model.classes["class1"].relationships[0].other, "class2") self.assertEqual(model.classes["class2"].relationships[0].other, "class1") # ensure it fails when invalid class_data["class_name2"] = "invalid_class" cmd = EditRelationshipGUICommand(model, class_data) cmd.saveBackup() status, msg = cmd.execute() self.assertFalse(status)
def test_create_method(self): model = UMLModel() model.create_class("class1") testClass = model.classes["class1"] # Ensure method is created model.create_method("class1", "public", "void", "add") self.assertTrue(testClass.has_method("add")) # Ensure we get correct output when class doesn't exist status, msg = model.create_method("class3", "public", "void", "subtract") self.assertFalse(status) self.assertEqual(msg, "class3 does not exist") # Ensure duplicate method is not created status, msg = model.create_method("class1", "public", "void", "add") # ensure it failed self.assertFalse(status) self.assertEqual(msg, "method add already exists in class1")
def test_create_field(self): model = UMLModel() model.create_class("class1") testClass = model.classes["class1"] # Ensure field is created model.create_field("class1", "public", "void", "a1") self.assertTrue(testClass.has_field("a1")) # Ensure we get correct output when class does not exist status, msg = model.create_field("class5", "private", "void", "a1") self.assertFalse(status) self.assertEqual(msg, "class5 does not exist") # Ensure duplicate field is not created status, msg = model.create_field("class1", "public", "void", "a1") # ensure it failed self.assertFalse(status) self.assertEqual(msg, "field a1 already exists in class1")
def test_set_class_position(self): model = UMLModel() model.create_class("class1") # variables used for testing equality message = model.set_class_position("class3", 10, 20, 30)[1] # test output equality when class3 is a non-existent class self.assertEqual(message, "class3 does not exist") # set position of c1 message = model.set_class_position("class1", 10, 20, 0)[1] # test output equality self.assertEqual(message, "The position of 'class1' has been set to ('10', '20')")
def test_list_classes(self): model = UMLModel() # variables used for testing equality message = model.list_classes()[1] # test output equality without creating classes self.assertEqual(message, "No classes in the model") # create some classes model.create_class("class1") model.create_class("class2") model.create_class("class3") # variables used for testing equality message = model.list_classes()[1] outString = "".join(("Listing all classes in the model\n", "class1\n", "class2\n", "class3")) # test output equality self.assertEqual(message,outString)
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 test_fetch_classes(self): model = UMLModel() # Test 1: no classes classes = fetch_classes(model) self.assertEqual(classes, []) # Test 2: multiple classes model.create_class("class1") model.create_class("class2") model.create_class("class3") classes = fetch_classes(model) self.assertTrue("class1" in classes) self.assertTrue("class2" in classes) self.assertTrue("class3" in classes)
def test_get_data(self): model = UMLModel() # Test 1: empty model data = model.get_data() self.assertEqual(data, {}) # Test 2: model with data model.create_class('class1') model.create_class('class2') model.create_field('class1', 'private', 'string', 'name') expectedData = { "class1" : { "name" : "class1", "fields" : [{ "visibility" : 'private', 'type' : 'string', 'name' : 'name' }], "methods" : [], "relationships" : [], "x" : 200, "y" : 0, "zindex" : 0 }, "class2" : { "name" : "class2", "fields" : [], "methods" : [], "relationships" : [], "x" : 200, "y" : 0, "zindex" : 0 } } data = model.get_data() self.assertEqual(data, expectedData)