From 3a9726783f388b13b29510089affa9b9d85b0a22 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 1 May 2015 01:03:55 +1000 Subject: RNA defaults test Alternative to T32894, simple test which creates new data and compares with RNA defaults. Can be used to keep the values in sync without having to maintain a large set of defines. --- tests/python/bl_rna_defaults.py | 117 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 tests/python/bl_rna_defaults.py (limited to 'tests/python') diff --git a/tests/python/bl_rna_defaults.py b/tests/python/bl_rna_defaults.py new file mode 100644 index 00000000000..1d6f82b06c2 --- /dev/null +++ b/tests/python/bl_rna_defaults.py @@ -0,0 +1,117 @@ +# Apache License, Version 2.0 + +# ./blender.bin --background -noaudio --factory-startup --python tests/python/bl_rna_defaults.py + +import bpy + +DUMMY_NAME = "Untitled" +DUMMY_PATH = __file__ +GLOBALS = { + "error_num": 0, + } + + +def validate_defaults(test_id, o): + + def warning(prop_id, val_real, val_default): + print("Error %s: '%s.%s' is:%r, expected:%r" % + (test_id, o.__class__.__name__, prop_id, val_real, val_default)) + GLOBALS["error_num"] += 1 + + properties = type(o).bl_rna.properties.items() + for prop_id, prop in properties: + if prop_id == "rna_type": + continue + prop_type = prop.type + if prop_type in {'STRING', 'COLLECTION'}: + continue + + if prop_type == 'POINTER': + # traverse down pointers if they're set + val_real = getattr(o, prop_id) + if (val_real is not None) and (not isinstance(val_real, bpy.types.ID)): + validate_defaults("%s.%s" % (test_id, prop_id), val_real) + elif prop_type in {'INT', 'BOOL'}: + array_length = prop.array_length + if array_length == 0: + val_real = getattr(o, prop_id) + val_default = prop.default + if val_real != val_default: + warning(prop_id, val_real, val_default) + else: + pass # TODO, array defaults + elif prop_type == 'FLOAT': + array_length = prop.array_length + if array_length == 0: + val_real = getattr(o, prop_id) + val_default = prop.default + if val_real != val_default: + warning(prop_id, val_real, val_default) + else: + pass # TODO, array defaults + elif prop_type == 'ENUM': + val_real = getattr(o, prop_id) + if prop.is_enum_flag: + val_default = prop.default_flag + else: + val_default = prop.default + if val_real != val_default: + warning(prop_id, val_real, val_default) + + # print(prop_id, prop_type) + + +def _test_id_gen(data_attr, args_create=(DUMMY_NAME,), create_method="new"): + def test_gen(test_id): + id_collection = getattr(bpy.data, data_attr) + create_fn = getattr(id_collection, create_method) + o = create_fn(*args_create) + o.user_clear() + validate_defaults(test_id, o) + id_collection.remove(o) + return test_gen + + +test_Action = _test_id_gen("actions") +test_Armature = _test_id_gen("armatures") +test_Camera = _test_id_gen("cameras") +test_Group = _test_id_gen("groups") +test_Lattice = _test_id_gen("lattices") +test_LineStyle = _test_id_gen("linestyles") +test_Mask = _test_id_gen("masks") +test_Material = _test_id_gen("materials") +test_Mesh = _test_id_gen("meshes") +test_MetaBall = _test_id_gen("metaballs") +test_MovieClip = _test_id_gen("movieclips", args_create=(DUMMY_PATH,), create_method="load") +test_Object = _test_id_gen("objects", args_create=(DUMMY_NAME, None)) +test_Palette = _test_id_gen("palettes") +test_Particle = _test_id_gen("particles") +test_Scene = _test_id_gen("scenes") +test_Sound = _test_id_gen("sounds", args_create=(DUMMY_PATH,), create_method="load") +test_Speaker = _test_id_gen("speakers") +test_Text = _test_id_gen("texts") +test_VectorFont = _test_id_gen("fonts", args_create=("",), create_method="load") +test_World = _test_id_gen("worlds") + +ns = globals() +for t in bpy.data.curves.bl_rna.functions["new"].parameters["type"].enum_items.keys(): + ns["test_Curve_%s" % t] = _test_id_gen("curves", args_create=(DUMMY_NAME, t)) +for t in bpy.data.lamps.bl_rna.functions["new"].parameters["type"].enum_items.keys(): + ns["test_Lamp_%s" % t] = _test_id_gen("lamps", args_create=(DUMMY_NAME, t)) +# types are a dynamic enum, have to hard-code. +for t in "ShaderNodeTree", "CompositorNodeTree", "TextureNodeTree": + ns["test_NodeGroup_%s" % t] = _test_id_gen("node_groups", args_create=(DUMMY_NAME, t)) +for t in bpy.data.textures.bl_rna.functions["new"].parameters["type"].enum_items.keys(): + ns["test_Texture_%s" % t] = _test_id_gen("textures", args_create=(DUMMY_NAME, t)) +del ns + + +def main(): + for fn_id, fn_val in sorted(globals().items()): + if fn_id.startswith("test_") and callable(fn_val): + fn_val(fn_id) + + print("Error (total): %d" % GLOBALS["error_num"]) + +if __name__ == "__main__": + main() -- cgit v1.2.3