def test_wrong_types_set_links(self): self.c1.association(self.c2, name="l", multiplicity="1") o1 = CObject(self.c1, "o1") o2 = CObject(self.c2, "o2") try: set_links({o1: self.mcl}) exception_expected_() except CException as e: eq_(e.value, "link target 'MCL' is not an object, class, or link") try: set_links({o1: [o2, self.mcl]}) exception_expected_() except CException as e: eq_(e.value, "link target 'MCL' is not an object, class, or link") try: set_links({o1: [o2, 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: o2}) exception_expected_() except CException as e: eq_(e.value, "link source 'MCL' is not an object, class, or link") try: set_links({None: o2}) exception_expected_() except CException as e: eq_(e.value, "link should not contain an empty source")
def test_link_association_ambiguous(self): self.c1.association(self.c2, name="a1", role_name="c2", multiplicity="*") self.c1.association(self.c2, name="a2", role_name="c2", multiplicity="*") o1 = CObject(self.c1, "o1") o2 = CObject(self.c2, "o2") try: set_links({o1: o2}) exception_expected_() except CException as e: eq_( e.value, "link specification ambiguous, multiple matching associations " + "found for source 'o1' and targets '['o2']'") try: set_links({o1: o2}, role_name="c2") exception_expected_() except CException as e: eq_( e.value, "link specification ambiguous, multiple matching associations " + "found for source 'o1' and targets '['o2']'")
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_add_one_to_one_link(self): self.m1.association(self.m2, "l: 1 -> [target] 0..1") c1 = CClass(self.m1, "c1") c2 = CClass(self.m2, "c2") c3 = CClass(self.m2, "c3") eq_(c1.linked, []) add_links({c1: c3}) eq_(c1.linked, [c3]) eq_(c3.linked, [c1]) set_links({c1: []}, role_name="target") eq_(c1.linked, []) c1.add_links(c2) eq_(c1.linked, [c2]) eq_(c2.linked, [c1]) try: add_links({c1: c3}) exception_expected_() except CException as e: eq_(e.value, "links of object 'c1' have wrong multiplicity '2': should be '0..1'") eq_(c1.linked, [c2]) eq_(c2.linked, [c1]) eq_(c3.linked, [])
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_get_links_self_link(self): a1 = self.c1.association(self.c1, role_name="to", source_role_name="from", source_multiplicity="*", multiplicity="*") o1 = CObject(self.c1, "o1") o2 = CObject(self.c1, "o2") o3 = CObject(self.c1, "o3") o4 = CObject(self.c1, "o4") set_links({o1: [o2, o3, o1]}) o4.add_links([o1, o3]) link1 = o1.links[0] link2 = [o for o in o1.links if o.association == a1][0] link3 = [o for o in o1.links if o.role_name == "to"][0] link4 = [o for o in o1.links if o.source_role_name == "from"][0] eq_(link1, link2) eq_(link1, link3) eq_(link1, link4) eq_(link1.association, a1) eq_(link1.source, o1) eq_(link1.target, o2) eq_(len(o1.links), 4) eq_(len(o2.links), 1) eq_(len(o3.links), 2) eq_(len(o4.links), 2)
def test_link_delete_association(self): a = self.c1.association(self.c2, name="l", source_multiplicity="*", multiplicity="*") o1 = CObject(self.c1, "o2") o2 = CObject(self.c2, "o2") o3 = CObject(self.c2, "o3") o4 = CObject(self.c1, "o4") set_links({o1: [o2, o3]}) set_links({o4: [o2]}) set_links({o1: [o2]}) set_links({o4: [o3, o2]}) a.delete() eq_(o1.linked, []) eq_(o2.linked, []) eq_(o3.linked, []) eq_(o4.linked, []) try: set_links({o1: [o2, o3]}) exception_expected_() except CException as e: eq_( e.value, "matching association not found for source 'o2' and targets '['o2', 'o3']'" )
def test_n_to_n_set_self_link(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]}, role_name="sub") mid1.add_links([bottom1, bottom2], role_name="sub") eq_(top.linked, [mid1, mid2, mid3]) eq_(mid1.linked, [top, bottom1, bottom2]) eq_(mid2.linked, [top]) eq_(mid3.linked, [top]) eq_(bottom1.linked, [mid1]) eq_(bottom2.linked, [mid1]) eq_(top.get_linked(role_name="sub"), [mid1, mid2, 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"), [top]) eq_(mid3.get_linked(role_name="super"), [top]) eq_(bottom1.get_linked(role_name="super"), [mid1]) eq_(bottom2.get_linked(role_name="super"), [mid1])
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_add_one_to_one_link(self): self.c1.association(self.c2, "l: 1 -> [target] 0..1") o1 = CObject(self.c1, "o1") o2 = CObject(self.c2, "o2") o3 = CObject(self.c2, "o3") eq_(o1.linked, []) add_links({o1: o3}) eq_(o1.linked, [o3]) eq_(o3.linked, [o1]) set_links({o1: []}, role_name="target") eq_(o1.linked, []) o1.add_links(o2) eq_(o1.linked, [o2]) eq_(o2.linked, [o1]) try: add_links({o1: o3}) exception_expected_() except CException as e: eq_( e.value, "links of object 'o1' have wrong multiplicity '2': should be '0..1'" ) eq_(o1.linked, [o2]) eq_(o2.linked, [o1]) eq_(o3.linked, [])
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_non_existing_role_name(self): self.m1.association(self.m1, role_name="next", source_role_name="prior", source_multiplicity="1", multiplicity="1") c1 = CClass(self.m1, "c1") try: set_links({c1: c1}, role_name="target") exception_expected_() except CException as e: eq_(e.value, "matching association not found for source 'c1' and targets '['c1']'")
def test_wrong_format_set_links(self): self.m1.association(self.m2, name="l", multiplicity="1") c1 = CClass(self.m1, "c1") c2 = CClass(self.m2, "c2") try: # noinspection PyTypeChecker set_links([c1, c2]) exception_expected_() except CException as e: eq_(e.value, "link definitions should be of the form {<link source 1>: " + "<link target(s) 1>, ..., <link source n>: <link target(s) n>}")
def test_remove_n_to_n_link(self): self.m1.association(self.m2, name="l", source_multiplicity="*", multiplicity="*") c1 = CClass(self.m1, "c2") c2 = CClass(self.m2, "c2") c3 = CClass(self.m2, "c3") c4 = CClass(self.m1, "c4") set_links({c1: [c2, c3], c4: c2}) set_links({c1: c2, c4: [c3, c2]}) eq_(c1.linked, [c2]) eq_(c2.linked, [c1, c4]) eq_(c3.linked, [c4]) eq_(c4.linked, [c3, c2])
def test_link_source_multiplicity(self): self.c1.association(self.c2, "[sourceRole1] 1 -> [role1] *") self.c1.association(self.c2, "[sourceRole2] 1 -> [role2] 1") o1 = CObject(self.c1, "o1") o2 = CObject(self.c1, "o2") o3 = CObject(self.c2, "o3") CObject(self.c2, "o4") CObject(self.c2, "o5") set_links({o1: o3}, role_name="role1") set_links({o2: o3}, role_name="role1") eq_(o3.get_linked(role_name="sourceRole1"), [o2])
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_link_label_none_default(self): a1 = self.m1.association(self.m2, name="a1", multiplicity="*") a2 = self.m1.association(self.m2, multiplicity="*") c1 = CClass(self.m1, "c1") c2 = CClass(self.m2, "c2") c3 = CClass(self.m2, "c3") l1 = set_links({c1: c2}, association=a1) l2 = set_links({c1: [c2, c3]}, association=a2) eq_(l1[0].label, None) eq_(l2[0].label, None) eq_(l2[1].label, None)
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_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_n_to_n_link(self): a = self.c1.association(self.c2, name="l", source_multiplicity="*") o1a = CObject(self.c1, "o1a") o1b = CObject(self.c1, "o1b") o1c = CObject(self.c1, "o1c") o2a = CObject(self.c2, "o2a") o2b = CObject(self.c2, "o2b") set_links({o1a: [o2a, o2b], o1b: [o2a], o1c: [o2b]}) eq_(o1a.linked, [o2a, o2b]) eq_(o1b.linked, [o2a]) eq_(o1c.linked, [o2b]) eq_(o2a.linked, [o1a, o1b]) eq_(o2b.linked, [o1a, o1c]) set_links({o2a: [o1a, o1b]}) try: set_links({o2b: []}) exception_expected_() except CException as e: eq_( e.value, "matching association not found for source 'o2b' and targets '[]'" ) set_links({o2b: []}, association=a) eq_(o1a.linked, [o2a]) eq_(o1b.linked, [o2a]) eq_(o1c.linked, []) eq_(o2a.linked, [o1a, o1b]) eq_(o2b.linked, [])
def test_link_label_none_default(self): a1 = self.c1.association(self.c2, name="a1", multiplicity="*") a2 = self.c1.association(self.c2, multiplicity="*") o1 = CObject(self.c1, "o1") o2 = CObject(self.c2, "o2") o3 = CObject(self.c2, "o3") l1 = set_links({o1: o2}, association=a1) l2 = set_links({o1: [o2, o3]}, association=a2) eq_(l1[0].label, None) eq_(l2[0].label, None) eq_(l2[1].label, None)
def test_non_existing_role_name(self): self.c1.association(self.c1, role_name="next", source_role_name="prior", source_multiplicity="1", multiplicity="1") o1 = CObject(self.c1, "o1") try: set_links({o1: o1}, role_name="target") exception_expected_() except CException as e: eq_( e.value, "matching association not found for source 'o1' and targets '['o1']'" )
def test_remove_n_to_n_link(self): self.c1.association(self.c2, name="l", source_multiplicity="*", multiplicity="*") o1 = CObject(self.c1, "o2") o2 = CObject(self.c2, "o2") o3 = CObject(self.c2, "o3") o4 = CObject(self.c1, "o4") set_links({o1: [o2, o3], o4: o2}) set_links({o1: o2, o4: [o3, o2]}) eq_(o1.linked, [o2]) eq_(o2.linked, [o1, o4]) eq_(o3.linked, [o4]) eq_(o4.linked, [o3, o2])
def test_set_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") set_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_set_links_multiple_links_in_definition(self): self.c1.association(self.c2, "[sourceRole1] * -> [role1] *") o1 = CObject(self.c1, "o1") o2 = CObject(self.c1, "o2") o3 = CObject(self.c1, "o3") o4 = CObject(self.c2, "o4") o5 = CObject(self.c2, "o5") set_links({o1: o4, o2: [o4], o5: [o1, o2, o3]}) eq_(o1.get_linked(), [o4, o5]) eq_(o2.get_linked(), [o4, o5]) eq_(o3.get_linked(), [o5]) eq_(o4.get_linked(), [o1, o2]) eq_(o5.get_linked(), [o1, o2, o3])
def test_stereotype_instances_on_association_link(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") c3 = CClass(self.m2, "C3") links = set_links({c1: [c2, c3]}) l1 = links[0] eq_(l1.stereotype_instances, []) eq_(s1.extended_instances, []) l1.stereotype_instances = [s1] eq_(s1.extended_instances, [l1]) eq_(l1.stereotype_instances, [s1]) l1.stereotype_instances = [s1, s2, s3] eq_(s1.extended_instances, [l1]) eq_(s2.extended_instances, [l1]) eq_(s3.extended_instances, [l1]) eq_(set(l1.stereotype_instances), {s1, s2, s3}) l1.stereotype_instances = s2 eq_(l1.stereotype_instances, [s2]) eq_(s1.extended_instances, []) eq_(s2.extended_instances, [l1]) eq_(s3.extended_instances, []) eq_(c1.get_links_for_association(self.a), links) eq_(c2.get_links_for_association(self.a), [l1]) eq_(c3.get_links_for_association(self.a), [links[1]])
def test_incompatible_classifier(self): self.m1.association(self.m2, name="l", multiplicity="*") cl = CClass(self.mcl, "CLX") c1 = CClass(self.m1, "c1") c2 = CClass(self.m2, "c2") c3 = CObject(cl, "c3") try: set_links({c1: [c2, c3]}) exception_expected_() except CException as e: eq_(e.value, "link target 'c3' is an object, but source is a class") try: set_links({c1: c3}) exception_expected_() except CException as e: eq_(e.value, "link target 'c3' is an object, but source is a class")
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 = CMetaclass("ASC") self.a_association.superclasses = [self.a, another_sc] exception_expected_() except CException as e: eq_( "cannot add superclass 'ASC': not a class or class 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 class or class association", e.value) another_sc = CClass(self.mcl, "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_set_one_to_one_link(self): self.m1.association(self.m2, name="l", multiplicity="1") c1 = CClass(self.m1, "c1") c2 = CClass(self.m2, "c2") c3 = CClass(self.m2, "c3") eq_(c1.linked, []) set_links({c1: c2}) eq_(c1.linked, [c2]) eq_(c2.linked, [c1]) set_links({c1: c3}) eq_(c1.linked, [c3]) eq_(c2.linked, []) eq_(c3.linked, [c1])
def test_set_one_to_one_link(self): self.c1.association(self.c2, name="l", multiplicity="1") o1 = CObject(self.c1, "o1") o2 = CObject(self.c2, "o2") o3 = CObject(self.c2, "o3") eq_(o1.linked, []) set_links({o1: o2}) eq_(o1.linked, [o2]) eq_(o2.linked, [o1]) set_links({o1: o3}) eq_(o1.linked, [o3]) eq_(o2.linked, []) eq_(o3.linked, [o1])