def test_generate_with_inheritance_alt(self): room = ClassDiagramPart("Room", fields=["width", "height"], methods=["set_color()"]) inheritance = InheritanceDiagramPart() kitchen = ClassDiagramPart("Kitchen", methods=[ "arrange_kitchen()", "place_floor_cabinet()", "place_wall_cabinet()" ]) diagram = Diagram(kitchen, parent=room, inheritance=inheritance) expected = (" ___________ \n" "| Room |\n" "|-----------|\n" "|width |\n" "|height |\n" "|set_color()|\n" "|___________|\n" "∆\n" "|_____________________ \n" "| Kitchen |\n" "|---------------------|\n" "|arrange_kitchen() |\n" "|place_floor_cabinet()|\n" "|place_wall_cabinet() |\n" "|_____________________|\n") encoder = PrettyPrintEncoder() actual = encoder.generate(diagram) self.assertEqual(expected, actual)
def test_generate_with_inheritance(self): person = ClassDiagramPart("Person", fields=[ "name", "age" ]) inheritance = InheritanceDiagramPart() employee = ClassDiagramPart("Employee", fields=[ "job_title" ]) diagram = Diagram(employee, parent=person, inheritance=inheritance) person_class = ("class Person:\n" " def __init__(self, name, age):\n" " self.name = name\n" " self.age = age\n") employee_class = ("class Employee(Person):\n" " def __init__(self, job_title):\n" " self.job_title = job_title\n") encoder = SourceCodeEncoder() actual = encoder.generate(diagram) # Returns and array of classes self.assertEqual("person", actual[0][0]) self.assertEqual(person_class, actual[0][1]) self.assertEqual("employee", actual[1][0]) self.assertEqual(employee_class, actual[1][1])
def test_generate_with_aggregation(self): task_list_diagram = ClassDiagramPart("TaskList", methods=[ "get_the_tasks()", "prioritize()" ], fields=["the_tasks"]) task_list_aggregation = AggregationDiagramPart("the_tasks", right_multiplicity="*") task_diagram = ClassDiagramPart("Task") diagram = Diagram(task_list_diagram, aggregation=task_list_aggregation, aggregated=task_diagram) task_list_class = ("class TaskList:\n" " def __init__(self, the_tasks):\n" " self.the_tasks = the_tasks\n" "\n" " def get_the_tasks(self):\n" " pass\n" "\n" " def prioritize(self):\n" " pass\n") task_class = ("class Task:\n" " pass\n") encoder = SourceCodeEncoder() actual = encoder.generate(diagram) self.assertEqual("tasklist", actual[1][0]) self.assertEqual(task_list_class, actual[1][1]) self.assertEqual("task", actual[0][0]) self.assertEqual(task_class, actual[0][1])
def test_generate_with_inheritance(self): person = ClassDiagramPart("Person", fields=["name", "age"]) inheritance = InheritanceDiagramPart() employee = ClassDiagramPart("Employee", fields=["job_title"]) expected = """<?xml version="1.0" encoding="UTF-8"?> <xmi:XMI xmi:version="2.1" xmlns:uml="http://schema.omg.org/spec/UML/2.0" xmlns:xmi="http://schema.omg.org/spec/XMI/2.1"> <xmi:Documentation exporter="Prexel" exporterVersion="1.0"/> <uml:Model name="RootModel" xmi:id="" xmi:type="uml:Model"> <packagedElement isAbstract="false" isActive="false" isFinalSpecialization="false" isLeaf="false" name="Person" visibility="public" xmi:id="" xmi:type="uml:Class"> <ownedAttribute aggregation="none" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" name="name" visibility="public" xmi:id="" xmi:type="uml:Property"/> <ownedAttribute aggregation="none" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" name="age" visibility="public" xmi:id="" xmi:type="uml:Property"/> </packagedElement> <packagedElement isAbstract="false" isActive="false" isFinalSpecialization="false" isLeaf="false" name="Employee" visibility="public" xmi:id="" xmi:type="uml:Class"> <ownedAttribute aggregation="none" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" name="job_title" visibility="public" xmi:id="" xmi:type="uml:Property"/> <generalization general="" specific="" xmi:type="uml:Generalization"/> </packagedElement> </uml:Model> </xmi:XMI> """ diagram = Diagram(employee, parent=person, inheritance=inheritance) encoder = XMIEncoder() actual = encoder.generate(diagram, display_id=False) self.assertEqual(expected, actual)
def evaluate(self): # Check for the first PREXEL marker self.start_marker() # Process the first class name first_class_diagram = ClassDiagramPart() first_class_diagram.name = self.class_name() # Optionally check for FIELD and METHOD tokens self.class_body(first_class_diagram) # Optional - Check for inheritance if self.inheritance(): self.diagram.parent = first_class_diagram else: self.diagram.main = first_class_diagram # Optional - Check for aggregation but don't # consider the fields and methods following the aggregation # token as part of the aggregated class.In this position # they belong to the main class self.aggregation(include_following_tokens=False) # Process fields and methods for main class self.class_body(self.diagram.main) # Optional - Check for aggregation self.aggregation() return self.diagram
def test_concat_aggregation_alt(self): task_list_diagram = ClassDiagramPart( "TaskList", methods=["get_the_tasks()", "prioritize()"]) task_list_aggregation = AggregationDiagramPart("the_tasks", left_multiplicity="10", right_multiplicity="*") task_diagram = ClassDiagramPart( "Task", fields=["field1", "field2", "field3"], methods=["method1()", "method2()", "method3()"]) expected = (" _______________ _________ \n" "| TaskList |<>10-the_tasks---*>| Task |\n" "|---------------| |---------|\n" "|get_the_tasks()| |field1 |\n" "|prioritize() | |field2 |\n" "|_______________| |field3 |\n" " |method1()|\n" " |method2()|\n" " |method3()|\n" " |_________|\n") encoder = PrettyPrintEncoder() task_list = encoder.create_class(task_list_diagram) aggregation = encoder.create_aggregation_arrow(task_list_aggregation) task = encoder.create_class(task_diagram) actual = encoder.concat_aggregation(aggregator=task_list, aggregation=aggregation, aggregated=task) self.assertEqual(expected, actual)
def aggregation(self, include_following_tokens=True): """ Process any aggregated classes. The class process both the AGGREGATION token and a CLASS_NAME token for the aggregated class. """ if self.current_token and self.current_token.type is Token.AGGREGATION: # Cache the current token token = self.current_token # Process AGGREGATION Token self.process_token(Token.AGGREGATION) # Confirm that a CLASS_NAME token follows the AGGREGATION TOKEN if not self.next_token_is_class_token(): self.error("There is no class name following the aggregation.") # Process aggregated ClassDiagramPart. Optionally include class body aggregated = ClassDiagramPart() aggregated.name = self.class_name() if include_following_tokens: self.class_body(aggregated) self.diagram.aggregated = aggregated # Process AggregationDiagramPart aggregation = AggregationDiagramPart() # Create a list for the fields on the main ClassDiagramPart object if not self.diagram.main.fields: self.diagram.main.fields = [] # Check that the AGGREGATION token has a name, if not # default to the aggregated class's name name = token.value["name"] if name: self.diagram.main.fields.append(name) aggregation.name = name else: # Generate an aggregation name from the aggregated class generated_name = aggregated.name.lower() self.diagram.main.fields.append(generated_name) aggregation.name = generated_name # Add multiplicity values aggregation.left_multiplicity = token.value["left_multi"] aggregation.right_multiplicity = token.value["right_multi"] # Save aggregation value to Diagram object self.diagram.aggregation = aggregation
def test_create_class(self): diagram = ClassDiagramPart("Kitchen", methods=[ "arrange_kitchen()", "place_floor_cabinet()", "place_wall_cabinet()" ], fields=[ "width", "height" ]) expected = ("class Kitchen:\n" " def __init__(self, width, height):\n" " self.width = width\n" " self.height = height\n" "\n" " def arrange_kitchen(self):\n" " pass\n" "\n" " def place_floor_cabinet(self):\n" " pass\n" "\n" " def place_wall_cabinet(self):\n" " pass\n" ) encoder = SourceCodeEncoder() actual = encoder.create_class(diagram) self.assertEqual(expected, actual)
def test_convert_simple(self): simple_class = ClassDiagramPart("Kitchen", methods=[ "arrange_kitchen()", "place_floor_cabinet()", "place_wall_cabinet()" ], fields=["field1"]) expected = """<?xml version="1.0" encoding="UTF-8"?> <xmi:XMI xmi:version="2.1" xmlns:uml="http://schema.omg.org/spec/UML/2.0" xmlns:xmi="http://schema.omg.org/spec/XMI/2.1"> <xmi:Documentation exporter="Prexel" exporterVersion="1.0"/> <uml:Model name="RootModel" xmi:id="" xmi:type="uml:Model"> <packagedElement isAbstract="false" isActive="false" isFinalSpecialization="false" isLeaf="false" name="Kitchen" visibility="public" xmi:id="" xmi:type="uml:Class"> <ownedAttribute aggregation="none" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" name="field1" visibility="public" xmi:id="" xmi:type="uml:Property"/> <ownedOperation concurrency="sequential" isAbstract="false" isLeaf="false" isQuery="false" isStatic="false" name="arrange_kitchen" visibility="public" xmi:id="" xmi:type="uml:Operation"/> <ownedOperation concurrency="sequential" isAbstract="false" isLeaf="false" isQuery="false" isStatic="false" name="place_floor_cabinet" visibility="public" xmi:id="" xmi:type="uml:Operation"/> <ownedOperation concurrency="sequential" isAbstract="false" isLeaf="false" isQuery="false" isStatic="false" name="place_wall_cabinet" visibility="public" xmi:id="" xmi:type="uml:Operation"/> </packagedElement> </uml:Model> </xmi:XMI> """ diagram = Diagram(main=simple_class) xmi_encoder = XMIEncoder() actual = xmi_encoder.generate(diagram, display_id=False) self.assertEqual(expected, actual)
def test_class_body(self): """ Test the class_body() method, which processes FIELD and METHOD tokens """ text = "|Airplane size color take_off()" lexer = Lexer(text) interpreter = Interpreter(lexer) interpreter.start_marker() class_diagram = ClassDiagramPart() class_diagram.name = interpreter.class_name() interpreter.class_body(class_diagram) self.assertEqual(class_diagram.fields, ["size", "color"]) self.assertEqual(class_diagram.methods, ["take_off()"])
def test_create_class_empty(self): diagram = ClassDiagramPart("Kitchen") expected = (" _______ \n" "|Kitchen|\n" "|_______|\n") encoder = PrettyPrintEncoder() actual = encoder.create_class(diagram) self.assertEqual(expected, actual)
def test_generate_with_aggregation_with_multiplicity(self): employer_diagram = ClassDiagramPart( "Employer", fields=["name", "age", "employees"]) employees_aggregation = AggregationDiagramPart("employees", left_multiplicity="1", right_multiplicity="*") employee_diagram = ClassDiagramPart("Employee", fields=["position"]) expected = """<?xml version="1.0" encoding="UTF-8"?> <xmi:XMI xmi:version="2.1" xmlns:uml="http://schema.omg.org/spec/UML/2.0" xmlns:xmi="http://schema.omg.org/spec/XMI/2.1"> <xmi:Documentation exporter="Prexel" exporterVersion="1.0"/> <uml:Model name="RootModel" xmi:id="" xmi:type="uml:Model"> <packagedElement isAbstract="false" isActive="false" isFinalSpecialization="false" isLeaf="false" name="Employer" visibility="public" xmi:id="" xmi:type="uml:Class"> <ownedAttribute aggregation="none" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" name="name" visibility="public" xmi:id="" xmi:type="uml:Property"/> <ownedAttribute aggregation="none" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" name="age" visibility="public" xmi:id="" xmi:type="uml:Property"/> <ownedAttribute aggregation="none" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" name="employees" visibility="public" xmi:id="" xmi:type="uml:Property"/> </packagedElement> <packagedElement isAbstract="false" isActive="false" isFinalSpecialization="false" isLeaf="false" name="Employee" visibility="public" xmi:id="" xmi:type="uml:Class"> <ownedAttribute aggregation="none" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" name="position" visibility="public" xmi:id="" xmi:type="uml:Property"/> <ownedMember isDerived="false" name="employees" visibility="public" xmi:id="" xmi:type="uml:Association"> <ownedEnd aggregation="none" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" type="" visibility="public" xmi:type="uml:Property" xmi:id=""> <lowerValue value="1" xmi:id="" xmi:type="uml:LiteralInteger"/> <upperValue value="1" xmi:id="" xmi:type="uml:LiteralInteger"/> </ownedEnd> <ownedEnd aggregation="shared" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" type="" visibility="public" xmi:type="uml:Property" xmi:id=""> <lowerValue value="*" xmi:id="" xmi:type="uml:LiteralUnlimitedNatural"/> <upperValue value="*" xmi:id="" xmi:type="uml:LiteralUnlimitedNatural"/> </ownedEnd> <memberEnd xmi:idref=""/> <memberEnd xmi:idref=""/> </ownedMember> </packagedElement> </uml:Model> </xmi:XMI> """ diagram = Diagram(employer_diagram, aggregation=employees_aggregation, aggregated=employee_diagram) encoder = XMIEncoder() actual = encoder.generate(diagram, display_id=False) self.assertEqual(expected, actual)
def test_aggregation_with_missing_aggregation_name(self): """ Test the aggregation() method, """ text = "|Kitchen <>---> Cupboard" lexer = Lexer(text) interpreter = Interpreter(lexer) diagram = interpreter.diagram class_diagram_part = ClassDiagramPart() interpreter.start_marker() class_diagram_part.name = interpreter.class_name() diagram.main = class_diagram_part interpreter.aggregation() self.assertEqual(diagram.aggregation.name, "cupboard") self.assertEqual(diagram.main.fields, ["cupboard"]) self.assertEqual(diagram.aggregated.name, "Cupboard")
def test_inheritance_with_error(self): """ Test the inheritance() method, with an improper syntax """ text = "|Kitchen >>" lexer = Lexer(text) interpreter = Interpreter(lexer) class_diagram_part = ClassDiagramPart() interpreter.start_marker() class_diagram_part.name = interpreter.class_name() # Should raise a InterpreterException with self.assertRaises(InterpreterException) as context: interpreter.inheritance() self.assertEqual(context.exception.args[0], "Missing child class after \">>\"")
def test_generate_class_with_method_params_as_object(self): style_diagram = ClassDiagramPart("Style", methods=[ {"signature": "get_cabinet(height)", "body": "return XCabinet()"} ]) xcabinet_diagram = ClassDiagramPart("XCabinet") expected = ("class Style:\n" " def get_cabinet(self, height):\n" " return XCabinet()\n" "class XCabinet:\n" " pass\n" ) encoder = SourceCodeEncoder() style = encoder.create_class(style_diagram) xcabinet = encoder.create_class(xcabinet_diagram) actual = style + xcabinet self.assertEqual(expected, actual)
def test_generate_full(self): task_list_diagram = ClassDiagramPart( "TaskList", methods=["get_the_tasks()", "prioritize()"]) task_list_aggregation = AggregationDiagramPart("the_tasks", right_multiplicity="*") task_diagram = ClassDiagramPart("Task", fields=["name", "description"]) parent = ClassDiagramPart("Manager", fields=["field1", "field2"], methods=["method1()", "method2()"]) inheritance = InheritanceDiagramPart() diagram = Diagram(task_list_diagram, parent=parent, inheritance=inheritance, aggregation=task_list_aggregation, aggregated=task_diagram) expected = (" _________ \n" "| Manager |\n" "|---------|\n" "|field1 |\n" "|field2 |\n" "|method1()|\n" "|method2()|\n" "|_________|\n" "∆\n" "|_______________ ___________ \n" "| TaskList |<>-the_tasks---*>| Task |\n" "|---------------| |-----------|\n" "|get_the_tasks()| |name |\n" "|prioritize() | |description|\n" "|_______________| |___________|\n") encoder = PrettyPrintEncoder() actual = encoder.generate(diagram) self.assertEqual(expected, actual)
def test_generate_empty_class(self): wing = ClassDiagramPart("Wing") diagram = Diagram(wing) expected = ("class Wing:\n" " pass\n") encoder = SourceCodeEncoder() actual = encoder.generate(diagram) self.assertEqual("wing", actual[0][0]) self.assertEqual(expected, actual[0][1])
def test_generate_class_with_method_params(self): diagram = ClassDiagramPart("MyClass", methods=[ "crazy_method2Name(param1, param2)" ]) expected = ("class MyClass:\n" " def crazy_method2Name(self, param1, param2):\n" " pass\n") encoder = SourceCodeEncoder() actual = encoder.create_class(diagram) self.assertEqual(expected, actual)
def test_generate_full(self): task_list_diagram = ClassDiagramPart("TaskList", methods=[ "get_the_tasks()", "prioritize()" ]) task_list_aggregation = AggregationDiagramPart("name", right_multiplicity="*") task_diagram = ClassDiagramPart("Task", fields=[ "name", "description" ], methods=[ "complete()", "delete()" ]) parent = ClassDiagramPart("Manager", fields=[ "field1", "field2" ], methods=[ "method1()", "method2()" ]) inheritance = InheritanceDiagramPart() diagram = Diagram(task_list_diagram, parent=parent, inheritance=inheritance, aggregation=task_list_aggregation, aggregated=task_diagram) encoder = SourceCodeEncoder() actual = encoder.generate(diagram) # NOT TESTING ANYTHING, JUST CHECKING OUTPUT print(actual[0][1]) print(actual[1][1])
def test_inheritance(self): """ Test the inheritance() method, which processes an inheritance relationship """ text = "|Room height width >> Kitchen" lexer = Lexer(text) interpreter = Interpreter(lexer) diagram = interpreter.diagram class_diagram_part = ClassDiagramPart() interpreter.start_marker() class_diagram_part.name = interpreter.class_name() interpreter.class_body(class_diagram_part) if interpreter.inheritance(): diagram.parent = class_diagram_part else: diagram.main = class_diagram_part self.assertEqual(diagram.parent.name, "Room") self.assertEqual(diagram.parent.fields, ["height", "width"]) self.assertEqual(diagram.main.name, "Kitchen")
def test_generate_with_aggregation(self): task_list_diagram = ClassDiagramPart( "TaskList", methods=["get_the_tasks()", "prioritize()"]) task_list_aggregation = AggregationDiagramPart("the_tasks", right_multiplicity="*") task_diagram = ClassDiagramPart("Task") diagram = Diagram(task_list_diagram, aggregation=task_list_aggregation, aggregated=task_diagram) expected = (" _______________ ____ \n" "| TaskList |<>-the_tasks---*>|Task|\n" "|---------------| |____|\n" "|get_the_tasks()| \n" "|prioritize() | \n" "|_______________| \n") encoder = PrettyPrintEncoder() actual = encoder.generate(diagram) self.assertEqual(expected, actual)
def test_generate_with_aggregation(self): task_list_diagram = ClassDiagramPart( "TaskList", methods=["get_the_tasks()", "prioritize()"], fields=["the_tasks"]) task_list_aggregation = AggregationDiagramPart("the_tasks") task_diagram = ClassDiagramPart("Task") expected = """<?xml version="1.0" encoding="UTF-8"?> <xmi:XMI xmi:version="2.1" xmlns:uml="http://schema.omg.org/spec/UML/2.0" xmlns:xmi="http://schema.omg.org/spec/XMI/2.1"> <xmi:Documentation exporter="Prexel" exporterVersion="1.0"/> <uml:Model name="RootModel" xmi:id="" xmi:type="uml:Model"> <packagedElement isAbstract="false" isActive="false" isFinalSpecialization="false" isLeaf="false" name="TaskList" visibility="public" xmi:id="" xmi:type="uml:Class"> <ownedAttribute aggregation="none" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" name="the_tasks" visibility="public" xmi:id="" xmi:type="uml:Property"/> <ownedOperation concurrency="sequential" isAbstract="false" isLeaf="false" isQuery="false" isStatic="false" name="get_the_tasks" visibility="public" xmi:id="" xmi:type="uml:Operation"/> <ownedOperation concurrency="sequential" isAbstract="false" isLeaf="false" isQuery="false" isStatic="false" name="prioritize" visibility="public" xmi:id="" xmi:type="uml:Operation"/> </packagedElement> <packagedElement isAbstract="false" isActive="false" isFinalSpecialization="false" isLeaf="false" name="Task" visibility="public" xmi:id="" xmi:type="uml:Class"> <ownedMember isDerived="false" name="the_tasks" visibility="public" xmi:id="" xmi:type="uml:Association"> <ownedEnd aggregation="none" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" type="" visibility="public" xmi:type="uml:Property" xmi:id=""/> <ownedEnd aggregation="shared" isDerived="false" isID="false" isLeaf="false" isOrdered="false" isReadOnly="false" isStatic="false" isUnique="false" type="" visibility="public" xmi:type="uml:Property" xmi:id=""/> <memberEnd xmi:idref=""/> <memberEnd xmi:idref=""/> </ownedMember> </packagedElement> </uml:Model> </xmi:XMI> """ diagram = Diagram(task_list_diagram, aggregation=task_list_aggregation, aggregated=task_diagram) encoder = XMIEncoder() actual = encoder.generate(diagram, display_id=False) self.assertEqual(expected, actual)
def test_aggregation_multi_line(self): """ Test the aggregation() method using multi-line syntax """ text = """ |Kitchen <>-cupboard--> Cupboard |size |color""" lexer = Lexer(text) interpreter = Interpreter(lexer) diagram = interpreter.diagram class_diagram_part = ClassDiagramPart() interpreter.start_marker() class_diagram_part.name = interpreter.class_name() diagram.main = class_diagram_part interpreter.aggregation(include_following_tokens=False) interpreter.class_body(diagram.main) self.assertEqual(diagram.aggregation.name, "cupboard") self.assertEqual(diagram.main.fields, ["cupboard", "size", "color"]) self.assertEqual(diagram.aggregated.name, "Cupboard")
def inheritance(self): """ Process an INHERITANCE TOKEN. Sets the parent and inheritance fields on the Diagram object. ___________ ________________ | Diagram |<>-parent--->|ClassDiagramPart| |-----------| |________________| |inheritance| |parent | |___________| """ has_inheritance = False if self.current_token and self.current_token.type is Token.INHERITANCE: inheritance = InheritanceDiagramPart() # Process token self.process_token(Token.INHERITANCE) # Check CLASS_NAME token follows the INHERITANCE token if self.next_token_is_class_token(): child = ClassDiagramPart() # Determine child class name child.name = self.class_name() # Append inheritance diagram and then parent class diagram self.diagram.inheritance = inheritance self.diagram.main = child has_inheritance = True else: self.error("Missing child class after \">>\"") return has_inheritance
def test_create_class(self): diagram = ClassDiagramPart("Kitchen", methods=[ "arrange_kitchen()", "place_floor_cabinet()", "place_wall_cabinet()" ]) expected = (" _____________________ \n" "| Kitchen |\n" "|---------------------|\n" "|arrange_kitchen() |\n" "|place_floor_cabinet()|\n" "|place_wall_cabinet() |\n" "|_____________________|\n") encoder = PrettyPrintEncoder() actual = encoder.create_class(diagram) self.assertEqual(expected, actual)