def test_one_to_one_link_multiplicity(self): a = self.m1.association(self.m2, name="l", multiplicity="1", source_multiplicity="1..1") c1 = CClass(self.m1, "c1") c2 = CClass(self.m2, "c2") c3 = CClass(self.m2, "c3") c4 = CClass(self.m1, "c4") try: set_links({c1: []}, association=a) exception_expected_() except CException as e: eq_(e.value, "links of object 'c1' have wrong multiplicity '0': should be '1'") try: set_links({c1: [c2, c3]}) exception_expected_() except CException as e: eq_(e.value, "links of object 'c1' have wrong multiplicity '2': should be '1'") try: set_links({c2: []}, association=a) exception_expected_() except CException as e: eq_(e.value, "links of object 'c2' have wrong multiplicity '0': should be '1..1'") try: set_links({c2: [c1, c4]}) exception_expected_() except CException as e: eq_(e.value, "links of object 'c2' have wrong multiplicity '2': should be '1..1'")
def test_default_values_on_stereotype__initialize_after_class_constructor( self): mcl = CMetaclass("MCL", attributes={ "aStr1": str, "aList1": list, "aStr2": "def", "aList2": ["d1", "d2"], "b": True }) s = CStereotype("S", extended=mcl, default_values={ "aStr1": "a", "aList1": ["a"], "aStr2": "def2", "aList2": [] }) c1 = CClass(mcl, "C1") c1.stereotype_instances = s # after construction, metaclass defaults are set. The stereotype defaults are set only for # values not yet set eq_( c1.values, { 'aStr2': 'def', 'aList2': ['d1', 'd2'], 'b': True, 'aStr1': 'a', 'aList1': ['a'] })
def test_delete_attribute_values_with_superclass(self): scl = CClass(self.mcl, "SCL", attributes={ "intVal": 20, "intVal2": 30}) cl = CClass(self.mcl, "C", superclasses=scl, attributes={ "isBoolean": True, "intVal": 1}) o = CObject(cl, "o", values={ "isBoolean": False}) o.delete_value("isBoolean") o.delete_value("intVal2") eq_(o.values, {"intVal": 1}) o.set_value("intVal", 2, scl) o.set_value("intVal", 3, cl) eq_(o.values, {"intVal": 3}) o.delete_value("intVal") eq_(o.values, {"intVal": 2}) o.set_value("intVal", 2, scl) o.set_value("intVal", 3, cl) o.delete_value("intVal", cl) eq_(o.values, {"intVal": 2}) o.set_value("intVal", 2, scl) o.set_value("intVal", 3, cl) o.delete_value("intVal", scl) eq_(o.values, {"intVal": 3})
def test_delete_default_values(self): mcl = CMetaclass("MCL", attributes={ "isBoolean": True, "intVal": int, "floatVal": 1.1, "string": "def", "list": list }) s = CStereotype("S", extended=mcl, default_values={ "isBoolean": False, "intVal": 1, "string": "abc", "list": ["a", "b"] }) c1 = CClass(mcl, "C1", stereotype_instances=s) s.delete_default_value("isBoolean") s.delete_default_value("intVal") list_value = s.delete_default_value("list") eq_(s.default_values, {"string": "abc"}) eq_(list_value, ['a', 'b']) c2 = CClass(mcl, "C2", stereotype_instances=s) eq_( c1.values, { 'isBoolean': False, 'floatVal': 1.1, 'string': 'abc', 'intVal': 1, 'list': ['a', 'b'] }) eq_(c2.values, {'isBoolean': True, 'floatVal': 1.1, 'string': 'abc'})
def test_delete_metaclass(self): m = CMetaclass("M1") cl = CClass(m, "C") m.delete() eq_(cl.metaclass, None) m1 = CMetaclass("M1") m2 = CMetaclass("M2") m3 = CMetaclass("M3", superclasses=m2, attributes={"i": 1}, stereotypes=CStereotype("S")) cl = CClass(m3, "C") m1.delete() eq_(cl.metaclass, m3) m3.delete() eq_(cl.metaclass, None) eq_(m3.superclasses, []) eq_(m2.subclasses, []) eq_(m3.attributes, []) eq_(m3.attribute_names, []) eq_(m3.stereotypes, []) eq_(m3.classes, []) eq_(m3.name, None) eq_(m3.bundles, [])
def test_delete_one_to_n_links(self): self.m1.association(self.m2, "l: 0..1 -> *") c1 = CClass(self.m1, "c1") c2 = CClass(self.m1, "c2") c3 = CClass(self.m2, "c3") c4 = CClass(self.m2, "c4") c5 = CClass(self.m2, "c5") add_links({c1: [c3, c4], c2: [c5]}) c4.delete_links([c1]) eq_(c1.linked, [c3]) eq_(c2.linked, [c5]) eq_(c3.linked, [c1]) eq_(c4.linked, []) eq_(c5.linked, [c2]) c4.add_links([c2]) eq_(c2.linked, [c5, c4]) delete_links({c1: c3, c2: c2.linked}) eq_(c1.linked, []) eq_(c2.linked, []) eq_(c3.linked, []) eq_(c4.linked, []) eq_(c5.linked, [])
def test_stereotype_instances_on_derived_association(self): s1 = CStereotype("S1", extended=self.a) s2 = CStereotype("S2", extended=self.a) s3 = CStereotype("S3", extended=self.a) c1 = CClass(self.m1, "C1") c2 = CClass(self.m2, "C2") a1 = c1.association(c2, name="a", multiplicity="*", role_name="c2", source_multiplicity="1", source_role_name="c1", derived_from=self.a) eq_(a1.stereotype_instances, []) eq_(s1.extended_instances, []) a1.stereotype_instances = [s1] eq_(s1.extended_instances, [a1]) eq_(a1.stereotype_instances, [s1]) a1.stereotype_instances = [s1, s2, s3] eq_(s1.extended_instances, [a1]) eq_(s2.extended_instances, [a1]) eq_(s3.extended_instances, [a1]) eq_(set(a1.stereotype_instances), {s1, s2, s3}) a1.stereotype_instances = s2 eq_(a1.stereotype_instances, [s2]) eq_(s1.extended_instances, []) eq_(s2.extended_instances, [a1]) eq_(s3.extended_instances, []) eq_(c1.associations, [a1]) eq_(c2.associations, [a1])
def test_remove_one_to_one_link(self): a = self.m1.association(self.m2, "l: 1 -> [c2] 0..1") c1 = CClass(self.m1, "c1") c2 = CClass(self.m2, "c2") c3 = CClass(self.m1, "c3") c4 = CClass(self.m2, "c4") links = set_links({c1: c2, c3: c4}) eq_(c1.linked, [c2]) eq_(c2.linked, [c1]) eq_(c3.linked, [c4]) eq_(c4.linked, [c3]) eq_(c1.links, [links[0]]) eq_(c2.links, [links[0]]) eq_(c3.links, [links[1]]) eq_(c4.links, [links[1]]) try: links = set_links({c1: None}) exception_expected_() except CException as e: eq_(e.value, "matching association not found for source 'c1' and targets '[]'") set_links({c1: None}, association=a) eq_(c1.linked, []) eq_(c2.linked, []) eq_(c3.linked, [c4]) eq_(c4.linked, [c3]) eq_(c1.links, []) eq_(c2.links, []) eq_(c3.links, [links[1]]) eq_(c4.links, [links[1]])
def test_get_links_self_link(self): a1 = self.m1.association(self.m1, role_name="to", source_role_name="from", source_multiplicity="*", multiplicity="*") c1 = CClass(self.m1, "c1") c2 = CClass(self.m1, "c2") c3 = CClass(self.m1, "c3") c4 = CClass(self.m1, "c4") set_links({c1: [c2, c3, c1]}) add_links({c4: [c1, c3]}) link1 = c1.links[0] link2 = [o for o in c1.links if o.association == a1][0] link3 = [o for o in c1.links if o.role_name == "to"][0] link4 = [o for o in c1.links if o.source_role_name == "from"][0] eq_(link1, link2) eq_(link1, link3) eq_(link1, link4) eq_(link1.association, a1) eq_(link1.source, c1) eq_(link1.target, c2) eq_(len(c1.links), 4) eq_(len(c2.links), 1) eq_(len(c3.links), 2) eq_(len(c4.links), 2)
def test_n_to_n_link(self): a = self.m1.association(self.m2, name="l", source_multiplicity="*") c1a = CClass(self.m1, "c1a") c1b = CClass(self.m1, "c1b") c1c = CClass(self.m1, "c1c") c2a = CClass(self.m2, "c2a") c2b = CClass(self.m2, "c2b") set_links({c1a: [c2a, c2b], c1b: [c2a], c1c: [c2b]}) eq_(c1a.linked, [c2a, c2b]) eq_(c1b.linked, [c2a]) eq_(c1c.linked, [c2b]) eq_(c2a.linked, [c1a, c1b]) eq_(c2b.linked, [c1a, c1c]) set_links({c2a: [c1a, c1b]}) try: set_links({c2b: []}) exception_expected_() except CException as e: eq_(e.value, "matching association not found for source 'c2b' and targets '[]'") set_links({c2b: []}, association=a) eq_(c1a.linked, [c2a]) eq_(c1b.linked, [c2a]) eq_(c1c.linked, []) eq_(c2a.linked, [c1a, c1b]) eq_(c2b.linked, [])
def test_wrong_types_set_links(self): self.m1.association(self.m2, name="l", multiplicity="1") c1 = CClass(self.m1, "c1") c2 = CClass(self.m2, "c2") try: set_links({c1: self.mcl}) exception_expected_() except CException as e: eq_(e.value, "link target 'MCL' is not an object, class, or link") try: set_links({c1: [c2, self.mcl]}) exception_expected_() except CException as e: eq_(e.value, "link target 'MCL' is not an object, class, or link") try: set_links({c1: [c2, None]}) exception_expected_() except CException as e: eq_(e.value, "link target 'None' is not an object, class, or link") try: set_links({self.mcl: c2}) exception_expected_() except CException as e: eq_(e.value, "link source 'MCL' is not an object, class, or link") try: set_links({None: c2}) exception_expected_() except CException as e: eq_(e.value, "link should not contain an empty source")
def test_link_association_has_a_compatible_superclass(self): code = CMetaclass("Code") source = CMetaclass("Source") code.association(source, "[contained_code] * -> [source] *") code_a = CMetaclass("Code A", superclasses=code) code_b = CMetaclass("Code B", superclasses=code) a_b_association = code_a.association(code_b, "a_b: [code_a] * -> [code_b] *") source_1 = CClass(source, "source_1") code_a1 = CClass(code_a, "code_a1") code_b1 = CClass(code_b, "code_b1") code_b2 = CClass(code_b, "code_b2") links = add_links({code_a1: [code_b1, code_b2]}, association=a_b_association) try: add_links({source_1: [code_a1, code_b2, code_b1, links[0], links[1]]}, role_name="contained_code") exception_expected_() except CException as e: eq_("the metaclass link's association is missing a compatible classifier", e.value) a_b_association.superclasses = self.mcl try: add_links({source_1: [code_a1, code_b2, code_b1, links[0], links[1]]}, role_name="contained_code") exception_expected_() except CException as e: eq_("no common metaclass for classes or links found", e.value) a_b_association.superclasses = code_b add_links({source_1: [code_a1, code_b2, code_b1, links[0], links[1]]}, role_name="contained_code")
def test_values_setter_malformed_description(self): mcl = CMetaclass("M", attributes={"isBoolean": True, "intVal": 1}) cl = CClass(mcl, "C") try: cl.values = [1, 2, 3] exception_expected_() except CException as e: eq_(e.value, "malformed attribute values description: '[1, 2, 3]'")
def test_attribute_get_name_and_classifier(self): cl = CClass(self.mcl, "C", attributes={"isBoolean": True}) a = cl.get_attribute("isBoolean") eq_(a.name, "isBoolean") eq_(a.classifier, cl) cl.delete() eq_(a.name, None) eq_(a.classifier, None)
def test_default_init_after_instance_creation(self): enum_type = CEnum("EnumT", values=["A", "B", "C"]) mcl = CMetaclass(attributes={"e1": enum_type, "e2": enum_type}) cl = CClass(mcl, "C") e2 = mcl.get_attribute("e2") e2.default = "A" eq_(cl.get_value("e1"), None) eq_(cl.get_value("e2"), "A")
def test_classifier_change(self): cl1 = CClass(self.mcl, "CL1") cl2 = CClass(self.mcl, "CL2") o1 = CObject(cl1, "O1") o1.classifier = cl2 eq_(o1.classifier, cl2) eq_(cl1.objects, []) eq_(cl2.objects, [o1])
def test_creation_of_unnamed_class(self): c1 = CClass(self.mcl) c2 = CClass(self.mcl) c3 = CClass(self.mcl, "x") eq_(set(self.mcl.classes), {c1, c2, c3}) eq_(c1.name, None) eq_(c2.name, None) eq_(c3.name, "x")
def test_metaclass_change(self): m1 = CMetaclass("M1") m2 = CMetaclass("M2") c1 = CClass(m1, "C1") c1.metaclass = m2 eq_(c1.metaclass, m2) eq_(m1.classes, []) eq_(m2.classes, [c1])
def test_superclasses_that_are_deleted(self): c1 = CClass(self.mcl, "C1") c1.delete() try: CClass(self.mcl, superclasses=[c1]) exception_expected_() except CException as e: eq_(e.value, "cannot access named element that has been deleted")
def test_bundle_elements_that_are_deleted(self): c = CClass(self.mcl, "C") c.delete() try: CBundle("B1", elements=[c]) exception_expected_() except CException as e: eq_(e.value, "cannot access named element that has been deleted")
def test_type_object_attribute_class_is_deleted_in_constructor(self): attribute_class = CClass(self.mcl, "AC") attribute_class.delete() try: CMetaclass("M", attributes={"ac": attribute_class}) exception_expected_() except CException as e: eq_(e.value, "cannot access named element that has been deleted")
def test_default_object_attribute_is_deleted_in_constructor(self): attr_cl = CClass(self.mcl, "AC") default_obj = CObject(attr_cl) default_obj.delete() try: CClass(self.mcl, "C", attributes={"ac": default_obj}) exception_expected_() except CException as e: eq_(e.value, "cannot access named element that has been deleted")
def test_setting_derived_from_relation_to_none(self): c1 = CClass(self.m1, "C1") c2 = CClass(self.m2, "C2") a1 = c1.association(c2, "1 -> *", derived_from=self.a) a1.derived_from = None eq_(a1.derived_from, None) eq_(self.a.derived_associations, [])
def test_stereotype_instances_wrong_type_in_assignment(self): CStereotype("S1", extended=self.mcl) c = CClass(self.mcl, "C") try: c.stereotype_instances = self.mcl exception_expected_() except CException as e: eq_(e.value, "a list or a stereotype is required as input") eq_(c.stereotype_instances, [])
def test_stereotype_instances_none_assignment(self): CStereotype("S1", extended=self.mcl) c = CClass(self.mcl, "C") try: c.stereotype_instances = [None] exception_expected_() except CException as e: eq_(e.value, "'None' is not a stereotype") eq_(c.stereotype_instances, [])
def test_stereotype_instances_double_assignment(self): s1 = CStereotype("S1", extended=self.mcl) c = CClass(self.mcl, "C") try: c.stereotype_instances = [s1, s1] exception_expected_() except CException as e: eq_(e.value, "'S1' is already a stereotype instance on 'C'") eq_(c.stereotype_instances, [s1])
def test_all_extended_instances(self): s1 = CStereotype("S1", extended=self.mcl) s2 = CStereotype("S2", superclasses=s1) c1 = CClass(self.mcl, "C1", stereotype_instances=s1) c2 = CClass(self.mcl, "C2", stereotype_instances=s2) eq_(s1.extended_instances, [c1]) eq_(s2.extended_instances, [c2]) eq_(s1.all_extended_instances, [c1, c2]) eq_(s2.all_extended_instances, [c2])
def test_type_object_attribute_class_is_deleted_in_type_method(self): attr_cl = CClass(self.mcl, "AC") attr_cl.delete() try: a = CAttribute() a.type = attr_cl exception_expected_() except CException as e: eq_(e.value, "cannot access named element that has been deleted")
def test_attribute_value_type_check_list(self): self.mcl.attributes = {"t": list} cl = CClass(self.mcl, "C") try: cl.set_value("t", True) exception_expected_() except CException as e: eq_(f"value type for attribute 't' does not match attribute type", e.value)
def test_attribute_value_type_check_bool1(self): self.mcl.attributes = {"t": bool} cl = CClass(self.mcl, "C") try: cl.set_value("t", self.mcl) exception_expected_() except CException as e: eq_(f"value for attribute 't' is not a known attribute type", e.value)