symtest-cli 1.4.0__tar.gz → 1.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {symtest_cli-1.4.0/src/symtest_cli.egg-info → symtest_cli-1.5.0}/PKG-INFO +1 -1
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/docs/design.md +44 -28
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/docs/design_en.md +1 -20
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/docs/user_manual.md +177 -27
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/docs/user_manual_en.md +184 -23
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/__init__.py +1 -1
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/cli.py +16 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/commands/compare.py +27 -15
- symtest_cli-1.5.0/src/symtest/commands/migrate.py +160 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/config/config_schema.py +86 -10
- symtest_cli-1.5.0/src/symtest/config/normalize.py +43 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/base_runner.py +0 -19
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/config_loader.py +28 -26
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/orchestration/sequence.py +11 -23
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/orchestration/single.py +2 -13
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/parallel_runner.py +0 -2
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/process_worker.py +4 -4
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/test_case.py +88 -20
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/validation/assertions.py +50 -2
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/validation/validator.py +48 -9
- symtest_cli-1.5.0/src/symtest/file_comparator/__init__.py +44 -0
- symtest_cli-1.5.0/src/symtest/file_comparator/base_comparator.py +128 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/file_comparator/binary_comparator.py +6 -6
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/file_comparator/csv_comparator.py +6 -5
- symtest_cli-1.5.0/src/symtest/file_comparator/extractor_comparator.py +199 -0
- symtest_cli-1.5.0/src/symtest/file_comparator/factory.py +341 -0
- symtest_cli-1.4.0/src/symtest/file_comparator/base_comparator.py → symtest_cli-1.5.0/src/symtest/file_comparator/file_comparator_base.py +57 -30
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/file_comparator/h5_comparator.py +14 -8
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/file_comparator/json_comparator.py +3 -4
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/file_comparator/numeric_compare.py +43 -40
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/file_comparator/result.py +66 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/file_comparator/script_comparator.py +22 -41
- symtest_cli-1.5.0/src/symtest/file_comparator/script_extract_comparator.py +160 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/file_comparator/text_comparator.py +2 -2
- symtest_cli-1.5.0/src/symtest/reporting/__init__.py +17 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/reporting/diagnosis.py +65 -2
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/tui/controllers/case_controller.py +15 -5
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/tui/widgets/steps_editor.py +5 -5
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/utils/report_generator.py +80 -17
- {symtest_cli-1.4.0 → symtest_cli-1.5.0/src/symtest_cli.egg-info}/PKG-INFO +1 -1
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest_cli.egg-info/SOURCES.txt +14 -1
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/__pycache__/conftest.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/__pycache__/conftest.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/e2e/__pycache__/test_user_flows.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/e2e/__pycache__/test_user_flows.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/__pycache__/test_history_feature.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/__pycache__/test_history_feature.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/__pycache__/test_new_cli_features.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/__pycache__/test_new_cli_features.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/__pycache__/test_real_command_execution.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/integration/__pycache__/test_real_command_execution.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/__pycache__/test_sequence.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/integration/__pycache__/test_sequence.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_binary_compare.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_binary_compare.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_csv_compare.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_csv_compare.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_h5_compare.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_h5_compare.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_json_compare.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_json_compare.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_text_compare.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_text_compare.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_xml_compare.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_xml_compare.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/test_csv_compare.py +2 -2
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/test_text_compare.py +8 -1
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/parallel/__pycache__/test_depends_on.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/integration/parallel/__pycache__/test_depends_on.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/parallel/__pycache__/test_parallel_runner.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/integration/parallel/__pycache__/test_parallel_runner.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/path_handling/__pycache__/test_spaces_in_paths.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/integration/path_handling/__pycache__/test_spaces_in_paths.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/test_sequence.py +8 -8
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_binary_comparator.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_binary_comparator.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_cli.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_cli.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_config_io.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/__pycache__/test_config_io.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_h5_comparator.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_h5_comparator.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_import_expander.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_import_expander.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_inheritance_expander.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_inheritance_expander.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/__pycache__/test_migrate.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/__pycache__/test_migrate.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_result.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_result.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/commands/__pycache__/test_compare_command.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/commands/__pycache__/test_compare_command.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_architecture_guard.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_architecture_guard.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_assertions.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_assertions.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_case_env.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/core/__pycache__/test_case_env.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_config_loader.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/core/__pycache__/test_config_loader.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_config_loader_new_features.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/core/__pycache__/test_config_loader_new_features.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_execution.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_execution.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_execution_new_features.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/core/__pycache__/test_execution_new_features.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_history_store.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_history_store.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_last_run_store.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_last_run_store.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_model_v2.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_model_v2.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_orchestration_accept.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_orchestration_accept.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_process_worker.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/core/__pycache__/test_process_worker.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_sequence_state.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_sequence_state.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_setup.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_setup.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_validation_error.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_validation_error.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_xfail.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_xfail.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_architecture_guard.py +5 -5
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_assertions.py +20 -5
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_case_env.py +4 -4
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_config_loader.py +3 -3
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_config_loader_new_features.py +13 -10
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_execution_new_features.py +31 -27
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_model_v2.py +9 -9
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_orchestration_accept.py +11 -3
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_process_worker.py +6 -6
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_sequence_state.py +3 -3
- symtest_cli-1.5.0/tests/unit/file_comparator/__pycache__/test_error_analysis.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/file_comparator/__pycache__/test_error_analysis.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/file_comparator/__pycache__/test_extractor_channels.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/file_comparator/__pycache__/test_extractor_channels.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/__pycache__/test_numeric_compare.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/__pycache__/test_numeric_compare.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/__pycache__/test_numeric_parity.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/__pycache__/test_numeric_parity.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/file_comparator/__pycache__/test_plugin_lifecycle.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/file_comparator/__pycache__/test_plugin_lifecycle.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/file_comparator/__pycache__/test_script_comparator.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/file_comparator/__pycache__/test_script_comparator.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/file_comparator/__pycache__/test_script_extract.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/file_comparator/__pycache__/test_script_extract.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/file_comparator/__pycache__/test_workspace_plugins.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/file_comparator/__pycache__/test_workspace_plugins.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/test_error_analysis.py +24 -2
- symtest_cli-1.5.0/tests/unit/file_comparator/test_extractor_channels.py +253 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/test_numeric_compare.py +5 -3
- symtest_cli-1.5.0/tests/unit/file_comparator/test_plugin_lifecycle.py +390 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/test_script_comparator.py +10 -9
- symtest_cli-1.5.0/tests/unit/file_comparator/test_script_extract.py +187 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/test_workspace_plugins.py +29 -48
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/__pycache__/test_test_case_filter.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/__pycache__/test_test_case_filter.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/__pycache__/test_test_case_tag_filter.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/__pycache__/test_test_case_tag_filter.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/test_migrate.py +199 -4
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/conftest.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.5.0/tests/unit/tui/__pycache__/conftest.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_app.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_app.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_case_controller.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_case_controller.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_search_functions.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_search_functions.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_tui_run_test.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_tui_run_test.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_widgets_data.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_widgets_data.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/conftest.py +3 -3
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/test_case_controller.py +18 -12
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/test_tui_run_test.py +3 -3
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/test_widgets_data.py +2 -2
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/utils/__pycache__/test_junit_xml_writer.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/utils/__pycache__/test_junit_xml_writer.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/utils/__pycache__/test_report_generator.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/utils/__pycache__/test_report_generator.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/utils/test_report_generator.py +177 -0
- symtest_cli-1.4.0/docs/design_1_4.md +0 -305
- symtest_cli-1.4.0/src/symtest/commands/migrate.py +0 -63
- symtest_cli-1.4.0/src/symtest/file_comparator/__init__.py +0 -10
- symtest_cli-1.4.0/src/symtest/file_comparator/factory.py +0 -191
- symtest_cli-1.4.0/src/symtest/reporting/__init__.py +0 -10
- symtest_cli-1.4.0/tests/e2e/__pycache__/test_user_flows.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/integration/__pycache__/test_real_command_execution.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/integration/__pycache__/test_sequence.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/integration/parallel/__pycache__/test_depends_on.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/integration/parallel/__pycache__/test_parallel_runner.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/integration/path_handling/__pycache__/test_spaces_in_paths.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/__pycache__/test_config_io.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/__pycache__/test_migrate.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/core/__pycache__/test_case_env.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/core/__pycache__/test_config_loader.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/core/__pycache__/test_config_loader_new_features.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/core/__pycache__/test_execution_new_features.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/core/__pycache__/test_process_worker.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/file_comparator/__pycache__/test_error_analysis.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/file_comparator/__pycache__/test_error_analysis.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/file_comparator/__pycache__/test_script_comparator.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/file_comparator/__pycache__/test_script_comparator.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/file_comparator/__pycache__/test_workspace_plugins.cpython-312-pytest-7.4.4.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/file_comparator/__pycache__/test_workspace_plugins.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-312-pytest-9.0.3.pyc +0 -0
- symtest_cli-1.4.0/tests/unit/tui/__pycache__/conftest.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/LICENSE +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/MANIFEST.in +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/README.md +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/docs/tui_and_config_split_design.md +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/pyproject.toml +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/setup.cfg +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/setup.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/commands/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/config/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/config/config_io.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/config/import_expander.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/config/inheritance_expander.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/config/migrate.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/execution/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/execution/executor.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/execution/result.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/history_store.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/last_run_store.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/orchestration/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/orchestration/accept.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/result.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/sequence_state.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/setup.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/types.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/validation/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/core/validation/result.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/file_comparator/xml_comparator.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/logging_config.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/runners/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/runners/config_runner.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/runners/json_runner.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/runners/parallel_config_runner.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/runners/parallel_json_runner.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/runners/parallel_yaml_runner.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/runners/yaml_runner.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/tui/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/tui/app.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/tui/controllers/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/tui/screens/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/tui/screens/case_editor.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/tui/screens/case_list.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/tui/widgets/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/tui/widgets/case_table.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/tui/widgets/expected_editor.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/tui/widgets/search_bar.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/utils/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/utils/junit_xml_writer.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest/utils/path_resolver.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest_cli.egg-info/dependency_links.txt +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest_cli.egg-info/entry_points.txt +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest_cli.egg-info/requires.txt +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/src/symtest_cli.egg-info/top_level.txt +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/README.md +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/__pycache__/__init__.cpython-312.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/__pycache__/__init__.cpython-313.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/__pycache__/__init__.cpython-39.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/__pycache__/conftest.cpython-39-pytest-8.3.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/__pycache__/run_all.cpython-312.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/__pycache__/run_all.cpython-313.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/__pycache__/run_all.cpython-39.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/__pycache__/test_setup_module.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/conftest.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/demos/h5_filter_demo.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/demos/manual_report_example.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/demos/perf_parallel.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/e2e/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/e2e/__pycache__/__init__.cpython-312.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/e2e/__pycache__/__init__.cpython-313.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/e2e/__pycache__/__init__.cpython-39.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/e2e/__pycache__/test_user_flows.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/e2e/__pycache__/test_user_flows.cpython-39-pytest-8.3.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/e2e/test_user_flows.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/circular_config_a.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/circular_config_b.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/hourglass_stdout_mismatch.txt +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/hourglass_stdout_sample.txt +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/inheritance_base.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/inheritance_chain.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/inheritance_circular.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/main_config.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/circular_config_a.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/circular_config_b.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/inheritance_base.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/inheritance_chain.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/inheritance_circular.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/main_config.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/missing_fields.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/setup_main.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/setup_sub.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/skill_test_cases_golden_file.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/skill_test_cases_simple.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/skill_test_cases_simple.yaml +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/skill_test_cases_steps.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/sub_json_tests.yaml +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/sub_text_tests.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/test_cases.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/test_cases.yaml +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/test_cases1.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/test_with_setup.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/migration/v1/test_with_setup.yaml +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/missing_fields.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/mock_fail_script.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/mock_pass_script.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/setup_main.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/setup_sub.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/sub_json_tests.yaml +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/sub_text_tests.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/test_cases.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/test_cases.yaml +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/test_cases1.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/test_with_setup.json +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/fixtures/test_with_setup.yaml +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/__pycache__/test_history_feature.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/__pycache__/test_new_cli_features.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/__pycache__/test_real_command_execution.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/__pycache__/test_sequence.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_binary_compare.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_binary_compare.cpython-39-pytest-8.3.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_csv_compare.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_h5_compare.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_h5_compare.cpython-39-pytest-8.3.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_json_compare.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_json_compare.cpython-39-pytest-8.3.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_text_compare.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_text_compare.cpython-39-pytest-8.3.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/__pycache__/test_xml_compare.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/test_binary_compare.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/test_h5_compare.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/test_json_compare.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/file_compare/test_xml_compare.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/parallel/__pycache__/test_parallel_runner.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/parallel/__pycache__/test_parallel_runner.cpython-39-pytest-8.3.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/parallel/test_depends_on.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/parallel/test_parallel_runner.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/path_handling/__pycache__/test_spaces_in_paths.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/path_handling/__pycache__/test_spaces_in_paths.cpython-39-pytest-8.3.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/path_handling/test_spaces_in_paths.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/test_history_feature.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/test_new_cli_features.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/integration/test_real_command_execution.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/run_all.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_binary_comparator.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_cli.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_config_io.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_h5_comparator.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_import_expander.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_inheritance_expander.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_result.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_run_all.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_run_all.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/__pycache__/test_run_all.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/commands/__pycache__/test_compare_command.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/commands/test_compare_command.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_assertions.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_config_loader.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_config_loader_new_features.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_execution.cpython-312.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_execution.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_execution_new_features.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_history_store.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_last_run_store.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_process_worker.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_setup.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_setup.cpython-39-pytest-8.3.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_validation_error.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/__pycache__/test_xfail.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_execution.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_history_store.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_last_run_store.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_setup.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_validation_error.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/core/test_xfail.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/__pycache__/__init__.cpython-312.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/__pycache__/test_error_analysis.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/__pycache__/test_hourglass_tangent_comparator.cpython-312-pytest-7.4.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/__pycache__/test_hourglass_tangent_comparator.cpython-312-pytest-9.0.3.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/__pycache__/test_hourglass_tangent_comparator.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/__pycache__/test_script_comparator.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/__pycache__/test_workspace_plugins.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/test_hourglass_tangent_comparator.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/file_comparator/test_numeric_parity.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-312.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-39-pytest-8.3.4.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/__pycache__/test_test_case_filter.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/__pycache__/test_test_case_tag_filter.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/test_json_yaml_runner.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/test_test_case_filter.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/runners/test_test_case_tag_filter.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/test_binary_comparator.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/test_cli.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/test_config_io.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/test_h5_comparator.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/test_import_expander.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/test_inheritance_expander.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/test_result.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/test_run_all.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__init__.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/__init__.cpython-312.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/__init__.cpython-313.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_app.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_case_controller.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_search_functions.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_tui_run_test.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/__pycache__/test_widgets_data.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/test_app.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/tui/test_search_functions.py +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/utils/__pycache__/test_junit_xml_writer.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/utils/__pycache__/test_report_generator.cpython-313-pytest-9.0.2.pyc +0 -0
- {symtest_cli-1.4.0 → symtest_cli-1.5.0}/tests/unit/utils/test_junit_xml_writer.py +0 -0
|
@@ -155,14 +155,11 @@ PathResolver 解析(系统命令直通、shell builtin 平台包装、复合
|
|
|
155
155
|
→ 超时 kill 整个进程组
|
|
156
156
|
→ 返回附带 `next_action_hint` 的结构化结果。
|
|
157
157
|
|
|
158
|
-
当前实现的上述行为仍聚合在一处;1.4 将按 §10 宪法重排为
|
|
159
|
-
Executor / Validator / Orchestration 三段(迁移明细见 docs/design_1_4.md)。
|
|
160
|
-
|
|
161
158
|
### 4.6 断言与文件比较集成
|
|
162
159
|
|
|
163
160
|
- `compare_files` 是一等断言,经 ComparatorFactory 按类型分发(详见 §6)
|
|
164
161
|
- 所有断言可选;未声明的字段不做校验
|
|
165
|
-
- `--error-analysis` 为 CSV/H5 数值比较提供流式误差统计:`total_numeric_cells` / `mismatched_cells` / `max_abs_error` / `max_rel_error` / `mean_abs_error` / `rms_abs_error`
|
|
162
|
+
- `--error-analysis` 为 CSV/H5 数值比较提供流式误差统计:`total_numeric_cells` / `mismatched_cells` / `max_abs_error` / `max_rel_error` / `mean_abs_error` / `rms_abs_error`;幅值统计(max/mean/rms)覆盖全体参与比较的数值单元格(含通过格),mean/rms 以 `total_numeric_cells` 为分母。`--error-analysis-all` 额外对通过用例输出统计,除此之外两者行为一致
|
|
166
163
|
|
|
167
164
|
## 5. 运行时状态持久化(`.symtest/`)
|
|
168
165
|
|
|
@@ -178,24 +175,57 @@ Executor / Validator / Orchestration 三段(迁移明细见 docs/design_1_4.md
|
|
|
178
175
|
|
|
179
176
|
## 6. 文件比较子系统
|
|
180
177
|
|
|
181
|
-
### 6.1
|
|
178
|
+
### 6.1 三泳道比较器架构
|
|
179
|
+
|
|
180
|
+
所有比较器共享根契约 `ComparatorBase.compare(ctx) -> ComparisonResult`:
|
|
181
|
+
框架构建 `CompareContext`(workspace / actual / baseline / params / error_analysis);
|
|
182
|
+
`actual`/`baseline` 以及插件 `path_params` 声明的构造参数在**比较器构造之前**
|
|
183
|
+
按 workspace 统一解析,插件不得自行对 CWD resolve。配置单一事实源:
|
|
184
|
+
比较器配置只存在于构造器捕获的实例状态,`ctx` 仅承载调用级上下文。
|
|
185
|
+
三条泳道职责互斥:
|
|
186
|
+
|
|
187
|
+
| 泳道 | 基类 | 契约 | verdict 归属 | 内置实例 |
|
|
188
|
+
|---|---|---|---|---|
|
|
189
|
+
| 文件泳道 | `FileComparator` | `read_content` + `compare_content`(两文件模型,行列窗口、line N 偏移、chunk_size、similarity 均属本泳道) | 插件 | text / json / csv / xml / h5 / binary |
|
|
190
|
+
| 数据泳道 | `ExtractorComparator` | `extract(ctx) -> {channel: ChannelData}`;框架逐通道跑 `compare_numeric`,per-channel 容差(`channels` / `default_channel`),聚合 `ChannelResult` | **框架**(容差语义对 AI 消费端可预期) | script_extract、extractor 插件 |
|
|
191
|
+
| 自主泳道 | 直接继承根 | `compare(ctx)` 全权判定 | 插件 | script、hourglass 式分析插件 |
|
|
192
|
+
|
|
193
|
+
- 文本系共享 difflib 行级基底,json / csv / xml 为其结构化特化;h5 面向科学数据集;binary 流式分块 + LCS 相似度
|
|
194
|
+
- 统一返回 `ComparisonResult`(identical / differences / error / error_stats / command_output / channels),支持 text / json / html 渲染
|
|
195
|
+
- 数据泳道插件可通过 `ChannelData.extra_stats` 附带自定义误差指标,存放在独立命名空间(`ChannelResult.extra_stats`),不可覆盖框架规范指标;但 verdict 仍由框架容差持有——需要自定 verdict 的走自主泳道
|
|
196
|
+
|
|
197
|
+
### 6.2 通道协议(数据泳道)
|
|
198
|
+
|
|
199
|
+
- 通道判定:`identical = all(channels.passed)`;差异 position 带通道前缀(`channel S33`);`error_stats` 按通道名嵌套
|
|
200
|
+
- 内置 `script_extract` 类型:子进程执行用户脚本(零改动接入),脚本 stdout 输出约定 JSON:
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{"channels": {"S11": {"expected": [...], "actual": [...], "extra_stats": {...}}}}
|
|
204
|
+
```
|
|
182
205
|
|
|
183
|
-
|
|
184
|
-
-
|
|
185
|
-
- 统一返回 ComparisonResult(identical / differences / error / script command_output),支持 text / json / html 渲染;支持行列窗口范围参数截取后比较
|
|
206
|
+
非零退出、超时、畸形 JSON 一律判为比较 error(绝不静默通过);`actual`/`baseline` 按惯例以 baseline 在前的顺序追加为尾部 argv 槽位(可缺省)
|
|
207
|
+
- 结果粒度:一条 compareSpec = 一条断言;`ComparisonResult.channels` 携带通道级子结果,报告逐通道展示 pass/fail + stats;JSON 输出中通道 differences 按 per-channel 配额截断
|
|
186
208
|
|
|
187
|
-
### 6.
|
|
209
|
+
### 6.3 工厂与插件发现
|
|
188
210
|
|
|
189
|
-
- `file_type` 取值:`text` / `json` / `csv` / `xml` / `h5` / `binary` / `script`;工厂按类型分发,支持动态注册与全局 reset(测试用)
|
|
211
|
+
- `file_type` 取值:`text` / `json` / `csv` / `xml` / `h5` / `binary` / `script` / `script_extract`;工厂按类型分发,支持动态注册与全局 reset(测试用)
|
|
190
212
|
- 插件发现四处来源:内置 `*_comparator.py` 自动发现、`workspace/comparators/` 自动扫描、`--plugin-dir` CLI 参数、`CLITEST_PLUGIN_DIRS` 环境变量(供进程模式 worker 使用)
|
|
191
|
-
- 命名约定:`*_comparator.py` + `*Comparator`
|
|
213
|
+
- 命名约定:`*_comparator.py` + `*Comparator` 类名;可用类属性 `comparator_type` 显式指定类型名(如 `script_extract`);抽象基类自动跳过注册
|
|
214
|
+
- 配置传递与严格校验:`actual`/`baseline`/`type`/`options` 之外的键转发给比较器构造函数(kwargs);构造器参数是**严格**的——未声明的键(拼写错误)在构造时大声失败并给出支持参数清单。`options` 是框架持有的插件配置命名空间(并入构造参数,显式顶层键优先),核心 schema 不为单个插件增加专属字段;`channels`/`default_channel` 属数据泳道框架结构
|
|
192
215
|
|
|
193
|
-
### 6.
|
|
216
|
+
### 6.4 script 比较协议(自主泳道对外契约)
|
|
194
217
|
|
|
195
|
-
- 子进程方式执行 `<interpreter> <script> <
|
|
218
|
+
- 子进程方式执行 `<interpreter> <script> <baseline> <actual>`(文件槽位可缺省)
|
|
196
219
|
- 默认 exit code 0 → 通过;可选 `pass_pattern` / `fail_pattern` 正则匹配 stdout 细化判定
|
|
197
220
|
- 超时可配
|
|
198
221
|
|
|
222
|
+
### 6.5 插件公共 API
|
|
223
|
+
|
|
224
|
+
`symtest.file_comparator` 包导出:`ComparatorBase` / `CompareContext` /
|
|
225
|
+
`FileComparator` / `ExtractorComparator` / `ChannelData` / `ChannelResult` /
|
|
226
|
+
`compare_numeric` / `NumericComparisonStats` / `parse_data_filter`。
|
|
227
|
+
数据泳道插件只需依赖 `ExtractorComparator` + `ChannelData`,数值判定全部复用框架核心。
|
|
228
|
+
|
|
199
229
|
## 7. TUI 子系统
|
|
200
230
|
|
|
201
231
|
基于 Textual 的终端交互界面:App + Controller(load / create / update /
|
|
@@ -213,7 +243,7 @@ TUI 与 runner 共用同一解析器;宽松的展示形态在 TUI 侧自行处
|
|
|
213
243
|
| 新配置格式 | `BaseRunner` | 支持新的测试定义格式(如 XML、TOML) |
|
|
214
244
|
| 自定义 Setup | `BaseSetup` | 数据库初始化、服务启停等 |
|
|
215
245
|
| 自定义断言 | 扩展 `Assertions` | 特定业务校验逻辑 |
|
|
216
|
-
| 新比较器 | `
|
|
246
|
+
| 新比较器 | `FileComparator` / `ExtractorComparator` / `ComparatorBase` | 按泳道选择基类(文件格式 / 数据提取+通道 / 全权分析),放入 `comparators/` 目录自动发现 |
|
|
217
247
|
| 新 Runner | `ParallelRunner` / `BaseRunner` | 自定义并行调度策略 |
|
|
218
248
|
| TUI 扩展 | `CaseController` / Widgets | 扩展终端管理界面 |
|
|
219
249
|
|
|
@@ -252,7 +282,6 @@ TUI 与 runner 共用同一解析器;宽松的展示形态在 TUI 侧自行处
|
|
|
252
282
|
> **地位与效力**:本节自 Symtest 1.4 Phase 0 评审定稿,是本项目的核心架构契约,
|
|
253
283
|
> 对所有后续 feature 具有最高约束力——任何功能需求先对照本宪法确定归属,再写代码。
|
|
254
284
|
> 修订宪法必须在变更说明中显式指出所放宽/违反的条款及理由。
|
|
255
|
-
> 定稿前的演进推导见开发阶段文档 docs/design_1_4.md。
|
|
256
285
|
|
|
257
286
|
### 10.1 数据流主线
|
|
258
287
|
|
|
@@ -373,16 +402,3 @@ Reporter 的合法输入只能是 Result 类型;`next_action_hint` 属于 resu
|
|
|
373
402
|
`reporter`;
|
|
374
403
|
- guard 测试纳入常规回归套件(`python tests\run_all.py`),违规即失败;
|
|
375
404
|
- 冲突裁决次序:guard 测试 > 本节文字 > 个人偏好。
|
|
376
|
-
|
|
377
|
-
### 10.6 现状差距与收敛路径
|
|
378
|
-
|
|
379
|
-
定稿时刻(1.4 Phase 0)现行实现与本宪法的已知偏差如下,将在 1.4 对应 Phase 内
|
|
380
|
-
逐项收敛(迁移明细见 docs/design_1_4.md):
|
|
381
|
-
|
|
382
|
-
| 现状 | 违反 | 收敛 |
|
|
383
|
-
|---|---|---|
|
|
384
|
-
| `execution.py::validate_result` 住在执行层 | 原则 2 | Phase 2 迁入 `validation/validator.py` |
|
|
385
|
-
| `next_action_hint` 在 execution 层构造 | 原则 5 | Phase 2 迁入 `reporting/diagnosis.py` |
|
|
386
|
-
| retry 循环在 executor 内部 | 原则 2 / 4 | Phase 2 上移编排层 |
|
|
387
|
-
| Validator 侧 update_baseline 写文件 | 原则 3 | Phase 2 改为 runner 独立 accept 步骤 |
|
|
388
|
-
| `parse_test_cases` TUI mode 后门 | 原则 6 | Phase 2 拆除,单一解析器 |
|
|
@@ -164,10 +164,6 @@ stdout / stderr / returncode / duration) → assertions (return_code / contains
|
|
|
164
164
|
matches / compare_files) → retries on failure up to `retry_count` → kills the
|
|
165
165
|
whole process group on timeout → structured result with `next_action_hint`.
|
|
166
166
|
|
|
167
|
-
Today these behaviors are aggregated in one place; 1.4 rearranges them into
|
|
168
|
-
Executor / Validator / Orchestration per the §10 Constitution (migration details
|
|
169
|
-
in docs/design_1_4.md).
|
|
170
|
-
|
|
171
167
|
### 4.6 Assertions and File Comparison Integration
|
|
172
168
|
|
|
173
169
|
- `compare_files` is a first-class assertion dispatched via ComparatorFactory (see §6)
|
|
@@ -266,8 +262,7 @@ TUI side itself (§10 Principle 6).
|
|
|
266
262
|
> project's core architectural contract with supreme authority over all future
|
|
267
263
|
> features — resolve ownership against this constitution before writing any code.
|
|
268
264
|
> Amending it requires explicitly naming the clause being relaxed/waived and the
|
|
269
|
-
> rationale in the change description.
|
|
270
|
-
> the development-phase document docs/design_1_4.md.
|
|
265
|
+
> rationale in the change description.
|
|
271
266
|
|
|
272
267
|
### 10.1 Data Flow Spine
|
|
273
268
|
|
|
@@ -398,17 +393,3 @@ architecture guard tests enforced by CI:
|
|
|
398
393
|
- Guard tests are part of the regular regression suite
|
|
399
394
|
(`python tests\run_all.py`); violations fail the build;
|
|
400
395
|
- Conflict resolution order: guard tests > this text > personal preference.
|
|
401
|
-
|
|
402
|
-
### 10.6 Current Gap to This Constitution
|
|
403
|
-
|
|
404
|
-
Known deviations of the current implementation from this constitution as of
|
|
405
|
-
ratification (1.4 Phase 0). Each item converges during the corresponding 1.4
|
|
406
|
-
phase (migration details in docs/design_1_4.md):
|
|
407
|
-
|
|
408
|
-
| Current state | Violated | Convergence |
|
|
409
|
-
|---|---|---|
|
|
410
|
-
| `execution.py::validate_result` lives in the execution layer | Principle 2 | Phase 2: move to `validation/validator.py` |
|
|
411
|
-
| `next_action_hint` built in the execution layer | Principle 5 | Phase 2: move to `reporting/diagnosis.py` |
|
|
412
|
-
| Retry loop inside the executor | Principles 2 / 4 | Phase 2: lift to orchestration |
|
|
413
|
-
| update_baseline writes files inside validation | Principle 3 | Phase 2: runner-side independent accept step |
|
|
414
|
-
| `parse_test_cases` TUI-mode back door | Principle 6 | Phase 2: remove; single parser |
|
|
@@ -48,7 +48,7 @@ HDF5 文件比较依赖 `h5py`(已随框架安装)。如需在无 HDF5 环
|
|
|
48
48
|
|
|
49
49
|
## 测试用例定义
|
|
50
50
|
|
|
51
|
-
> **Schema v2(1.4)**:配置采用分层 DSL——执行相关字段(`command`、`args`、`timeout`、`retry_count`、`env`、`steps`)位于 `execution` 块,调度相关字段(`depends_on`、`resources`)位于 `scheduling` 块,`expected` 保持在顶层。旧的扁平布局已移除,可使用 `symtest migrate`
|
|
51
|
+
> **Schema v2(1.4)**:配置采用分层 DSL——执行相关字段(`command`、`args`、`timeout`、`retry_count`、`env`、`steps`)位于 `execution` 块,调度相关字段(`depends_on`、`resources`)位于 `scheduling` 块,`expected` 保持在顶层。旧的扁平布局已移除,可使用 `symtest migrate` 迁移。迁移会递归处理整棵 `import` 树:默认为每个文件生成 `<stem>.v2<ext>` 副本并自动重写父文件中的 import 路径;`--in-place` 则原地覆盖所有文件(与 `--output` 互斥)。
|
|
52
52
|
|
|
53
53
|
### JSON 格式
|
|
54
54
|
|
|
@@ -275,6 +275,13 @@ test_cases:
|
|
|
275
275
|
| `expected.output_matches` | 否 | 输出需匹配的正则表达式(单个字符串) |
|
|
276
276
|
| `expected.compare_files` | 否 | 文件比较断言列表,见下文 |
|
|
277
277
|
|
|
278
|
+
### execution 二选一(互斥)
|
|
279
|
+
|
|
280
|
+
`execution` 有两种形态,**二选一**且互斥,同时声明两种形态属于配置错误:
|
|
281
|
+
|
|
282
|
+
- **单命令形态**:`command` + `args`(`timeout` / `retry_count` / `env` 可选)
|
|
283
|
+
- **序列形态**:`steps`(列表,每个 step 为 `command + args + expected`);`command` / `args` 不得与 `steps` 并存
|
|
284
|
+
|
|
278
285
|
## Case 级环境变量(env)
|
|
279
286
|
|
|
280
287
|
通过 `execution` 内与 `command`、`steps` 同级的 `env` 字段,可为单个用例注入环境变量,仅在该用例(序列模式为所有 step)的子进程内生效,不影响其他用例。
|
|
@@ -1788,12 +1795,12 @@ CSV 比较按行列结构逐单元格比对;数值单元格在容差范围内
|
|
|
1788
1795
|
|---|---|
|
|
1789
1796
|
| `total_numeric_cells` | 参与数值比较的单元格总数 |
|
|
1790
1797
|
| `mismatched_cells` | 超出容差的单元格数 |
|
|
1791
|
-
| `max_abs_error` |
|
|
1792
|
-
| `max_rel_error` |
|
|
1793
|
-
| `mean_abs_error` |
|
|
1794
|
-
| `rms_abs_error` |
|
|
1798
|
+
| `max_abs_error` | 全体数值单元格中的最大绝对误差及其位置 |
|
|
1799
|
+
| `max_rel_error` | 全体数值单元格中的最大相对误差及其位置 |
|
|
1800
|
+
| `mean_abs_error` | 全体数值单元格的平均绝对误差(分母为 `total_numeric_cells`) |
|
|
1801
|
+
| `rms_abs_error` | 全体数值单元格的均方根绝对误差(RMSE,分母为 `total_numeric_cells`) |
|
|
1795
1802
|
|
|
1796
|
-
|
|
1803
|
+
统计是**流式**计算的,不依赖差异截断,幅值统计(max/mean/rms)覆盖**全体**参与比较的数值单元格(含在容差内通过的单元格),可用于观察通过格离容差的余量;非有限值(NaN/inf)单元格不参与幅值统计。两个参数的统计口径完全一致,区别仅在于:默认仅失败的比较输出统计,通过的比较不输出。
|
|
1797
1804
|
|
|
1798
1805
|
如需让**通过**的用例也输出统计信息(例如用于监控容差余量),可改用 `--error-analysis-all`(它会隐含启用 `--error-analysis`):
|
|
1799
1806
|
|
|
@@ -1965,11 +1972,31 @@ class MySetup(BaseSetup):
|
|
|
1965
1972
|
|
|
1966
1973
|
### 自定义文件比较器
|
|
1967
1974
|
|
|
1968
|
-
|
|
1975
|
+
#### 三泳道架构(v2)
|
|
1976
|
+
|
|
1977
|
+
比较器插件体系围绕根契约 `ComparatorBase.compare(ctx) -> ComparisonResult` 组织,
|
|
1978
|
+
按判定权归属分为三条泳道:
|
|
1979
|
+
|
|
1980
|
+
| 泳道 | 基类 | 适用场景 | verdict 归属 |
|
|
1981
|
+
|---|---|---|---|
|
|
1982
|
+
| **文件泳道** | `FileComparator` | 比较两个同类文件(text/json/csv/xml/h5/binary 内置即此类) | 插件 |
|
|
1983
|
+
| **数据泳道** | `ExtractorComparator` | 从任意上游(文件/求解器输出/跨文件整理)提取数值数据,**复用框架数值核心**做通道化容差判定 | **框架** |
|
|
1984
|
+
| **自主泳道** | 直接继承 `ComparatorBase` | 独特判定逻辑(阈值组合、标签解析、渐近分析等) | 插件 |
|
|
1985
|
+
|
|
1986
|
+
选型决策:
|
|
1969
1987
|
|
|
1970
|
-
|
|
1988
|
+
- 数据本来就是 `(expected, actual)` 数值数组、只需 rtol/atol 判定 → **数据泳道**(可享受通道、per-channel 容差、统一 error_stats 与报告渲染)
|
|
1989
|
+
- 需要自定 verdict(比如"主分量紧、EAS 分量松"的组合判定、符号/渐近检查)→ **自主泳道**
|
|
1990
|
+
- 只是想让现成脚本快速接入 → 优先考虑内置 `script`(自定判定)或 `script_extract`(框架容差判定),零 Python 插件代码
|
|
1971
1991
|
|
|
1972
|
-
|
|
1992
|
+
**路径解析约定**:`actual`/`baseline` 以及插件用 `path_params` 类属性声明的路径参数,
|
|
1993
|
+
由框架在**比较器构造之前**统一按 workspace 解析为绝对路径——构造器捕获的状态
|
|
1994
|
+
(`self.script`、`self.cwd` 等)持有的已是解析后的绝对路径。插件内部
|
|
1995
|
+
**禁止**对 CWD 做 `Path.resolve()`——并行/process 模式下 CWD 不可靠。
|
|
1996
|
+
|
|
1997
|
+
#### 插件发现方式(三种泳道通用)
|
|
1998
|
+
|
|
1999
|
+
在 workspace 下创建 `comparators/` 目录,放入 `*_comparator.py` 文件,框架会在首次使用时自动发现并注册其中的 `*Comparator` 类。
|
|
1973
2000
|
|
|
1974
2001
|
```
|
|
1975
2002
|
your-workspace/
|
|
@@ -1986,26 +2013,148 @@ symtest run test_config.json --plugin-dir ./extra_plugins
|
|
|
1986
2013
|
|
|
1987
2014
|
插件也会通过环境变量 `CLITEST_PLUGIN_DIRS` 自动继承到 process 模式子进程。
|
|
1988
2015
|
|
|
1989
|
-
|
|
1990
|
-
-
|
|
2016
|
+
**命名约定**:
|
|
2017
|
+
- 文件名必须以 `_comparator.py` 结尾(如 `my_analysis_comparator.py`)
|
|
1991
2018
|
- 类名必须以 `Comparator` 结尾(如 `MyAnalysisComparator`)
|
|
1992
|
-
- 注册的 type 名 = 类名去掉 `Comparator` 再小写(如 `myanalysis
|
|
1993
|
-
-
|
|
1994
|
-
- 通过 `from symtest.file_comparator import ComparisonResult, Difference` 构造结构化结果
|
|
1995
|
-
- `extra_kwargs` 自动从 config `compareSpec` 透传
|
|
2019
|
+
- 注册的 type 名 = 类名去掉 `Comparator` 再小写(如 `myanalysis`);也可用类属性 `comparator_type = "my_analysis"` 显式指定
|
|
2020
|
+
- 抽象基类(未实现全部抽象方法)自动跳过注册
|
|
1996
2021
|
|
|
1997
|
-
|
|
2022
|
+
在配置中直接使用注册的类型名。比较器构造参数是**严格**的:`actual`/`baseline`/
|
|
2023
|
+
`type` 以外的键会透传给插件构造函数,但插件未声明的参数(如拼写错误
|
|
2024
|
+
`pass_threhsold`)会在构造时**大声失败**(错误信息包含比较器类型名与支持的
|
|
2025
|
+
参数清单),绝不静默回退到默认值。插件自有配置建议放入 `options` 命名空间
|
|
2026
|
+
(其条目并入构造参数,显式顶层键优先),避免向核心 schema 增加插件专属字段:
|
|
1998
2027
|
|
|
1999
2028
|
```json
|
|
2000
2029
|
{
|
|
2001
2030
|
"type": "myanalysis",
|
|
2002
2031
|
"actual": "optional_for_plugins",
|
|
2003
2032
|
"baseline": "optional_for_plugins",
|
|
2004
|
-
"param1": "value1"
|
|
2033
|
+
"options": {"param1": "value1", "param2": 42}
|
|
2034
|
+
}
|
|
2035
|
+
```
|
|
2036
|
+
|
|
2037
|
+
#### 数据泳道:通道提取器插件
|
|
2038
|
+
|
|
2039
|
+
适用场景:一个脚本/插件产出多通道数据(如 CSV 的不同列、不同物理量),
|
|
2040
|
+
每通道需要独立的容差与误差分析。插件只负责"提取",判定完全由框架完成。
|
|
2041
|
+
|
|
2042
|
+
```python
|
|
2043
|
+
# comparators/uel_stress_comparator.py
|
|
2044
|
+
import numpy as np
|
|
2045
|
+
from symtest.file_comparator import (
|
|
2046
|
+
ExtractorComparator, ChannelData, CompareContext,
|
|
2047
|
+
)
|
|
2048
|
+
|
|
2049
|
+
class UelStressComparator(ExtractorComparator):
|
|
2050
|
+
path_params = ("uel_csv", "ref_csv") # 由框架按 workspace 解析
|
|
2051
|
+
|
|
2052
|
+
def __init__(self, uel_csv="", ref_csv="", **kwargs):
|
|
2053
|
+
super().__init__(**kwargs)
|
|
2054
|
+
self.uel_csv = uel_csv
|
|
2055
|
+
self.ref_csv = ref_csv
|
|
2056
|
+
|
|
2057
|
+
def extract(self, ctx: CompareContext):
|
|
2058
|
+
uel = np.loadtxt(self.uel_csv, delimiter=",")
|
|
2059
|
+
ref = np.loadtxt(self.ref_csv, delimiter=",")
|
|
2060
|
+
return {
|
|
2061
|
+
"S11": ChannelData(expected=ref[:, 0], actual=uel[:, 0]),
|
|
2062
|
+
"S33": ChannelData(
|
|
2063
|
+
expected=ref[:, 2], actual=uel[:, 2],
|
|
2064
|
+
extra_stats={"hydrostatic_shift": float(uel[:, 2].mean())},
|
|
2065
|
+
),
|
|
2066
|
+
}
|
|
2067
|
+
```
|
|
2068
|
+
|
|
2069
|
+
配置(per-channel 容差按名路由,未声明的通道用 `default_channel`):
|
|
2070
|
+
|
|
2071
|
+
```json
|
|
2072
|
+
{
|
|
2073
|
+
"type": "uelstress",
|
|
2074
|
+
"uel_csv": "out/uel.csv",
|
|
2075
|
+
"ref_csv": "out/native.csv",
|
|
2076
|
+
"channels": {
|
|
2077
|
+
"S33": {"atol": 600.0, "data_filter": "abs>1e-12"}
|
|
2078
|
+
},
|
|
2079
|
+
"default_channel": {"rtol": 1e-5, "atol": 1e-8}
|
|
2005
2080
|
}
|
|
2006
2081
|
```
|
|
2007
2082
|
|
|
2008
|
-
|
|
2083
|
+
**判定与结果语义**:
|
|
2084
|
+
- 每通道独立跑 `compare_numeric`(对称容差 `|a-b| <= max(rtol*max(|a|,|b|), atol)`)
|
|
2085
|
+
- `identical = 所有通道全过`;一条 compareSpec 仍是一条断言
|
|
2086
|
+
- 差异 position 带通道前缀(`channel S33`);`error_stats` 按通道名嵌套
|
|
2087
|
+
- 报告逐通道展示 pass/fail、容差与统计;JSON 输出中通道差异按 per-channel 配额截断
|
|
2088
|
+
- 自定义误差指标通过 `ChannelData.extra_stats` 附带,存放在**独立命名空间**
|
|
2089
|
+
(`ChannelResult.extra_stats`),不可能覆盖框架规范指标(`max_abs_error`、
|
|
2090
|
+
`total` 等);报告逐通道分别渲染两个命名空间
|
|
2091
|
+
- verdict 不可由插件干预——需要自定 verdict 请走自主泳道
|
|
2092
|
+
|
|
2093
|
+
#### 数据泳道:内置 `script_extract` 类型(零改动脚本接入)
|
|
2094
|
+
|
|
2095
|
+
现成分析脚本无需包装成 Python 插件:脚本以子进程执行,向 stdout 打印约定
|
|
2096
|
+
JSON,各通道即进入上述框架判定管线。
|
|
2097
|
+
|
|
2098
|
+
```json
|
|
2099
|
+
{
|
|
2100
|
+
"type": "script_extract",
|
|
2101
|
+
"script": "extract_channels.py",
|
|
2102
|
+
"args": ["--frame", "10"],
|
|
2103
|
+
"cwd": "case/subdir",
|
|
2104
|
+
"channels": {"S33": {"atol": 600.0}},
|
|
2105
|
+
"default_channel": {"rtol": 1e-5, "atol": 1e-8},
|
|
2106
|
+
"timeout": 600
|
|
2107
|
+
}
|
|
2108
|
+
```
|
|
2109
|
+
|
|
2110
|
+
**stdout JSON 协议**:
|
|
2111
|
+
|
|
2112
|
+
```json
|
|
2113
|
+
{
|
|
2114
|
+
"channels": {
|
|
2115
|
+
"S11": {"expected": [1.0, 2.0], "actual": [1.0, 2.0]},
|
|
2116
|
+
"S33": {"expected": [...], "actual": [...], "extra_stats": {"asymmetry": 2e-13}}
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
```
|
|
2120
|
+
|
|
2121
|
+
**错误语义**:非零退出码、超时、畸形 JSON、缺 `channels` 键或通道缺
|
|
2122
|
+
`expected`/`actual` 数组 → 一律判为比较 error(绝不静默通过)。
|
|
2123
|
+
`actual`/`baseline`(若配置)以 baseline 在前的顺序追加为脚本尾部参数,可缺省。
|
|
2124
|
+
|
|
2125
|
+
#### 自主泳道:全权判定插件
|
|
2126
|
+
|
|
2127
|
+
适用场景:独特判定逻辑。插件实现 `compare(ctx)` 并直接返回结果。
|
|
2128
|
+
|
|
2129
|
+
```python
|
|
2130
|
+
# comparators/my_analysis_comparator.py
|
|
2131
|
+
from symtest.file_comparator import ComparatorBase, CompareContext, ComparisonResult, Difference
|
|
2132
|
+
|
|
2133
|
+
class MyAnalysisComparator(ComparatorBase):
|
|
2134
|
+
path_params = ("script", "case_dir")
|
|
2135
|
+
|
|
2136
|
+
def __init__(self, script="", case_dir=None, pass_threshold=1e-6):
|
|
2137
|
+
super().__init__() # 参数严格:未声明/拼错的配置键在构造时报错
|
|
2138
|
+
self.script = script # 构造前已由框架按 workspace 解析
|
|
2139
|
+
self.case_dir = case_dir
|
|
2140
|
+
self.pass_threshold = pass_threshold
|
|
2141
|
+
|
|
2142
|
+
def compare(self, ctx: CompareContext) -> ComparisonResult:
|
|
2143
|
+
result = ComparisonResult(
|
|
2144
|
+
file1=ctx.baseline, # 无文件输入时保持 None,不伪造空串
|
|
2145
|
+
file2=ctx.actual,
|
|
2146
|
+
)
|
|
2147
|
+
# ... 执行分析、解析指标 ...
|
|
2148
|
+
result.identical = True # 或 False + differences
|
|
2149
|
+
result.error_stats = {"full_rel": 8e-8} # 自由 dict,报告通用渲染
|
|
2150
|
+
return result
|
|
2151
|
+
```
|
|
2152
|
+
|
|
2153
|
+
`ctx` 字段(仅调用级上下文):`workspace` / `actual` / `baseline`(可空,
|
|
2154
|
+
无文件输入时为 `None`)/ `params`(文件泳道窗口参数)/ `error_analysis`。
|
|
2155
|
+
比较器配置的唯一权威在构造器捕获的实例状态中——`ctx` 不携带配置副本。
|
|
2156
|
+
|
|
2157
|
+
#### 内置 `script` 类型比较器(自主泳道开箱即用)
|
|
2009
2158
|
|
|
2010
2159
|
适用于独立分析脚本快速接入,无需编写比较器类:
|
|
2011
2160
|
|
|
@@ -2028,8 +2177,8 @@ symtest run test_config.json --plugin-dir ./extra_plugins
|
|
|
2028
2177
|
| 参数 | 必填 | 默认值 | 说明 |
|
|
2029
2178
|
|---|---|---|---|
|
|
2030
2179
|
| `script` | 是 | — | 脚本路径(相对 workspace 或绝对) |
|
|
2031
|
-
| `actual` | 否 | — |
|
|
2032
|
-
| `baseline` | 否 | — |
|
|
2180
|
+
| `actual` | 否 | — | 传给脚本的文件参数(尾部第二位) |
|
|
2181
|
+
| `baseline` | 否 | — | 传给脚本的文件参数(尾部第一位) |
|
|
2033
2182
|
| `cwd` | 否 | — | 脚本工作目录 |
|
|
2034
2183
|
| `interpreter` | 否 | `sys.executable` | Python 解释器 |
|
|
2035
2184
|
| `pass_exit_code` | 否 | `0` | 判定为通过的退出码 |
|
|
@@ -2045,15 +2194,15 @@ symtest run test_config.json --plugin-dir ./extra_plugins
|
|
|
2045
2194
|
|
|
2046
2195
|
脚本的 stdout 和 stderr 会完整捕获到 `Comparator Output` 区块中,在报告渲染时限 20 行展示。
|
|
2047
2196
|
|
|
2048
|
-
####
|
|
2197
|
+
#### 手动注册(编程方式)
|
|
2049
2198
|
|
|
2050
2199
|
```python
|
|
2051
|
-
from symtest.file_comparator import ComparatorFactory
|
|
2052
|
-
from symtest.file_comparator.
|
|
2200
|
+
from symtest.file_comparator import ComparatorFactory, ComparatorBase, CompareContext
|
|
2201
|
+
from symtest.file_comparator.result import ComparisonResult
|
|
2053
2202
|
|
|
2054
|
-
class FooComparator(
|
|
2055
|
-
|
|
2056
|
-
|
|
2203
|
+
class FooComparator(ComparatorBase):
|
|
2204
|
+
def compare(self, ctx: CompareContext) -> ComparisonResult:
|
|
2205
|
+
...
|
|
2057
2206
|
|
|
2058
2207
|
ComparatorFactory.register_comparator("foo", FooComparator)
|
|
2059
2208
|
|
|
@@ -2063,7 +2212,7 @@ comparator = ComparatorFactory.create_comparator("foo")
|
|
|
2063
2212
|
|
|
2064
2213
|
#### 专用插件示例:hourglass 切线刚度分析
|
|
2065
2214
|
|
|
2066
|
-
`examples/plugins/hourglass_tangent_comparator.py`
|
|
2215
|
+
`examples/plugins/hourglass_tangent_comparator.py` 是一个完整的自主泳道工作区插件示例,展示了如何将专用的 `analyze_*_tangent.py` 分析脚本接入框架:
|
|
2067
2216
|
|
|
2068
2217
|
```json
|
|
2069
2218
|
{
|
|
@@ -2078,6 +2227,7 @@ comparator = ComparatorFactory.create_comparator("foo")
|
|
|
2078
2227
|
**特点**:
|
|
2079
2228
|
- 通过 subprocess 调分析脚本(**零改动** analyze 代码),捕获 stdout 后用正则解析 `RESULT:` 行和 `full_rel`/`aa_rel`/`hh_rel`/`asymmetry` 等数值指标
|
|
2080
2229
|
- 构造结构化 `ComparisonResult`:`identical` 基于 `full_rel < pass_threshold` 判定;`differences` 列出超限指标;`error_stats` 包含全部数值
|
|
2230
|
+
- `path_params` 声明 `script`/`case_dir`,路径由框架按 workspace 解析
|
|
2081
2231
|
- 脚本 stdout 进入 `Comparator Output` 区块
|
|
2082
2232
|
|
|
2083
2233
|
使用方法:将插件文件复制到 workspace 的 `comparators/` 目录下即可自动发现,无需改框架代码。
|