Changeset View
Changeset View
Standalone View
Standalone View
tests/python/modules/mesh_test.py
| Show All 37 Lines | |||||
| class ModifierSpec: | class ModifierSpec: | ||||
| """ | """ | ||||
| Holds a Generate or Deform or Physics modifier type and its parameters. | Holds a Generate or Deform or Physics modifier type and its parameters. | ||||
| """ | """ | ||||
| def __init__(self, modifier_name: str, modifier_type: str, modifier_parameters: dict, frame_end=0): | def __init__(self, modifier_name: str, modifier_type: str, modifier_parameters: dict, frame_end=0): | ||||
| """ | """ | ||||
| Constructs a modifier spec. | Constructs a modifier spec. | ||||
| :param modifier_name: str - name of object modifier, e.g. "myFirstSubsurfModif" | :arg modifier_name: str - name of object modifier, e.g. "myFirstSubsurfModif" | ||||
| :param modifier_type: str - type of object modifier, e.g. "SUBSURF" | :arg modifier_type: str - type of object modifier, e.g. "SUBSURF" | ||||
| :param modifier_parameters: dict - {name : val} dictionary giving modifier parameters, e.g. {"quality" : 4} | :arg modifier_parameters: dict - {name : val} dictionary giving modifier parameters, e.g. {"quality" : 4} | ||||
| :param frame_end: int - frame at which simulation needs to be baked or modifier needs to be applied. | :arg frame_end: int - frame at which simulation needs to be baked or modifier needs to be applied. | ||||
| """ | """ | ||||
| self.modifier_name = modifier_name | self.modifier_name = modifier_name | ||||
| self.modifier_type = modifier_type | self.modifier_type = modifier_type | ||||
| self.modifier_parameters = modifier_parameters | self.modifier_parameters = modifier_parameters | ||||
| self.frame_end = frame_end | self.frame_end = frame_end | ||||
| def __str__(self): | def __str__(self): | ||||
| return "Modifier: " + self.modifier_name + " of type " + self.modifier_type + \ | return "Modifier: " + self.modifier_name + " of type " + self.modifier_type + \ | ||||
| " with parameters: " + str(self.modifier_parameters) | " with parameters: " + str(self.modifier_parameters) | ||||
| class ParticleSystemSpec: | class ParticleSystemSpec: | ||||
| """ | """ | ||||
| Holds a Particle System modifier and its parameters. | Holds a Particle System modifier and its parameters. | ||||
| """ | """ | ||||
| def __init__(self, modifier_name: str, modifier_type: str, modifier_parameters: dict, frame_end: int): | def __init__(self, modifier_name: str, modifier_type: str, modifier_parameters: dict, frame_end: int): | ||||
| """ | """ | ||||
| Constructs a particle system spec. | Constructs a particle system spec. | ||||
| :param modifier_name: str - name of object modifier, e.g. "Particles" | :arg modifier_name: str - name of object modifier, e.g. "Particles" | ||||
| :param modifier_type: str - type of object modifier, e.g. "PARTICLE_SYSTEM" | :arg modifier_type: str - type of object modifier, e.g. "PARTICLE_SYSTEM" | ||||
| :param modifier_parameters: dict - {name : val} dictionary giving modifier parameters, e.g. {"seed" : 1} | :arg modifier_parameters: dict - {name : val} dictionary giving modifier parameters, e.g. {"seed" : 1} | ||||
| :param frame_end: int - the last frame of the simulation at which the modifier is applied | :arg frame_end: int - the last frame of the simulation at which the modifier is applied | ||||
| """ | """ | ||||
| self.modifier_name = modifier_name | self.modifier_name = modifier_name | ||||
| self.modifier_type = modifier_type | self.modifier_type = modifier_type | ||||
| self.modifier_parameters = modifier_parameters | self.modifier_parameters = modifier_parameters | ||||
| self.frame_end = frame_end | self.frame_end = frame_end | ||||
| def __str__(self): | def __str__(self): | ||||
| return "Physics Modifier: " + self.modifier_name + " of type " + self.modifier_type + \ | return "Physics Modifier: " + self.modifier_name + " of type " + self.modifier_type + \ | ||||
| Show All 11 Lines | def __init__( | ||||
| operator_parameters: dict, | operator_parameters: dict, | ||||
| select_mode: str, | select_mode: str, | ||||
| selection, | selection, | ||||
| *, | *, | ||||
| select_history: bool = False, | select_history: bool = False, | ||||
| ): | ): | ||||
| """ | """ | ||||
| Constructs an OperatorSpecEditMode. Raises ValueError if selec_mode is invalid. | Constructs an OperatorSpecEditMode. Raises ValueError if selec_mode is invalid. | ||||
| :param operator_name: str - name of mesh operator from bpy.ops.mesh, e.g. "bevel" or "fill" | :arg operator_name: str - name of mesh operator from bpy.ops.mesh, e.g. "bevel" or "fill" | ||||
| :param operator_parameters: dict - {name : val} dictionary containing operator parameters. | :arg operator_parameters: dict - {name : val} dictionary containing operator parameters. | ||||
| :param select_mode: str - mesh selection mode, must be either 'VERT', 'EDGE' or 'FACE' | :arg select_mode: str - mesh selection mode, must be either 'VERT', 'EDGE' or 'FACE' | ||||
| :param selection: sequence - vertices/edges/faces indices to select, e.g. [0, 9, 10]. | :arg selection: sequence - vertices/edges/faces indices to select, e.g. [0, 9, 10]. | ||||
| :param: select_history: bool - load selection into bmesh selection history. | :arg: select_history: bool - load selection into bmesh selection history. | ||||
| """ | """ | ||||
| self.operator_name = operator_name | self.operator_name = operator_name | ||||
| self.operator_parameters = operator_parameters | self.operator_parameters = operator_parameters | ||||
| if select_mode not in {'VERT', 'EDGE', 'FACE'}: | if select_mode not in {'VERT', 'EDGE', 'FACE'}: | ||||
| raise ValueError("select_mode must be either {}, {} or {}".format('VERT', 'EDGE', 'FACE')) | raise ValueError("select_mode must be either {}, {} or {}".format('VERT', 'EDGE', 'FACE')) | ||||
| self.select_mode = select_mode | self.select_mode = select_mode | ||||
| self.selection = selection | self.selection = selection | ||||
| self.select_history = select_history | self.select_history = select_history | ||||
| def __str__(self): | def __str__(self): | ||||
| return "Operator: " + self.operator_name + " with parameters: " + str(self.operator_parameters) + \ | return "Operator: " + self.operator_name + " with parameters: " + str(self.operator_parameters) + \ | ||||
| " in selection mode: " + self.select_mode + ", selecting " + str(self.selection) + \ | " in selection mode: " + self.select_mode + ", selecting " + str(self.selection) + \ | ||||
| ("and loading bmesh selection history" if (self.select_history) else "") | ("and loading bmesh selection history" if (self.select_history) else "") | ||||
| class OperatorSpecObjectMode: | class OperatorSpecObjectMode: | ||||
| """ | """ | ||||
| Holds an object operator and its parameters. Helper class for DeformModifierSpec. | Holds an object operator and its parameters. Helper class for DeformModifierSpec. | ||||
| Needed to support operations in Object Mode and not Edit Mode which is supported by OperatorSpecEditMode. | Needed to support operations in Object Mode and not Edit Mode which is supported by OperatorSpecEditMode. | ||||
| """ | """ | ||||
| def __init__(self, operator_name: str, operator_parameters: dict): | def __init__(self, operator_name: str, operator_parameters: dict): | ||||
| """ | """ | ||||
| :param operator_name: str - name of the object operator from bpy.ops.object, e.g. "shade_smooth" or "shape_keys" | :arg operator_name: str - name of the object operator from bpy.ops.object, e.g. "shade_smooth" or "shape_keys" | ||||
| :param operator_parameters: dict - contains operator parameters. | :arg operator_parameters: dict - contains operator parameters. | ||||
| """ | """ | ||||
| self.operator_name = operator_name | self.operator_name = operator_name | ||||
| self.operator_parameters = operator_parameters | self.operator_parameters = operator_parameters | ||||
| def __str__(self): | def __str__(self): | ||||
| return "Operator: " + self.operator_name + " with parameters: " + str(self.operator_parameters) | return "Operator: " + self.operator_name + " with parameters: " + str(self.operator_parameters) | ||||
| class DeformModifierSpec: | class DeformModifierSpec: | ||||
| """ | """ | ||||
| Holds a list of deform modifier and OperatorSpecObjectMode. | Holds a list of deform modifier and OperatorSpecObjectMode. | ||||
| For deform modifiers which have an object operator | For deform modifiers which have an object operator | ||||
| """ | """ | ||||
| def __init__(self, frame_number: int, modifier_list: list, object_operator_spec: OperatorSpecObjectMode = None): | def __init__(self, frame_number: int, modifier_list: list, object_operator_spec: OperatorSpecObjectMode = None): | ||||
| """ | """ | ||||
| Constructs a Deform Modifier spec (for user input) | Constructs a Deform Modifier spec (for user input) | ||||
| :param frame_number: int - the frame at which animated keyframe is inserted | :arg frame_number: int - the frame at which animated keyframe is inserted | ||||
| :param modifier_list: ModifierSpec - contains modifiers | :arg modifier_list: ModifierSpec - contains modifiers | ||||
| :param object_operator_spec: OperatorSpecObjectMode - contains object operators | :arg object_operator_spec: OperatorSpecObjectMode - contains object operators | ||||
| """ | """ | ||||
| self.frame_number = frame_number | self.frame_number = frame_number | ||||
| self.modifier_list = modifier_list | self.modifier_list = modifier_list | ||||
| self.object_operator_spec = object_operator_spec | self.object_operator_spec = object_operator_spec | ||||
| def __str__(self): | def __str__(self): | ||||
| return "Modifier: " + str(self.modifier_list) + " with object operator " + str(self.object_operator_spec) | return "Modifier: " + str(self.modifier_list) + " with object operator " + str(self.object_operator_spec) | ||||
| class MeshTest(ABC): | class MeshTest(ABC): | ||||
| """ | """ | ||||
| A mesh testing Abstract class that hold common functionalities for testting operations. | A mesh testing Abstract class that hold common functionalities for testting operations. | ||||
| """ | """ | ||||
| def __init__(self, test_object_name, exp_object_name, test_name=None, threshold=None, do_compare=True): | def __init__(self, test_object_name, exp_object_name, test_name=None, threshold=None, do_compare=True): | ||||
| """ | """ | ||||
| :param test_object_name: str - Name of object of mesh type to run the operations on. | :arg test_object_name: str - Name of object of mesh type to run the operations on. | ||||
| :param exp_object_name: str - Name of object of mesh type that has the expected | :arg exp_object_name: str - Name of object of mesh type that has the expected | ||||
| geometry after running the operations. | geometry after running the operations. | ||||
| :param test_name: str - Name of the test. | :arg test_name: str - Name of the test. | ||||
| :param threshold: exponent: To allow variations and accept difference to a certain degree. | :arg threshold: exponent: To allow variations and accept difference to a certain degree. | ||||
| :param do_compare: bool - True if we want to compare the test and expected objects, False otherwise. | :arg do_compare: bool - True if we want to compare the test and expected objects, False otherwise. | ||||
| """ | """ | ||||
| self.test_object_name = test_object_name | self.test_object_name = test_object_name | ||||
| self.exp_object_name = exp_object_name | self.exp_object_name = exp_object_name | ||||
| if test_name: | if test_name: | ||||
| self.test_name = test_name | self.test_name = test_name | ||||
| else: | else: | ||||
| filepath = bpy.data.filepath | filepath = bpy.data.filepath | ||||
| self.test_name = bpy.path.display_name_from_filepath(filepath) | self.test_name = bpy.path.display_name_from_filepath(filepath) | ||||
| ▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Lines | def print_passed_test_result(self, result): | ||||
| Print results for passing test. | Print results for passing test. | ||||
| """ | """ | ||||
| print("\nPASSED {} test successfully.".format(self.test_name)) | print("\nPASSED {} test successfully.".format(self.test_name)) | ||||
| self._print_result(result) | self._print_result(result) | ||||
| def do_selection(self, mesh: bpy.types.Mesh, select_mode: str, selection, select_history: bool): | def do_selection(self, mesh: bpy.types.Mesh, select_mode: str, selection, select_history: bool): | ||||
| """ | """ | ||||
| Do selection on a mesh. | Do selection on a mesh. | ||||
| :param mesh: bpy.types.Mesh - input mesh | :arg mesh: bpy.types.Mesh - input mesh | ||||
| :param: select_mode: str - selection mode. Must be 'VERT', 'EDGE' or 'FACE' | :arg: select_mode: str - selection mode. Must be 'VERT', 'EDGE' or 'FACE' | ||||
| :param: selection: sequence - indices of selection. | :arg: selection: sequence - indices of selection. | ||||
| :param: select_history: bool - load selection into bmesh selection history | :arg: select_history: bool - load selection into bmesh selection history | ||||
| Example: select_mode='VERT' and selection={1,2,3} selects veritces 1, 2 and 3 of input mesh | Example: select_mode='VERT' and selection={1,2,3} selects veritces 1, 2 and 3 of input mesh | ||||
| """ | """ | ||||
| if select_history and isinstance(selection, set): | if select_history and isinstance(selection, set): | ||||
| raise Exception("'selection' must be an ordered sequence, not a 'set' type when 'select_history=True'") | raise Exception("'selection' must be an ordered sequence, not a 'set' type when 'select_history=True'") | ||||
| # Deselect all objects. | # Deselect all objects. | ||||
| bpy.ops.object.mode_set(mode='EDIT') | bpy.ops.object.mode_set(mode='EDIT') | ||||
| ▲ Show 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | def update_failed_test(self): | ||||
| bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath) | bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath) | ||||
| self.test_updated_counter += 1 | self.test_updated_counter += 1 | ||||
| self.expected_object = self.evaluated_object | self.expected_object = self.evaluated_object | ||||
| @staticmethod | @staticmethod | ||||
| def compare_meshes(evaluated_object, expected_object, threshold): | def compare_meshes(evaluated_object, expected_object, threshold): | ||||
| """ | """ | ||||
| Compares evaluated object mesh with expected object mesh. | Compares evaluated object mesh with expected object mesh. | ||||
| :param evaluated_object: first object for comparison. | :arg evaluated_object: first object for comparison. | ||||
| :param expected_object: second object for comparison. | :arg expected_object: second object for comparison. | ||||
| :param threshold: exponent: To allow variations and accept difference to a certain degree. | :arg threshold: exponent: To allow variations and accept difference to a certain degree. | ||||
| :return: dict: Contains results of different comparisons. | :return: dict: Contains results of different comparisons. | ||||
| """ | """ | ||||
| objects = bpy.data.objects | objects = bpy.data.objects | ||||
| evaluated_test_mesh = objects[evaluated_object.name].data | evaluated_test_mesh = objects[evaluated_object.name].data | ||||
| expected_mesh = expected_object.data | expected_mesh = expected_object.data | ||||
| result_codes = {} | result_codes = {} | ||||
| # Mesh Comparison. | # Mesh Comparison. | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | def __init__(self, test_name, | ||||
| test_object_name, | test_object_name, | ||||
| exp_object_name, | exp_object_name, | ||||
| operations_stack=None, | operations_stack=None, | ||||
| apply_modifier=True, | apply_modifier=True, | ||||
| threshold=None): | threshold=None): | ||||
| """ | """ | ||||
| Constructor for SpecMeshTest. | Constructor for SpecMeshTest. | ||||
| :param test_name: str - Name of the test. | :arg test_name: str - Name of the test. | ||||
| :param test_object_name: str - Name of object of mesh type to run the operations on. | :arg test_object_name: str - Name of object of mesh type to run the operations on. | ||||
| :param exp_object_name: str - Name of object of mesh type that has the expected | :arg exp_object_name: str - Name of object of mesh type that has the expected | ||||
| geometry after running the operations. | geometry after running the operations. | ||||
| :param operations_stack: list - stack holding operations to perform on the test_object. | :arg operations_stack: list - stack holding operations to perform on the test_object. | ||||
| :param apply_modifier: bool - True if we want to apply the modifiers right after adding them to the object. | :arg apply_modifier: bool - True if we want to apply the modifiers right after adding them to the object. | ||||
| - True if we want to apply the modifier to list of modifiers, after some operation. | - True if we want to apply the modifier to list of modifiers, after some operation. | ||||
| This affects operations of type ModifierSpec and DeformModifierSpec. | This affects operations of type ModifierSpec and DeformModifierSpec. | ||||
| """ | """ | ||||
| super().__init__(test_object_name, exp_object_name, test_name, threshold) | super().__init__(test_object_name, exp_object_name, test_name, threshold) | ||||
| self.test_name = test_name | self.test_name = test_name | ||||
| if operations_stack is None: | if operations_stack is None: | ||||
| self.operations_stack = [] | self.operations_stack = [] | ||||
| else: | else: | ||||
| self.operations_stack = operations_stack | self.operations_stack = operations_stack | ||||
| Show All 28 Lines | def apply_operations(self, evaluated_test_object_name): | ||||
| else: | else: | ||||
| raise ValueError("Expected operation of type {} or {} or {} or {}. Got {}". | raise ValueError("Expected operation of type {} or {} or {} or {}. Got {}". | ||||
| format(type(ModifierSpec), type(OperatorSpecEditMode), | format(type(ModifierSpec), type(OperatorSpecEditMode), | ||||
| type(OperatorSpecObjectMode), type(ParticleSystemSpec), type(operation))) | type(OperatorSpecObjectMode), type(ParticleSystemSpec), type(operation))) | ||||
| def _set_parameters_impl(self, modifier, modifier_parameters, nested_settings_path, modifier_name): | def _set_parameters_impl(self, modifier, modifier_parameters, nested_settings_path, modifier_name): | ||||
| """ | """ | ||||
| Doing a depth first traversal of the modifier parameters and setting their values. | Doing a depth first traversal of the modifier parameters and setting their values. | ||||
| :param: modifier: Of type modifier, its altered to become a setting in recursion. | :arg: modifier: Of type modifier, its altered to become a setting in recursion. | ||||
| :param: modifier_parameters : dict or sequence, a simple/nested dictionary of modifier parameters. | :arg: modifier_parameters : dict or sequence, a simple/nested dictionary of modifier parameters. | ||||
| :param: nested_settings_path : list(stack): helps in tracing path to each node. | :arg: nested_settings_path : list(stack): helps in tracing path to each node. | ||||
| """ | """ | ||||
| if not isinstance(modifier_parameters, dict): | if not isinstance(modifier_parameters, dict): | ||||
| param_setting = None | param_setting = None | ||||
| for i, setting in enumerate(nested_settings_path): | for i, setting in enumerate(nested_settings_path): | ||||
| # We want to set the attribute only when we have reached the last setting. | # We want to set the attribute only when we have reached the last setting. | ||||
| # Applying of intermediate settings is meaningless. | # Applying of intermediate settings is meaningless. | ||||
| if i == len(nested_settings_path) - 1: | if i == len(nested_settings_path) - 1: | ||||
| Show All 30 Lines | def set_parameters(self, modifier, modifier_parameters): | ||||
| """ | """ | ||||
| settings = [] | settings = [] | ||||
| modifier_name = modifier.name | modifier_name = modifier.name | ||||
| self._set_parameters_impl(modifier, modifier_parameters, settings, modifier_name) | self._set_parameters_impl(modifier, modifier_parameters, settings, modifier_name) | ||||
| def _add_modifier(self, test_object, modifier_spec: ModifierSpec): | def _add_modifier(self, test_object, modifier_spec: ModifierSpec): | ||||
| """ | """ | ||||
| Add modifier to object. | Add modifier to object. | ||||
| :param test_object: bpy.types.Object - Blender object to apply modifier on. | :arg test_object: bpy.types.Object - Blender object to apply modifier on. | ||||
| :param modifier_spec: ModifierSpec - ModifierSpec object with parameters | :arg modifier_spec: ModifierSpec - ModifierSpec object with parameters | ||||
| """ | """ | ||||
| bakers_list = ['CLOTH', 'SOFT_BODY', 'DYNAMIC_PAINT', 'FLUID'] | bakers_list = ['CLOTH', 'SOFT_BODY', 'DYNAMIC_PAINT', 'FLUID'] | ||||
| scene = bpy.context.scene | scene = bpy.context.scene | ||||
| scene.frame_set(1) | scene.frame_set(1) | ||||
| modifier = test_object.modifiers.new(modifier_spec.modifier_name, | modifier = test_object.modifiers.new(modifier_spec.modifier_name, | ||||
| modifier_spec.modifier_type) | modifier_spec.modifier_type) | ||||
| if modifier is None: | if modifier is None: | ||||
| ▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | def _apply_particle_system(self, test_object, particle_sys_spec: ParticleSystemSpec): | ||||
| test_object.select_set(True) | test_object.select_set(True) | ||||
| bpy.ops.object.join() | bpy.ops.object.join() | ||||
| if self.apply_modifier: | if self.apply_modifier: | ||||
| self._apply_modifier(test_object, particle_sys_spec.modifier_name) | self._apply_modifier(test_object, particle_sys_spec.modifier_name) | ||||
| def _apply_operator_edit_mode(self, test_object, operator: OperatorSpecEditMode): | def _apply_operator_edit_mode(self, test_object, operator: OperatorSpecEditMode): | ||||
| """ | """ | ||||
| Apply operator on test object. | Apply operator on test object. | ||||
| :param test_object: bpy.types.Object - Blender object to apply operator on. | :arg test_object: bpy.types.Object - Blender object to apply operator on. | ||||
| :param operator: OperatorSpecEditMode - OperatorSpecEditMode object with parameters. | :arg operator: OperatorSpecEditMode - OperatorSpecEditMode object with parameters. | ||||
| """ | """ | ||||
| self.do_selection( | self.do_selection( | ||||
| test_object.data, | test_object.data, | ||||
| operator.select_mode, | operator.select_mode, | ||||
| operator.selection, | operator.selection, | ||||
| select_history=operator.select_history, | select_history=operator.select_history, | ||||
| ) | ) | ||||
| Show All 32 Lines | def _apply_operator_object_mode(self, operator: OperatorSpecObjectMode): | ||||
| if retval != {'FINISHED'}: | if retval != {'FINISHED'}: | ||||
| raise RuntimeError("Unexpected operator return value: {}".format(retval)) | raise RuntimeError("Unexpected operator return value: {}".format(retval)) | ||||
| if self.verbose: | if self.verbose: | ||||
| print("Applied operator {}".format(operator)) | print("Applied operator {}".format(operator)) | ||||
| def _apply_deform_modifier(self, test_object, operation: list): | def _apply_deform_modifier(self, test_object, operation: list): | ||||
| """ | """ | ||||
| param: operation: list: List of modifiers or combination of modifier and object operator. | arg: operation: list: List of modifiers or combination of modifier and object operator. | ||||
| """ | """ | ||||
| scene = bpy.context.scene | scene = bpy.context.scene | ||||
| scene.frame_set(1) | scene.frame_set(1) | ||||
| bpy.ops.object.mode_set(mode='OBJECT') | bpy.ops.object.mode_set(mode='OBJECT') | ||||
| modifier_operations_list = operation.modifier_list | modifier_operations_list = operation.modifier_list | ||||
| modifier_names = [] | modifier_names = [] | ||||
| object_operations = operation.object_operator_spec | object_operations = operation.object_operator_spec | ||||
| ▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | class RunTest: | ||||
| >>> ] | >>> ] | ||||
| >>> modifiers_test = RunTest(tests) | >>> modifiers_test = RunTest(tests) | ||||
| >>> modifiers_test.run_all_tests() | >>> modifiers_test.run_all_tests() | ||||
| """ | """ | ||||
| def __init__(self, tests, apply_modifiers=False, do_compare=False): | def __init__(self, tests, apply_modifiers=False, do_compare=False): | ||||
| """ | """ | ||||
| Construct a test suite. | Construct a test suite. | ||||
| :param tests: list - list of modifier or operator test cases. Each element in the list must contain the | :arg tests: list - list of modifier or operator test cases. Each element in the list must contain the | ||||
| following | following | ||||
| in the correct order: | in the correct order: | ||||
| 0) test_name: str - unique test name | 0) test_name: str - unique test name | ||||
| 1) test_object_name: bpy.Types.Object - test object | 1) test_object_name: bpy.Types.Object - test object | ||||
| 2) expected_object_name: bpy.Types.Object - expected object | 2) expected_object_name: bpy.Types.Object - expected object | ||||
| 3) modifiers or operators: list - list of mesh_test.ModifierSpec objects or | 3) modifiers or operators: list - list of mesh_test.ModifierSpec objects or | ||||
| mesh_test.OperatorSpecEditMode objects | mesh_test.OperatorSpecEditMode objects | ||||
| """ | """ | ||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | def run_all_tests(self): | ||||
| print("{} {} --python {} -- {} {}" | print("{} {} --python {} -- {} {}" | ||||
| .format(blender_path, blend_path, python_path, "--run-test", "<test_name>")) | .format(blender_path, blend_path, python_path, "--run-test", "<test_name>")) | ||||
| raise Exception("Tests {} failed".format(self._failed_tests_list)) | raise Exception("Tests {} failed".format(self._failed_tests_list)) | ||||
| def run_test(self, test_name: str): | def run_test(self, test_name: str): | ||||
| """ | """ | ||||
| Run a single test from self.tests list | Run a single test from self.tests list | ||||
| :param test_name: int - name of test | :arg test_name: int - name of test | ||||
| :return: bool - True if test passed, False otherwise. | :return: bool - True if test passed, False otherwise. | ||||
| """ | """ | ||||
| case = None | case = None | ||||
| for index, each_test in enumerate(self.tests): | for index, each_test in enumerate(self.tests): | ||||
| if test_name == each_test.test_name: | if test_name == each_test.test_name: | ||||
| case = self.tests[index] | case = self.tests[index] | ||||
| break | break | ||||
| Show All 9 Lines | |||||