RNA defaults test
[blender.git] / tests / python / bl_rna_defaults.py
1 # Apache License, Version 2.0
2
3 # ./blender.bin --background -noaudio --factory-startup --python tests/python/bl_rna_defaults.py
4
5 import bpy
6
7 DUMMY_NAME = "Untitled"
8 DUMMY_PATH = __file__
9 GLOBALS = {
10     "error_num": 0,
11     }
12
13
14 def validate_defaults(test_id, o):
15
16     def warning(prop_id, val_real, val_default):
17         print("Error %s: '%s.%s' is:%r, expected:%r" %
18               (test_id, o.__class__.__name__, prop_id, val_real, val_default))
19         GLOBALS["error_num"] += 1
20
21     properties = type(o).bl_rna.properties.items()
22     for prop_id, prop in properties:
23         if prop_id == "rna_type":
24             continue
25         prop_type = prop.type
26         if prop_type in {'STRING', 'COLLECTION'}:
27             continue
28
29         if prop_type == 'POINTER':
30             # traverse down pointers if they're set
31             val_real = getattr(o, prop_id)
32             if (val_real is not None) and (not isinstance(val_real, bpy.types.ID)):
33                 validate_defaults("%s.%s" % (test_id, prop_id), val_real)
34         elif prop_type in {'INT', 'BOOL'}:
35             array_length = prop.array_length
36             if array_length == 0:
37                 val_real = getattr(o, prop_id)
38                 val_default = prop.default
39                 if val_real != val_default:
40                     warning(prop_id, val_real, val_default)
41             else:
42                 pass  # TODO, array defaults
43         elif prop_type == 'FLOAT':
44             array_length = prop.array_length
45             if array_length == 0:
46                 val_real = getattr(o, prop_id)
47                 val_default = prop.default
48                 if val_real != val_default:
49                     warning(prop_id, val_real, val_default)
50             else:
51                 pass  # TODO, array defaults
52         elif prop_type == 'ENUM':
53             val_real = getattr(o, prop_id)
54             if prop.is_enum_flag:
55                 val_default = prop.default_flag
56             else:
57                 val_default = prop.default
58             if val_real != val_default:
59                 warning(prop_id, val_real, val_default)
60
61         # print(prop_id, prop_type)
62
63
64 def _test_id_gen(data_attr, args_create=(DUMMY_NAME,), create_method="new"):
65     def test_gen(test_id):
66         id_collection = getattr(bpy.data, data_attr)
67         create_fn = getattr(id_collection, create_method)
68         o = create_fn(*args_create)
69         o.user_clear()
70         validate_defaults(test_id, o)
71         id_collection.remove(o)
72     return test_gen
73
74
75 test_Action = _test_id_gen("actions")
76 test_Armature = _test_id_gen("armatures")
77 test_Camera = _test_id_gen("cameras")
78 test_Group = _test_id_gen("groups")
79 test_Lattice = _test_id_gen("lattices")
80 test_LineStyle = _test_id_gen("linestyles")
81 test_Mask = _test_id_gen("masks")
82 test_Material = _test_id_gen("materials")
83 test_Mesh = _test_id_gen("meshes")
84 test_MetaBall = _test_id_gen("metaballs")
85 test_MovieClip = _test_id_gen("movieclips", args_create=(DUMMY_PATH,), create_method="load")
86 test_Object = _test_id_gen("objects", args_create=(DUMMY_NAME, None))
87 test_Palette = _test_id_gen("palettes")
88 test_Particle = _test_id_gen("particles")
89 test_Scene = _test_id_gen("scenes")
90 test_Sound = _test_id_gen("sounds", args_create=(DUMMY_PATH,), create_method="load")
91 test_Speaker = _test_id_gen("speakers")
92 test_Text = _test_id_gen("texts")
93 test_VectorFont = _test_id_gen("fonts", args_create=("<builtin>",), create_method="load")
94 test_World = _test_id_gen("worlds")
95
96 ns = globals()
97 for t in bpy.data.curves.bl_rna.functions["new"].parameters["type"].enum_items.keys():
98     ns["test_Curve_%s" % t] = _test_id_gen("curves", args_create=(DUMMY_NAME, t))
99 for t in bpy.data.lamps.bl_rna.functions["new"].parameters["type"].enum_items.keys():
100     ns["test_Lamp_%s" % t] = _test_id_gen("lamps", args_create=(DUMMY_NAME, t))
101 # types are a dynamic enum, have to hard-code.
102 for t in "ShaderNodeTree", "CompositorNodeTree", "TextureNodeTree":
103     ns["test_NodeGroup_%s" % t] = _test_id_gen("node_groups", args_create=(DUMMY_NAME, t))
104 for t in bpy.data.textures.bl_rna.functions["new"].parameters["type"].enum_items.keys():
105     ns["test_Texture_%s" % t] = _test_id_gen("textures", args_create=(DUMMY_NAME, t))
106 del ns
107
108
109 def main():
110     for fn_id, fn_val in sorted(globals().items()):
111         if fn_id.startswith("test_") and callable(fn_val):
112             fn_val(fn_id)
113
114     print("Error (total): %d" % GLOBALS["error_num"])
115
116 if __name__ == "__main__":
117     main()