예제 #1
0
class TestBundlesOfStereotypes:
    def setup(self):
        self.mcl = CMetaclass("MCL")
        self.b1 = CBundle("B1")
        self.b2 = CBundle("B2")
        self.m1 = CMetaclass("M1")
        self.m2 = CMetaclass("M2")
        self.a = self.m1.association(self.m2,
                                     name="A",
                                     multiplicity="1",
                                     role_name="m1",
                                     source_multiplicity="*",
                                     source_role_name="m2")

    def test_stereotype_name_fail(self):
        try:
            # noinspection PyTypeChecker
            CStereotype(self.b1)
            exception_expected_()
        except CException as e:
            ok_(e.value.startswith("is not a name string: '"))
            ok_(e.value.endswith(" B1'"))

    def test_stereotype_defined_bundles(self):
        eq_(set(self.b1.get_elements(type=CStereotype)), set())
        s1 = CStereotype("s1", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CStereotype)), {s1})
        s2 = CStereotype("s2", bundles=[self.b1])
        s3 = CStereotype("s3", bundles=[self.b1, self.b2])
        cl = CClass(self.mcl, "C", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CStereotype)), {s1, s2, s3})
        eq_(set(self.b1.elements), {s1, s2, s3, cl})
        eq_(set(self.b2.get_elements(type=CStereotype)), {s3})
        eq_(set(self.b2.elements), {s3})

    def test_bundle_defined_stereotype(self):
        s1 = CStereotype("s1")
        s2 = CStereotype("s2")
        s3 = CStereotype("s3")
        eq_(set(self.b1.get_elements(type=CStereotype)), set())
        b1 = CBundle("B1", elements=[s1, s2, s3])
        eq_(set(b1.elements), {s1, s2, s3})
        cl = CClass(self.mcl, "C", bundles=b1)
        eq_(set(b1.elements), {s1, s2, s3, cl})
        eq_(set(b1.get_elements(type=CStereotype)), {s1, s2, s3})
        b2 = CBundle("B2")
        b2.elements = [s2, s3]
        eq_(set(b2.get_elements(type=CStereotype)), {s2, s3})
        eq_(set(s1.bundles), {b1})
        eq_(set(s2.bundles), {b1, b2})
        eq_(set(s3.bundles), {b1, b2})

    def test_get_stereotypes_by_name(self):
        eq_(set(self.b1.get_elements(type=CStereotype, name="s1")), set())
        s1 = CStereotype("s1", bundles=self.b1)
        c1 = CClass(self.mcl, "C1", bundles=self.b1)
        eq_(self.b1.get_elements(type=CClass), [c1])
        eq_(set(self.b1.get_elements(type=CStereotype, name="s1")), {s1})
        s2 = CStereotype("s1", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CStereotype, name="s1")), {s1, s2})
        ok_(s1 != s2)
        s3 = CStereotype("s1", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CStereotype, name="s1")),
            {s1, s2, s3})
        eq_(self.b1.get_element(type=CStereotype, name="s1"), s1)

    def test_get_stereotype_elements_by_name(self):
        eq_(set(self.b1.get_elements(name="s1")), set())
        s1 = CStereotype("s1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="s1")), {s1})
        c1 = CClass(self.mcl, "s1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="s1")), {s1, c1})
        s2 = CStereotype("s1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="s1")), {s1, c1, s2})
        ok_(s1 != s2)
        s3 = CStereotype("s1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="s1")), {s1, c1, s2, s3})
        eq_(self.b1.get_element(name="s1"), s1)

    def test_stereotype_defined_bundle_change(self):
        s1 = CStereotype("s1", bundles=self.b1)
        s2 = CStereotype("s2", bundles=self.b1)
        s3 = CStereotype("s3", bundles=self.b1)
        cl1 = CClass(self.mcl, "C1", bundles=self.b1)
        cl2 = CClass(self.mcl, "C2", bundles=self.b1)
        b = CBundle()
        s2.bundles = b
        s3.bundles = None
        cl2.bundles = b
        eq_(set(self.b1.elements), {cl1, s1})
        eq_(set(self.b1.get_elements(type=CStereotype)), {s1})
        eq_(set(b.elements), {s2, cl2})
        eq_(set(b.get_elements(type=CStereotype)), {s2})
        eq_(s1.bundles, [self.b1])
        eq_(s2.bundles, [b])
        eq_(s3.bundles, [])

    def test_bundle_delete_stereotype_metaclass(self):
        s1 = CStereotype("s1", bundles=self.b1, extended=self.mcl)
        eq_(s1.extended, [self.mcl])
        s2 = CStereotype("s2", bundles=self.b1)
        s3 = CStereotype("s3", bundles=self.b1)
        self.b1.delete()
        eq_(set(self.b1.elements), set())
        eq_(s1.bundles, [])
        eq_(s1.extended, [self.mcl])
        eq_(s2.bundles, [])
        eq_(s3.bundles, [])

    def test_bundle_delete_stereotype_association(self):
        s1 = CStereotype("s1", bundles=self.b1, extended=self.a)
        eq_(s1.extended, [self.a])
        s2 = CStereotype("s2", bundles=self.b1)
        s3 = CStereotype("s3", bundles=self.b1)
        self.b1.delete()
        eq_(set(self.b1.elements), set())
        eq_(s1.bundles, [])
        eq_(s1.extended, [self.a])
        eq_(s2.bundles, [])
        eq_(s3.bundles, [])

    def test_creation_of_unnamed_stereotype_in_bundle(self):
        cl = CClass(self.mcl)
        s1 = CStereotype()
        s2 = CStereotype()
        s3 = CStereotype("x")
        self.b1.elements = [s1, s2, s3, cl]
        eq_(set(self.b1.get_elements(type=CStereotype)), {s1, s2, s3})
        eq_(self.b1.get_element(name=None), s1)
        eq_(set(self.b1.get_elements(type=CStereotype, name=None)), {s1, s2})
        eq_(self.b1.get_element(name=None), s1)
        eq_(set(self.b1.get_elements(name=None)), {s1, s2, cl})

    def test_remove_stereotype_from_bundle(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        s1 = CStereotype("s1", bundles=b1)
        try:
            # noinspection PyTypeChecker
            b1.remove(None)
            exception_expected_()
        except CException as e:
            eq_("'None' is not an element of the bundle", e.value)
        try:
            b1.remove(CEnum("A"))
            exception_expected_()
        except CException as e:
            eq_("'A' is not an element of the bundle", e.value)
        try:
            b2.remove(s1)
            exception_expected_()
        except CException as e:
            eq_("'s1' is not an element of the bundle", e.value)
        b1.remove(s1)
        eq_(set(b1.get_elements(type=CStereotype)), set())

        s1 = CStereotype("s1", bundles=b1)
        s2 = CStereotype("s1", bundles=b1)
        s3 = CStereotype("s1",
                         superclasses=s2,
                         attributes={"i": 1},
                         bundles=b1,
                         extended=self.mcl)
        s4 = CStereotype("s1",
                         superclasses=s2,
                         attributes={"i": 1},
                         bundles=b1,
                         extended=self.a)

        b1.remove(s1)
        try:
            b1.remove(CStereotype("s2", bundles=b2))
            exception_expected_()
        except CException as e:
            eq_("'s2' is not an element of the bundle", e.value)
        try:
            b1.remove(s1)
            exception_expected_()
        except CException as e:
            eq_("'s1' is not an element of the bundle", e.value)

        eq_(set(b1.get_elements(type=CStereotype)), {s2, s3, s4})
        b1.remove(s3)
        b1.remove(s4)
        eq_(set(b1.get_elements(type=CStereotype)), {s2})

        eq_(s3.superclasses, [s2])
        eq_(s2.subclasses, [s3, s4])
        eq_(s3.attribute_names, ["i"])
        eq_(s3.extended, [self.mcl])
        eq_(s3.name, "s1")
        eq_(s3.bundles, [])
        eq_(s4.superclasses, [s2])
        eq_(s4.attribute_names, ["i"])
        eq_(s4.extended, [self.a])
        eq_(s4.name, "s1")
        eq_(s4.bundles, [])

    def test_delete_stereotype_from_bundle(self):
        b1 = CBundle("B1")
        s1 = CStereotype("s1", bundles=b1)
        s1.delete()
        eq_(set(b1.get_elements(type=CStereotype)), set())

        s1 = CStereotype("s1", bundles=b1)
        s2 = CStereotype("s1", bundles=b1)
        s3 = CStereotype("s1",
                         superclasses=s2,
                         attributes={"i": 1},
                         bundles=b1,
                         extended=self.mcl)
        s4 = CStereotype("s1",
                         superclasses=s2,
                         attributes={"i": 1},
                         bundles=b1,
                         extended=self.a)

        s1.delete()
        eq_(set(b1.get_elements(type=CStereotype)), {s2, s3, s4})
        s3.delete()
        s4.delete()
        eq_(set(b1.get_elements(type=CStereotype)), {s2})

        eq_(s3.superclasses, [])
        eq_(s2.subclasses, [])
        eq_(s3.attributes, [])
        eq_(s3.attribute_names, [])
        eq_(s3.extended, [])
        eq_(s3.name, None)
        eq_(s3.bundles, [])

        eq_(s4.superclasses, [])
        eq_(s4.attributes, [])
        eq_(s4.attribute_names, [])
        eq_(s4.extended, [])
        eq_(s4.name, None)
        eq_(s4.bundles, [])

    def test_remove_bundle_from_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        s1 = CStereotype("s1", bundles=[b1, b2])
        b1.remove(s1)
        eq_(set(b1.get_elements(type=CStereotype)), set())
        eq_(set(b2.get_elements(type=CStereotype)), {s1})
        eq_(set(s1.bundles), {b2})

    def test_delete_bundle_from_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        s1 = CStereotype("s1", bundles=[b1, b2])
        b1.delete()
        eq_(set(b1.get_elements(type=CStereotype)), set())
        eq_(set(b2.get_elements(type=CStereotype)), {s1})
        eq_(set(s1.bundles), {b2})

    def test_delete_stereotype_having_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        s1 = CStereotype("s1", bundles=[b1, b2])
        s2 = CStereotype("s2", bundles=[b2])
        s1.delete()
        eq_(set(b1.get_elements(type=CStereotype)), set())
        eq_(set(b2.get_elements(type=CStereotype)), {s2})
        eq_(set(s1.bundles), set())
        eq_(set(s2.bundles), {b2})

    def test_stereotype_remove_stereotype_or_metaclass(self):
        mcl = CMetaclass("MCL1")
        s1 = CStereotype("S1", extended=[mcl])
        s2 = CStereotype("S2", extended=[mcl])
        s3 = CStereotype("S3", extended=[mcl])
        s4 = CStereotype("S4", extended=[mcl])
        self.b1.elements = [mcl, s1, s2, s3, s4]
        eq_(set(self.b1.get_elements(type=CStereotype)), {s1, s2, s3, s4})
        s2.delete()
        eq_(set(self.b1.get_elements(type=CStereotype)), {s1, s3, s4})
        eq_(set(s2.extended), set())
        eq_(set(s1.extended), {mcl})
        mcl.delete()
        eq_(set(mcl.stereotypes), set())
        eq_(set(s1.extended), set())
        eq_(set(self.b1.get_elements(type=CStereotype)), {s1, s3, s4})

    def test_double_assignment_stereotype_extension_metaclass(self):
        try:
            CStereotype("S1", bundles=self.b1, extended=[self.mcl, self.mcl])
            exception_expected_()
        except CException as e:
            eq_("'MCL' is already extended by stereotype 'S1'", e.value)
        s1 = self.b1.get_element(type=CStereotype, name="S1")
        eq_(s1.name, "S1")
        eq_(set(self.b1.get_elements(type=CStereotype)), {s1})
        eq_(s1.bundles, [self.b1])
        eq_(self.mcl.stereotypes, [s1])

    def test_double_assignment_stereotype_extension_association(self):
        try:
            CStereotype("S1", bundles=self.b1, extended=[self.a, self.a])
            exception_expected_()
        except CException as e:
            eq_("'A' is already extended by stereotype 'S1'", e.value)
        s1 = self.b1.get_element(type=CStereotype, name="S1")
        eq_(s1.name, "S1")
        eq_(set(self.b1.get_elements(type=CStereotype)), {s1})
        eq_(s1.bundles, [self.b1])
        eq_(self.a.stereotypes, [s1])

    def test_double_assignment_metaclass_stereotype(self):
        try:
            s1 = CStereotype("S1", bundles=self.b1)
            self.mcl.stereotypes = [s1, s1]
            exception_expected_()
        except CException as e:
            eq_("'S1' is already a stereotype of 'MCL'", e.value)
        s1 = self.b1.get_element(type=CStereotype, name="S1")
        eq_(s1.name, "S1")
        eq_(set(self.b1.get_elements(type=CStereotype)), {s1})

    def test_double_assignment_association_stereotype(self):
        try:
            s1 = CStereotype("S1", bundles=self.b1)
            self.a.stereotypes = [s1, s1]
            exception_expected_()
        except CException as e:
            eq_("'S1' is already a stereotype of 'A'", e.value)
        s1 = self.b1.get_element(type=CStereotype, name="S1")
        eq_(s1.name, "S1")
        eq_(set(self.b1.get_elements(type=CStereotype)), {s1})

    def test_bundle_that_is_deleted(self):
        b1 = CBundle("B1")
        b1.delete()
        try:
            CStereotype("S1", bundles=b1)
            exception_expected_()
        except CException as e:
            eq_(e.value, "cannot access named element that has been deleted")

    def test_set_bundle_to_none(self):
        s = CStereotype("S1", bundles=None)
        eq_(s.bundles, [])
        eq_(s.name, "S1")
class TestBundlesOfClasses:
    def setup(self):
        self.mcl = CMetaclass("MCL", attributes={"i": 1})
        self.b1 = CBundle("B1")
        self.b2 = CBundle("B2")

    def test_class_name_fail(self):
        try:
            # noinspection PyTypeChecker
            CClass(self.mcl, self.mcl)
            exception_expected_()
        except CException as e:
            ok_(e.value.startswith("is not a name string: '"))
            ok_(e.value.endswith(" MCL'"))

    def test_class_defined_bundles(self):
        eq_(set(self.b1.get_elements()), set())
        cl1 = CClass(self.mcl, "Class1", bundles=self.b1)
        eq_(set(self.b1.get_elements()), {cl1})
        cl2 = CClass(self.mcl, "Class2", bundles=[self.b1])
        cl3 = CClass(self.mcl, "Class3", bundles=[self.b1, self.b2])
        mcl = CMetaclass("MCL", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CClass)), {cl1, cl2, cl3})
        eq_(set(self.b1.elements), {cl1, cl2, cl3, mcl})
        eq_(set(self.b2.get_elements(type=CClass)), {cl3})
        eq_(set(self.b2.elements), {cl3})

    def test_bundle_defined_classes(self):
        cl1 = CClass(self.mcl, "Class1")
        cl2 = CClass(self.mcl, "Class2")
        cl3 = CClass(self.mcl, "Class3")
        eq_(set(self.b1.get_elements(type=CClass)), set())
        b1 = CBundle("B1", elements=[cl1, cl2, cl3])
        eq_(set(b1.elements), {cl1, cl2, cl3})
        self.mcl.bundles = b1
        eq_(set(b1.elements), {cl1, cl2, cl3, self.mcl})
        eq_(set(b1.get_elements(type=CClass)), {cl1, cl2, cl3})
        b2 = CBundle("B2")
        b2.elements = [cl2, cl3]
        eq_(set(b2.get_elements(type=CClass)), {cl2, cl3})
        eq_(set(cl1.bundles), {b1})
        eq_(set(cl2.bundles), {b1, b2})
        eq_(set(cl3.bundles), {b1, b2})

    def test_get_classes_by_name(self):
        eq_(set(self.b1.get_elements(type=CClass, name="CL1")), set())
        c1 = CClass(self.mcl, "CL1", bundles=self.b1)
        m = CMetaclass("CL1", bundles=self.b1)
        eq_(self.b1.get_elements(type=CMetaclass), [m])
        eq_(set(self.b1.get_elements(type=CClass, name="CL1")), {c1})
        c2 = CClass(self.mcl, "CL1", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CClass, name="CL1")), {c1, c2})
        ok_(c1 != c2)
        c3 = CClass(self.mcl, "CL1", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CClass, name="CL1")), {c1, c2, c3})
        eq_(self.b1.get_element(type=CClass, name="CL1"), c1)

    def test_get_class_elements_by_name(self):
        eq_(set(self.b1.get_elements(name="CL1")), set())
        c1 = CClass(self.mcl, "CL1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="CL1")), {c1})
        m = CMetaclass("CL1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="CL1")), {m, c1})
        c2 = CClass(self.mcl, "CL1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="CL1")), {m, c1, c2})
        ok_(c1 != c2)
        c3 = CClass(self.mcl, "CL1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="CL1")), {m, c1, c2, c3})
        eq_(self.b1.get_element(name="CL1"), c1)

    def test_class_defined_bundle_change(self):
        cl1 = CClass(self.mcl, "Class1", bundles=self.b1)
        cl2 = CClass(self.mcl, "Class2", bundles=self.b1)
        cl3 = CClass(self.mcl, "Class3", bundles=self.b1)
        mcl = CMetaclass("MCL", bundles=self.b1)
        b = CBundle()
        cl2.bundles = b
        cl3.bundles = None
        self.mcl.bundles = b
        eq_(set(self.b1.elements), {mcl, cl1})
        eq_(set(self.b1.get_elements(type=CClass)), {cl1})
        eq_(set(b.elements), {cl2, self.mcl})
        eq_(set(b.get_elements(type=CClass)), {cl2})
        eq_(cl1.bundles, [self.b1])
        eq_(cl2.bundles, [b])
        eq_(cl3.bundles, [])

    def test_bundle_delete_class(self):
        cl1 = CClass(self.mcl, "Class1", bundles=self.b1)
        cl2 = CClass(self.mcl, "Class2", bundles=self.b1)
        cl3 = CClass(self.mcl, "Class3", bundles=self.b1)
        self.b1.delete()
        eq_(set(self.b1.elements), set())
        eq_(cl1.bundles, [])
        eq_(cl1.metaclass, self.mcl)
        eq_(cl2.bundles, [])
        eq_(cl3.bundles, [])

    def test_creation_of_unnamed_class_in_bundle(self):
        c1 = CClass(self.mcl)
        c2 = CClass(self.mcl)
        c3 = CClass(self.mcl, "x")
        mcl = CMetaclass()
        self.b1.elements = [c1, c2, c3, mcl]
        eq_(set(self.b1.get_elements(type=CClass)), {c1, c2, c3})
        eq_(self.b1.get_element(type=CClass, name=None), c1)
        eq_(set(self.b1.get_elements(type=CClass, name=None)), {c1, c2})
        eq_(set(self.b1.get_elements(name=None)), {c1, c2, mcl})

    def test_remove_class_from_bundle(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        cl1 = CClass(self.mcl, "CL1", bundles=b1)
        try:
            # noinspection PyTypeChecker
            b1.remove(None)
            exception_expected_()
        except CException as e:
            eq_("'None' is not an element of the bundle", e.value)
        try:
            b1.remove(CEnum("A"))
            exception_expected_()
        except CException as e:
            eq_("'A' is not an element of the bundle", e.value)
        try:
            b2.remove(cl1)
            exception_expected_()
        except CException as e:
            eq_("'CL1' is not an element of the bundle", e.value)
        b1.remove(cl1)
        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)
        o = CObject(cl3, bundles=b1)

        b1.remove(cl1)
        try:
            b1.remove(CClass(CMetaclass("MCL", bundles=b2), "CL2", bundles=b2))
            exception_expected_()
        except CException as e:
            eq_("'CL2' is not an element of the bundle", e.value)
        try:
            b1.remove(cl1)
            exception_expected_()
        except CException as e:
            eq_("'CL1' is not an element of the bundle", e.value)

        eq_(set(b1.get_elements(type=CClass)), {cl2, cl3})
        b1.remove(cl3)
        eq_(set(b1.get_elements(type=CClass)), {cl2})

        eq_(cl3.superclasses, [cl2])
        eq_(cl2.subclasses, [cl3])
        eq_(cl3.attribute_names, ["i"])
        eq_(cl3.metaclass, self.mcl)
        eq_(cl3.objects, [o])
        eq_(cl3.name, "CL3")
        eq_(cl3.bundles, [])
        eq_(b1.get_elements(type=CObject), [o])
        eq_(cl3.get_value("i"), 7)

    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_remove_bundle_from_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        c1 = CClass(self.mcl, "c1", bundles=[b1, b2])
        b1.remove(c1)
        eq_(set(b1.get_elements(type=CClass)), set())
        eq_(set(b2.get_elements(type=CClass)), {c1})
        eq_(set(c1.bundles), {b2})

    def test_delete_bundle_from_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        c1 = CClass(self.mcl, "c1", bundles=[b1, b2])
        b1.delete()
        eq_(set(b1.get_elements(type=CClass)), set())
        eq_(set(b2.get_elements(type=CClass)), {c1})
        eq_(set(c1.bundles), {b2})

    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_delete_class_that_is_an_attribute_type(self):
        b1 = CBundle("B1")
        cl1 = CClass(self.mcl, "CL1", bundles=b1)
        cl2 = CClass(self.mcl, "CL2", bundles=b1)
        cl3 = CClass(self.mcl, "CL3", bundles=b1)
        o3 = CObject(cl3, "O3")

        ea1 = CAttribute(type=cl3, default=o3)
        c = CClass(self.mcl, "C", bundles=b1, attributes={"o": ea1})
        o = CObject(c)
        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:
            o.set_value("o", CObject(cl2))
            exception_expected_()
        except CException as e:
            eq_("cannot access named element that has been deleted", e.value)
        try:
            o.get_value("o")
            exception_expected_()
        except CException as e:
            eq_("cannot access named element that has been deleted", e.value)

    def test_bundle_that_is_deleted(self):
        b1 = CBundle("B1")
        CBundle("B2")
        b1.delete()
        try:
            CClass(self.mcl, "CL1", bundles=b1)
            exception_expected_()
        except CException as e:
            eq_(e.value, "cannot access named element that has been deleted")

    def test_set_bundle_to_none(self):
        c = CClass(self.mcl, "C", bundles=None)
        eq_(c.bundles, [])
        eq_(c.name, "C")

    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_bundle_elements_that_are_none(self):
        try:
            CBundle("B1", elements=[None])
            exception_expected_()
        except CException as e:
            eq_(e.value, "'None' cannot be an element of bundle")
예제 #3
0
class TestBundles:
    def setup(self):
        self.mcl = CMetaclass("MCL")
        self.b1 = CBundle("B1")

    def test_bundle_name_fail(self):
        try:
            # noinspection PyTypeChecker
            CBundle(self.mcl)
            exception_expected_()
        except CException as e:
            ok_(e.value.startswith("is not a name string: '"))
            ok_(e.value.endswith(" MCL'"))

    def test_get_elements_wrong_kw_arg(self):
        try:
            self.b1.get_elements(x=CBundle)
            exception_expected_()
        except CException as e:
            eq_(e.value, "unknown argument to getElements: 'x'")

    def test_get_element_wrong_kw_arg(self):
        try:
            self.b1.get_element(x=CBundle)
            exception_expected_()
        except CException as e:
            eq_(e.value, "unknown argument to getElements: 'x'")

    def test_package_and_layer_subclasses(self):
        layer1 = CLayer("L1")
        layer2 = CLayer("L2", sub_layer=layer1)
        package1 = CPackage("P1")
        c1 = CClass(self.mcl, "C1")
        c2 = CClass(self.mcl, "C2")
        c3 = CClass(self.mcl, "C3")
        layer1.elements = [c1, c2]
        layer2.elements = [c3]
        package1.elements = [layer1, layer2
                             ] + layer1.elements + layer2.elements
        eq_(set(package1.elements), {layer1, layer2, c1, c2, c3})
        eq_(set(layer1.elements), {c1, c2})
        eq_(set(layer2.elements), {c3})
        eq_(set(c1.bundles), {layer1, package1})
        eq_(set(c2.bundles), {layer1, package1})
        eq_(set(c3.bundles), {layer2, package1})

    def test_layer_sub_layers(self):
        layer1 = CLayer("L1")
        eq_(layer1.super_layer, None)
        eq_(layer1.sub_layer, None)

        layer1 = CLayer("L1", sub_layer=None)
        eq_(layer1.super_layer, None)
        eq_(layer1.sub_layer, None)

        layer2 = CLayer("L2", sub_layer=layer1)
        eq_(layer1.super_layer, layer2)
        eq_(layer1.sub_layer, None)
        eq_(layer2.super_layer, None)
        eq_(layer2.sub_layer, layer1)

        layer3 = CLayer("L3", sub_layer=layer1)
        eq_(layer1.super_layer, layer3)
        eq_(layer1.sub_layer, None)
        eq_(layer2.super_layer, None)
        eq_(layer2.sub_layer, None)
        eq_(layer3.super_layer, None)
        eq_(layer3.sub_layer, layer1)

        layer3.sub_layer = layer2
        eq_(layer1.super_layer, None)
        eq_(layer1.sub_layer, None)
        eq_(layer2.super_layer, layer3)
        eq_(layer2.sub_layer, None)
        eq_(layer3.super_layer, None)
        eq_(layer3.sub_layer, layer2)

        layer2.sub_layer = layer1
        eq_(layer1.super_layer, layer2)
        eq_(layer1.sub_layer, None)
        eq_(layer2.super_layer, layer3)
        eq_(layer2.sub_layer, layer1)
        eq_(layer3.super_layer, None)
        eq_(layer3.sub_layer, layer2)

    def test_layer_super_layers(self):
        layer1 = CLayer("L1")
        eq_(layer1.super_layer, None)
        eq_(layer1.sub_layer, None)

        layer1 = CLayer("L1", super_layer=None)
        eq_(layer1.super_layer, None)
        eq_(layer1.sub_layer, None)

        layer2 = CLayer("L2", super_layer=layer1)
        eq_(layer1.super_layer, None)
        eq_(layer1.sub_layer, layer2)
        eq_(layer2.super_layer, layer1)
        eq_(layer2.sub_layer, None)

        layer3 = CLayer("L3", super_layer=layer1)
        eq_(layer1.super_layer, None)
        eq_(layer1.sub_layer, layer3)
        eq_(layer2.super_layer, None)
        eq_(layer2.sub_layer, None)
        eq_(layer3.super_layer, layer1)
        eq_(layer3.sub_layer, None)

        layer3.super_layer = layer2
        eq_(layer1.super_layer, None)
        eq_(layer1.sub_layer, None)
        eq_(layer2.super_layer, None)
        eq_(layer2.sub_layer, layer3)
        eq_(layer3.super_layer, layer2)
        eq_(layer3.sub_layer, None)

        layer2.super_layer = layer1
        eq_(layer1.super_layer, None)
        eq_(layer1.sub_layer, layer2)
        eq_(layer2.super_layer, layer1)
        eq_(layer2.sub_layer, layer3)
        eq_(layer3.super_layer, layer2)
        eq_(layer3.sub_layer, None)
class TestBundlesOfMetaclasses:
    def setup(self):
        self.b1 = CBundle("B1")
        self.b2 = CBundle("B2")

    def test_metaclass_name_fail(self):
        try:
            # noinspection PyTypeChecker
            CMetaclass(self.b1)
            exception_expected_()
        except CException as e:
            ok_(e.value.startswith("is not a name string: '"))
            ok_(e.value.endswith(" B1'"))

    def test_metaclass_defined_bundles(self):
        eq_(set(self.b1.get_elements()), set())
        m1 = CMetaclass("M1", bundles=self.b1)
        eq_(set(self.b1.get_elements()), {m1})
        m2 = CMetaclass("M2", bundles=[self.b1])
        m3 = CMetaclass("M3", bundles=[self.b1, self.b2])
        cl = CClass(m1, "C", bundles=[self.b1, self.b2])
        eq_(set(self.b1.get_elements(type=CMetaclass)), {m1, m2, m3})
        eq_(set(self.b1.elements), {m1, m2, m3, cl})
        eq_(set(self.b2.get_elements(type=CMetaclass)), {m3})
        eq_(set(self.b2.elements), {m3, cl})

    def test_bundle_defined_metaclasses(self):
        m1 = CMetaclass("M1")
        m2 = CMetaclass("M2")
        m3 = CMetaclass("M3")
        eq_(set(self.b1.get_elements(type=CMetaclass)), set())
        b1 = CBundle("B1", elements=[m1, m2, m3])
        eq_(set(b1.elements), {m1, m2, m3})
        cl = CClass(m1, "C", bundles=b1)
        eq_(set(b1.elements), {m1, m2, m3, cl})
        eq_(set(b1.get_elements(type=CMetaclass)), {m1, m2, m3})
        b2 = CBundle("B2")
        b2.elements = [m2, m3]
        eq_(set(b2.get_elements(type=CMetaclass)), {m2, m3})
        eq_(set(m1.bundles), {b1})
        eq_(set(m2.bundles), {b1, b2})
        eq_(set(m3.bundles), {b1, b2})

    def test_get_metaclasses_by_name(self):
        eq_(set(self.b1.get_elements(type=CMetaclass, name="m1")), set())
        m1 = CMetaclass("M1", bundles=self.b1)
        c1 = CClass(m1, "C1", bundles=self.b1)
        eq_(self.b1.get_elements(type=CClass), [c1])
        eq_(set(self.b1.get_elements(type=CMetaclass, name="M1")), {m1})
        m2 = CMetaclass("M1", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CMetaclass, name="M1")), {m1, m2})
        ok_(m1 != m2)
        m3 = CMetaclass("M1", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CMetaclass, name="M1")),
            {m1, m2, m3})
        eq_(self.b1.get_element(type=CMetaclass, name="M1"), m1)

    def test_get_metaclass_elements_by_name(self):
        eq_(set(self.b1.get_elements(name="M1")), set())
        m1 = CMetaclass("M1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="M1")), {m1})
        c1 = CClass(m1, "M1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="M1")), {m1, c1})
        m2 = CMetaclass("M1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="M1")), {m1, c1, m2})
        ok_(m1 != m2)
        m3 = CMetaclass("M1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="M1")), {m1, c1, m2, m3})
        eq_(self.b1.get_element(name="M1"), m1)

    def test_metaclass_defined_bundle_change(self):
        m1 = CMetaclass("M1", bundles=self.b1)
        m2 = CMetaclass("M2", bundles=self.b1)
        m3 = CMetaclass("M3", bundles=self.b1)
        cl1 = CClass(m1, "C1", bundles=self.b1)
        cl2 = CClass(m1, "C2", bundles=self.b1)
        b = CBundle()
        m2.bundles = b
        m3.bundles = None
        cl2.bundles = b
        eq_(set(self.b1.elements), {cl1, m1})
        eq_(set(self.b1.get_elements(type=CMetaclass)), {m1})
        eq_(set(b.elements), {m2, cl2})
        eq_(set(b.get_elements(type=CMetaclass)), {m2})
        eq_(m1.bundles, [self.b1])
        eq_(m2.bundles, [b])
        eq_(m3.bundles, [])

    def test_bundle_delete_metaclass(self):
        m1 = CMetaclass("M1", bundles=self.b1)
        c = CClass(m1)
        eq_(m1.classes, [c])
        m2 = CMetaclass("M2", bundles=self.b1)
        m3 = CMetaclass("M3", bundles=self.b1)
        self.b1.delete()
        eq_(set(self.b1.elements), set())
        eq_(m1.bundles, [])
        eq_(m1.classes, [c])
        eq_(m2.bundles, [])
        eq_(m3.bundles, [])

    def test_creation_of_unnamed_metaclass_in_bundle(self):
        m1 = CMetaclass()
        m2 = CMetaclass()
        m3 = CMetaclass("x")
        cl = CClass(m1)
        self.b1.elements = [m1, m2, m3, cl]
        eq_(set(self.b1.get_elements(type=CMetaclass)), {m1, m2, m3})
        eq_(self.b1.get_element(name=None), m1)
        eq_(set(self.b1.get_elements(type=CMetaclass, name=None)), {m1, m2})
        eq_(set(self.b1.get_elements(name=None)), {m1, m2, cl})

    def test_remove_metaclass_from_bundle(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        m1 = CMetaclass("M1", bundles=b1)
        try:
            # noinspection PyTypeChecker
            b1.remove(None)
            exception_expected_()
        except CException as e:
            eq_("'None' is not an element of the bundle", e.value)
        try:
            b1.remove(CEnum("A"))
            exception_expected_()
        except CException as e:
            eq_("'A' is not an element of the bundle", e.value)
        try:
            b2.remove(m1)
            exception_expected_()
        except CException as e:
            eq_("'M1' is not an element of the bundle", e.value)
        b1.remove(m1)
        eq_(set(b1.get_elements(type=CMetaclass)), set())

        m1 = CMetaclass("M1", bundles=b1)
        m2 = CMetaclass("M1", bundles=b1)
        m3 = CMetaclass("M1", superclasses=m2, attributes={"i": 1}, bundles=b1)
        c = CClass(m3, bundles=b1)

        b1.remove(m1)
        try:
            b1.remove(CMetaclass("M2", bundles=b2))
            exception_expected_()
        except CException as e:
            eq_("'M2' is not an element of the bundle", e.value)
        try:
            b1.remove(m1)
            exception_expected_()
        except CException as e:
            eq_("'M1' is not an element of the bundle", e.value)

        eq_(set(b1.get_elements(type=CMetaclass)), {m2, m3})
        b1.remove(m3)
        eq_(set(b1.get_elements(type=CMetaclass)), {m2})

        eq_(m3.superclasses, [m2])
        eq_(m2.subclasses, [m3])
        eq_(m3.attribute_names, ["i"])
        eq_(m3.classes, [c])
        eq_(m3.name, "M1")
        eq_(m3.bundles, [])
        eq_(b1.get_elements(type=CClass), [c])

    def test_delete_metaclass_from_bundle(self):
        b1 = CBundle("B1")
        CBundle("B2")
        m1 = CMetaclass("M1", bundles=b1)
        m1.delete()
        eq_(set(b1.get_elements(type=CMetaclass)), set())

        m1 = CMetaclass("M1", bundles=b1)
        m2 = CMetaclass("M1", bundles=b1)
        m3 = CMetaclass("M1", superclasses=m2, attributes={"i": 1}, bundles=b1)
        CClass(m3, bundles=b1)
        m1.delete()
        eq_(set(b1.get_elements(type=CMetaclass)), {m2, m3})
        m3.delete()
        eq_(set(b1.get_elements(type=CMetaclass)), {m2})

        eq_(m3.superclasses, [])
        eq_(m2.subclasses, [])
        eq_(m3.attributes, [])
        eq_(m3.attribute_names, [])
        eq_(m3.classes, [])
        eq_(m3.name, None)
        eq_(m3.bundles, [])
        eq_(b1.get_elements(type=CClass), [])

    def test_remove_bundle_from_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        m1 = CMetaclass("m1", bundles=[b1, b2])
        b1.remove(m1)
        eq_(set(b1.get_elements(type=CMetaclass)), set())
        eq_(set(b2.get_elements(type=CMetaclass)), {m1})
        eq_(set(m1.bundles), {b2})

    def test_delete_bundle_from_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        m1 = CMetaclass("m1", bundles=[b1, b2])
        b1.delete()
        eq_(set(b1.get_elements(type=CMetaclass)), set())
        eq_(set(b2.get_elements(type=CMetaclass)), {m1})
        eq_(set(m1.bundles), {b2})

    def test_delete_metaclass_having_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        m1 = CMetaclass("m1", bundles=[b1, b2])
        m2 = CMetaclass("m2", bundles=[b2])
        m1.delete()
        eq_(set(b1.get_elements(type=CMetaclass)), set())
        eq_(set(b2.get_elements(type=CMetaclass)), {m2})
        eq_(set(m1.bundles), set())
        eq_(set(m2.bundles), {b2})

    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_bundle_that_is_deleted(self):
        b1 = CBundle("B1")
        b1.delete()
        try:
            CMetaclass("M", bundles=b1)
            exception_expected_()
        except CException as e:
            eq_(e.value, "cannot access named element that has been deleted")

    def test_set_bundle_to_none(self):
        c = CMetaclass("M", bundles=None)
        eq_(c.bundles, [])
        eq_(c.name, "M")
예제 #5
0
class TestBundlesOfEnums:
    def setup(self):
        self.mcl = CMetaclass("MCL")
        self.b1 = CBundle("B1")
        self.b2 = CBundle("B2")

    def test_enum_name_fail(self):
        try:
            # noinspection PyTypeChecker
            CEnum(self.mcl)
            exception_expected_()
        except CException as e:
            ok_(e.value.startswith("is not a name string: '"))
            ok_(e.value.endswith(" MCL'"))

    def test_enum_defined_bundles(self):
        eq_(set(self.b1.get_elements()), set())
        e1 = CEnum("E1", values=["A", "B", "C"], bundles=self.b1)
        eq_(set(self.b1.get_elements()), {e1})
        e2 = CEnum("E2", values=["A", "B", "C"], bundles=[self.b1])
        e3 = CEnum("E3", values=["A", "B", "C"], bundles=[self.b1, self.b2])
        mcl = CMetaclass("MCL", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CEnum)), {e1, e2, e3})
        eq_(set(self.b1.elements), {e1, e2, e3, mcl})
        eq_(set(self.b2.get_elements(type=CEnum)), {e3})
        eq_(set(self.b2.elements), {e3})

    def test_bundle_defined_enums(self):
        e1 = CEnum("E1", values=["A", "B", "C"])
        e2 = CEnum("E2", values=["A", "B", "C"])
        e3 = CEnum("E3", values=["A", "B", "C"])
        eq_(set(self.b1.get_elements(type=CEnum)), set())
        b1 = CBundle("B1", elements=[e1, e2, e3])
        eq_(set(b1.elements), {e1, e2, e3})
        self.mcl.bundles = b1
        eq_(set(b1.elements), {e1, e2, e3, self.mcl})
        eq_(set(b1.get_elements(type=CEnum)), {e1, e2, e3})
        b2 = CBundle("B2")
        b2.elements = [e2, e3]
        eq_(set(b2.get_elements(type=CEnum)), {e2, e3})
        eq_(set(e1.bundles), {b1})
        eq_(set(e2.bundles), {b1, b2})
        eq_(set(e3.bundles), {b1, b2})

    def test_get_enums_by_name(self):
        eq_(set(self.b1.get_elements(type=CEnum, name="E1")), set())
        e1 = CEnum("E1", bundles=self.b1)
        m = CMetaclass("E1", bundles=self.b1)
        eq_(self.b1.get_elements(type=CMetaclass), [m])
        eq_(set(self.b1.get_elements(type=CEnum, name="E1")), {e1})
        e2 = CEnum("E1", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CEnum, name="E1")), {e1, e2})
        ok_(e1 != e2)
        e3 = CEnum("E1", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CEnum, name="E1")), {e1, e2, e3})
        eq_(self.b1.get_element(type=CEnum, name="E1"), e1)

    def test_get_enum_elements_by_name(self):
        eq_(set(self.b1.get_elements(name="E1")), set())
        e1 = CEnum("E1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="E1")), {e1})
        m = CMetaclass("E1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="E1")), {m, e1})
        e2 = CEnum("E1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="E1")), {m, e1, e2})
        ok_(e1 != e2)
        e3 = CEnum("E1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="E1")), {m, e1, e2, e3})
        eq_(self.b1.get_element(name="E1"), e1)

    def test_enum_defined_bundle_change(self):
        e1 = CEnum("E1", bundles=self.b1)
        e2 = CEnum("E2", bundles=self.b1)
        e3 = CEnum("E3", bundles=self.b1)
        mcl = CMetaclass("MCL", bundles=self.b1)
        b = CBundle()
        e2.bundles = b
        e3.bundles = None
        self.mcl.bundles = b
        eq_(set(self.b1.elements), {mcl, e1})
        eq_(set(self.b1.get_elements(type=CEnum)), {e1})
        eq_(set(b.elements), {e2, self.mcl})
        eq_(set(b.get_elements(type=CEnum)), {e2})
        eq_(e1.bundles, [self.b1])
        eq_(e2.bundles, [b])
        eq_(e3.bundles, [])

    def test_bundle_delete_enum(self):
        e1 = CEnum("E1", bundles=self.b1)
        e2 = CEnum("E2", bundles=self.b1)
        e3 = CEnum("E3", bundles=self.b1)
        self.b1.delete()
        eq_(set(self.b1.elements), set())
        eq_(e1.bundles, [])
        eq_(e1.name, "E1")
        eq_(e2.bundles, [])
        eq_(e3.bundles, [])

    def test_creation_of_unnamed_enum_in_bundle(self):
        e1 = CEnum()
        e2 = CEnum()
        e3 = CEnum("x")
        mcl = CMetaclass()
        self.b1.elements = [e1, e2, e3, mcl]
        eq_(set(self.b1.get_elements(type=CEnum)), {e1, e2, e3})
        eq_(self.b1.get_element(type=CEnum, name=None), e1)
        eq_(set(self.b1.get_elements(type=CEnum, name=None)), {e1, e2})
        eq_(set(self.b1.get_elements(name=None)), {e1, e2, mcl})

    def test_remove_enum_from_bundle(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        e1 = CEnum("E1", bundles=b1)
        try:
            # noinspection PyTypeChecker
            b1.remove(None)
            exception_expected_()
        except CException as e:
            eq_("'None' is not an element of the bundle", e.value)
        try:
            b1.remove(CEnum("A"))
            exception_expected_()
        except CException as e:
            eq_("'A' is not an element of the bundle", e.value)
        try:
            b2.remove(e1)
            exception_expected_()
        except CException as e:
            eq_("'E1' is not an element of the bundle", e.value)
        b1.remove(e1)
        eq_(set(b1.get_elements(type=CEnum)), set())

        e1 = CEnum("E1", bundles=b1)
        e2 = CEnum("E2", bundles=b1)
        e3 = CEnum("E3", values=["1", "2"], bundles=b1)

        b1.remove(e1)
        try:
            b1.remove(CEnum("E2", bundles=b2))
            exception_expected_()
        except CException as e:
            eq_("'E2' is not an element of the bundle", e.value)
        try:
            b1.remove(e1)
            exception_expected_()
        except CException as e:
            eq_("'E1' is not an element of the bundle", e.value)

        eq_(set(b1.get_elements(type=CEnum)), {e2, e3})
        b1.remove(e3)
        eq_(set(b1.get_elements(type=CEnum)), {e2})

        eq_(e3.name, "E3")
        eq_(e3.bundles, [])
        eq_(e3.values, ["1", "2"])

    def test_delete_enum_from_bundle(self):
        b1 = CBundle("B1")
        e1 = CEnum("E1", bundles=b1)
        e1.delete()
        eq_(set(b1.get_elements(type=CEnum)), set())

        e1 = CEnum("E1", bundles=b1)
        e2 = CEnum("E2", bundles=b1)
        e3 = CEnum("E3", values=["1", "2"], bundles=b1)
        ea1 = CAttribute(type=e3, default="1")
        ea2 = CAttribute(type=e3)
        cl = CClass(self.mcl, attributes={"letters1": ea1, "letters2": ea2})
        o = CObject(cl, "o")

        e1.delete()
        eq_(set(b1.get_elements(type=CEnum)), {e2, e3})
        e3.delete()
        eq_(set(b1.get_elements(type=CEnum)), {e2})

        eq_(e3.name, None)
        eq_(e3.bundles, [])
        eq_(e3.values, [])
        eq_(set(cl.attributes), {ea1, ea2})
        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 = e1
            exception_expected_()
        except CException as e:
            eq_("cannot access named element that has been deleted", e.value)
        try:
            ea1.type = e2
            exception_expected_()
        except CException as e:
            eq_("default value '1' incompatible with attribute's type 'E2'",
                e.value)
        try:
            o.set_value("letters1", "1")
            exception_expected_()
        except CException as e:
            eq_("cannot access named element that has been deleted", e.value)
        try:
            o.get_value("letters1")
            exception_expected_()
        except CException as e:
            eq_("cannot access named element that has been deleted", e.value)

    def test_remove_bundle_from_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        e1 = CEnum("e1", bundles=[b1, b2])
        b1.remove(e1)
        eq_(set(b1.get_elements(type=CEnum)), set())
        eq_(set(b2.get_elements(type=CEnum)), {e1})
        eq_(set(e1.bundles), {b2})

    def test_delete_bundle_from_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        e1 = CEnum("e1", bundles=[b1, b2])
        b1.delete()
        eq_(set(b1.get_elements(type=CEnum)), set())
        eq_(set(b2.get_elements(type=CEnum)), {e1})
        eq_(set(e1.bundles), {b2})

    def test_delete_enum_having_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        e1 = CEnum("e1", bundles=[b1, b2])
        e2 = CEnum("e2", bundles=[b2])
        e1.delete()
        eq_(set(b1.get_elements(type=CEnum)), set())
        eq_(set(b2.get_elements(type=CEnum)), {e2})
        eq_(set(e1.bundles), set())
        eq_(set(e2.bundles), {b2})

    def test_delete_enum_that_is_an_attribute_type(self):
        b1 = CBundle("B1")
        CBundle("B2")
        e1 = CEnum("E1", bundles=b1)
        e2 = CEnum("E2", bundles=b1)
        e3 = CEnum("E3", values=["1", "2"], bundles=b1)
        ea1 = CAttribute(type=e3, default="1")
        ea2 = CAttribute(type=e3)
        cl = CClass(self.mcl, attributes={"letters1": ea1, "letters2": ea2})
        o = CObject(cl, "o")
        e1.delete()
        e3.delete()
        try:
            ea1.default = "3"
            exception_expected_()
        except CException as e:
            eq_("cannot access named element that has been deleted", e.value)
        try:
            ea1.type = e1
            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 = e1
            exception_expected_()
        except CException as e:
            eq_("cannot access named element that has been deleted", e.value)
        try:
            ea1.type = e2
            exception_expected_()
        except CException as e:
            eq_("default value '1' incompatible with attribute's type 'E2'",
                e.value)
        try:
            o.set_value("letters1", "1")
            exception_expected_()
        except CException as e:
            eq_("cannot access named element that has been deleted", e.value)
        try:
            o.get_value("letters1")
            exception_expected_()
        except CException as e:
            eq_("cannot access named element that has been deleted", e.value)

    def test_bundle_that_is_deleted(self):
        b1 = CBundle("B1")
        b1.delete()
        try:
            CEnum("E1", bundles=b1)
            exception_expected_()
        except CException as e:
            eq_(e.value, "cannot access named element that has been deleted")

    def test_set_bundle_to_none(self):
        c = CEnum("E1", bundles=None)
        eq_(c.bundles, [])
        eq_(c.name, "E1")
class TestBundlesOfBundles:
    def setup(self):
        self.mcl = CMetaclass("MCL")
        self.b1 = CBundle("B1")
        self.b2 = CBundle("B2")

    def test_bundle_defined_bundles(self):
        eq_(set(self.b1.get_elements()), set())
        b1 = CBundle("B1", bundles=self.b1)
        eq_(set(self.b1.get_elements()), {b1})
        b2 = CBundle("B2", bundles=[self.b1])
        b3 = CBundle("B3", bundles=[self.b1, self.b2])
        mcl = CMetaclass("MCL", bundles=self.b1)
        eq_(set(self.b1.get_elements(type=CBundle)), {b1, b2, b3})
        eq_(set(self.b1.elements), {b1, b2, b3, mcl})
        eq_(set(self.b2.get_elements(type=CBundle)), {b3})
        eq_(set(self.b2.elements), {b3})

    def test_bundle_defined_by_bundle_list(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        b3 = CBundle("P3")
        eq_(set(self.b1.get_elements(type=CBundle)), set())
        ba = CBundle("PA", elements=[b1, b2, b3])
        eq_(set(ba.elements), {b1, b2, b3})
        self.mcl.bundles = ba
        eq_(set(ba.elements), {b1, b2, b3, self.mcl})
        eq_(set(ba.get_elements(type=CBundle)), {b1, b2, b3})
        bb = CBundle("PB")
        bb.elements = [b2, b3]
        eq_(set(bb.get_elements(type=CBundle)), {b2, b3})
        eq_(set(b1.bundles), {ba})
        eq_(set(b2.bundles), {ba, bb})
        eq_(set(b3.bundles), {ba, bb})
        eq_(set(ba.bundles), set())
        eq_(set(bb.bundles), set())
        eq_(set(b1.elements), set())
        eq_(set(b2.elements), set())
        eq_(set(b3.elements), set())

    def test_get_bundles_by_name(self):
        eq_(set(self.b1.get_elements(name="B1")), set())
        b1 = CBundle("B1", bundles=self.b1)
        m = CMetaclass("B1", bundles=self.b1)
        eq_(self.b1.get_elements(type=CMetaclass), [m])
        eq_(set(self.b1.get_elements(name="B1", type=CBundle)), {b1})
        b2 = CBundle("B1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="B1", type=CBundle)), {b1, b2})
        ok_(b1 != b2)
        b3 = CBundle("B1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="B1", type=CBundle)), {b1, b2, b3})
        eq_(self.b1.get_element(name="B1", type=CBundle), b1)

    def test_get_bundle_elements_by_name(self):
        eq_(set(self.b1.get_elements(name="B1")), set())
        b1 = CBundle("B1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="B1")), {b1})
        m = CMetaclass("B1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="B1")), {m, b1})
        b2 = CBundle("B1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="B1")), {m, b1, b2})
        ok_(b1 != b2)
        b3 = CBundle("B1", bundles=self.b1)
        eq_(set(self.b1.get_elements(name="B1")), {m, b1, b2, b3})
        eq_(self.b1.get_element(name="B1"), b1)

    def test_bundle_defined_bundle_change(self):
        b1 = CBundle("B1", bundles=self.b1)
        b2 = CBundle("B2", bundles=self.b1)
        b3 = CBundle("P3", bundles=self.b1)
        mcl = CMetaclass("MCL", bundles=self.b1)
        b = CBundle()
        b2.bundles = b
        b3.bundles = None
        self.mcl.bundles = b
        eq_(set(self.b1.elements), {mcl, b1})
        eq_(set(self.b1.get_elements(type=CBundle)), {b1})
        eq_(set(b.elements), {b2, self.mcl})
        eq_(set(b.get_elements(type=CBundle)), {b2})
        eq_(b1.bundles, [self.b1])
        eq_(b2.bundles, [b])
        eq_(b3.bundles, [])

    def test_bundle_delete_bundle(self):
        b1 = CBundle("B1", bundles=self.b1)
        b2 = CBundle("B2", bundles=self.b1)
        b3 = CBundle("P3", bundles=self.b1)
        self.b1.delete()
        eq_(set(self.b1.elements), set())
        eq_(b1.get_elements(type=CBundle), [])
        eq_(b1.elements, [])
        eq_(b2.get_elements(type=CBundle), [])
        eq_(b3.get_elements(type=CBundle), [])

    def test_creation_of_unnamed_bundle_in_bundle(self):
        b1 = CBundle()
        b2 = CBundle()
        b3 = CBundle("x")
        mcl = CMetaclass()
        self.b1.elements = [b1, b2, b3, mcl]
        eq_(set(self.b1.get_elements(type=CBundle)), {b1, b2, b3})
        eq_(self.b1.get_element(name=None, type=CBundle), b1)
        eq_(set(self.b1.get_elements(name=None, type=CBundle)), {b1, b2})
        eq_(set(self.b1.get_elements(name=None)), {b1, b2, mcl})

    def test_remove_bundle_from_bundle(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        ba = CBundle("A", bundles=b1)
        try:
            # noinspection PyTypeChecker
            b1.remove(None)
            exception_expected_()
        except CException as e:
            eq_("'None' is not an element of the bundle", e.value)
        try:
            b1.remove(CEnum("A"))
            exception_expected_()
        except CException as e:
            eq_("'A' is not an element of the bundle", e.value)
        try:
            b2.remove(ba)
            exception_expected_()
        except CException as e:
            eq_("'A' is not an element of the bundle", e.value)
        b1.remove(ba)
        eq_(set(b1.get_elements(type=CBundle)), set())

        mcl1 = CMetaclass("MCL")
        cl1 = CClass(mcl1, "CL")

        ba = CBundle("PA", bundles=b1)
        bb = CBundle("PB", bundles=b1)
        bc = CBundle("PC", bundles=b1, elements=[mcl1, cl1])

        b1.remove(ba)
        try:
            b1.remove(CBundle("PB", bundles=b2))
            exception_expected_()
        except CException as e:
            eq_("'PB' is not an element of the bundle", e.value)
        try:
            b1.remove(ba)
            exception_expected_()
        except CException as e:
            eq_("'PA' is not an element of the bundle", e.value)

        eq_(set(b1.get_elements(type=CBundle)), {bb, bc})
        b1.remove(bc)
        eq_(set(b1.get_elements(type=CBundle)), {bb})

        eq_(bc.get_elements(type=CBundle), [])
        eq_(bc.get_elements(type=CBundle), [])
        eq_(bc.elements, [mcl1, cl1])

    def test_delete_bundle_from_bundle(self):
        b1 = CBundle("B1")
        ba = CBundle("A", bundles=b1)
        ba.delete()
        eq_(set(b1.get_elements(type=CBundle)), set())

        mcl1 = CMetaclass("MCL")
        cl1 = CClass(mcl1, "CL")

        ba = CBundle("PA", bundles=b1)
        bb = CBundle("PB", bundles=b1)
        bc = CBundle("PC", bundles=b1, elements=[mcl1, cl1])

        ba.delete()
        eq_(set(b1.get_elements(type=CBundle)), {bb, bc})
        bc.delete()
        eq_(set(b1.get_elements(type=CBundle)), {bb})

        eq_(bc.get_elements(type=CBundle), [])
        eq_(bc.get_elements(type=CBundle), [])
        eq_(bc.elements, [])

    def test_remove_bundle_from_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        ba = CBundle("ba", bundles=[b1, b2])
        b1.remove(ba)
        eq_(set(b1.get_elements(type=CBundle)), set())
        eq_(set(b2.get_elements(type=CBundle)), {ba})
        eq_(set(ba.bundles), {b2})

    def test_delete_bundle_from_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        ba = CBundle("ba", bundles=[b1, b2])
        b1.delete()
        eq_(set(b1.get_elements(type=CBundle)), set())
        eq_(set(b2.get_elements(type=CBundle)), {ba})
        eq_(set(ba.bundles), {b2})

    def test_delete_bundle_having_two_bundles(self):
        b1 = CBundle("B1")
        b2 = CBundle("B2")
        ba = CBundle("ba", bundles=[b1, b2])
        bb = CBundle("bb", bundles=[b2])
        ba.delete()
        eq_(set(b1.get_elements(type=CBundle)), set())
        eq_(set(b2.get_elements(type=CBundle)), {bb})
        eq_(set(ba.bundles), set())
        eq_(set(bb.bundles), {b2})

    def test_delete_top_level_bundle(self):
        b1 = CBundle("B1")
        ba = CBundle("A", bundles=b1)
        b1.delete()
        eq_(b1.get_elements(type=CBundle), [])
        eq_(ba.get_elements(type=CBundle), [])

        b1 = CBundle("B1")
        mcl1 = CMetaclass("MCL")
        cl1 = CClass(mcl1, "CL")

        ba = CBundle("BA", bundles=b1)
        bb = CBundle("BB", bundles=b1)
        bc = CBundle("BC", bundles=b1, elements=[mcl1, cl1])

        b1.delete()
        eq_(b1.get_elements(type=CBundle), [])
        eq_(b1.elements, [])
        eq_(ba.get_elements(type=CBundle), [])
        eq_(bb.get_elements(type=CBundle), [])
        eq_(bc.get_elements(type=CBundle), [])
        eq_(bc.elements, [mcl1, cl1])
        eq_(bc.get_elements(type=CBundle), [])
        eq_(mcl1.classes, [cl1])
        eq_(mcl1.bundles, [bc])
        eq_(cl1.metaclass, mcl1)
        eq_(cl1.bundles, [bc])

    def test_bundle_that_is_deleted(self):
        b1 = CBundle("B1")
        b1.delete()
        try:
            CBundle("A", bundles=b1)
            exception_expected_()
        except CException as e:
            eq_(e.value, "cannot access named element that has been deleted")

    def test_set_bundle_to_none(self):
        p = CBundle("A", bundles=None)
        eq_(p.get_elements(type=CBundle), [])
        eq_(p.name, "A")