diff options
Diffstat (limited to 'tests')
23 files changed, 353 insertions, 39 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8f72db07d92..8941cc671dd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -30,7 +30,7 @@ endif() # The installation directory's Python is the best one to use. However, it can only be there after the install step, # which means that Python will never be there on a fresh system. To suit different needs, the user can pass # -DTEST_PYTHON_EXE=/path/to/python to CMake. -if (NOT TEST_PYTHON_EXE) +if(NOT TEST_PYTHON_EXE) set(TEST_PYTHON_EXE ${_default_test_python_exe}) message(STATUS "Tests: Using Python executable: ${TEST_PYTHON_EXE}") elseif(NOT EXISTS ${TEST_PYTHON_EXE}) diff --git a/tests/gtests/runner/CMakeLists.txt b/tests/gtests/runner/CMakeLists.txt index 8b3390e7aec..6640d798ed6 100644 --- a/tests/gtests/runner/CMakeLists.txt +++ b/tests/gtests/runner/CMakeLists.txt @@ -51,7 +51,7 @@ BLENDER_SRC_GTEST_EX( EXTRA_LIBS "${TEST_LIBS}" SKIP_ADD_TEST ) -setup_liblinks(blender_test) +setup_platform_linker_libs(blender_test) if(WIN32) foreach(_lib ${_test_libs}) @@ -86,7 +86,11 @@ set(_GOOGLETEST_DISCOVER_TESTS_SCRIPT if(APPLE) set(_test_release_dir ${TEST_INSTALL_DIR}/Blender.app/Contents/Resources/${BLENDER_VERSION}) else() - set(_test_release_dir ${TEST_INSTALL_DIR}/${BLENDER_VERSION}) + if(WIN32 OR WITH_INSTALL_PORTABLE) + set(_test_release_dir ${TEST_INSTALL_DIR}/${BLENDER_VERSION}) + else() + set(_test_release_dir ${TEST_INSTALL_DIR}/share/blender/${BLENDER_VERSION}) + endif() endif() gtest_discover_tests(blender_test diff --git a/tests/gtests/testing/testing.h b/tests/gtests/testing/testing.h index 34928035b7d..8136a93314e 100644 --- a/tests/gtests/testing/testing.h +++ b/tests/gtests/testing/testing.h @@ -137,4 +137,22 @@ inline void EXPECT_EQ_ARRAY_ND(const T *expected, const T *actual, const size_t } } +#ifdef _WIN32 +# define ABORT_PREDICATE ::testing::ExitedWithCode(3) +#else +# define ABORT_PREDICATE ::testing::KilledBySignal(SIGABRT) +#endif + +/* Test macro for when BLI_assert() is expected to fail. + * Note that the EXPECT_BLI_ASSERT macro is a no-op, unless used in a debug build with + * WITH_ASSERT_ABORT=ON. */ +#if defined(WITH_ASSERT_ABORT) && !defined(NDEBUG) +/* EXPECT_EXIT() is used as that's the only exit-expecting function in GTest that allows us to + * check for SIGABRT. */ +# define EXPECT_BLI_ASSERT(function_call, expect_message) \ + EXPECT_EXIT(function_call, ABORT_PREDICATE, expect_message) +#else +# define EXPECT_BLI_ASSERT(function_call, expect_message) function_call +#endif + #endif // __BLENDER_TESTING_H__ diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt index 18f61d83c3c..22426a6d6fc 100644 --- a/tests/python/CMakeLists.txt +++ b/tests/python/CMakeLists.txt @@ -43,7 +43,9 @@ function(add_blender_test testname) # Don't fail tests on leaks since these often happen in external libraries # that we can't fix. - set_tests_properties(${testname} PROPERTIES ENVIRONMENT LSAN_OPTIONS=exitcode=0) + set_tests_properties(${testname} PROPERTIES ENVIRONMENT + LSAN_OPTIONS=exitcode=0:$ENV{LSAN_OPTIONS} + ) endfunction() # Run Python script outside Blender. @@ -56,7 +58,9 @@ function(add_python_test testname testscript) NAME ${testname} COMMAND ${TEST_PYTHON_EXE} ${testscript} ${ARGN} ) - set_tests_properties(${testname} PROPERTIES ENVIRONMENT LSAN_OPTIONS=exitcode=0) + set_tests_properties(${testname} PROPERTIES ENVIRONMENT + LSAN_OPTIONS=exitcode=0:$ENV{LSAN_OPTIONS} + ) endfunction() # ------------------------------------------------------------------------------ @@ -218,6 +222,15 @@ add_blender_test( ) # ------------------------------------------------------------------------------ +# ANIMATION TESTS +add_blender_test( + bl_animation_fcurves + --python ${CMAKE_CURRENT_LIST_DIR}/bl_animation_fcurves.py + -- + --testdir "${TEST_SRC_DIR}/animation" +) + +# ------------------------------------------------------------------------------ # IO TESTS # OBJ Import tests @@ -686,6 +699,30 @@ if(WITH_CODEC_FFMPEG) ) endif() + +# ------------------------------------------------------------------------------ +# SEQUENCER RENDER TESTS + +if(NOT OPENIMAGEIO_IDIFF) + MESSAGE(STATUS "Disabling sequencer render tests because OIIO idiff does not exist") +else() + set(render_tests + transform + ) + + foreach(render_test ${render_tests}) + add_python_test( + sequencer_render_${render_test} + ${CMAKE_CURRENT_LIST_DIR}/sequencer_render_tests.py + -blender "${TEST_BLENDER_EXE}" + -testdir "${TEST_SRC_DIR}/sequence_editing/${render_test}" + -idiff "${OPENIMAGEIO_IDIFF}" + -outdir "${TEST_OUT_DIR}/sequence_editing" + ) + endforeach() +endif() + + add_subdirectory(collada) # TODO: disabled for now after collection unification diff --git a/tests/python/alembic_export_tests.py b/tests/python/alembic_export_tests.py index b5d6bf65f3f..9d1738691f0 100644 --- a/tests/python/alembic_export_tests.py +++ b/tests/python/alembic_export_tests.py @@ -111,6 +111,7 @@ class AbstractAlembicTest(AbstractBlenderRunnerTest): 'uint64_t': int, 'float64_t': float, 'float32_t': float, + 'string': str, } result = {} @@ -586,6 +587,72 @@ class InvisibleObjectExportTest(AbstractAlembicTest): test('InvisibleAnimatedCube', False) +class CustomPropertiesExportTest(AbstractAlembicTest): + """Test export of custom properties.""" + + def _run_export(self, tempdir: pathlib.Path) -> pathlib.Path: + abc = tempdir / 'custom-properties.abc' + script = ( + "import bpy; bpy.context.scene.frame_set(1); " + "bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1)" % abc.as_posix() + ) + self.run_blender('custom-properties.blend', script) + return abc + + @with_tempdir + def test_xform_props(self, tempdir: pathlib.Path) -> None: + abc = self._run_export(tempdir) + abcprop = self.abcprop(abc, '/Cube/.xform/.userProperties') + + # Simple, single values. + self.assertEqual(abcprop['static_int'], [327]) + self.assertEqual(abcprop['static_float'], [47.01]) + self.assertEqual(abcprop['static_string'], ['Agents']) + self.assertEqual(abcprop['keyed_float'], [-1]) + self.assertEqual(abcprop['keyed_int'], [-47]) + + # Arrays. + self.assertEqual(abcprop['keyed_array_float'], [-1.000, 0.000, 1.000]) + self.assertEqual(abcprop['keyed_array_int'], [42, 47, 327]) + + # Multi-dimensional arrays. + self.assertEqual(abcprop['array_of_strings'], ['ผัดไทย', 'Pad Thai']) + self.assertEqual( + abcprop['matrix_tuple'], + [1.0, 0.0, 0.0, 3.33333, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]) + self.assertEqual( + abcprop['static_matrix'], + [1.0, 0.0, 0.0, 3.33333, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]) + self.assertEqual( + abcprop['nonuniform_array'], + [10, 20, 30, 1, 2, 47]) + + @with_tempdir + def test_mesh_props(self, tempdir: pathlib.Path) -> None: + abc = self._run_export(tempdir) + abcprop = self.abcprop(abc, '/Cube/Cube/.geom/.userProperties') + self.assertEqual(abcprop['mesh_tags'], ['cube', 'box', 'low-poly-sphere']) + + @with_tempdir + def test_camera_props(self, tempdir: pathlib.Path) -> None: + abc = self._run_export(tempdir) + abcprop = self.abcprop(abc, '/Camera/Hasselblad/.geom/.userProperties') + self.assertEqual(abcprop['type'], ['500c/m']) + + @with_tempdir + def test_disabled_export_option(self, tempdir: pathlib.Path) -> None: + abc = tempdir / 'custom-properties.abc' + script = ( + "import bpy; bpy.context.scene.frame_set(1); " + "bpy.ops.wm.alembic_export(filepath='%s', start=1, end=1, export_custom_properties=False)" % abc.as_posix() + ) + self.run_blender('custom-properties.blend', script) + + abcprop = self.abcprop(abc, '/Camera/Hasselblad/.geom/.userProperties') + self.assertIn('eyeSeparation', abcprop, 'Regular non-standard properties should still be written') + self.assertNotIn('type', abcprop, 'Custom properties should not be written') + + if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--blender', required=True) diff --git a/tests/python/batch_import.py b/tests/python/batch_import.py index 20d96a69a79..7e64081cfbb 100644 --- a/tests/python/batch_import.py +++ b/tests/python/batch_import.py @@ -150,10 +150,20 @@ def main(): # Example background utility, add some text and renders or saves it (with options) # Possible types are: string, int, long, choice, float and complex. - parser.add_option("-o", "--operator", dest="operator", help="This text will be used to render an image", type="string") + parser.add_option( + "-o", + "--operator", + dest="operator", + help="This text will be used to render an image", + type="string") parser.add_option("-p", "--path", dest="path", help="Path to use for searching for files", type='string') parser.add_option("-m", "--match", dest="match", help="Wildcard to match filename", type="string") - parser.add_option("-s", "--save_path", dest="save_path", help="Save the input file to a blend file in a new location", metavar='string') + parser.add_option( + "-s", + "--save_path", + dest="save_path", + help="Save the input file to a blend file in a new location", + metavar='string') parser.add_option("-S", "--start", dest="start", help="From collected files, start with this index", metavar='int') parser.add_option("-E", "--end", dest="end", help="From collected files, end with this index", metavar='int') diff --git a/tests/python/bl_alembic_io_test.py b/tests/python/bl_alembic_io_test.py index b9eca3057e7..53a0879f160 100644 --- a/tests/python/bl_alembic_io_test.py +++ b/tests/python/bl_alembic_io_test.py @@ -313,13 +313,13 @@ class CameraExportImportTest(unittest.TestCase): self.loc_rot_scale('CAM_Unit_Transform', (0, 0, 0), (0, 0, 0)) self.loc_rot_scale('CAM_Look_+Y', (2, 0, 0), (90, 0, 0)) - self.loc_rot_scale('CAM_Static_Child_Left', (2-0.15, 0, 0), (90, 0, 0)) - self.loc_rot_scale('CAM_Static_Child_Right', (2+0.15, 0, 0), (90, 0, 0)) + self.loc_rot_scale('CAM_Static_Child_Left', (2 - 0.15, 0, 0), (90, 0, 0)) + self.loc_rot_scale('CAM_Static_Child_Right', (2 + 0.15, 0, 0), (90, 0, 0)) self.loc_rot_scale('Static_Child', (2, 0, 1), (90, 0, 0)) self.loc_rot_scale('CAM_Animated', (4, 0, 0), (90, 0, 0)) - self.loc_rot_scale('CAM_Animated_Child_Left', (4-0.15, 0, 0), (90, 0, 0)) - self.loc_rot_scale('CAM_Animated_Child_Right', (4+0.15, 0, 0), (90, 0, 0)) + self.loc_rot_scale('CAM_Animated_Child_Left', (4 - 0.15, 0, 0), (90, 0, 0)) + self.loc_rot_scale('CAM_Animated_Child_Right', (4 + 0.15, 0, 0), (90, 0, 0)) self.loc_rot_scale('Animated_Child', (4, 0, 1), (90, 0, 0)) bpy.context.scene.frame_set(10) diff --git a/tests/python/bl_animation_fcurves.py b/tests/python/bl_animation_fcurves.py new file mode 100644 index 00000000000..b5772b8d335 --- /dev/null +++ b/tests/python/bl_animation_fcurves.py @@ -0,0 +1,93 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# <pep8 compliant> + +""" +blender -b -noaudio --factory-startup --python tests/python/bl_animation_fcurves.py -- --testdir /path/to/lib/tests/animation +""" + +import pathlib +import sys +import unittest + +import bpy + + +class FCurveEvaluationTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.testdir = args.testdir + + def setUp(self): + self.assertTrue(self.testdir.exists(), + 'Test dir %s should exist' % self.testdir) + + def test_fcurve_versioning_291(self): + # See D8752. + bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "fcurve-versioning-291.blend")) + cube = bpy.data.objects['Cube'] + fcurve = cube.animation_data.action.fcurves.find('location', index=0) + + self.assertAlmostEqual(0.0, fcurve.evaluate(1)) + self.assertAlmostEqual(0.019638698548078537, fcurve.evaluate(2)) + self.assertAlmostEqual(0.0878235399723053, fcurve.evaluate(3)) + self.assertAlmostEqual(0.21927043795585632, fcurve.evaluate(4)) + self.assertAlmostEqual(0.41515052318573, fcurve.evaluate(5)) + self.assertAlmostEqual(0.6332430243492126, fcurve.evaluate(6)) + self.assertAlmostEqual(0.8106040954589844, fcurve.evaluate(7)) + self.assertAlmostEqual(0.924369215965271, fcurve.evaluate(8)) + self.assertAlmostEqual(0.9830065965652466, fcurve.evaluate(9)) + self.assertAlmostEqual(1.0, fcurve.evaluate(10)) + + def test_fcurve_extreme_handles(self): + # See D8752. + bpy.ops.wm.open_mainfile(filepath=str(self.testdir / "fcurve-extreme-handles.blend")) + cube = bpy.data.objects['Cube'] + fcurve = cube.animation_data.action.fcurves.find('location', index=0) + + self.assertAlmostEqual(0.0, fcurve.evaluate(1)) + self.assertAlmostEqual(0.004713400732725859, fcurve.evaluate(2)) + self.assertAlmostEqual(0.022335870191454887, fcurve.evaluate(3)) + self.assertAlmostEqual(0.06331237405538559, fcurve.evaluate(4)) + self.assertAlmostEqual(0.16721539199352264, fcurve.evaluate(5)) + self.assertAlmostEqual(0.8327845335006714, fcurve.evaluate(6)) + self.assertAlmostEqual(0.9366875886917114, fcurve.evaluate(7)) + self.assertAlmostEqual(0.9776642322540283, fcurve.evaluate(8)) + self.assertAlmostEqual(0.9952865839004517, fcurve.evaluate(9)) + self.assertAlmostEqual(1.0, fcurve.evaluate(10)) + + +def main(): + global args + import argparse + + if '--' in sys.argv: + argv = [sys.argv[0]] + sys.argv[sys.argv.index('--') + 1:] + else: + argv = sys.argv + + parser = argparse.ArgumentParser() + parser.add_argument('--testdir', required=True, type=pathlib.Path) + args, remaining = parser.parse_known_args(argv) + + unittest.main(argv=remaining) + + +if __name__ == "__main__": + main() diff --git a/tests/python/bl_blendfile_io.py b/tests/python/bl_blendfile_io.py index ab06e313566..49814ea5902 100644 --- a/tests/python/bl_blendfile_io.py +++ b/tests/python/bl_blendfile_io.py @@ -44,10 +44,9 @@ class TestBlendFileSaveLoadBasic(TestHelper): assert(orig_data == read_data) - TESTS = ( TestBlendFileSaveLoadBasic, - ) +) def argparse_create(): diff --git a/tests/python/bl_blendfile_liblink.py b/tests/python/bl_blendfile_liblink.py index d1cc7efc7fd..b48deb7bd7b 100644 --- a/tests/python/bl_blendfile_liblink.py +++ b/tests/python/bl_blendfile_liblink.py @@ -42,10 +42,9 @@ class TestBlendLibLinkSaveLoadBasic(TestHelper): assert(orig_data == read_data) - TESTS = ( TestBlendLibLinkSaveLoadBasic, - ) +) def argparse_create(): diff --git a/tests/python/bl_blendfile_utils.py b/tests/python/bl_blendfile_utils.py index 48e24cd0684..c87b47e5ce7 100644 --- a/tests/python/bl_blendfile_utils.py +++ b/tests/python/bl_blendfile_utils.py @@ -15,7 +15,7 @@ class TestHelper: @classmethod def blender_data_to_tuple(cls, bdata, pprint_name=None): ret = sorted(tuple((cls.id_to_uid(k), sorted(tuple(cls.id_to_uid(vv) for vv in v))) - for k, v in bdata.user_map().items())) + for k, v in bdata.user_map().items())) if pprint_name is not None: print("\n%s:" % pprint_name) pprint.pprint(ret) diff --git a/tests/python/bl_constraints.py b/tests/python/bl_constraints.py index 323dd874ac0..4deabc5f541 100644 --- a/tests/python/bl_constraints.py +++ b/tests/python/bl_constraints.py @@ -44,7 +44,7 @@ class AbstractConstraintTests(unittest.TestCase): collection = top_collection.children[self.layer_collection] collection.exclude = False - def assert_matrix(self, actual_matrix, expect_matrix, object_name: str, places=6, delta=None): + def assert_matrix(self, actual_matrix, expect_matrix, object_name: str, places=None, delta=1e-6): """Asserts that the matrices almost equal.""" self.assertEqual(len(actual_matrix), 4, 'Expected a 4x4 matrix') @@ -85,7 +85,7 @@ class AbstractConstraintTests(unittest.TestCase): actual = self.bone_matrix(object_name, bone_name) self.assert_matrix(actual, expect, object_name) - def constraint_context(self, constraint_name: str, owner_name: str='') -> dict: + def constraint_context(self, constraint_name: str, owner_name: str = '') -> dict: """Return a context suitable for calling object constraint operators. Assumes the owner is called "{constraint_name}.owner" if owner_name=''. @@ -100,7 +100,7 @@ class AbstractConstraintTests(unittest.TestCase): } return context - def bone_constraint_context(self, constraint_name: str, owner_name: str='', bone_name: str='') -> dict: + def bone_constraint_context(self, constraint_name: str, owner_name: str = '', bone_name: str = '') -> dict: """Return a context suitable for calling bone constraint operators. Assumes the owner's object is called "{constraint_name}.owner" if owner_name=''. diff --git a/tests/python/bl_run_operators.py b/tests/python/bl_run_operators.py index b8b534a0a11..26fe6dac93d 100644 --- a/tests/python/bl_run_operators.py +++ b/tests/python/bl_run_operators.py @@ -503,7 +503,7 @@ def main(): if __name__ == "__main__": - # ~ for i in range(200): - # ~ RANDOM_SEED[0] += 1 - #~ main() + # for i in range(200): + # RANDOM_SEED[0] += 1 + # main() main() diff --git a/tests/python/cycles_render_tests.py b/tests/python/cycles_render_tests.py index cc949248ce6..3c597b39cb8 100644 --- a/tests/python/cycles_render_tests.py +++ b/tests/python/cycles_render_tests.py @@ -43,6 +43,7 @@ def get_arguments(filepath, output_filepath): return args + def create_argparse(): parser = argparse.ArgumentParser() parser.add_argument("-blender", nargs="+") diff --git a/tests/python/eevee_render_tests.py b/tests/python/eevee_render_tests.py index a90d7730ace..4c3ca28402f 100644 --- a/tests/python/eevee_render_tests.py +++ b/tests/python/eevee_render_tests.py @@ -8,6 +8,7 @@ import shutil import subprocess import sys + def setup(): import bpy @@ -42,13 +43,13 @@ def setup(): # Simple probe setup bpy.ops.object.lightprobe_add(type='CUBEMAP', location=(0.5, 0, 1.5)) cubemap = bpy.context.selected_objects[0] - cubemap.scale = (2.5,2.5,1.0) + cubemap.scale = (2.5, 2.5, 1.0) cubemap.data.falloff = 0 cubemap.data.clip_start = 2.4 bpy.ops.object.lightprobe_add(type='GRID', location=(0, 0, 0.25)) grid = bpy.context.selected_objects[0] - grid.scale = (1.735,1.735,1.735) + grid.scale = (1.735, 1.735, 1.735) grid.data.grid_resolution_x = 3 grid.data.grid_resolution_y = 3 grid.data.grid_resolution_z = 2 diff --git a/tests/python/modifiers.py b/tests/python/modifiers.py index 4bbcf226aba..ba156cef8ea 100644 --- a/tests/python/modifiers.py +++ b/tests/python/modifiers.py @@ -186,7 +186,7 @@ def main(): ["testMergedWeld", "expectedMergedWeld", [ModifierSpec("weld", 'WELD', {"merge_threshold": 0.021})]], ["testMergedAllWeld", "expectedMergedAllWeld", - [ModifierSpec("weld", 'WELD', {"merge_threshold": 1.1})]], + [ModifierSpec("weld", 'WELD', {"merge_threshold": 1.8})]], ["testMergedNoneWeld", "expectedMergedNoneWeld", [ModifierSpec("weld", 'WELD', {"merge_threshold": 0.019})]], diff --git a/tests/python/modules/global_report.py b/tests/python/modules/global_report.py index 8ed8551beb9..f7f181c4736 100755 --- a/tests/python/modules/global_report.py +++ b/tests/python/modules/global_report.py @@ -6,6 +6,7 @@ import glob import os import pathlib + def _write_html(output_dir): combined_reports = "" @@ -21,7 +22,7 @@ def _write_html(output_dir): filepath = os.path.join(output_dir, filename) combined_reports += pathlib.Path(filepath).read_text() - combined_reports += "<br/>\n"; + combined_reports += "<br/>\n" html = """ <html> @@ -66,7 +67,7 @@ def add(output_dir, category, name, filepath, failed=None): name=name, filepath=filepath) - dirpath = os.path.join(output_dir, "report", category); + dirpath = os.path.join(output_dir, "report", category) os.makedirs(dirpath, exist_ok=True) filepath = os.path.join(dirpath, name + ".data") pathlib.Path(filepath).write_text(html) diff --git a/tests/python/modules/mesh_test.py b/tests/python/modules/mesh_test.py index af0e78257d5..c85e7acf4e8 100644 --- a/tests/python/modules/mesh_test.py +++ b/tests/python/modules/mesh_test.py @@ -95,6 +95,7 @@ class PhysicsSpec: return "Physics Modifier: " + self.modifier_name + " of type " + self.modifier_type + \ " with parameters: " + str(self.modifier_parameters) + " with frame end: " + str(self.frame_end) + class OperatorSpec: """ Holds one operator and its parameters. @@ -127,7 +128,14 @@ class MeshTest: the public method run_test(). """ - def __init__(self, test_object_name: str, expected_object_name: str, operations_stack=None, apply_modifiers=False, threshold=None): + def __init__( + self, + test_object_name: str, + expected_object_name: str, + operations_stack=None, + apply_modifiers=False, + threshold=None, + ): """ Constructs a MeshTest object. Raises a KeyError if objects with names expected_object_name or test_object_name don't exist. @@ -258,7 +266,6 @@ class MeshTest: if self.apply_modifier: bpy.ops.object.modifier_apply(modifier=modifier_spec.modifier_name) - def _bake_current_simulation(self, obj, test_mod_type, test_mod_name, frame_end): for scene in bpy.data.scenes: for modifier in obj.modifiers: @@ -281,7 +288,6 @@ class MeshTest: print("Created modifier '{}' of type '{}'.". format(physics_spec.modifier_name, physics_spec.modifier_type)) - for param_name in physics_spec.modifier_parameters: try: setattr(physics_setting, param_name, physics_spec.modifier_parameters[param_name]) @@ -296,11 +302,15 @@ class MeshTest: scene.frame_set(physics_spec.frame_end + 1) - self._bake_current_simulation(test_object, physics_spec.modifier_type, physics_spec.modifier_name, physics_spec.frame_end) + self._bake_current_simulation( + test_object, + physics_spec.modifier_type, + physics_spec.modifier_name, + physics_spec.frame_end, + ) if self.apply_modifier: bpy.ops.object.modifier_apply(modifier=physics_spec.modifier_name) - def _apply_operator(self, test_object, operator: OperatorSpec): """ Apply operator on test object. diff --git a/tests/python/modules/render_report.py b/tests/python/modules/render_report.py index b6cafc2ee24..832d3849f01 100755 --- a/tests/python/modules/render_report.py +++ b/tests/python/modules/render_report.py @@ -31,9 +31,10 @@ COLORS = COLORS_DUMMY # NOTE: Keep everything lowercase. BLACKLIST = ( - # 'file_to_blacklist.blend', + # 'file_to_blacklist.blend', ) + def print_message(message, type=None, status=''): if type == 'SUCCESS': print(COLORS.GREEN, end="") diff --git a/tests/python/operators.py b/tests/python/operators.py index 626aaedc724..901820c7b2d 100644 --- a/tests/python/operators.py +++ b/tests/python/operators.py @@ -146,7 +146,7 @@ def main(): "expectedCubeInsetDepth", "inset", {"thickness": 0.2, "depth": 0.2}], ["FACE", {35, 36, 37, 45, 46, 47, 55, 56, 57}, "testGridInsetRelativeOffset", "expectedGridInsetRelativeOffset", "inset", {"thickness": 0.4, "use_relative_offset": True}], - ] + ] operators_test = OperatorTest(tests) diff --git a/tests/python/rna_array.py b/tests/python/rna_array.py index e0d63cf75ea..623766aa0a1 100644 --- a/tests/python/rna_array.py +++ b/tests/python/rna_array.py @@ -164,7 +164,8 @@ class TestMArray(unittest.TestCase): def test_assign_item(self): # arr[i] = x - for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool) * 2): + for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), + (rand_float, rand_int, rand_bool) * 2): rval = make_random_2d_array((4, 5), func) for i in range(3): @@ -172,7 +173,8 @@ class TestMArray(unittest.TestCase): self.assertEqual(prop_to_list(getattr(test, arr)[i]), rval) # arr[i][j] = x - for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), (rand_float, rand_int, rand_bool) * 2): + for arr, func in zip(("fmarr", "imarr", "bmarr", "fdmarr", "idmarr", "bdmarr"), + (rand_float, rand_int, rand_bool) * 2): arr = getattr(test, arr) rval = make_random_array(5, func) @@ -283,7 +285,10 @@ def prop_to_list(prop): def suite(): - return unittest.TestSuite([unittest.TestLoader().loadTestsFromTestCase(TestArray), unittest.TestLoader().loadTestsFromTestCase(TestMArray)]) + return unittest.TestSuite([ + unittest.TestLoader().loadTestsFromTestCase(TestArray), + unittest.TestLoader().loadTestsFromTestCase(TestMArray), + ]) if __name__ == "__main__": diff --git a/tests/python/rna_info_dump.py b/tests/python/rna_info_dump.py index 01cbe8d290b..bca912f39cf 100644 --- a/tests/python/rna_info_dump.py +++ b/tests/python/rna_info_dump.py @@ -81,7 +81,10 @@ def api_dump(use_properties=True, use_functions=True): for prop in v.properties: if prop.collection_type: - funcs = [(prop.identifier + "." + func.identifier, func) for func in prop.collection_type.functions] + funcs = [ + (prop.identifier + "." + func.identifier, func) + for func in prop.collection_type.functions + ] for func_id, func in funcs: data.append(func_to_str(struct_id_str, func_id, func)) data.sort() @@ -100,7 +103,10 @@ def api_dump(use_properties=True, use_functions=True): for prop in v.properties: if prop.collection_type: - props = [(prop.identifier + "." + prop_sub.identifier, prop_sub) for prop_sub in prop.collection_type.properties] + props = [ + (prop.identifier + "." + prop_sub.identifier, prop_sub) + for prop_sub in prop.collection_type.properties + ] for prop_sub_id, prop_sub in props: data.append(prop_to_str(struct_id_str, prop_sub_id, prop_sub)) data.sort() diff --git a/tests/python/sequencer_render_tests.py b/tests/python/sequencer_render_tests.py new file mode 100644 index 00000000000..54c9d68817b --- /dev/null +++ b/tests/python/sequencer_render_tests.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# Apache License, Version 2.0 + +import argparse +import os +import shlex +import shutil +import subprocess +import sys +from pathlib import Path + + +def get_arguments(filepath, output_filepath): + dirname = os.path.dirname(filepath) + basedir = os.path.dirname(dirname) + + args = [ + "--background", + "-noaudio", + "--factory-startup", + "--enable-autoexec", + "--debug-memory", + "--debug-exit-on-error", + filepath, + "-o", output_filepath, + "-f", "1", + "-F", "PNG"] + + return args + + +def create_argparse(): + parser = argparse.ArgumentParser() + parser.add_argument("-blender", nargs="+") + parser.add_argument("-testdir", nargs=1) + parser.add_argument("-outdir", nargs=1) + parser.add_argument("-idiff", nargs=1) + return parser + + +def main(): + parser = create_argparse() + args = parser.parse_args() + + blender = args.blender[0] + test_dir = args.testdir[0] + idiff = args.idiff[0] + output_dir = args.outdir[0] + + from modules import render_report + report = render_report.Report("Sequencer", output_dir, idiff) + report.set_pixelated(True) + report.set_reference_dir("reference") + + test_dir_name = Path(test_dir).name + ok = report.run(test_dir, blender, get_arguments, batch=True) + + sys.exit(not ok) + + +if __name__ == "__main__": + main() |