blender/tests/python/bl_rna_defaults.py
Campbell Barton 3a9726783f 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.
2015-05-01 01:15:55 +10:00

118 lines
4.3 KiB
Python

# 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=("<builtin>",), 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()