Tests: remove noisy output from bl_pyapi_idprop_datablock

As part of expected behavior this printed an exception,
making it seem as if there was an error in the test.

Now the exception is suppressed from the output, ensuring it matches
an the expected output.
This commit is contained in:
Campbell Barton 2021-10-12 17:57:41 +11:00
parent 6139782d81
commit eb8afc39f8
1 changed files with 85 additions and 38 deletions

View File

@ -18,13 +18,17 @@
# ./blender.bin --background -noaudio --python tests/python/bl_pyapi_idprop_datablock.py -- --verbose
import bpy
import sys
import os
import tempfile
import contextlib
import inspect
from bpy.types import UIList
import io
import os
import re
import sys
import tempfile
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()