mirror of
https://projects.blender.org/blender/blender.git
synced 2025-01-22 07:22:12 -05:00
194 lines
6.8 KiB
Python
194 lines
6.8 KiB
Python
# SPDX-FileCopyrightText: 2020-2023 Blender Authors
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
from abc import ABC, abstractmethod
|
|
import bpy
|
|
import os
|
|
import sys
|
|
|
|
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
|
|
from modules.mesh_test import RunTest
|
|
|
|
|
|
class CurvesTest(ABC):
|
|
|
|
def __init__(self, test_object_name, exp_object_name, test_name=None):
|
|
self.test_object_name = test_object_name
|
|
self.exp_object_name = exp_object_name
|
|
self.test_object = bpy.data.objects[self.test_object_name]
|
|
self.expected_object = bpy.data.objects[self.exp_object_name]
|
|
self.verbose = os.getenv("BLENDER_VERBOSE") is not None
|
|
|
|
if test_name:
|
|
self.test_name = test_name
|
|
else:
|
|
filepath = bpy.data.filepath
|
|
self.test_name = bpy.path.display_name_from_filepath(filepath)
|
|
self._failed_tests_list = []
|
|
|
|
def create_evaluated_object(self):
|
|
"""
|
|
Creates an evaluated object.
|
|
"""
|
|
bpy.context.view_layer.objects.active = self.test_object
|
|
|
|
# Duplicate test object.
|
|
bpy.ops.object.mode_set(mode="OBJECT")
|
|
bpy.ops.object.select_all(action="DESELECT")
|
|
bpy.context.view_layer.objects.active = self.test_object
|
|
|
|
self.test_object.select_set(True)
|
|
bpy.ops.object.duplicate()
|
|
self.evaluated_object = bpy.context.active_object
|
|
self.evaluated_object.name = "evaluated_object"
|
|
|
|
@staticmethod
|
|
def _print_result(result):
|
|
"""
|
|
Prints the comparison, selection and validation result.
|
|
"""
|
|
print("Results:")
|
|
for key in result:
|
|
print("{} : {}".format(key, result[key][1]))
|
|
print()
|
|
|
|
def run_test(self):
|
|
"""
|
|
Runs a single test, runs it again if test file is updated.
|
|
"""
|
|
print("\nSTART {} test.".format(self.test_name))
|
|
|
|
self.create_evaluated_object()
|
|
self.apply_operations()
|
|
|
|
result = self.compare_objects(self.evaluated_object, self.expected_object)
|
|
|
|
# Initializing with True to get correct resultant of result_code booleans.
|
|
success = True
|
|
inside_loop_flag = False
|
|
for key in result:
|
|
inside_loop_flag = True
|
|
success = success and result[key][0]
|
|
|
|
# Check "success" is actually evaluated and is not the default True value.
|
|
if not inside_loop_flag:
|
|
success = False
|
|
|
|
if success:
|
|
self.print_passed_test_result(result)
|
|
# Clean up.
|
|
if self.verbose:
|
|
print("Cleaning up...")
|
|
# Delete evaluated_test_object.
|
|
bpy.ops.object.delete()
|
|
return True
|
|
|
|
else:
|
|
self.print_failed_test_result(result)
|
|
return False
|
|
|
|
@abstractmethod
|
|
def apply_operations(self, evaluated_test_object_name):
|
|
pass
|
|
|
|
@staticmethod
|
|
def compare_curves(evaluated_curves, expected_curves):
|
|
if len(evaluated_curves.attributes.items()) != len(expected_curves.attributes.items()):
|
|
print("Attribute count doesn't match")
|
|
|
|
for a_idx, attribute in evaluated_curves.attributes.items():
|
|
expected_attribute = expected_curves.attributes[a_idx]
|
|
|
|
if len(attribute.data.items()) != len(expected_attribute.data.items()):
|
|
print("Attribute data length doesn't match")
|
|
|
|
value_attr_name = (
|
|
'vector' if attribute.data_type == 'FLOAT_VECTOR' or
|
|
attribute.data_type == 'FLOAT2' else
|
|
'color' if attribute.data_type == 'FLOAT_COLOR' else 'value'
|
|
)
|
|
|
|
for v_idx, attribute_value in attribute.data.items():
|
|
if getattr(
|
|
attribute_value,
|
|
value_attr_name) != getattr(
|
|
expected_attribute.data[v_idx],
|
|
value_attr_name):
|
|
print("Attribute '{}' values do not match".format(attribute.name))
|
|
return False
|
|
|
|
return True
|
|
|
|
def compare_objects(self, evaluated_object, expected_object):
|
|
result_codes = {}
|
|
|
|
equal = self.compare_curves(evaluated_object.data, expected_object.data)
|
|
|
|
result_codes['Curves Comparison'] = (equal, evaluated_object.data)
|
|
return result_codes
|
|
|
|
def print_failed_test_result(self, result):
|
|
"""
|
|
Print results for failed test.
|
|
"""
|
|
print("FAILED {} test with the following: ".format(self.test_name))
|
|
|
|
def print_passed_test_result(self, result):
|
|
"""
|
|
Print results for passing test.
|
|
"""
|
|
print("PASSED {} test successfully.".format(self.test_name))
|
|
|
|
|
|
class CurvesOpTest(CurvesTest):
|
|
|
|
def __init__(self, test_name, test_object_name, exp_object_name, operators_stack):
|
|
super().__init__(test_object_name, exp_object_name, test_name)
|
|
self.operators_stack = operators_stack
|
|
|
|
def apply_operations(self):
|
|
for operator_name in self.operators_stack:
|
|
bpy.ops.object.mode_set(mode='EDIT')
|
|
curves_operator = getattr(bpy.ops.curves, operator_name)
|
|
|
|
try:
|
|
retval = curves_operator()
|
|
except AttributeError:
|
|
raise AttributeError("bpy.ops.curves has no attribute {}".format(operator_name))
|
|
except TypeError as ex:
|
|
raise TypeError("Incorrect operator parameters {!r} raised {!r}".format([], ex))
|
|
|
|
if retval != {'FINISHED'}:
|
|
raise RuntimeError("Unexpected operator return value: {}".format(operator_name))
|
|
bpy.ops.object.mode_set(mode='OBJECT')
|
|
|
|
|
|
def main():
|
|
tests = [
|
|
CurvesOpTest("Extrude 1 Point Curve", "a_test1PointCurve", "a_test1PointCurveExpected", ['extrude']),
|
|
CurvesOpTest("Extrude Middle Points", "b_testMiddlePoints", "b_testMiddlePointsExpected", ['extrude']),
|
|
CurvesOpTest("Extrude End Points", "c_testEndPoints", "c_testEndPointsExpected", ['extrude']),
|
|
CurvesOpTest("Extrude Neighbors In Separate Curves", "d_testNeighborsInCurves", "d_testNeighborsInCurvesExpected", ['extrude']),
|
|
CurvesOpTest("Extrude Edge Curves", "e_testEdgeCurves", "e_testEdgeCurvesExpected", ['extrude']),
|
|
CurvesOpTest("Extrude Middle Curve", "f_testMiddleCurve", "f_testMiddleCurveExpected", ['extrude']),
|
|
CurvesOpTest("Extrude All Points", "g_testAllPoints", "g_testAllPointsExpected", ['extrude'])
|
|
]
|
|
|
|
curves_extrude_test = RunTest(tests)
|
|
|
|
command = list(sys.argv)
|
|
for i, cmd in enumerate(command):
|
|
if cmd == "--run-all-tests":
|
|
curves_extrude_test.do_compare = True
|
|
curves_extrude_test.run_all_tests()
|
|
break
|
|
elif cmd == "--run-test":
|
|
curves_extrude_test.do_compare = False
|
|
name = command[i + 1]
|
|
curves_extrude_test.run_test(name)
|
|
break
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|