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_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_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_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_values_inheritance_after_delete_superclass(self): t1 = CClass(self.mcl, "T1") t2 = CClass(self.mcl, "T2") c = CClass(self.mcl, "C", superclasses=[t1, t2]) sc = CClass(self.mcl, "C", superclasses=c) t1.attributes = {"i0": 0} t2.attributes = {"i1": 1} c.attributes = {"i2": 2} sc.attributes = {"i3": 3} o = CObject(sc, "o") t2.delete() for name, value in {"i0": 0, "i2": 2, "i3": 3}.items(): eq_(o.get_value(name), value) try: o.get_value("i1") exception_expected_() except CException as e: eq_(e.value, "attribute 'i1' unknown for 'o'") eq_(o.get_value("i0", t1), 0) try: o.get_value("i1", t2) exception_expected_() except CException as e: eq_(e.value, "attribute 'i1' unknown for ''") eq_(o.get_value("i2", c), 2) eq_(o.get_value("i3", sc), 3) for name, value in {"i0": 10, "i2": 12, "i3": 13}.items(): o.set_value(name, value) try: o.set_value("i1", 11) exception_expected_() except CException as e: eq_(e.value, "attribute 'i1' unknown for 'o'") for name, value in {"i0": 10, "i2": 12, "i3": 13}.items(): eq_(o.get_value(name), value) try: o.get_value("i1") exception_expected_() except CException as e: eq_(e.value, "attribute 'i1' unknown for 'o'") eq_(o.get_value("i0", t1), 10) try: o.get_value("i1", t2) exception_expected_() except CException as e: eq_(e.value, "attribute 'i1' unknown for ''") eq_(o.get_value("i2", c), 12) eq_(o.get_value("i3", sc), 13)
def test_delete_class_having_two_bundles(self): b1 = CBundle("B1") b2 = CBundle("B2") c1 = CClass(self.mcl, "c1", bundles=[b1, b2]) c2 = CClass(self.mcl, "c2", bundles=[b2]) c1.delete() eq_(set(b1.get_elements(type=CClass)), set()) eq_(set(b2.get_elements(type=CClass)), {c2}) eq_(set(c1.bundles), set()) eq_(set(c2.bundles), {b2})
def test_class_is_deleted_in_constructor(self): c1 = CClass(self.mcl, "CL1") c1.delete() try: CObject(c1, "O1") exception_expected_() except CException as e: ok_( e.value.endswith( "cannot access named element that has been deleted"))
def test_class_is_deleted_in_classifier_method(self): c1 = CClass(self.mcl, "CL1") c2 = CClass(self.mcl, "CL2") o1 = CObject(c2, "O1") c1.delete() try: o1.classifier = c1 exception_expected_() except CException as e: ok_( e.value.endswith( "cannot access named element that has been deleted"))
def test_delete_class_that_is_an_attribute_type(self): b1 = CBundle("B1") mcl = CMetaclass("MCL") cl1 = CClass(mcl, "CL1", bundles=b1) cl2 = CClass(mcl, "CL2", bundles=b1) cl3 = CClass(mcl, "CL3", bundles=b1) o3 = CObject(cl3, "O3") ea1 = CAttribute(type=cl3, default=o3) m = CMetaclass("M", bundles=b1, attributes={"o": ea1}) c = CClass(m) cl1.delete() cl3.delete() try: # we just use list here, in order to not get a warning that ea1.default has no effect list([ea1.default]) exception_expected_() except CException as e: eq_("cannot access named element that has been deleted", e.value) try: # we just use list here, in order to not get a warning that ea1.type has no effect list([ea1.type]) exception_expected_() except CException as e: eq_("cannot access named element that has been deleted", e.value) try: ea1.default = "3" exception_expected_() except CException as e: eq_("cannot access named element that has been deleted", e.value) try: ea1.type = cl1 exception_expected_() except CException as e: eq_("cannot access named element that has been deleted", e.value) try: ea1.type = cl2 exception_expected_() except CException as e: eq_("default value '' incompatible with attribute's type 'CL2'", e.value) try: c.set_value("o", CObject(cl2)) exception_expected_() except CException as e: eq_("cannot access named element that has been deleted", e.value) try: c.get_value("o") exception_expected_() except CException as e: eq_("cannot access named element that has been deleted", e.value)
def test_delete_class_instance_relation(self): cl1 = CClass(self.mcl, "CL1") cl2 = CClass(self.mcl, "CL2") obj1 = CObject(cl1, "O1") obj2 = CObject(cl1, "O2") obj3 = CObject(cl2, "O3") cl1.delete() eq_(obj1.classifier, None) eq_(obj2.classifier, None) eq_(obj3.classifier, cl2) eq_(set(cl2.objects), {obj3}) eq_(cl1.objects, [])
def test_metaclass_instance_of(self): a = CMetaclass() b = CMetaclass(superclasses=[a]) c = CMetaclass() cl = CClass(b, "C") eq_(cl.instance_of(a), True) eq_(cl.instance_of(b), True) eq_(cl.instance_of(c), False) try: cl.instance_of(cl) exception_expected_() except CException as e: eq_("'C' is not a metaclass", e.value) cl.delete() eq_(cl.instance_of(a), False)
def test_tagged_values_exceptional_cases(self): s = CStereotype("S", attributes={"b": True}) self.mcl.stereotypes = s cl1 = CClass(self.mcl, "C", stereotype_instances=s) cl1.delete() try: cl1.get_tagged_value("b") exception_expected_() except CException as e: eq_(e.value, "can't get tagged value 'b' on deleted class") try: cl1.set_tagged_value("b", 1) exception_expected_() except CException as e: eq_(e.value, "can't set tagged value 'b' on deleted class") try: cl1.delete_tagged_value("b") exception_expected_() except CException as e: eq_(e.value, "can't delete tagged value 'b' on deleted class") try: cl1.tagged_values = {"b": 1} exception_expected_() except CException as e: eq_(e.value, "can't set tagged values on deleted class") try: # we just use list here, in order to not get a warning that cl1.tagged_values has no effect list(cl1.tagged_values) exception_expected_() except CException as e: eq_(e.value, "can't get tagged values on deleted class") cl = CClass(self.mcl, "C", stereotype_instances=s) try: cl.delete_tagged_value("x") exception_expected_() except CException as e: eq_(e.value, "tagged value 'x' unknown for 'C'")
def test_attribute_values_exceptional_cases(self): mcl = CMetaclass("M", attributes={"b": True}) cl1 = CClass(mcl, "C") cl1.delete() try: cl1.get_value("b") exception_expected_() except CException as e: eq_(e.value, "can't get value 'b' on deleted class") try: cl1.set_value("b", 1) exception_expected_() except CException as e: eq_(e.value, "can't set value 'b' on deleted class") try: cl1.delete_value("b") exception_expected_() except CException as e: eq_(e.value, "can't delete value 'b' on deleted class") try: cl1.values = {"b": 1} exception_expected_() except CException as e: eq_(e.value, "can't set values on deleted class") try: # we just use list here, in order to not get a warning that cl1.values has no effect list(cl1.values) exception_expected_() except CException as e: eq_(e.value, "can't get values on deleted class") cl = CClass(mcl, "C") try: cl.delete_value("x") exception_expected_() except CException as e: eq_(e.value, "attribute 'x' unknown for 'C'")
def test_delete_class(self): cl1 = CClass(self.mcl, "CL1") cl1.delete() eq_(set(self.mcl.classes), set()) cl1 = CClass(self.mcl, "CL1") cl2 = CClass(self.mcl, "CL2") cl3 = CClass(self.mcl, "CL3", superclasses=cl2, attributes={"i": 1}) cl3.set_value("i", 7) CObject(cl3) cl1.delete() eq_(set(self.mcl.classes), {cl2, cl3}) cl3.delete() eq_(set(self.mcl.classes), {cl2}) eq_(cl3.superclasses, []) eq_(cl2.subclasses, []) eq_(cl3.attributes, []) eq_(cl3.attribute_names, []) eq_(cl3.metaclass, None) eq_(cl3.objects, []) eq_(cl3.name, None) eq_(cl3.bundles, []) try: cl3.get_value("i") exception_expected_() except CException as e: eq_("can't get value 'i' on deleted class", e.value)
def test_class_inheritance_delete_top_class(self): t = CClass(self.mcl, "T") m1 = CClass(self.mcl, "M1", superclasses=[t]) m2 = CClass(self.mcl, "M2", superclasses=[t]) b1 = CClass(self.mcl, "B1", superclasses=[m1]) b2 = CClass(self.mcl, "B2", superclasses=[m1]) b3 = CClass(self.mcl, "B3", superclasses=[t]) t.delete() eq_(t.name, None) eq_(set(t.superclasses), set()) eq_(set(t.subclasses), set()) eq_(set(t.all_superclasses), set()) eq_(set(t.all_subclasses), set()) eq_(set(m1.superclasses), set()) eq_(set(m1.subclasses), {b1, b2}) eq_(set(m1.all_superclasses), set()) eq_(set(m1.all_subclasses), {b1, b2}) eq_(set(m2.superclasses), set()) eq_(set(m2.subclasses), set()) eq_(set(m2.all_superclasses), set()) eq_(set(m2.all_subclasses), set()) eq_(set(b1.superclasses), {m1}) eq_(set(b1.subclasses), set()) eq_(set(b1.all_superclasses), {m1}) eq_(set(b1.all_subclasses), set()) eq_(set(b2.superclasses), {m1}) eq_(set(b2.subclasses), set()) eq_(set(b2.all_superclasses), {m1}) eq_(set(b2.all_subclasses), set()) eq_(set(b3.superclasses), set()) eq_(set(b3.subclasses), set()) eq_(set(b3.all_superclasses), set()) eq_(set(b3.all_subclasses), set())
def test_delete_class_from_bundle(self): b1 = CBundle("B1") cl1 = CClass(self.mcl, "CL1", bundles=b1) cl1.delete() eq_(set(b1.get_elements(type=CClass)), set()) cl1 = CClass(self.mcl, "CL1", bundles=b1) cl2 = CClass(self.mcl, "CL2", bundles=b1) cl3 = CClass(self.mcl, "CL3", superclasses=cl2, attributes={"i": 1}, bundles=b1) cl3.set_value("i", 7) CObject(cl3, bundles=b1) cl1.delete() eq_(set(b1.get_elements(type=CClass)), {cl2, cl3}) cl3.delete() eq_(set(b1.get_elements(type=CClass)), {cl2}) eq_(cl3.superclasses, []) eq_(cl2.subclasses, []) eq_(cl3.attributes, []) eq_(cl3.attribute_names, []) eq_(cl3.metaclass, None) eq_(cl3.objects, []) eq_(cl3.name, None) eq_(cl3.bundles, []) eq_(b1.get_elements(type=CObject), []) try: cl3.get_value("i") exception_expected_() except CException as e: eq_("can't get value 'i' on deleted class", e.value)
def test_class_inheritance_delete_inner_class(self): t = CClass(self.mcl, "T") m1 = CClass(self.mcl, "M1", superclasses=[t]) m2 = CClass(self.mcl, "M2", superclasses=[t]) b1 = CClass(self.mcl, "B1", superclasses=[m1]) b2 = CClass(self.mcl, "B2", superclasses=[m1]) b3 = CClass(self.mcl, "B3", superclasses=[t]) m1.delete() eq_(set(t.superclasses), set()) eq_(set(t.subclasses), {m2, b3}) eq_(set(t.all_superclasses), set()) eq_(set(t.all_subclasses), {m2, b3}) eq_(set(m1.superclasses), set()) eq_(set(m1.subclasses), set()) eq_(set(m1.all_superclasses), set()) eq_(set(m1.all_subclasses), set()) eq_(set(m2.superclasses), {t}) eq_(set(m2.subclasses), set()) eq_(set(m2.all_superclasses), {t}) eq_(set(m2.all_subclasses), set()) eq_(set(b1.superclasses), set()) eq_(set(b1.subclasses), set()) eq_(set(b1.all_superclasses), set()) eq_(set(b1.all_subclasses), set()) eq_(set(b2.superclasses), set()) eq_(set(b2.subclasses), set()) eq_(set(b2.all_superclasses), set()) eq_(set(b2.all_subclasses), set()) eq_(set(b3.superclasses), {t}) eq_(set(b3.subclasses), set()) eq_(set(b3.all_superclasses), {t}) eq_(set(b3.all_subclasses), set())
def test_link_delete_class_object(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") add_links({c1: [c2, c3]}) add_links({c4: [c3, c2]}) c2.delete() eq_(c1.linked, [c3]) eq_(c3.linked, [c1, c4]) eq_(c4.linked, [c3]) try: add_links({c1: [c2]}) exception_expected_() except CException as e: eq_(e.value, "cannot link to deleted target") try: add_links({c2: [c1]}) exception_expected_() except CException as e: eq_(e.value, "cannot link to deleted source")
def test_delete_stereotyped_element_instance(self): s1 = CStereotype("S1", extended=self.mcl) c = CClass(self.mcl, "C1", stereotype_instances=[s1]) c.delete() eq_(s1.extended_instances, []) eq_(c.stereotype_instances, [])
class TestClassAssociations: def setup(self): self.mcl = CMetaclass("MCL") self.c1 = CClass(self.mcl, "C1") self.c2 = CClass(self.mcl, "C2") self.c3 = CClass(self.mcl, "C3") self.c4 = CClass(self.mcl, "C4") self.c5 = CClass(self.mcl, "C5") def get_all_associations_of_metaclass(self): associations = [] for c in self.mcl.all_classes: for a in c.all_associations: if a not in associations: associations.append(a) return associations def test_association_creation(self): a1 = self.c1.association(self.c2, multiplicity="1", role_name="t", source_multiplicity="*", source_role_name="i") a2 = self.c1.association(self.c2, "[o]*->[s]1") a3 = self.c1.association(self.c3, "[a] 0..1 <*>- [n]*") a4 = self.c1.association(self.c3, multiplicity="*", role_name="e", source_multiplicity="0..1", source_role_name="a", composition=True) a5 = self.c4.association(self.c3, multiplicity="*", role_name="n", source_multiplicity="0..1", source_role_name="a", aggregation=True) a6 = self.c3.association(self.c2, '[a] 3 <>- [e]*') eq_(len(self.get_all_associations_of_metaclass()), 6) eq_(self.c1.associations[0].role_name, "t") eq_(a5.role_name, "n") eq_(a2.role_name, "s") eq_(a1.multiplicity, "1") eq_(a1.source_multiplicity, "*") eq_(a4.source_multiplicity, "0..1") eq_(a6.source_multiplicity, "3") eq_(a1.composition, False) eq_(a1.aggregation, False) eq_(a3.composition, True) eq_(a3.aggregation, False) eq_(a5.composition, False) eq_(a5.aggregation, True) a1.aggregation = True eq_(a1.composition, False) eq_(a1.aggregation, True) a1.composition = True eq_(a1.composition, True) eq_(a1.aggregation, False) def test_mixed_association_types(self): m1 = CMetaclass("M1") s1 = CStereotype("S1") try: self.c1.association(s1, multiplicity="1", role_name="t", source_multiplicity="*", source_role_name="i") exception_expected_() except CException as e: eq_("class 'C1' is not compatible with association target 'S1'", e.value) try: self.c1.association(m1, multiplicity="1", role_name="t", source_multiplicity="*", source_role_name="i") exception_expected_() except CException as e: eq_("class 'C1' is not compatible with association target 'M1'", e.value) def test_get_association_by_role_name(self): self.c1.association(self.c2, multiplicity="1", role_name="t", source_multiplicity="*", source_role_name="i") self.c1.association(self.c2, multiplicity="1", role_name="s", source_multiplicity="*", source_role_name="o") self.c1.association(self.c3, multiplicity="*", role_name="n", source_multiplicity="0..1", source_role_name="a", composition=True) a_2 = next(a for a in self.c1.associations if a.role_name == "s") eq_(a_2.multiplicity, "1") eq_(a_2.source_role_name, "o") eq_(a_2.source_multiplicity, "*") def test_get_association_by_name(self): self.c1.association(self.c2, name="n1", multiplicity="1", role_name="t", source_multiplicity="*", source_role_name="i") self.c1.association(self.c2, name="n2", multiplicity="1", role_name="s", source_multiplicity="*", source_role_name="o") self.c1.association(self.c3, "n3: [a] 0..1 <*>- [n] *") a_2 = next(a for a in self.c1.associations if a.name == "n2") eq_(a_2.multiplicity, "1") eq_(a_2.source_role_name, "o") eq_(a_2.source_multiplicity, "*") a_3 = next(a for a in self.c1.associations if a.name == "n3") eq_(a_3.multiplicity, "*") eq_(a_3.role_name, "n") eq_(a_3.source_multiplicity, "0..1") eq_(a_3.source_role_name, "a") eq_(a_3.composition, True) def test_get_associations(self): a1 = self.c1.association(self.c2, multiplicity="1", role_name="t", source_multiplicity="*", source_role_name="i") a2 = self.c1.association(self.c2, multiplicity="1", role_name="s", source_multiplicity="*", source_role_name="o") a3 = self.c1.association(self.c3, multiplicity="*", role_name="n", source_multiplicity="0..1", source_role_name="a", composition=True) a4 = self.c1.association(self.c3, multiplicity="*", role_name="e", source_multiplicity="0..1", source_role_name="a", composition=True) a5 = self.c4.association(self.c3, multiplicity="*", role_name="n", source_multiplicity="0..1", source_role_name="a", aggregation=True) a6 = self.c3.association(self.c2, multiplicity="*", role_name="e", source_multiplicity="3", source_role_name="a", aggregation=True) eq_(self.c1.associations, [a1, a2, a3, a4]) eq_(self.c2.associations, [a1, a2, a6]) eq_(self.c3.associations, [a3, a4, a5, a6]) eq_(self.c4.associations, [a5]) eq_(self.c5.associations, []) def test_delete_associations(self): a1 = self.c1.association(self.c2, multiplicity="1", role_name="t", source_multiplicity="*", source_role_name="i") a2 = self.c1.association(self.c2, multiplicity="1", role_name="s", source_multiplicity="*", source_role_name="o") a3 = self.c1.association(self.c3, multiplicity="*", role_name="n", source_multiplicity="0..1", source_role_name="a", composition=True) a4 = self.c1.association(self.c3, multiplicity="*", role_name="e", source_multiplicity="0..1", source_role_name="a", composition=True) a5 = self.c4.association(self.c3, multiplicity="*", role_name="n", source_multiplicity="0..1", source_role_name="a", aggregation=True) a6 = self.c3.association(self.c2, multiplicity="*", role_name="e", source_multiplicity="3", source_role_name="a", aggregation=True) a7 = self.c1.association(self.c1, multiplicity="*", role_name="x", source_multiplicity="3", source_role_name="y") eq_(len(self.get_all_associations_of_metaclass()), 7) a2.delete() a4.delete() eq_(len(self.get_all_associations_of_metaclass()), 5) eq_(self.c1.associations, [a1, a3, a7]) eq_(self.c2.associations, [a1, a6]) eq_(self.c3.associations, [a3, a5, a6]) eq_(self.c4.associations, [a5]) eq_(self.c5.associations, []) def test_delete_class_and_get_associations(self): self.c1.association(self.c2, multiplicity="1", role_name="t", source_multiplicity="*", source_role_name="i") self.c1.association(self.c2, multiplicity="1", role_name="s", source_multiplicity="*", source_role_name="o") self.c1.association(self.c3, multiplicity="*", role_name="n", source_multiplicity="0..1", source_role_name="a", composition=True) self.c1.association(self.c3, multiplicity="*", role_name="e", source_multiplicity="0..1", source_role_name="a", composition=True) a5 = self.c4.association(self.c3, multiplicity="*", role_name="n", source_multiplicity="0..1", source_role_name="a", aggregation=True) a6 = self.c3.association(self.c2, multiplicity="*", role_name="e", source_multiplicity="3", source_role_name="a", aggregation=True) self.c1.association(self.c1, multiplicity="*", role_name="x", source_multiplicity="3", source_role_name="y") eq_(len(self.get_all_associations_of_metaclass()), 7) self.c1.delete() eq_(len(self.get_all_associations_of_metaclass()), 2) eq_(self.c1.associations, []) eq_(self.c2.associations, [a6]) eq_(self.c3.associations, [a5, a6]) eq_(self.c4.associations, [a5]) eq_(self.c5.associations, []) def test_all_associations(self): s = CClass(self.mcl, "S") d = CClass(self.mcl, "D", superclasses=s) a = s.association(d, "is next: [prior s] * -> [next d] *") eq_(d.all_associations, [a]) eq_(s.all_associations, [a]) def test_get_opposite_classifier(self): a = self.c1.association(self.c2, "[o]*->[s]1") eq_(a.get_opposite_classifier(self.c1), self.c2) eq_(a.get_opposite_classifier(self.c2), self.c1) try: a.get_opposite_classifier(self.c3) exception_expected_() except CException as e: eq_("can only get opposite if either source or target classifier is provided", e.value)