def test_add_links_source_multiplicity(self): self.m1.association(self.m2, "[sourceRole1] 1 -> [role1] *") self.m1.association(self.m2, "[sourceRole2] 1 -> [role2] 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") c6 = CClass(self.m2, "c6") add_links({c2: c3}, role_name="role1") add_links({c2: c4}, role_name="role1") eq_(c3.get_linked(role_name="sourceRole1"), [c2]) add_links({c2: c5}, role_name="role1") eq_(c2.get_linked(role_name="role1"), [c3, c4, c5]) try: add_links({c1: [c4]}, role_name="role1") exception_expected_() except CException as e: eq_(e.value, "links of object 'c4' have wrong multiplicity '2': should be '1'") add_links({c1: c6}, role_name="role2") eq_(c1.get_linked(role_name="role2"), [c6]) try: add_links({c1: [c3, c4]}, role_name="role2") exception_expected_() except CException as e: eq_(e.value, "links of object 'c1' have wrong multiplicity '3': should be '1'") eq_(c1.get_linked(role_name="role2"), [c6])
def test_link_with_inheritance_in_classifier_targets(self): sub_class = CMetaclass(superclasses=self.m2) a1 = self.m1.association(sub_class, name="a1", multiplicity="*") a2 = self.m1.association(self.m2, name="a2", multiplicity="*") c1 = CClass(self.m1, "c1") c2 = CClass(self.m1, "c2") c_sub_1 = CClass(sub_class, "c_sub_1") c_sub_2 = CClass(sub_class, "c_sub_2") c_super_1 = CClass(self.m2, "c_super_1") c_super_2 = CClass(self.m2, "c_super_2") try: # ambiguous, list works for both associations set_links({c1: [c_sub_1, c_sub_2]}) exception_expected_() except CException as e: eq_(e.value, "link specification ambiguous, multiple matching associations found " + "for source 'c1' and targets '['c_sub_1', 'c_sub_2']'") set_links({c1: [c_sub_1, c_sub_2]}, association=a1) set_links({c1: [c_sub_1]}, association=a2) set_links({c2: [c_super_1, c_super_2]}) eq_(c1.linked, [c_sub_1, c_sub_2, c_sub_1]) eq_(c1.get_linked(), [c_sub_1, c_sub_2, c_sub_1]) eq_(c2.get_linked(), [c_super_1, c_super_2]) eq_(c1.get_linked(association=a1), [c_sub_1, c_sub_2]) eq_(c1.get_linked(association=a2), [c_sub_1]) eq_(c2.get_linked(association=a1), []) eq_(c2.get_linked(association=a2), [c_super_1, c_super_2]) # this mixed list is applicable only for a2 set_links({c2: [c_sub_1, c_super_1]}) eq_(c2.get_linked(association=a1), []) eq_(c2.get_linked(association=a2), [c_sub_1, c_super_1])
def test_link_with_inheritance_in_classifier_targets_using_role_names(self): sub_class = CMetaclass(superclasses=self.m2) a1 = self.m1.association(sub_class, "a1: * -> [sub_class] *") a2 = self.m1.association(self.m2, "a2: * -> [c2] *") c1 = CClass(self.m1, "c1") c2 = CClass(self.m1, "c2") c_sub_1 = CClass(sub_class, "c_sub_1") c_sub_2 = CClass(sub_class, "c_sub_2") c_super_1 = CClass(self.m2, "c_super_1") c_super_2 = CClass(self.m2, "c_super_2") set_links({c1: [c_sub_1, c_sub_2]}, role_name="sub_class") set_links({c1: [c_sub_1]}, role_name="c2") set_links({c2: [c_super_1, c_super_2]}) eq_(c1.linked, [c_sub_1, c_sub_2, c_sub_1]) eq_(c1.get_linked(), [c_sub_1, c_sub_2, c_sub_1]) eq_(c2.get_linked(), [c_super_1, c_super_2]) eq_(c1.get_linked(association=a1), [c_sub_1, c_sub_2]) eq_(c1.get_linked(association=a2), [c_sub_1]) eq_(c2.get_linked(association=a1), []) eq_(c2.get_linked(association=a2), [c_super_1, c_super_2]) eq_(c1.get_linked(role_name="sub_class"), [c_sub_1, c_sub_2]) eq_(c1.get_linked(role_name="c2"), [c_sub_1]) eq_(c2.get_linked(role_name="sub_class"), []) eq_(c2.get_linked(role_name="c2"), [c_super_1, c_super_2])
def test_add_links_multiple_links_in_definition(self): self.m1.association(self.m2, "[sourceRole1] * -> [role1] *") c1 = CClass(self.m1, "c1") c2 = CClass(self.m1, "c2") c3 = CClass(self.m1, "c3") c4 = CClass(self.m2, "c4") c5 = CClass(self.m2, "c5") add_links({c1: c4, c2: [c4], c5: [c1, c2, c3]}) eq_(c1.get_linked(), [c4, c5]) eq_(c2.get_linked(), [c4, c5]) eq_(c3.get_linked(), [c5]) eq_(c4.get_linked(), [c1, c2]) eq_(c5.get_linked(), [c1, c2, c3])
def test_one_to_n_link_multiplicity(self): a = self.m1.association(self.m2, name="l", source_multiplicity="1", multiplicity="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..*'") set_links({c1: [c2, c3]}) eq_(c1.get_linked(association=a), [c2, c3]) 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'") 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'")
def test_duplicate_assignment(self): a = self.m1.association(self.m2, "l: *->*") c1 = CClass(self.m1, "c1") c2 = CClass(self.m2, "c2") try: set_links({c1: [c2, c2]}) exception_expected_() except CException as e: eq_(e.value, "trying to link the same link twice 'c1 -> c2'' twice for the same association") eq_(c1.get_linked(), []) eq_(c2.get_linked(), []) b = self.m1.association(self.m2, "l: *->*") c1.add_links(c2, association=a) c1.add_links(c2, association=b) eq_(c1.get_linked(), [c2, c2]) eq_(c2.get_linked(), [c1, c1])
def test_link_and_get_links_by_association(self): a1 = self.m1.association(self.m2, name="a1", multiplicity="*") a2 = self.m1.association(self.m2, name="a2", multiplicity="*") c1 = CClass(self.m1, "c1") c2 = CClass(self.m2, "c2") c3 = CClass(self.m2, "c3") links_a1 = set_links({c1: c2}, association=a1) links_a2 = set_links({c1: [c2, c3]}, association=a2) eq_(c1.get_linked(), [c2, c2, c3]) eq_(c1.linked, [c2, c2, c3]) eq_(c1.get_linked(association=a1), [c2]) eq_(c1.get_linked(association=a2), [c2, c3]) eq_(c1.get_links_for_association(a1), links_a1) eq_(c1.get_links_for_association(a2), links_a2)
def test_specific_n_to_n_link_multiplicity(self): a = self.m1.association(self.m2, name="l", source_multiplicity="1..2", multiplicity="2") c1 = CClass(self.m1, "c1") c2 = CClass(self.m2, "c2") c3 = CClass(self.m2, "c3") c4 = CClass(self.m1, "c4") c5 = CClass(self.m1, "c5") c6 = CClass(self.m2, "c6") 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 '2'") try: set_links({c1: [c2]}, association=a) exception_expected_() except CException as e: eq_(e.value, "links of object 'c1' have wrong multiplicity '1': should be '2'") try: set_links({c1: [c2, c3, c6]}, association=a) exception_expected_() except CException as e: eq_(e.value, "links of object 'c1' have wrong multiplicity '3': should be '2'") set_links({c1: [c2, c3]}) eq_(c1.get_linked(association=a), [c2, c3]) set_links({c2: [c1, c4], c1: c3, c4: c3}) eq_(c2.get_linked(association=a), [c1, c4]) 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..2'") try: set_links({c2: [c1, c4, c5]}) exception_expected_() except CException as e: eq_(e.value, "links of object 'c2' have wrong multiplicity '3': should be '1..2'")
def test_link_source_multiplicity(self): self.m1.association(self.m2, "[sourceRole1] 1 -> [role1] *") self.m1.association(self.m2, "[sourceRole2] 1 -> [role2] 1") c1 = CClass(self.m1, "c1") c2 = CClass(self.m1, "c2") c3 = CClass(self.m2, "c3") CClass(self.m2, "c4") CClass(self.m2, "c5") set_links({c1: c3}, role_name="role1") set_links({c2: c3}, role_name="role1") eq_(c3.get_linked(role_name="sourceRole1"), [c2])
def test_link_methods_wrong_keyword_args(self): c1 = CClass(self.m1, "C1") try: add_links({c1: c1}, associationX=None) exception_expected_() except CException as e: eq_(e.value, "unknown keywords argument") try: c1.add_links(c1, associationX=None) exception_expected_() except CException as e: eq_(e.value, "unknown keywords argument") try: set_links({c1: c1}, associationX=None) exception_expected_() except CException as e: eq_(e.value, "unknown keywords argument") try: c1.delete_links(c1, associationX=None) exception_expected_() except CException as e: eq_(e.value, "unknown keywords argument") try: delete_links({c1: c1}, associationX=None) exception_expected_() except CException as e: eq_(e.value, "unknown keywords argument") try: c1.get_linked(associationX=None) exception_expected_() except CException as e: eq_(e.value, "unknown keywords argument") try: delete_links({c1: c1}, stereotype_instances=None) exception_expected_() except CException as e: eq_(e.value, "unknown keywords argument")
def test_add_links(self): self.m1.association(self.m2, "1 -> [role1] *") self.m1.association(self.m2, "* -> [role2] *") self.m1.association(self.m2, "1 -> [role3] 1") c1 = CClass(self.m1, "c1") c2 = CClass(self.m2, "c2") c3 = CClass(self.m2, "c3") c4 = CClass(self.m2, "c4") add_links({c1: c2}, role_name="role1") eq_(c1.get_linked(role_name="role1"), [c2]) add_links({c1: [c3, c4]}, role_name="role1") c1.get_linked(role_name="role1") eq_(c1.get_linked(role_name="role1"), [c2, c3, c4]) c1.add_links(c2, role_name="role2") eq_(c1.get_linked(role_name="role2"), [c2]) c1.add_links([c3, c4], role_name="role2") c1.get_linked(role_name="role2") eq_(c1.get_linked(role_name="role2"), [c2, c3, c4]) c1.add_links(c2, role_name="role3") eq_(c1.get_linked(role_name="role3"), [c2]) try: add_links({c1: [c3, c4]}, role_name="role3") exception_expected_() except CException as e: eq_(e.value, "links of object 'c1' have wrong multiplicity '3': should be '1'") try: add_links({c1: [c3]}, role_name="role3") exception_expected_() except CException as e: eq_(e.value, "links of object 'c1' have wrong multiplicity '2': should be '1'") eq_(c1.get_linked(role_name="role3"), [c2])
def test_add_links_with_inherited_common_classifiers(self): super_a = CMetaclass("SuperA") super_b = CMetaclass("SuperB") super_a.association(super_b, "[a] 1 -> [b] *") sub_b1 = CMetaclass("SubB1", superclasses=[super_b]) sub_b2 = CMetaclass("SubB2", superclasses=[super_b]) sub_a = CMetaclass("SubA", superclasses=[super_a]) cl_a = CClass(sub_a, "a") cl_b1 = CClass(sub_b1, "b1") cl_b2 = CClass(sub_b2, "b2") add_links({cl_a: [cl_b1, cl_b2]}, role_name="b") eq_(set(cl_a.get_linked(role_name="b")), {cl_b1, cl_b2})
def test_n_to_n_set_self_link_delete_links(self): self.m1.association(self.m1, name="a", source_multiplicity="*", multiplicity="*", source_role_name="super", role_name="sub") top = CClass(self.m1, "Top") mid1 = CClass(self.m1, "Mid1") mid2 = CClass(self.m1, "Mid2") mid3 = CClass(self.m1, "Mid3") bottom1 = CClass(self.m1, "Bottom1") bottom2 = CClass(self.m1, "Bottom2") set_links({top: [mid1, mid2, mid3], mid1: [bottom1, bottom2]}, role_name="sub") # delete links set_links({top: []}, role_name="sub") eq_(top.linked, []) eq_(mid1.linked, [bottom1, bottom2]) # change links set_links({mid1: top, mid3: top, bottom1: mid1, bottom2: mid1}, role_name="super") eq_(top.linked, [mid1, mid3]) eq_(mid1.linked, [top, bottom1, bottom2]) eq_(mid2.linked, []) eq_(mid3.linked, [top]) eq_(bottom1.linked, [mid1]) eq_(bottom2.linked, [mid1]) eq_(top.get_linked(role_name="sub"), [mid1, mid3]) eq_(mid1.get_linked(role_name="sub"), [bottom1, bottom2]) eq_(mid2.get_linked(role_name="sub"), []) eq_(mid3.get_linked(role_name="sub"), []) eq_(bottom1.get_linked(role_name="sub"), []) eq_(bottom2.get_linked(role_name="sub"), []) eq_(top.get_linked(role_name="super"), []) eq_(mid1.get_linked(role_name="super"), [top]) eq_(mid2.get_linked(role_name="super"), []) eq_(mid3.get_linked(role_name="super"), [top]) eq_(bottom1.get_linked(role_name="super"), [mid1]) eq_(bottom2.get_linked(role_name="super"), [mid1])
class TestLinkObjectsForMetaclasses: def setup(self): self.mcl = CMetaclass("MCL") def test_reference_to_link(self): code = CMetaclass("Code") source = CMetaclass("Source") code_association = 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] *", superclasses=code) 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") code_b3 = CClass(code_b, "code_b3") a_b_links = add_links({code_a1: [code_b1, code_b2]}, association=a_b_association) code_links = add_links({source_1: [code_a1, code_b2, code_b1, a_b_links[0], a_b_links[1]]}, role_name="contained_code") eq_(len(code_links), 5) # test getter methods on class eq_(set(source_1.get_linked(role_name="contained_code")), {code_a1, code_b2, code_b1, a_b_links[0], a_b_links[1]}) eq_(set(source_1.linked), {code_a1, code_b2, code_b1, a_b_links[0], a_b_links[1]}) eq_(set(source_1.links), set(code_links)) eq_(set(source_1.get_links_for_association(code_association)), set(code_links)) eq_(set(get_links([source_1])), set(code_links)) # test getter methods on link eq_(a_b_links[0].get_linked(role_name="source"), [source_1]) eq_(a_b_links[0].linked, [source_1]) eq_(a_b_links[0].links, [code_links[3]]) eq_(a_b_links[0].get_links_for_association(code_association), [code_links[3]]) eq_(set(get_links([a_b_links[0]])), {code_links[3]}) eq_(set(get_links([code_a1, a_b_links[0], a_b_links[1]])), {code_links[0], a_b_links[0], a_b_links[1], code_links[3], code_links[4]}) # test add/delete links code_b3_link = code_a1.add_links(code_b3)[0] source_1.add_links(code_b3_link) eq_(set(code_a1.linked), {code_b1, code_b2, source_1, code_b3}) eq_(set(source_1.linked), {code_a1, code_b2, code_b1, a_b_links[0], a_b_links[1], code_b3_link}) eq_(code_b3_link.linked, [source_1]) a_b_links[1].delete_links([source_1]) eq_(set(source_1.linked), {code_a1, code_b2, code_b1, a_b_links[0], code_b3_link}) source_1.delete_links([code_a1, a_b_links[0]]) eq_(set(source_1.linked), {code_b2, code_b1, code_b3_link}) # test whether class links fail on metaclass cl_a = CClass(self.mcl, "CLA") cl_b = CClass(self.mcl, "CLB") cl_association = cl_a.association(cl_b, "[a] * -> [b] *") o_a = CObject(cl_a, "oa") o_b = CObject(cl_a, "ob") object_link = add_links({o_a: [o_b]}, association=cl_association)[0] try: add_links({source_1: [code_a1, code_b2, code_b1, object_link]}, role_name="contained_code") exception_expected_() except CException as e: eq_("link target is an object link, but source is a class", e.value) 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_association_to_association_not_possible(self): clx = CMetaclass("X") cla = CMetaclass("A") clb = CMetaclass("B") a_b_association = cla.association(clb, "a_b: [a] * -> [b] *") try: clx.association(a_b_association, "[x] * -> [a_b_association] *") exception_expected_() except CException as e: eq_("metaclass 'X' is not compatible with association target 'a_b'", e.value) def test_link_to_link(self): collection1 = CMetaclass("Collection1") collection2 = CMetaclass("Collection2") collections_association = collection1.association(collection2, "element references: [references] * -> [referenced] *") type_a = CMetaclass("Type A", superclasses=collection1) type_b = CMetaclass("Type B", superclasses=collection1) a_b_association = type_a.association(type_b, "a_b: [type_a] * -> [type_b] *", superclasses=collection1) type_c = CMetaclass("Type C", superclasses=collection2) type_d = CMetaclass("Type D", superclasses=[collection1, collection2]) c_d_association = type_c.association(type_d, "c_d: [type_c] * -> [type_d] *", superclasses=collection2) a_d_association = type_a.association(type_d, "a_d: [type_a] * -> [type_d] *", superclasses=[collection1, collection2]) a1 = CClass(type_a, "a1") b1 = CClass(type_b, "b1") b2 = CClass(type_b, "b2") c1 = CClass(type_c, "c1") c2 = CClass(type_c, "c2") d1 = CClass(type_d, "d1") a_b_links = add_links({a1: [b1, b2]}, association=a_b_association) c_d_links = add_links({d1: [c1, c2]}, association=c_d_association) a_d_links = add_links({a1: [d1]}, association=a_d_association) references_links = add_links({a_b_links[0]: c_d_links[0], a_b_links[1]: [c1, c2, d1, c_d_links[1], c_d_links[0]], a_d_links[0]: [a_d_links[0], c_d_links[1], c1, d1]}, role_name="referenced") eq_(set(a_b_links[0].get_linked(role_name="referenced")), {c_d_links[0]}) eq_(set(a_b_links[0].linked), {c_d_links[0]}) eq_(set(a_b_links[0].links), {references_links[0]}) eq_(set(a_b_links[0].get_links_for_association(collections_association)), {references_links[0]}) eq_(set(get_links([a_b_links[0]])), {references_links[0]}) eq_(set(a_b_links[1].get_linked(role_name="referenced")), {c1, c2, d1, c_d_links[1], c_d_links[0]}) eq_(set(a_b_links[1].linked), {c1, c2, d1, c_d_links[1], c_d_links[0]}) correct_links_set = {references_links[1], references_links[2], references_links[3], references_links[4], references_links[5]} eq_(set(a_b_links[1].links), correct_links_set) eq_(set(a_b_links[1].get_links_for_association(collections_association)), correct_links_set) eq_(set(get_links([a_b_links[1]])), correct_links_set) eq_(set(a_d_links[0].get_linked(role_name="referenced")), {a_d_links[0], c_d_links[1], c1, d1}) eq_(set(a_d_links[0].linked), {a_d_links[0], c_d_links[1], c1, d1}) correct_links_set = {references_links[6], references_links[7], references_links[8], references_links[9]} eq_(set(a_d_links[0].links), correct_links_set) eq_(set(a_d_links[0].get_links_for_association(collections_association)), correct_links_set) eq_(set(get_links([a_d_links[0]])), correct_links_set) def test_links_as_attribute_values(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] *", superclasses=code) 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") a_b_links = add_links({code_a1: [code_b1, code_b2]}, association=a_b_association) links_list = [code_a1, code_b2, code_b1, a_b_links[0], a_b_links[1]] collection_type = CMetaclass("Collection Type", attributes={ "primary_code": code, "default_value_code": a_b_links[0], "codes": list, "default_values_list": links_list }) collection = CClass(collection_type) eq_(collection.get_value("primary_code"), None) eq_(collection.get_value("default_value_code"), a_b_links[0]) eq_(collection.get_value("codes"), None) eq_(collection.get_value("default_values_list"), links_list) collection.set_value("primary_code", a_b_links[1]) collection.set_value("default_value_code", a_b_links[1]) collection.set_value("codes", [code_a1, a_b_links[0]]) collection.set_value("default_values_list", [a_b_links[0], a_b_links[1]]) eq_(collection.get_value("primary_code"), a_b_links[1]) eq_(collection.get_value("default_value_code"), a_b_links[1]) eq_(collection.get_value("codes"), [code_a1, a_b_links[0]]) eq_(collection.get_value("default_values_list"), [a_b_links[0], a_b_links[1]]) collection.values = {'default_values_list': [a_b_links[0]], "codes": []} eq_(collection.values, {'default_value_code': a_b_links[1], 'default_values_list': [a_b_links[0]], 'codes': [], 'primary_code': a_b_links[1]}) collection.delete_value("primary_code") collection.delete_value("default_value_code") collection.delete_value("codes") collection.delete_value("default_values_list") eq_(collection.get_value("primary_code"), None) eq_(collection.get_value("default_value_code"), None) eq_(collection.get_value("codes"), None) eq_(collection.get_value("default_values_list"), None) def create_simple_link_object_test_setup(self): self.a = CMetaclass("A") self.a1 = CMetaclass("A1", superclasses=self.a) self.a2 = CMetaclass("A2", superclasses=self.a) self.a_association = self.a1.association(self.a2, "[a1] * -> [a2] *", superclasses=self.a) self.b = CMetaclass("B") self.b_a_association = self.b.association(self.a, "[b] * -> [a] *") self.a1_1 = CClass(self.a1, "a1_1") self.a1_2 = CClass(self.a1, "a1_2") self.a2_1 = CClass(self.a2, "a2_1") self.b_1 = CClass(self.b, "b_1") self.a_links = add_links({self.a2_1: [self.a1_1, self.a1_2]}, association=self.a_association) self.b_a_links = add_links({self.b_1: [self.a_links[0], self.a_links[1]]}, association=self.b_a_association) def test_attributes_on_association_classifier(self): self.create_simple_link_object_test_setup() eq_(self.b_a_association.attributes, []) eq_(self.b_a_association.attribute_names, []) try: self.b_a_association.attributes = { "i1": int, "i2": 15, "s1": str, "s2": "abc" } exception_expected_() except CException as e: eq_("setting of attributes not supported for associations", e.value) eq_(self.b_a_association.get_attribute("i1"), None) def test_superclass_sub_class_method_on_association_classifier(self): self.create_simple_link_object_test_setup() eq_(self.a_association.superclasses, [self.a]) eq_(self.a_association.subclasses, []) eq_(self.b_a_association.superclasses, []) eq_(self.b_a_association.subclasses, []) eq_(self.a.subclasses, [self.a1, self.a2, self.a_association]) try: another_sc = CClass(self.mcl, "ASC") self.a_association.superclasses = [self.a, another_sc] exception_expected_() except CException as e: eq_("cannot add superclass 'ASC': not a metaclass or metaclass association", e.value) try: another_sc = CStereotype("ASC") self.a_association.superclasses = [self.a, another_sc] exception_expected_() except CException as e: eq_("cannot add superclass 'ASC': not a metaclass or metaclass association", e.value) another_sc = CMetaclass("ASC") self.a_association.superclasses = [self.a, another_sc] eq_(self.a_association.superclasses, [self.a, another_sc]) eq_(set(self.a_association.all_superclasses), {self.a, another_sc}) a2_association = self.a1.association(self.a2, "[a1] * -> [a2] *", superclasses=self.a) self.a_association.superclasses = [a2_association] eq_(self.a_association.superclasses, [a2_association]) eq_(self.a_association.all_subclasses, set()) eq_(self.a_association.all_superclasses, {a2_association, self.a}) eq_(a2_association.superclasses, [self.a]) eq_(a2_association.subclasses, [self.a_association]) eq_(a2_association.all_subclasses, {self.a_association}) eq_(a2_association.has_subclass(self.a_association), True) eq_(a2_association.has_subclass(self.a1), False) eq_(a2_association.has_superclass(self.a_association), False) eq_(a2_association.has_superclass(self.a), True) eq_(self.a_association.is_classifier_of_type(self.a_association), True) eq_(self.a_association.is_classifier_of_type(a2_association), True) eq_(self.a_association.is_classifier_of_type(self.a), True) eq_(self.a_association.is_classifier_of_type(self.a1), False) # test linking still works after superclass changes self.b_1.delete_links([self.a_links[0], self.a_links[1]]) eq_(self.b_1.get_linked(), []) self.b_a_links = set_links({self.b_1: [self.a_links[1], self.a_links[0]]}, association=self.b_a_association) eq_(self.b_1.get_linked(), [self.a_links[1], self.a_links[0]]) def test_delete_linked_association(self): self.create_simple_link_object_test_setup() self.a_association.delete() eq_(self.a.subclasses, [self.a1, self.a2]) eq_(self.a2_1.get_linked(), []) eq_(self.b_1.get_linked(), []) def test_delete_linking_association(self): self.create_simple_link_object_test_setup() self.b_a_association.delete() eq_(self.a2_1.get_linked(), [self.a1_1, self.a1_2]) eq_(self.b_1.get_linked(), []) def test_link_object_classifier(self): self.create_simple_link_object_test_setup() eq_(self.a_links[0].classifier, self.a_association) eq_(self.b_a_links[0].classifier, self.b_a_association) try: self.a_links[0].classifier = self.b_a_association exception_expected_() except CException as e: eq_("Changes to the classifier (i.e., the association) of a link" + " should not be performed with CObject methods", e.value) def test_link_object_class_object_class(self): self.create_simple_link_object_test_setup() eq_(self.a_links[0].class_object_class, None) eq_(self.b_a_links[0].class_object_class, None) def test_link_object_instance_of(self): self.create_simple_link_object_test_setup() eq_(self.a_links[0].instance_of(self.a_association), True) eq_(self.a_links[0].instance_of(self.b_a_association), False) eq_(self.a_links[0].instance_of(self.a), True) eq_(self.a_links[0].instance_of(self.a1), False) try: cl = CClass(self.mcl, "CL") eq_(self.a_links[0].instance_of(cl), False) exception_expected_() except CException as e: eq_("'CL' is not an association or a metaclass", e.value) eq_(self.b_a_links[0].instance_of(self.a_association), False) eq_(self.b_a_links[0].instance_of(self.b_a_association), True) eq_(self.b_a_links[0].instance_of(self.a), False) def test_link_object_delete(self): self.create_simple_link_object_test_setup() self.a_links[0].delete() self.b_a_links[0].delete() eq_(self.b_1.get_linked(), [self.a_links[1]]) eq_(self.a2_1.get_linked(), [self.a1_2]) eq_(self.a_links[1].get_linked(), [self.b_1]) try: self.a_links[0].get_value("a") exception_expected_() except CException as e: eq_("can't get value 'a' on deleted link", e.value) try: self.a_links[0].delete_value("a") exception_expected_() except CException as e: eq_("can't delete value 'a' on deleted link", e.value) try: self.a_links[0].set_value("a", 1) exception_expected_() except CException as e: eq_("can't set value 'a' on deleted link", e.value) try: self.a_links[0].values = {"a": 1} exception_expected_() except CException as e: eq_("can't set values on deleted link", e.value) def test_class_link_classifier_bundable(self): self.create_simple_link_object_test_setup() bundle = CBundle("Bundle", elements=self.a.get_connected_elements()) eq_(set(bundle.elements), {self.a, self.a1, self.a2, self.b}) try: bundle.elements = self.a.get_connected_elements(add_links=True) exception_expected_() except CException as e: eq_("unknown keyword argument 'add_links', should be one of:" + " ['add_associations', 'add_stereotypes', 'process_stereotypes', 'add_bundles', 'process_bundles'," + " 'stop_elements_inclusive', 'stop_elements_exclusive']", e.value) eq_(self.a_association.bundles, []) bundle.elements = self.a.get_connected_elements(add_associations=True) eq_(set(bundle.elements), {self.a, self.a1, self.a2, self.b, self.a_association}) eq_(self.a_association.bundles, [bundle]) bundle2 = CBundle("Bundle2", elements=self.a_association.get_connected_elements(add_associations=True)) eq_(set(bundle2.elements), {self.a, self.a1, self.a2, self.b, self.a_association}) eq_(set(self.a_association.bundles), {bundle, bundle2}) bundle2.delete() eq_(set(self.a_association.bundles), {bundle}) self.a_association.delete() eq_(set(bundle.elements), {self.a, self.a1, self.a2, self.b}) def test_class_link_bundable(self): self.create_simple_link_object_test_setup() bundle = CBundle("Bundle", elements=self.a1_1.class_object.get_connected_elements()) eq_(set(bundle.elements), {self.a1_1.class_object, self.a1_2.class_object, self.a2_1.class_object}) try: bundle.elements = self.a1_1.class_object.get_connected_elements(add_associations=True) exception_expected_() except CException as e: eq_("unknown keyword argument 'add_associations', should be one of:" + " ['add_links', 'add_bundles', 'process_bundles', 'stop_elements_inclusive', " + "'stop_elements_exclusive']", e.value) bundle.elements = self.b_1.class_object.get_connected_elements() eq_(set(bundle.elements), {self.b_1.class_object}) eq_(self.a_links[0].bundles, []) bundle.elements = self.b_1.class_object.get_connected_elements(add_links=True) eq_(set(bundle.elements), {self.b_1.class_object, self.a_links[0], self.a_links[1]}) eq_(self.a_links[0].bundles, [bundle]) bundle2 = CBundle("Bundle2", elements=self.a_links[0].get_connected_elements(add_links=True)) eq_(set(bundle2.elements), {self.b_1.class_object, self.a_links[0], self.a_links[1]}) eq_(set(self.a_links[0].bundles), {bundle, bundle2}) bundle2.delete() eq_(set(self.a_links[0].bundles), {bundle}) self.a_links[0].delete() eq_(set(bundle.elements), {self.b_1.class_object, self.a_links[1]})
def test_reference_to_link(self): code = CMetaclass("Code") source = CMetaclass("Source") code_association = 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] *", superclasses=code) 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") code_b3 = CClass(code_b, "code_b3") a_b_links = add_links({code_a1: [code_b1, code_b2]}, association=a_b_association) code_links = add_links({source_1: [code_a1, code_b2, code_b1, a_b_links[0], a_b_links[1]]}, role_name="contained_code") eq_(len(code_links), 5) # test getter methods on class eq_(set(source_1.get_linked(role_name="contained_code")), {code_a1, code_b2, code_b1, a_b_links[0], a_b_links[1]}) eq_(set(source_1.linked), {code_a1, code_b2, code_b1, a_b_links[0], a_b_links[1]}) eq_(set(source_1.links), set(code_links)) eq_(set(source_1.get_links_for_association(code_association)), set(code_links)) eq_(set(get_links([source_1])), set(code_links)) # test getter methods on link eq_(a_b_links[0].get_linked(role_name="source"), [source_1]) eq_(a_b_links[0].linked, [source_1]) eq_(a_b_links[0].links, [code_links[3]]) eq_(a_b_links[0].get_links_for_association(code_association), [code_links[3]]) eq_(set(get_links([a_b_links[0]])), {code_links[3]}) eq_(set(get_links([code_a1, a_b_links[0], a_b_links[1]])), {code_links[0], a_b_links[0], a_b_links[1], code_links[3], code_links[4]}) # test add/delete links code_b3_link = code_a1.add_links(code_b3)[0] source_1.add_links(code_b3_link) eq_(set(code_a1.linked), {code_b1, code_b2, source_1, code_b3}) eq_(set(source_1.linked), {code_a1, code_b2, code_b1, a_b_links[0], a_b_links[1], code_b3_link}) eq_(code_b3_link.linked, [source_1]) a_b_links[1].delete_links([source_1]) eq_(set(source_1.linked), {code_a1, code_b2, code_b1, a_b_links[0], code_b3_link}) source_1.delete_links([code_a1, a_b_links[0]]) eq_(set(source_1.linked), {code_b2, code_b1, code_b3_link}) # test whether class links fail on metaclass cl_a = CClass(self.mcl, "CLA") cl_b = CClass(self.mcl, "CLB") cl_association = cl_a.association(cl_b, "[a] * -> [b] *") o_a = CObject(cl_a, "oa") o_b = CObject(cl_a, "ob") object_link = add_links({o_a: [o_b]}, association=cl_association)[0] try: add_links({source_1: [code_a1, code_b2, code_b1, object_link]}, role_name="contained_code") exception_expected_() except CException as e: eq_("link target is an object link, but source is a class", e.value)