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")
示例#2
0
 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")
示例#3
0
 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")
示例#5
0
 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})
示例#8
0
 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"))
示例#9
0
 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)
示例#11
0
    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)
示例#13
0
    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'")
示例#14
0
    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'")
示例#15
0
    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())
示例#19
0
    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")
示例#20
0
 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, [])
示例#21
0
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)