def test_default_init_after_instance_creation(self): enum_type = CEnum("EnumT", values=["A", "B", "C"]) mcl = CMetaclass(attributes={"e1": enum_type, "e2": enum_type}) cl = CClass(mcl, "C") e2 = mcl.get_attribute("e2") e2.default = "A" eq_(cl.get_value("e1"), None) eq_(cl.get_value("e2"), "A")
def test_attribute_get_name_and_classifier(self): m = CMetaclass("M", attributes={"isBoolean": True}) a = m.get_attribute("isBoolean") eq_(a.name, "isBoolean") eq_(a.classifier, m) m.delete() eq_(a.name, None) eq_(a.classifier, None)
def test_enum_type_attribute_values(self): enum_type = CEnum("EnumT", values=["A", "B", "C"]) mcl = CMetaclass(attributes={"e1": enum_type, "e2": enum_type}) e2 = mcl.get_attribute("e2") e2.default = "A" cl = CClass(mcl, "C") eq_(cl.get_value("e1"), None) eq_(cl.get_value("e2"), "A") cl.set_value("e1", "B") cl.set_value("e2", "C") eq_(cl.get_value("e1"), "B") eq_(cl.get_value("e2"), "C") try: cl.set_value("e1", "X") exception_expected_() except CException as e: eq_(e.value, "value 'X' is not element of enumeration")
def test_primitive_type_attributes(self): cl = CMetaclass("MCL", attributes={ "isBoolean": True, "intVal": 1, "floatVal": 1.1, "string": "abc", "list": ["a", "b"]}) eq_(len(cl.attributes), 5) eq_(len(cl.attribute_names), 5) ok_({"isBoolean", "intVal", "floatVal", "string", "list"}.issubset(cl.attribute_names)) a1 = cl.get_attribute("isBoolean") a2 = cl.get_attribute("intVal") a3 = cl.get_attribute("floatVal") a4 = cl.get_attribute("string") a5 = cl.get_attribute("list") ok_({a1, a2, a3, a4}.issubset(cl.attributes)) eq_(None, cl.get_attribute("X")) eq_(a1.type, bool) eq_(a2.type, int) eq_(a3.type, float) eq_(a4.type, str) eq_(a5.type, list) d1 = a1.default d2 = a2.default d3 = a3.default d4 = a4.default d5 = a5.default ok_(isinstance(d1, bool)) ok_(isinstance(d2, int)) ok_(isinstance(d3, float)) ok_(isinstance(d4, str)) ok_(isinstance(d5, list)) eq_(d1, True) eq_(d2, 1) eq_(d3, 1.1) eq_(d4, "abc") eq_(d5, ["a", "b"])
def test_type_object_attribute_class_is_none(self): m = CMetaclass("M", attributes={"ac": None}) ac = m.get_attribute("ac") eq_(ac.default, None) eq_(ac.type, None)
class TestMetaClassAttributes: def setup(self): self.mcl = CMetaclass("MCL") def test_primitive_empty_input(self): cl = CMetaclass("MCL", attributes={}) eq_(len(cl.attributes), 0) eq_(len(cl.attribute_names), 0) def test_primitive_none_input(self): cl = CMetaclass("MCL", attributes=None) eq_(len(cl.attributes), 0) eq_(len(cl.attribute_names), 0) def test_primitive_type_attributes(self): cl = CMetaclass("MCL", attributes={ "isBoolean": True, "intVal": 1, "floatVal": 1.1, "string": "abc", "list": ["a", "b"]}) eq_(len(cl.attributes), 5) eq_(len(cl.attribute_names), 5) ok_({"isBoolean", "intVal", "floatVal", "string", "list"}.issubset(cl.attribute_names)) a1 = cl.get_attribute("isBoolean") a2 = cl.get_attribute("intVal") a3 = cl.get_attribute("floatVal") a4 = cl.get_attribute("string") a5 = cl.get_attribute("list") ok_({a1, a2, a3, a4}.issubset(cl.attributes)) eq_(None, cl.get_attribute("X")) eq_(a1.type, bool) eq_(a2.type, int) eq_(a3.type, float) eq_(a4.type, str) eq_(a5.type, list) d1 = a1.default d2 = a2.default d3 = a3.default d4 = a4.default d5 = a5.default ok_(isinstance(d1, bool)) ok_(isinstance(d2, int)) ok_(isinstance(d3, float)) ok_(isinstance(d4, str)) ok_(isinstance(d5, list)) eq_(d1, True) eq_(d2, 1) eq_(d3, 1.1) eq_(d4, "abc") eq_(d5, ["a", "b"]) def test_attribute_get_name_and_classifier(self): m = CMetaclass("M", attributes={"isBoolean": True}) a = m.get_attribute("isBoolean") eq_(a.name, "isBoolean") eq_(a.classifier, m) m.delete() eq_(a.name, None) eq_(a.classifier, None) def test_primitive_attributes_no_default(self): self.mcl.attributes = {"a": bool, "b": int, "c": str, "d": float, "e": list} a1 = self.mcl.get_attribute("a") a2 = self.mcl.get_attribute("b") a3 = self.mcl.get_attribute("c") a4 = self.mcl.get_attribute("d") a5 = self.mcl.get_attribute("e") ok_({a1, a2, a3, a4, a5}.issubset(self.mcl.attributes)) eq_(a1.default, None) eq_(a1.type, bool) eq_(a2.default, None) eq_(a2.type, int) eq_(a3.default, None) eq_(a3.type, str) eq_(a4.default, None) eq_(a4.type, float) eq_(a5.default, None) eq_(a5.type, list) def test_get_attribute_not_found(self): eq_(self.mcl.get_attribute("x"), None) self.mcl.attributes = {"a": bool, "b": int, "c": str, "d": float} eq_(self.mcl.get_attribute("x"), None) def test_same_named_arguments_c_attributes(self): a1 = CAttribute(default="") a2 = CAttribute(type=str) n1 = "a" self.mcl.attributes = {n1: a1, "a": a2} eq_(set(self.mcl.attributes), {a2}) eq_(self.mcl.attribute_names, ["a"]) def test_same_named_arguments_defaults(self): n1 = "a" self.mcl.attributes = {n1: "", "a": 1} ok_(len(self.mcl.attributes), 1) eq_(self.mcl.get_attribute("a").default, 1) eq_(self.mcl.attribute_names, ["a"]) def test_object_type_attribute(self): attribute_type = CClass(self.mcl, "AttrType") attribute_value = CObject(attribute_type, "attribute_value") self.mcl.attributes = {"attrTypeObj": attribute_value} object_attribute = self.mcl.get_attribute("attrTypeObj") attributes = self.mcl.attributes eq_(set(attributes), {object_attribute}) bool_attr = CAttribute(default=True) self.mcl.attributes = {"attrTypeObj": object_attribute, "isBoolean": bool_attr} attributes = self.mcl.attributes eq_(set(attributes), {object_attribute, bool_attr}) eq_(self.mcl.attribute_names, ["attrTypeObj", "isBoolean"]) object_attribute = self.mcl.get_attribute("attrTypeObj") eq_(object_attribute.type, attribute_type) default = object_attribute.default ok_(isinstance(default, CObject)) eq_(default, attribute_value) self.mcl.attributes = {"attrTypeObj": attribute_value, "isBoolean": bool_attr} eq_(self.mcl.attribute_names, ["attrTypeObj", "isBoolean"]) # using the CObject in attributes causes a new CAttribute to be created != object_attribute neq_(self.mcl.get_attribute("attrTypeObj"), object_attribute) def test_class_type_attribute(self): attribute_type = CMetaclass("AttrType") attribute_value = CClass(attribute_type, "attribute_value") self.mcl.attributes = {"attrTypeCl": attribute_type} class_attribute = self.mcl.get_attribute("attrTypeCl") class_attribute.default = attribute_value attributes = self.mcl.attributes eq_(set(attributes), {class_attribute}) bool_attr = CAttribute(default=True) self.mcl.attributes = {"attrTypeCl": class_attribute, "isBoolean": bool_attr} attributes = self.mcl.attributes eq_(set(attributes), {class_attribute, bool_attr}) eq_(self.mcl.attribute_names, ["attrTypeCl", "isBoolean"]) class_attribute = self.mcl.get_attribute("attrTypeCl") eq_(class_attribute.type, attribute_type) default = class_attribute.default ok_(isinstance(default, CClass)) eq_(default, attribute_value) self.mcl.attributes = {"attrTypeCl": attribute_value, "isBoolean": bool_attr} eq_(self.mcl.attribute_names, ["attrTypeCl", "isBoolean"]) # using the CClass in attributes causes a new CAttribute to be created != class_attribute neq_(self.mcl.get_attribute("attrTypeCl"), class_attribute) def test_use_enum_type_attribute(self): enum_values = ["A", "B", "C"] enum_obj = CEnum("ABCEnum", values=enum_values) ea1 = CAttribute(type=enum_obj, default="A") ea2 = CAttribute(type=enum_obj) self.mcl.attributes = {"letters1": ea1, "letters2": ea2} eq_(set(self.mcl.attributes), {ea1, ea2}) ok_(isinstance(ea1.type, CEnum)) self.mcl.attributes = {"letters1": ea1, "isBool": True, "letters2": ea2} bool_attr = self.mcl.get_attribute("isBool") l1 = self.mcl.get_attribute("letters1") eq_(set(self.mcl.attributes), {l1, ea2, bool_attr}) eq_(l1.default, "A") eq_(ea2.default, None) def test_unknown_attribute_type(self): try: self.mcl.attributes = {"x": CEnum, "b": bool} exception_expected_() except CException as e: ok_(re.match("^(unknown attribute type: '<class ).*(CEnum'>')$", e.value)) def test_set_attribute_default_value(self): enum_obj = CEnum("ABCEnum", values=["A", "B", "C"]) self.mcl.attributes = {"letters": enum_obj, "b": bool} letters = self.mcl.get_attribute("letters") b = self.mcl.get_attribute("b") eq_(letters.default, None) eq_(b.default, None) letters.default = "B" b.default = False eq_(letters.default, "B") eq_(b.default, False) eq_(letters.type, enum_obj) eq_(b.type, bool) def test_cclass_vs_cobject(self): cl_a = CClass(self.mcl, "A") cl_b = CClass(self.mcl, "B") obj_b = CObject(cl_b, "obj_b") self.mcl.attributes = {"a": cl_a, "b": obj_b} a = self.mcl.get_attribute("a") b = self.mcl.get_attribute("b") eq_(a.type, cl_a) eq_(a.default, None) eq_(b.type, cl_b) eq_(b.default, obj_b) testMetaclass = CMetaclass("A") testEnum = CEnum("AEnum", values=[1, 2]) testClass = CClass(testMetaclass, "CL") @parameterized.expand([ (bool, testMetaclass), (bool, 1.1), (int, testMetaclass), (int, "abc"), (float, "1"), (float, testMetaclass), (str, 1), (str, testMetaclass), (testEnum, "1"), (testEnum, testMetaclass), (testClass, "1"), (testClass, testMetaclass)]) def test_attribute_type_check(self, type_to_check, wrong_default): self.mcl.attributes = {"a": type_to_check} attr = self.mcl.get_attribute("a") try: attr.default = wrong_default exception_expected_() except CException as e: eq_(f"default value '{wrong_default!s}' incompatible with attribute's type '{type_to_check!s}'", e.value) def test_delete_attributes(self): self.mcl.attributes = { "isBoolean": True, "intVal": 1, "floatVal": 1.1, "string": "abc"} eq_(len(set(self.mcl.attributes)), 4) self.mcl.attributes = {} eq_(set(self.mcl.attributes), set()) self.mcl.attributes = { "isBoolean": True, "intVal": 1, "floatVal": 1.1, "string": "abc"} eq_(len(set(self.mcl.attributes)), 4) self.mcl.attributes = {} eq_(set(self.mcl.attributes), set()) 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_type_object_attribute_class_is_none(self): m = CMetaclass("M", attributes={"ac": None}) ac = m.get_attribute("ac") eq_(ac.default, None) eq_(ac.type, None) def test_default_object_attribute_is_deleted_in_constructor(self): attribute_class = CClass(self.mcl, "AC") default_object = CObject(attribute_class) default_object.delete() try: CMetaclass("M", attributes={"ac": default_object}) exception_expected_() except CException as e: eq_(e.value, "cannot access named element that has been deleted")
class TestClassAttributeValues: def setup(self): self.mcl = CMetaclass("MCL") def test_values_on_primitive_type_attributes(self): mcl = CMetaclass("M", attributes={ "isBoolean": True, "intVal": 1, "floatVal": 1.1, "string": "abc", "list": ["a", "b"] }) cl = CClass(mcl, "C") eq_(cl.get_value("isBoolean"), True) eq_(cl.get_value("intVal"), 1) eq_(cl.get_value("floatVal"), 1.1) eq_(cl.get_value("string"), "abc") eq_(cl.get_value("list"), ["a", "b"]) cl.set_value("isBoolean", False) cl.set_value("intVal", 2) cl.set_value("floatVal", 2.1) cl.set_value("string", "y") eq_(cl.get_value("isBoolean"), False) eq_(cl.get_value("intVal"), 2) eq_(cl.get_value("floatVal"), 2.1) eq_(cl.get_value("string"), "y") cl.set_value("list", []) eq_(cl.get_value("list"), []) cl.set_value("list", [1, 2, 3]) eq_(cl.get_value("list"), [1, 2, 3]) def test_attribute_of_value_unknown(self): cl = CClass(self.mcl, "C") try: cl.get_value("x") exception_expected_() except CException as e: eq_(e.value, "attribute 'x' unknown for 'C'") self.mcl.attributes = {"isBoolean": True, "intVal": 1} try: cl.set_value("x", 1) exception_expected_() except CException as e: eq_(e.value, "attribute 'x' unknown for 'C'") def test_integers_as_floats(self): mcl = CMetaclass("C", attributes={"floatVal": float}) cl = CClass(mcl, "C") cl.set_value("floatVal", 15) eq_(cl.get_value("floatVal"), 15) def test_attribute_defined_after_instance(self): mcl = CMetaclass("C") cl = CClass(mcl, "C") mcl.attributes = {"floatVal": float} cl.set_value("floatVal", 15) eq_(cl.get_value("floatVal"), 15) def test_object_type_attribute_values(self): attr_type = CClass(self.mcl, "AttrType") attr_value = CObject(attr_type, "attribute_value") self.mcl.attributes = {"attrTypeObj": attr_value} obj_attr = self.mcl.get_attribute("attrTypeObj") eq_(obj_attr.type, attr_type) cl = CClass(self.mcl, "C") eq_(cl.get_value("attrTypeObj"), attr_value) non_attr_value = CObject(CClass(self.mcl), "non_attribute_value") try: cl.set_value("attrTypeObj", non_attr_value) exception_expected_() except CException as e: eq_( e.value, "type of 'non_attribute_value' is not matching type of attribute 'attrTypeObj'" ) def test_class_type_attribute_values(self): attr_type = CMetaclass("AttrType") attr_value = CClass(attr_type, "attribute_value") self.mcl.attributes = {"attrTypeCl": attr_type} cl_attr = self.mcl.get_attribute("attrTypeCl") cl_attr.default = attr_value eq_(cl_attr.type, attr_type) cl = CClass(self.mcl, "C") eq_(cl.get_value("attrTypeCl"), attr_value) non_attr_value = CClass(CMetaclass("MX"), "non_attribute_value") try: cl.set_value("attrTypeCl", non_attr_value) exception_expected_() except CException as e: eq_( e.value, "type of 'non_attribute_value' is not matching type of attribute 'attrTypeCl'" ) def test_add_object_attribute_get_set_value(self): attr_type = CClass(self.mcl, "AttrType") attr_value = CObject(attr_type, "attribute_value") cl = CClass(self.mcl) self.mcl.attributes = { "attrTypeObj1": attr_type, "attrTypeObj2": attr_value } eq_(cl.get_value("attrTypeObj1"), None) eq_(cl.get_value("attrTypeObj2"), attr_value) def test_object_attribute_of_superclass_type(self): attr_super_type = CClass(self.mcl, "AttrSuperType") attr_type = CClass(self.mcl, "AttrType", superclasses=attr_super_type) attr_value = CObject(attr_type, "attribute_value") cl = CClass(self.mcl) self.mcl.attributes = { "attrTypeObj1": attr_super_type, "attrTypeObj2": attr_value } cl.set_value("attrTypeObj1", attr_value) cl.set_value("attrTypeObj2", attr_value) eq_(cl.get_value("attrTypeObj1"), attr_value) eq_(cl.get_value("attrTypeObj2"), attr_value) def test_values_on_attributes_with_no_default_values(self): attr_type = CClass(self.mcl, "AttrType") enum_type = CEnum("EnumT", values=["A", "B", "C"]) mcl = CMetaclass("M", attributes={ "b": bool, "i": int, "f": float, "s": str, "l": list, "C": attr_type, "e": enum_type }) cl = CClass(mcl, "C") for n in ["b", "i", "f", "s", "l", "C", "e"]: eq_(cl.get_value(n), None) def test_values_defined_in_constructor(self): obj_val_type = CClass(CMetaclass()) obj_val = CObject(obj_val_type, "object_value") mcl = CMetaclass("M", attributes={ "isBoolean": True, "intVal": 1, "floatVal": 1.1, "string": "abc", "list": ["a", "b"], "obj": obj_val_type }) cl = CClass(mcl, "C", values={ "isBoolean": False, "intVal": 2, "floatVal": 2.1, "string": "y", "list": [], "obj": obj_val }) eq_(cl.get_value("isBoolean"), False) eq_(cl.get_value("intVal"), 2) eq_(cl.get_value("floatVal"), 2.1) eq_(cl.get_value("string"), "y") eq_(cl.get_value("list"), []) eq_(cl.get_value("obj"), obj_val) eq_( cl.values, { "isBoolean": False, "intVal": 2, "floatVal": 2.1, "string": "y", "list": [], "obj": obj_val }) def test_values_setter_overwrite(self): mcl = CMetaclass("M", attributes={"isBoolean": True, "intVal": 1}) cl = CClass(mcl, "C", values={"isBoolean": False, "intVal": 2}) cl.values = {"isBoolean": True, "intVal": 20} eq_(cl.get_value("isBoolean"), True) eq_(cl.get_value("intVal"), 20) eq_(cl.values, {'isBoolean': True, 'intVal': 20}) cl.values = {} # values should not delete existing values eq_(cl.values, {"isBoolean": True, "intVal": 20}) def test_values_setter_with_superclass(self): mcl_super = CMetaclass("S_MCL", attributes={ "intVal": 20, "intVal2": 30 }) mcl = CMetaclass("M", superclasses=mcl_super, attributes={ "isBoolean": True, "intVal": 1 }) cl = CClass(mcl, "C", values={"isBoolean": False}) eq_(cl.values, {"isBoolean": False, "intVal": 1, "intVal2": 30}) cl.set_value("intVal", 12, mcl_super) cl.set_value("intVal", 15, mcl) cl.set_value("intVal2", 16, mcl_super) eq_(cl.values, {"isBoolean": False, "intVal": 15, "intVal2": 16}) eq_(cl.get_value("intVal", mcl_super), 12) eq_(cl.get_value("intVal", mcl), 15) def test_values_setter_malformed_description(self): mcl = CMetaclass("M", attributes={"isBoolean": True, "intVal": 1}) cl = CClass(mcl, "C") try: cl.values = [1, 2, 3] exception_expected_() except CException as e: eq_(e.value, "malformed attribute values description: '[1, 2, 3]'") def test_enum_type_attribute_values(self): enum_type = CEnum("EnumT", values=["A", "B", "C"]) mcl = CMetaclass(attributes={"e1": enum_type, "e2": enum_type}) e2 = mcl.get_attribute("e2") e2.default = "A" cl = CClass(mcl, "C") eq_(cl.get_value("e1"), None) eq_(cl.get_value("e2"), "A") cl.set_value("e1", "B") cl.set_value("e2", "C") eq_(cl.get_value("e1"), "B") eq_(cl.get_value("e2"), "C") try: cl.set_value("e1", "X") exception_expected_() except CException as e: eq_(e.value, "value 'X' is not element of enumeration") def test_default_init_after_instance_creation(self): enum_type = CEnum("EnumT", values=["A", "B", "C"]) mcl = CMetaclass(attributes={"e1": enum_type, "e2": enum_type}) cl = CClass(mcl, "C") e2 = mcl.get_attribute("e2") e2.default = "A" eq_(cl.get_value("e1"), None) eq_(cl.get_value("e2"), "A") def test_attribute_value_type_check_bool1(self): self.mcl.attributes = {"t": bool} cl = CClass(self.mcl, "C") try: cl.set_value("t", self.mcl) exception_expected_() except CException as e: eq_(f"value for attribute 't' is not a known attribute type", e.value) def test_attribute_value_type_check_bool2(self): self.mcl.attributes = {"t": bool} cl = CClass(self.mcl, "C") try: cl.set_value("t", 1) exception_expected_() except CException as e: eq_(f"value type for attribute 't' does not match attribute type", e.value) def test_attribute_value_type_check_int(self): self.mcl.attributes = {"t": int} cl = CClass(self.mcl, "C") try: cl.set_value("t", True) exception_expected_() except CException as e: eq_(f"value type for attribute 't' does not match attribute type", e.value) def test_attribute_value_type_check_float(self): self.mcl.attributes = {"t": float} cl = CClass(self.mcl, "C") try: cl.set_value("t", True) exception_expected_() except CException as e: eq_(f"value type for attribute 't' does not match attribute type", e.value) def test_attribute_value_type_check_str(self): self.mcl.attributes = {"t": str} cl = CClass(self.mcl, "C") try: cl.set_value("t", True) exception_expected_() except CException as e: eq_(f"value type for attribute 't' does not match attribute type", e.value) def test_attribute_value_type_check_list(self): self.mcl.attributes = {"t": list} cl = CClass(self.mcl, "C") try: cl.set_value("t", True) exception_expected_() except CException as e: eq_(f"value type for attribute 't' does not match attribute type", e.value) def test_attribute_value_type_check_object(self): attr_type = CMetaclass("AttrType") self.mcl.attributes = {"t": attr_type} cl = CClass(self.mcl, "C") try: cl.set_value("t", True) exception_expected_() except CException as e: eq_(f"value type for attribute 't' does not match attribute type", e.value) def test_attribute_value_type_check_enum(self): enum_type = CEnum("EnumT", values=["A", "B", "C"]) self.mcl.attributes = {"t": enum_type} cl = CClass(self.mcl, "C") try: cl.set_value("t", True) exception_expected_() except CException as e: eq_(f"value type for attribute 't' does not match attribute type", e.value) def test_attribute_deleted(self): mcl = CMetaclass(attributes={"isBoolean": True, "intVal": 15}) cl = CClass(mcl, "C") eq_(cl.get_value("intVal"), 15) mcl.attributes = {"isBoolean": False} eq_(cl.get_value("isBoolean"), True) try: cl.get_value("intVal") exception_expected_() except CException as e: eq_(e.value, "attribute 'intVal' unknown for 'C'") try: cl.set_value("intVal", 1) exception_expected_() except CException as e: eq_(e.value, "attribute 'intVal' unknown for 'C'") def test_attribute_deleted_no_default(self): mcl = CMetaclass(attributes={"isBoolean": bool, "intVal": int}) mcl.attributes = {"isBoolean": bool} cl = CClass(mcl, "C") eq_(cl.get_value("isBoolean"), None) try: cl.get_value("intVal") exception_expected_() except CException as e: eq_(e.value, "attribute 'intVal' unknown for 'C'") try: cl.set_value("intVal", 1) exception_expected_() except CException as e: eq_(e.value, "attribute 'intVal' unknown for 'C'") def test_attributes_overwrite(self): mcl = CMetaclass(attributes={"isBoolean": True, "intVal": 15}) cl = CClass(mcl, "C") eq_(cl.get_value("intVal"), 15) try: cl.get_value("floatVal") exception_expected_() except CException as e: eq_(e.value, "attribute 'floatVal' unknown for 'C'") cl.set_value("intVal", 18) mcl.attributes = {"isBoolean": False, "intVal": 19, "floatVal": 25.1} eq_(cl.get_value("isBoolean"), True) eq_(cl.get_value("floatVal"), 25.1) eq_(cl.get_value("intVal"), 18) cl.set_value("floatVal", 1.2) eq_(cl.get_value("floatVal"), 1.2) def test_attributes_overwrite_no_defaults(self): mcl = CMetaclass(attributes={"isBoolean": bool, "intVal": int}) cl = CClass(mcl, "C") eq_(cl.get_value("isBoolean"), None) cl.set_value("isBoolean", False) mcl.attributes = {"isBoolean": bool, "intVal": int, "floatVal": float} eq_(cl.get_value("isBoolean"), False) eq_(cl.get_value("floatVal"), None) eq_(cl.get_value("intVal"), None) cl.set_value("floatVal", 1.2) eq_(cl.get_value("floatVal"), 1.2) def test_attributes_deleted_on_subclass(self): mcl = CMetaclass("M", attributes={"isBoolean": True, "intVal": 1}) mcl2 = CMetaclass("M2", attributes={"isBoolean": False}, superclasses=mcl) cl = CClass(mcl2, "C") eq_(cl.get_value("isBoolean"), False) eq_(cl.get_value("isBoolean", mcl), True) eq_(cl.get_value("isBoolean", mcl2), False) mcl2.attributes = {} eq_(cl.get_value("isBoolean"), True) eq_(cl.get_value("intVal"), 1) eq_(cl.get_value("isBoolean", mcl), True) try: cl.get_value("isBoolean", mcl2) exception_expected_() except CException as e: eq_(e.value, "attribute 'isBoolean' unknown for 'M2'") def test_attributes_deleted_on_subclass_no_defaults(self): mcl = CMetaclass("M", attributes={"isBoolean": bool, "intVal": int}) mcl2 = CMetaclass("M2", attributes={"isBoolean": bool}, superclasses=mcl) cl = CClass(mcl2, "C") eq_(cl.get_value("isBoolean"), None) eq_(cl.get_value("isBoolean", mcl), None) eq_(cl.get_value("isBoolean", mcl2), None) mcl2.attributes = {} eq_(cl.get_value("isBoolean"), None) eq_(cl.get_value("intVal"), None) eq_(cl.get_value("isBoolean", mcl), None) try: cl.get_value("isBoolean", mcl2) exception_expected_() except CException as e: eq_(e.value, "attribute 'isBoolean' unknown for 'M2'") def test_attribute_values_inheritance(self): t1 = CMetaclass("T1") t2 = CMetaclass("T2") c = CMetaclass("C", superclasses=[t1, t2]) sc = CMetaclass("C", superclasses=c) t1.attributes = {"i0": 0} t2.attributes = {"i1": 1} c.attributes = {"i2": 2} sc.attributes = {"i3": 3} cl = CClass(sc, "C") for name, value in {"i0": 0, "i1": 1, "i2": 2, "i3": 3}.items(): eq_(cl.get_value(name), value) eq_(cl.get_value("i0", t1), 0) eq_(cl.get_value("i1", t2), 1) eq_(cl.get_value("i2", c), 2) eq_(cl.get_value("i3", sc), 3) for name, value in {"i0": 10, "i1": 11, "i2": 12, "i3": 13}.items(): cl.set_value(name, value) for name, value in {"i0": 10, "i1": 11, "i2": 12, "i3": 13}.items(): eq_(cl.get_value(name), value) eq_(cl.get_value("i0", t1), 10) eq_(cl.get_value("i1", t2), 11) eq_(cl.get_value("i2", c), 12) eq_(cl.get_value("i3", sc), 13) def test_attribute_values_inheritance_after_delete_superclass(self): t1 = CMetaclass("T1") t2 = CMetaclass("T2") c = CMetaclass("C", superclasses=[t1, t2]) sc = CMetaclass("C", superclasses=c) t1.attributes = {"i0": 0} t2.attributes = {"i1": 1} c.attributes = {"i2": 2} sc.attributes = {"i3": 3} cl = CClass(sc, "C") t2.delete() for name, value in {"i0": 0, "i2": 2, "i3": 3}.items(): eq_(cl.get_value(name), value) try: cl.get_value("i1") exception_expected_() except CException as e: eq_(e.value, "attribute 'i1' unknown for 'C'") eq_(cl.get_value("i0", t1), 0) try: cl.get_value("i1", t2) exception_expected_() except CException as e: eq_(e.value, "attribute 'i1' unknown for ''") eq_(cl.get_value("i2", c), 2) eq_(cl.get_value("i3", sc), 3) for name, value in {"i0": 10, "i2": 12, "i3": 13}.items(): cl.set_value(name, value) try: cl.set_value("i1", 11) exception_expected_() except CException as e: eq_(e.value, "attribute 'i1' unknown for 'C'") for name, value in {"i0": 10, "i2": 12, "i3": 13}.items(): eq_(cl.get_value(name), value) try: cl.get_value("i1") exception_expected_() except CException as e: eq_(e.value, "attribute 'i1' unknown for 'C'") eq_(cl.get_value("i0", t1), 10) try: cl.get_value("i1", t2) exception_expected_() except CException as e: eq_(e.value, "attribute 'i1' unknown for ''") eq_(cl.get_value("i2", c), 12) eq_(cl.get_value("i3", sc), 13) def test_attribute_values_same_name_inheritance(self): t1 = CMetaclass("T1") t2 = CMetaclass("T2") c = CMetaclass("C", superclasses=[t1, t2]) sc = CMetaclass("C", superclasses=c) t1.attributes = {"i": 0} t2.attributes = {"i": 1} c.attributes = {"i": 2} sc.attributes = {"i": 3} cl1 = CClass(sc) cl2 = CClass(c) cl3 = CClass(t1) eq_(cl1.get_value("i"), 3) eq_(cl2.get_value("i"), 2) eq_(cl3.get_value("i"), 0) eq_(cl1.get_value("i", sc), 3) eq_(cl1.get_value("i", c), 2) eq_(cl1.get_value("i", t2), 1) eq_(cl1.get_value("i", t1), 0) eq_(cl2.get_value("i", c), 2) eq_(cl2.get_value("i", t2), 1) eq_(cl2.get_value("i", t1), 0) eq_(cl3.get_value("i", t1), 0) cl1.set_value("i", 10) cl2.set_value("i", 11) cl3.set_value("i", 12) eq_(cl1.get_value("i"), 10) eq_(cl2.get_value("i"), 11) eq_(cl3.get_value("i"), 12) eq_(cl1.get_value("i", sc), 10) eq_(cl1.get_value("i", c), 2) eq_(cl1.get_value("i", t2), 1) eq_(cl1.get_value("i", t1), 0) eq_(cl2.get_value("i", c), 11) eq_(cl2.get_value("i", t2), 1) eq_(cl2.get_value("i", t1), 0) eq_(cl3.get_value("i", t1), 12) cl1.set_value("i", 130, sc) cl1.set_value("i", 100, t1) cl1.set_value("i", 110, t2) cl1.set_value("i", 120, c) eq_(cl1.get_value("i"), 130) eq_(cl1.get_value("i", sc), 130) eq_(cl1.get_value("i", c), 120) eq_(cl1.get_value("i", t2), 110) eq_(cl1.get_value("i", t1), 100) def test_values_multiple_inheritance(self): t1 = CMetaclass("T1") t2 = CMetaclass("T2") st_a = CMetaclass("STA", superclasses=[t1, t2]) sub_a = CMetaclass("SubA", superclasses=[st_a]) st_b = CMetaclass("STB", superclasses=[t1, t2]) sub_b = CMetaclass("SubB", superclasses=[st_b]) st_c = CMetaclass("STC") sub_c = CMetaclass("SubC", superclasses=[st_c]) mcl = CMetaclass("M", superclasses=[sub_a, sub_b, sub_c]) cl = CClass(mcl, "C") t1.attributes = {"i0": 0} t2.attributes = {"i1": 1} st_a.attributes = {"i2": 2} sub_a.attributes = {"i3": 3} st_b.attributes = {"i4": 4} sub_b.attributes = {"i5": 5} st_c.attributes = {"i6": 6} sub_c.attributes = {"i7": 7} eq_(cl.get_value("i0"), 0) eq_(cl.get_value("i1"), 1) eq_(cl.get_value("i2"), 2) eq_(cl.get_value("i3"), 3) eq_(cl.get_value("i4"), 4) eq_(cl.get_value("i5"), 5) eq_(cl.get_value("i6"), 6) eq_(cl.get_value("i7"), 7) eq_(cl.get_value("i0", t1), 0) eq_(cl.get_value("i1", t2), 1) eq_(cl.get_value("i2", st_a), 2) eq_(cl.get_value("i3", sub_a), 3) eq_(cl.get_value("i4", st_b), 4) eq_(cl.get_value("i5", sub_b), 5) eq_(cl.get_value("i6", st_c), 6) eq_(cl.get_value("i7", sub_c), 7) cl.set_value("i0", 10) cl.set_value("i1", 11) cl.set_value("i2", 12) cl.set_value("i3", 13) cl.set_value("i4", 14) cl.set_value("i5", 15) cl.set_value("i6", 16) cl.set_value("i7", 17) eq_(cl.get_value("i0"), 10) eq_(cl.get_value("i1"), 11) eq_(cl.get_value("i2"), 12) eq_(cl.get_value("i3"), 13) eq_(cl.get_value("i4"), 14) eq_(cl.get_value("i5"), 15) eq_(cl.get_value("i6"), 16) eq_(cl.get_value("i7"), 17) def test_delete_attribute_values(self): mcl = CMetaclass("M", attributes={ "isBoolean": True, "intVal": 1, "floatVal": 1.1, "string": "abc", "list": ["a", "b"] }) cl = CClass(mcl, "C") cl.delete_value("isBoolean") cl.delete_value("intVal") value_of_list = cl.delete_value("list") eq_(cl.values, {'floatVal': 1.1, 'string': 'abc'}) eq_(value_of_list, ['a', 'b']) def test_delete_attribute_values_with_superclass(self): mcl_super = CMetaclass("SCL_M", attributes={ "intVal": 20, "intVal2": 30 }) mcl = CMetaclass("M", superclasses=mcl_super, attributes={ "isBoolean": True, "intVal": 1 }) cl = CClass(mcl, "C", values={"isBoolean": False}) cl.delete_value("isBoolean") cl.delete_value("intVal2") eq_(cl.values, {"intVal": 1}) cl.set_value("intVal", 2, mcl_super) cl.set_value("intVal", 3, mcl) eq_(cl.values, {"intVal": 3}) cl.delete_value("intVal") eq_(cl.values, {"intVal": 2}) cl.set_value("intVal", 2, mcl_super) cl.set_value("intVal", 3, mcl) cl.delete_value("intVal", mcl) eq_(cl.values, {"intVal": 2}) cl.set_value("intVal", 2, mcl_super) cl.set_value("intVal", 3, mcl) cl.delete_value("intVal", mcl_super) eq_(cl.values, {"intVal": 3}) 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'")