Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/python/bl_pyapi_idprop_datablock.py121
1 files changed, 84 insertions, 37 deletions
diff --git a/tests/python/bl_pyapi_idprop_datablock.py b/tests/python/bl_pyapi_idprop_datablock.py
index 6cc99154cfe..d4253dc4665 100644
--- a/tests/python/bl_pyapi_idprop_datablock.py
+++ b/tests/python/bl_pyapi_idprop_datablock.py
@@ -18,13 +18,17 @@
# ./blender.bin --background -noaudio --python tests/python/bl_pyapi_idprop_datablock.py -- --verbose
-import bpy
-import sys
+import contextlib
+import inspect
+import io
import os
+import re
+import sys
import tempfile
-import inspect
-from bpy.types import UIList
+import bpy
+
+from bpy.types import UIList
arr_len = 100
ob_cp_count = 100
@@ -49,13 +53,40 @@ def print_fail_msg_and_exit(msg):
os._exit(1)
-def abort_if_false(expr, msg=None):
+def expect_false_or_abort(expr, msg=None):
if not expr:
if not msg:
msg = "test failed"
print_fail_msg_and_exit(msg)
+def expect_exception_or_abort(*, fn, ex):
+ try:
+ fn()
+ exception = False
+ except ex:
+ exception = True
+ if exception:
+ return # OK
+ print_fail_msg_and_exit("test failed")
+
+
+def expect_ouput_or_abort(*, fn, match_stderr=None, match_stdout=None):
+
+ stdout, stderr = io.StringIO(), io.StringIO()
+
+ with (contextlib.redirect_stderr(stderr), contextlib.redirect_stdout(stdout)):
+ fn()
+
+ for (handle, match) in ((stdout, match_stdout), (stderr, match_stderr)):
+ if not match:
+ continue
+ handle.seek(0)
+ output = handle.read()
+ if not re.match(match, output):
+ print_fail_msg_and_exit("%r not found in %r" % (match, output))
+
+
class TestClass(bpy.types.PropertyGroup):
test_prop: bpy.props.PointerProperty(type=bpy.types.Object)
name: bpy.props.StringProperty()
@@ -71,14 +102,6 @@ def get_scene(lib_name, sce_name):
return s
-def check_crash(fnc, args=None):
- try:
- fnc(args) if args else fnc()
- except:
- return
- print_fail_msg_and_exit("test failed")
-
-
def init():
bpy.utils.register_class(TestClass)
bpy.types.Object.prop_array = bpy.props.CollectionProperty(
@@ -122,12 +145,13 @@ def make_lib():
def check_lib():
# check pointer
- abort_if_false(bpy.data.objects["Cube"].prop == bpy.data.objects['Camera'])
+ expect_false_or_abort(bpy.data.objects["Cube"].prop == bpy.data.objects['Camera'])
# check array of pointers in duplicated object
for i in range(0, arr_len):
- abort_if_false(bpy.data.objects["Cube.001"].prop_array[i].test_prop ==
- bpy.data.objects['Light'])
+ expect_false_or_abort(
+ bpy.data.objects["Cube.001"].prop_array[i].test_prop ==
+ bpy.data.objects['Light'])
def check_lib_linking():
@@ -140,9 +164,9 @@ def check_lib_linking():
o = bpy.data.scenes["Scene_lib"].objects['Unique_Cube']
- abort_if_false(o.prop_array[0].test_prop == bpy.data.scenes["Scene_lib"].objects['Light'])
- abort_if_false(o.prop == bpy.data.scenes["Scene_lib"].objects['Camera'])
- abort_if_false(o.prop.library == o.library)
+ expect_false_or_abort(o.prop_array[0].test_prop == bpy.data.scenes["Scene_lib"].objects['Light'])
+ expect_false_or_abort(o.prop == bpy.data.scenes["Scene_lib"].objects['Camera'])
+ expect_false_or_abort(o.prop.library == o.library)
bpy.ops.wm.save_as_mainfile(filepath=test_path)
@@ -162,9 +186,10 @@ def check_linked_scene_copying():
# check node's props
# must point to own scene camera
- abort_if_false(intern_sce.node_tree.nodes['Render Layers']["prop"] and
- not (intern_sce.node_tree.nodes['Render Layers']["prop"] ==
- extern_sce.node_tree.nodes['Render Layers']["prop"]))
+ expect_false_or_abort(
+ intern_sce.node_tree.nodes['Render Layers']["prop"] and
+ not (intern_sce.node_tree.nodes['Render Layers']["prop"] ==
+ extern_sce.node_tree.nodes['Render Layers']["prop"]))
def check_scene_copying():
@@ -183,8 +208,9 @@ def check_scene_copying():
# check node's props
# must point to own scene camera
- abort_if_false(not (first_sce.node_tree.nodes['Render Layers']["prop"] ==
- second_sce.node_tree.nodes['Render Layers']["prop"]))
+ expect_false_or_abort(
+ not (first_sce.node_tree.nodes['Render Layers']["prop"] ==
+ second_sce.node_tree.nodes['Render Layers']["prop"]))
# count users
@@ -194,11 +220,11 @@ def test_users_counting():
n = 1000
for i in range(0, n):
bpy.data.objects["Cube"]["a%s" % i] = bpy.data.objects["Light"].data
- abort_if_false(bpy.data.objects["Light"].data.users == Light_us + n)
+ expect_false_or_abort(bpy.data.objects["Light"].data.users == Light_us + n)
for i in range(0, int(n / 2)):
bpy.data.objects["Cube"]["a%s" % i] = 1
- abort_if_false(bpy.data.objects["Light"].data.users == Light_us + int(n / 2))
+ expect_false_or_abort(bpy.data.objects["Light"].data.users == Light_us + int(n / 2))
# linking
@@ -240,16 +266,22 @@ def test_restrictions1():
self.layout.template_ID(context.scene, "prop1")
self.layout.prop_search(context.scene, "prop2", bpy.data, "node_groups")
- op = self.layout.operator("scene.test_op")
+ op = self.layout.operator(TEST_Op.bl_idname)
op.str_prop = "test string"
- def test_fnc(op):
+ def test_fn(op):
op["ob"] = bpy.data.objects['Unique_Cube']
- check_crash(test_fnc, op)
- abort_if_false(not hasattr(op, "id_prop"))
+ expect_exception_or_abort(
+ fn=lambda: test_fn(op),
+ ex=ImportError,
+ )
+ expect_false_or_abort(not hasattr(op, "id_prop"))
bpy.utils.register_class(TEST_PT_DatablockProp)
- bpy.utils.register_class(TEST_Op)
+ expect_ouput_or_abort(
+ fn=lambda: bpy.utils.register_class(TEST_Op),
+ match_stderr="^ValueError: bpy_struct \"SCENE_OT_test_op\" registration error:",
+ )
def poll(self, value):
return value.name in bpy.data.scenes["Scene_lib"].objects
@@ -270,12 +302,18 @@ def test_restrictions1():
# NodeTree id_prop
bpy.context.scene.prop2 = bpy.data.objects["Light.001"]
- check_crash(sub_test)
+ expect_exception_or_abort(
+ fn=sub_test,
+ ex=TypeError,
+ )
bpy.context.scene.prop2 = bpy.data.node_groups.new("Shader", "ShaderNodeTree")
- print("Please, test GUI performance manually on the Render tab, '%s' panel" %
- TEST_PT_DatablockProp.bl_label, file=sys.stderr)
+ # NOTE: keep since the author thought this useful information.
+ # print(
+ # "Please, test GUI performance manually on the Render tab, '%s' panel" %
+ # TEST_PT_DatablockProp.bl_label, file=sys.stderr,
+ # )
sys.stderr.flush()
@@ -318,8 +356,14 @@ def test_restrictions2():
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
layout.prop(item, "name", text="", emboss=False, icon_value=icon)
- check_crash(bpy.utils.register_class, TestPrefs)
- check_crash(bpy.utils.register_class, TEST_UL_list)
+ expect_exception_or_abort(
+ fn=lambda: bpy.utils.register_class(TestPrefs),
+ ex=ValueError,
+ )
+ expect_exception_or_abort(
+ fn=lambda: bpy.utils.register_class(TEST_UL_list),
+ ex=ValueError,
+ )
bpy.utils.unregister_class(TestClassCollection)
@@ -335,7 +379,10 @@ def main():
test_users_counting()
test_linking()
test_restrictions1()
- check_crash(test_regressions)
+ expect_exception_or_abort(
+ fn=test_regressions,
+ ex=AttributeError,
+ )
test_restrictions2()