Changeset View
Standalone View
tests/python/bevel_operator.py
- This file was added.
| # ##### 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 ##### | |||||
| import bpy | |||||
| import os | |||||
| import pathlib | |||||
| import sys | |||||
| import importlib | |||||
| blend_dir = pathlib.Path(bpy.data.filepath) | |||||
| test_dir = blend_dir.parent.parent.parent.parent/"blender"/"tests"/"python"/"modules" | |||||
| if str(test_dir) not in sys.path: | |||||
| sys.path.append(str(test_dir)) | |||||
| import mesh_test | |||||
brecht: Doesn't `from modules import mesh_test` work, without any changes to `sys.path`?
That's what… | |||||
zazizizouAuthorUnsubmitted Done Inline ActionsIt doesn't work. I get the error: ImportError: cannot import name 'mesh_test' from 'modules' (unknown location)s zazizizou: It doesn't work. I get the error:
ImportError: cannot import name 'mesh_test' from 'modules'… | |||||
brechtUnsubmitted Done Inline ActionsI guess it's different when running from inside Blender. Still this code can be simplified: import os import sys sys.path.append(os.path.dirname(os.path.realpath(__file__))) from modules.mesh_test import OperatorTest brecht: I guess it's different when running from inside Blender. Still this code can be simplified:
```… | |||||
| importlib.reload(mesh_test) | |||||
brechtUnsubmitted Done Inline ActionsWhy reload? brecht: Why reload? | |||||
| from mesh_test import MeshTest, OperatorSpec | |||||
| def main(): | |||||
| tests = [ | |||||
| # 0 | |||||
| ['EDGE', {10},'Cube_test', 'Cube_result_1', 'bevel', {'offset': 0.2} ], | |||||
brechtUnsubmitted Done Inline ActionsStyle: space after comma, no space before ]. brecht: Style: space after comma, no space before `]`. | |||||
| ['EDGE', {10, 7},'Cube_test', 'Cube_result_2', 'bevel', {'offset': 0.2, 'offset_type': 'WIDTH'} ], | |||||
| ['EDGE', {8, 10, 7},'Cube_test', 'Cube_result_3', 'bevel', {'offset': 0.2, 'offset_type': 'DEPTH'} ], | |||||
| ['EDGE', {10},'Cube_test', 'Cube_result_4', 'bevel', {'offset': 0.4, 'segments': 2} ], | |||||
| ['EDGE', {10, 7},'Cube_test', 'Cube_result_5', 'bevel', {'offset': 0.4, 'segments': 3} ], | |||||
| # 5 | |||||
| ['EDGE', {8, 10, 7},'Cube_test', 'Cube_result_6', 'bevel', {'offset': 0.4, 'segments': 4} ], | |||||
| ['EDGE', {0, 10, 4, 7},'Cube_test', 'Cube_result_7', 'bevel', {'offset': 0.4, 'segments': 5, 'profile': 0.2} ], | |||||
| ['EDGE', {8, 10, 7},'Cube_test', 'Cube_result_8', 'bevel', {'offset': 0.4, 'segments': 5, 'profile': 0.25} ], | |||||
| ['EDGE', {8, 10, 7},'Cube_test', 'Cube_result_9', 'bevel', {'offset': 0.4, 'segments': 6, 'profile': 0.9} ], | |||||
| ['EDGE', {10, 7},'Cube_test', 'Cube_result_10', 'bevel', {'offset': 0.4, 'segments': 4, 'profile': 1.0} ], | |||||
| # 10 | |||||
| ['EDGE', {8, 10, 7},'Cube_test', 'Cube_result_11', 'bevel', {'offset': 0.4, 'segments': 5, 'profile': 1.0} ], | |||||
| ['EDGE', {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},'Cube_test', 'Cube_result_12', 'bevel', {'offset': 0.4, 'segments': 8} ], | |||||
| ['EDGE', {5},'Pyr4_test', 'Pyr4_result_1', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {2, 5},'Pyr4_test', 'Pyr4_result_2', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {2, 3, 5},'Pyr4_test', 'Pyr4_result_3', 'bevel', {'offset': 0.2} ], | |||||
| # 15 | |||||
| ['EDGE', {1, 2, 3, 5},'Pyr4_test', 'Pyr4_result_4', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {1, 2, 3, 5},'Pyr4_test', 'Pyr4_result_5', 'bevel', {'offset': 0.2, 'segments': 3} ], | |||||
| ['EDGE', {2, 3},'Pyr4_test', 'Pyr4_result_6', 'bevel', {'offset': 0.2, 'segments': 2} ], | |||||
| ['EDGE', {1, 2, 3, 5},'Pyr4_test', 'Pyr4_result_7', 'bevel', {'offset': 0.2, 'segments': 4, 'profile': 0.15} ], | |||||
| ['VERT', {1},'Pyr4_test', 'Pyr4_result_8', 'bevel', {'offset': 0.75, 'segments': 4, 'vertex_only': True} ], | |||||
| # 20 | |||||
| ['VERT', {1},'Pyr4_test', 'Pyr4_result_9', 'bevel', {'offset': 0.75, 'segments': 3, 'vertex_only': True, 'profile': 0.25} ], | |||||
| ['EDGE', {2, 3},'Pyr6_test', 'Pyr6_result_1', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {8, 2, 3},'Pyr6_test', 'Pyr6_result_2', 'bevel', {'offset': 0.2, 'segments': 2} ], | |||||
| ['EDGE', {0, 2, 3, 4, 6, 7, 9, 10, 11},'Pyr6_test', 'Pyr6_result_3', 'bevel', {'offset': 0.2, 'segments': 4, 'profile': 0.8} ], | |||||
| ['EDGE', {8, 9, 3, 11},'Sept_test', 'Sept_result_1', 'bevel', {'offset': 0.1} ], | |||||
| # 25 | |||||
| ['EDGE', {8, 9, 11},'Sept_test', 'Sept_result_2', 'bevel', {'offset': 0.1, 'offset_type': 'WIDTH'} ], | |||||
| ['EDGE', {2, 8, 9, 12, 13, 14},'Saddle_test', 'Saddle_result_1', 'bevel', {'offset': 0.3, 'segments': 5} ], | |||||
| ['VERT', {4},'Saddle_test', 'Saddle_result_2', 'bevel', {'offset': 0.6, 'segments': 6, 'vertex_only': True} ], | |||||
| ['EDGE', {2, 5, 8, 11, 14, 18, 21, 24, 27, 30, 34, 37, 40, 43, 46, 50, 53, 56, 59, 62, 112, 113, 114, 115},'Bent_test', 'Bent_result_1', 'bevel', {'offset': 0.2, 'segments': 3} ], | |||||
| ['EDGE', {1, 8, 9, 10, 11},'Bentlines_test', 'Bentlines_result_1', 'bevel', {'offset': 0.2, 'segments': 3} ], | |||||
| # 30 | |||||
| ['EDGE', {26, 12, 20},'Flaretop_test', 'Flaretop_result_1', 'bevel', {'offset': 0.4, 'segments': 2} ], | |||||
| ['EDGE', {26, 12, 20},'Flaretop_test', 'Flaretop_result_2', 'bevel', {'offset': 0.4, 'segments': 2, 'profile': 1.0} ], | |||||
| ['FACE', {1, 6, 7, 8, 9, 10, 11, 12},'Flaretop_test', 'Flaretop_result_3', 'bevel', {'offset': 0.4, 'segments': 4} ], | |||||
| ['EDGE', {4, 8, 10, 18, 24},'BentL_test', 'BentL_result_1', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {0, 1, 2, 10},'Wires_test', 'Wires_test_result_1', 'bevel', {'offset': 0.3} ], | |||||
| # 35 | |||||
| ['VERT', {0, 1, 2, 3, 4, 5, 6, 7, 8, 9},'Wires_test', 'Wires_test_result_2', 'bevel', {'offset': 0.3, 'vertex_only': True} ], | |||||
| ['EDGE', {3, 4, 5},'tri', 'tri_result_1', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {3, 4, 5},'tri', 'tri_result_2', 'bevel', {'offset': 0.2, 'segments': 2} ], | |||||
| ['EDGE', {3, 4, 5},'tri', 'tri_result_3', 'bevel', {'offset': 0.2, 'segments': 3} ], | |||||
| ['EDGE', {3, 4},'tri', 'tri_result_4', 'bevel', {'offset': 0.2} ], | |||||
| # 40 | |||||
| ['EDGE', {3, 4},'tri', 'tri_result_5', 'bevel', {'offset': 0.2, 'segments': 2} ], | |||||
| ['VERT', {3},'tri', 'tri_result_6', 'bevel', {'offset': 0.2, 'vertex_only': True} ], | |||||
| ['VERT', {3},'tri', 'tri_result_7', 'bevel', {'offset': 0.2, 'segments': 2, 'vertex_only': True} ], | |||||
| ['VERT', {3},'tri', 'tri_result_8', 'bevel', {'offset': 0.2, 'segments': 3, 'vertex_only': True} ], | |||||
| ['VERT', {1},'tri', 'tri_result_9', 'bevel', {'offset': 0.2, 'vertex_only': True} ], | |||||
| # 45 | |||||
| ['EDGE', {3, 4, 5},'tri1gap', 'tri1gap_result_1', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {3, 4, 5},'tri1gap', 'tri1gap_result_2', 'bevel', {'offset': 0.2, 'segments': 2} ], | |||||
| ['EDGE', {3, 4, 5},'tri1gap', 'tri1gap_result_3', 'bevel', {'offset': 0.2, 'segments': 3} ], | |||||
| ['EDGE', {3, 4},'tri1gap', 'tri1gap_result_4', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {3, 4},'tri1gap', 'tri1gap_result_5', 'bevel', {'offset': 0.2, 'segments': 2} ], | |||||
| # 50 | |||||
| ['EDGE', {3, 4},'tri1gap', 'tri1gap_result_6', 'bevel', {'offset': 0.2, 'segments': 3} ], | |||||
| ['EDGE', {3, 5},'tri1gap', 'tri1gap_result_7', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {3, 5},'tri1gap', 'tri1gap_result_8', 'bevel', {'offset': 0.2, 'segments': 2} ], | |||||
| ['EDGE', {3, 5},'tri1gap', 'tri1gap_result_9', 'bevel', {'offset': 0.2, 'segments': 3} ], | |||||
| ['VERT', {3},'tri1gap', 'tri1gap_result_10', 'bevel', {'offset': 0.2, 'vertex_only': True} ], | |||||
| # 55 | |||||
| ['EDGE', {3, 4, 5},'tri2gaps', 'tri2gaps_result_1', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {3, 4, 5},'tri2gaps', 'tri2gaps_result_2', 'bevel', {'offset': 0.2, 'segments': 2} ], | |||||
| ['EDGE', {3, 4, 5},'tri2gaps', 'tri2gaps_result_3', 'bevel', {'offset': 0.2, 'segments': 3} ], | |||||
| ['EDGE', {3, 4},'tri2gaps', 'tri2gaps_result_4', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {3, 4},'tri2gaps', 'tri2gaps_result_5', 'bevel', {'offset': 0.2, 'segments': 2} ], | |||||
| # 60 | |||||
| ['EDGE', {3, 4},'tri2gaps', 'tri2gaps_result_6', 'bevel', {'offset': 0.2, 'segments': 3} ], | |||||
| ['EDGE', {3, 4, 5},'tri3gaps', 'tri3gaps_result_1', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {3, 4, 5},'tri3gaps', 'tri3gaps_result_2', 'bevel', {'offset': 0.2, 'segments': 2} ], | |||||
| ['EDGE', {3, 4, 5},'tri3gaps', 'tri3gaps_result_3', 'bevel', {'offset': 0.2, 'segments': 3} ], | |||||
| ['EDGE', {32, 33, 34, 35, 24, 25, 26, 27, 28, 29, 30, 31},'cube3', 'cube3_result_1', 'bevel', {'offset': 0.2} ], | |||||
| # 65 | |||||
| ['EDGE', {32, 33, 34, 35, 24, 25, 26, 27, 28, 29, 30, 31},'cube3', 'cube3_result_2', 'bevel', {'offset': 0.2, 'segments': 2} ], | |||||
| ['EDGE', {32, 35},'cube3', 'cube3_result_3', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {24, 35},'cube3', 'cube3_result_4', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {24, 32, 35},'cube3', 'cube3_result_5', 'bevel', {'offset': 0.2, 'segments': 2} ], | |||||
| ['EDGE', {24, 32, 35},'cube3', 'cube3_result_6', 'bevel', {'offset': 0.2, 'segments': 3} ], | |||||
| # 70 | |||||
| ['EDGE', {0, 1, 6, 7, 12, 14, 16, 17},'Tray', 'Tray_result_1', 'bevel', {'offset': 0.01, 'segments': 2} ], | |||||
| ['EDGE', {33, 4, 38, 8, 41, 10, 42, 12, 14, 17, 24, 31},'Bumptop', 'Bumptop_result_1', 'bevel', {'offset': 0.1, 'segments': 4} ], | |||||
| ['EDGE', {16, 14, 15},'Multisegment_test', 'Multisegment_result_1', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {16, 14, 15},'Multisegment_test', 'Multisegment_result_1', 'bevel', {'offset': 0.2} ], | |||||
| ['EDGE', {19, 20, 23, 15},'Window_test', 'Window_result_1', 'bevel', {'offset': 0.05, 'segments': 2} ], | |||||
| # 75 | |||||
| ['EDGE', {8},'Cube_hn_test', 'Cube_hn_result_1', 'bevel', {'offset': 0.2, 'harden_normals': True} ], | |||||
| ['EDGE', {4, 7, 39, 27, 30, 31},'Blocksteps_test', 'Blocksteps_result_1', 'bevel', {'offset': 0.2, 'miter_outer': 'PATCH'} ], | |||||
| ['EDGE', {4, 7, 39, 27, 30, 31},'Blocksteps_test', 'Blocksteps_result_2', 'bevel', {'offset': 0.2, 'segments': 2, 'miter_outer': 'PATCH'} ], | |||||
| ['EDGE', {4, 7, 39, 27, 30, 31},'Blocksteps_test', 'Blocksteps_result_3', 'bevel', {'offset': 0.2, 'segments': 3, 'miter_outer': 'PATCH'} ], | |||||
| ['EDGE', {4, 7, 39, 27, 30, 31},'Blocksteps_test', 'Blocksteps_result_4', 'bevel', {'offset': 0.2, 'miter_outer': 'ARC'} ], | |||||
| # 80 | |||||
| ['EDGE', {4, 7, 39, 27, 30, 31},'Blocksteps_test', 'Blocksteps_result_5', 'bevel', {'offset': 0.2, 'segments': 2, 'miter_outer': 'ARC'} ], | |||||
| ['EDGE', {4, 7, 39, 27, 30, 31},'Blocksteps_test', 'Blocksteps_result_6', 'bevel', {'offset': 0.2, 'segments': 3, 'miter_outer': 'ARC'} ], | |||||
| ['EDGE', {4, 7, 39, 27, 30, 31},'Blocksteps_test', 'Blocksteps_result_7', 'bevel', {'offset': 0.2, 'miter_outer': 'PATCH', 'miter_inner': 'ARC'} ], | |||||
| ['EDGE', {4, 7, 39, 27, 30, 31},'Blocksteps_test', 'Blocksteps_result_8', 'bevel', {'offset': 0.2, 'segments': 2, 'miter_outer': 'PATCH', 'miter_inner': 'ARC'} ], | |||||
| ['EDGE', {4, 7, 39, 27, 30, 31},'Blocksteps2_test', 'Blocksteps2_result_9', 'bevel', {'offset': 0.2, 'segments': 2, 'miter_outer': 'ARC'} ], | |||||
| # 85 | |||||
| ['EDGE', {4, 7, 39, 27, 30, 31},'Blocksteps3_test', 'Blocksteps3_result_10', 'bevel', {'offset': 0.2, 'segments': 2, 'miter_outer': 'ARC'} ], | |||||
| ['EDGE', {4, 7, 39, 27, 30, 31},'Blocksteps4_test', 'Blocksteps4_result_11', 'bevel', {'offset': 0.2, 'segments': 2, 'miter_outer': 'ARC'} ], | |||||
| ['EDGE', {4, 7, 39, 27, 30, 31},'Blocksteps4_test', 'Blocksteps4_result_12', 'bevel', {'offset': 0.2, 'segments': 3, 'miter_outer': 'ARC'} ], | |||||
| ['EDGE', {1, 7},'Spike_test', 'Spike_result_1', 'bevel', {'offset': 0.2, 'segments': 3} ] | |||||
| ] | |||||
| for case in tests: | |||||
| select_mode = case[0] | |||||
| selection = case[1] | |||||
| test_object_name = case[2] | |||||
| expected_object_name = case[3] | |||||
| operator_name = case[4] | |||||
| operator_parameters = case[5] | |||||
| operator_spec = OperatorSpec(operator_name, operator_parameters, select_mode, selection) | |||||
| test = MeshTest(test_object_name, expected_object_name) | |||||
| test.add_operator(operator_spec) | |||||
| success = test.run_test() | |||||
| if test.is_test_updated(): | |||||
| # run the test again if the blend file has been updated | |||||
| success = test.run_test() | |||||
| if not success: | |||||
| raise Exception("Test failed.") | |||||
brechtUnsubmitted Done Inline ActionsIt should run all the tests, not stop on the first failure. Otherwise you don't know what you're updating. Seeing all tests that failed also helps to see patterns to find the cause. brecht: It should run all the tests, not stop on the first failure. Otherwise you don't know what… | |||||
| if __name__ == "__main__": | |||||
| try: | |||||
Done Inline ActionsName these --run-all-tests and --run-test. Using underscores here is non-standard. brecht: Name these `--run-all-tests` and `--run-test`. Using underscores here is non-standard. | |||||
| main() | |||||
| except: | |||||
| import traceback | |||||
| traceback.print_exc() | |||||
| sys.exit(1) | |||||
brechtUnsubmitted Done Inline ActionsPerhaps the logic in this file could be deduplicated, by having something like this: if __name__ == "__main__":
... construct list of MeshTest ...
mesh_test.run_tests(test_list)Where mesh_test.run_tests handles the traceback, check for updates, etc. brecht: Perhaps the logic in this file could be deduplicated, by having something like this:
```
if… | |||||
Done Inline ActionsIs this code needed, wouldn't Python itself automatically print the traceback and exit with an error code? brecht: Is this code needed, wouldn't Python itself automatically print the traceback and exit with an… | |||||
Done Inline ActionsI think sys.exit(1) is necessary for the ctest to fail. This is why the modifiers test was passing even though an exception was thrown in main(). zazizizou: I think `sys.exit(1)` is necessary for the ctest to fail. This is why the modifiers test was… | |||||
Doesn't from modules import mesh_test work, without any changes to sys.path?
That's what we use in cycles_render_tests.py.