symtest-cli 1.3.0__tar.gz → 1.3.2__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.
Files changed (341) hide show
  1. {symtest_cli-1.3.0/src/symtest_cli.egg-info → symtest_cli-1.3.2}/PKG-INFO +15 -12
  2. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/README.md +10 -7
  3. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/docs/design.md +54 -10
  4. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/docs/design_en.md +52 -10
  5. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/docs/tui_and_config_split_design.md +3 -3
  6. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/docs/user_manual.md +137 -6
  7. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/docs/user_manual_en.md +137 -6
  8. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/setup.py +4 -4
  9. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/__init__.py +1 -1
  10. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/config/config_io.py +73 -0
  11. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/config/config_schema.py +38 -0
  12. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/core/assertions.py +1 -1
  13. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/core/base_runner.py +90 -4
  14. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/core/config_loader.py +73 -65
  15. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/core/execution.py +7 -1
  16. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/core/history_store.py +1 -1
  17. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/core/last_run_store.py +2 -2
  18. symtest_cli-1.3.2/src/symtest/core/parallel_runner.py +465 -0
  19. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/core/process_worker.py +2 -0
  20. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/core/sequence_state.py +5 -3
  21. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/core/test_case.py +48 -3
  22. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/core/types.py +1 -0
  23. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/file_comparator/base_comparator.py +13 -0
  24. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/file_comparator/text_comparator.py +56 -32
  25. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/runners/parallel_config_runner.py +69 -3
  26. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/tui/app.py +1 -1
  27. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/tui/screens/case_editor.py +38 -0
  28. {symtest_cli-1.3.0 → symtest_cli-1.3.2/src/symtest_cli.egg-info}/PKG-INFO +15 -12
  29. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest_cli.egg-info/SOURCES.txt +26 -0
  30. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/__pycache__/conftest.cpython-312-pytest-7.4.4.pyc +0 -0
  31. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/__pycache__/conftest.cpython-312-pytest-9.0.3.pyc +0 -0
  32. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/e2e/__pycache__/test_user_flows.cpython-312-pytest-7.4.4.pyc +0 -0
  33. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/e2e/__pycache__/test_user_flows.cpython-312-pytest-9.0.3.pyc +0 -0
  34. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/__pycache__/test_history_feature.cpython-312-pytest-7.4.4.pyc +0 -0
  35. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/__pycache__/test_history_feature.cpython-312-pytest-9.0.3.pyc +0 -0
  36. symtest_cli-1.3.2/tests/integration/__pycache__/test_new_cli_features.cpython-312-pytest-7.4.4.pyc +0 -0
  37. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/__pycache__/test_new_cli_features.cpython-312-pytest-9.0.3.pyc +0 -0
  38. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/__pycache__/test_real_command_execution.cpython-312-pytest-7.4.4.pyc +0 -0
  39. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/__pycache__/test_real_command_execution.cpython-312-pytest-9.0.3.pyc +0 -0
  40. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/__pycache__/test_sequence.cpython-312-pytest-7.4.4.pyc +0 -0
  41. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/__pycache__/test_sequence.cpython-312-pytest-9.0.3.pyc +0 -0
  42. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_binary_compare.cpython-312-pytest-7.4.4.pyc +0 -0
  43. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_binary_compare.cpython-312-pytest-9.0.3.pyc +0 -0
  44. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_csv_compare.cpython-312-pytest-7.4.4.pyc +0 -0
  45. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_csv_compare.cpython-312-pytest-9.0.3.pyc +0 -0
  46. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_h5_compare.cpython-312-pytest-7.4.4.pyc +0 -0
  47. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_h5_compare.cpython-312-pytest-9.0.3.pyc +0 -0
  48. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_json_compare.cpython-312-pytest-7.4.4.pyc +0 -0
  49. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_json_compare.cpython-312-pytest-9.0.3.pyc +0 -0
  50. symtest_cli-1.3.2/tests/integration/file_compare/__pycache__/test_text_compare.cpython-312-pytest-7.4.4.pyc +0 -0
  51. symtest_cli-1.3.2/tests/integration/file_compare/__pycache__/test_text_compare.cpython-312-pytest-9.0.3.pyc +0 -0
  52. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_xml_compare.cpython-312-pytest-7.4.4.pyc +0 -0
  53. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_xml_compare.cpython-312-pytest-9.0.3.pyc +0 -0
  54. symtest_cli-1.3.2/tests/integration/file_compare/test_text_compare.py +124 -0
  55. symtest_cli-1.3.2/tests/integration/parallel/__pycache__/test_depends_on.cpython-312-pytest-7.4.4.pyc +0 -0
  56. symtest_cli-1.3.2/tests/integration/parallel/__pycache__/test_depends_on.cpython-312-pytest-9.0.3.pyc +0 -0
  57. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/parallel/__pycache__/test_parallel_runner.cpython-312-pytest-7.4.4.pyc +0 -0
  58. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/parallel/__pycache__/test_parallel_runner.cpython-312-pytest-9.0.3.pyc +0 -0
  59. symtest_cli-1.3.2/tests/integration/parallel/test_depends_on.py +229 -0
  60. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/path_handling/__pycache__/test_spaces_in_paths.cpython-312-pytest-7.4.4.pyc +0 -0
  61. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/path_handling/__pycache__/test_spaces_in_paths.cpython-312-pytest-9.0.3.pyc +0 -0
  62. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/test_history_feature.py +5 -3
  63. symtest_cli-1.3.2/tests/unit/__pycache__/test_binary_comparator.cpython-312-pytest-7.4.4.pyc +0 -0
  64. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_binary_comparator.cpython-312-pytest-9.0.3.pyc +0 -0
  65. symtest_cli-1.3.2/tests/unit/__pycache__/test_cli.cpython-312-pytest-7.4.4.pyc +0 -0
  66. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_cli.cpython-312-pytest-9.0.3.pyc +0 -0
  67. symtest_cli-1.3.2/tests/unit/__pycache__/test_config_io.cpython-312-pytest-7.4.4.pyc +0 -0
  68. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_config_io.cpython-312-pytest-9.0.3.pyc +0 -0
  69. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_h5_comparator.cpython-312-pytest-7.4.4.pyc +0 -0
  70. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_h5_comparator.cpython-312-pytest-9.0.3.pyc +0 -0
  71. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_import_expander.cpython-312-pytest-7.4.4.pyc +0 -0
  72. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_import_expander.cpython-312-pytest-9.0.3.pyc +0 -0
  73. symtest_cli-1.3.2/tests/unit/__pycache__/test_inheritance_expander.cpython-312-pytest-7.4.4.pyc +0 -0
  74. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_inheritance_expander.cpython-312-pytest-9.0.3.pyc +0 -0
  75. symtest_cli-1.3.2/tests/unit/__pycache__/test_result.cpython-312-pytest-7.4.4.pyc +0 -0
  76. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_result.cpython-312-pytest-9.0.3.pyc +0 -0
  77. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/commands/__pycache__/test_compare_command.cpython-312-pytest-7.4.4.pyc +0 -0
  78. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/commands/__pycache__/test_compare_command.cpython-312-pytest-9.0.3.pyc +0 -0
  79. symtest_cli-1.3.2/tests/unit/core/__pycache__/test_assertions.cpython-312-pytest-7.4.4.pyc +0 -0
  80. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_assertions.cpython-312-pytest-9.0.3.pyc +0 -0
  81. symtest_cli-1.3.2/tests/unit/core/__pycache__/test_case_env.cpython-312-pytest-7.4.4.pyc +0 -0
  82. symtest_cli-1.3.2/tests/unit/core/__pycache__/test_case_env.cpython-312-pytest-9.0.3.pyc +0 -0
  83. symtest_cli-1.3.2/tests/unit/core/__pycache__/test_config_loader.cpython-312-pytest-7.4.4.pyc +0 -0
  84. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_config_loader.cpython-312-pytest-9.0.3.pyc +0 -0
  85. symtest_cli-1.3.2/tests/unit/core/__pycache__/test_config_loader_new_features.cpython-312-pytest-7.4.4.pyc +0 -0
  86. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_config_loader_new_features.cpython-312-pytest-9.0.3.pyc +0 -0
  87. symtest_cli-1.3.2/tests/unit/core/__pycache__/test_execution.cpython-312-pytest-7.4.4.pyc +0 -0
  88. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_execution.cpython-312-pytest-9.0.3.pyc +0 -0
  89. symtest_cli-1.3.2/tests/unit/core/__pycache__/test_execution_new_features.cpython-312-pytest-7.4.4.pyc +0 -0
  90. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_execution_new_features.cpython-312-pytest-9.0.3.pyc +0 -0
  91. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_history_store.cpython-312-pytest-7.4.4.pyc +0 -0
  92. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_history_store.cpython-312-pytest-9.0.3.pyc +0 -0
  93. symtest_cli-1.3.2/tests/unit/core/__pycache__/test_last_run_store.cpython-312-pytest-7.4.4.pyc +0 -0
  94. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_last_run_store.cpython-312-pytest-9.0.3.pyc +0 -0
  95. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_process_worker.cpython-312-pytest-7.4.4.pyc +0 -0
  96. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_process_worker.cpython-312-pytest-9.0.3.pyc +0 -0
  97. symtest_cli-1.3.2/tests/unit/core/__pycache__/test_sequence_state.cpython-312-pytest-7.4.4.pyc +0 -0
  98. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_sequence_state.cpython-312-pytest-9.0.3.pyc +0 -0
  99. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_setup.cpython-312-pytest-7.4.4.pyc +0 -0
  100. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_setup.cpython-312-pytest-9.0.3.pyc +0 -0
  101. symtest_cli-1.3.2/tests/unit/core/__pycache__/test_validation_error.cpython-312-pytest-7.4.4.pyc +0 -0
  102. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_validation_error.cpython-312-pytest-9.0.3.pyc +0 -0
  103. symtest_cli-1.3.2/tests/unit/core/__pycache__/test_xfail.cpython-312-pytest-7.4.4.pyc +0 -0
  104. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_xfail.cpython-312-pytest-9.0.3.pyc +0 -0
  105. symtest_cli-1.3.2/tests/unit/core/test_case_env.py +225 -0
  106. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/test_sequence_state.py +1 -1
  107. symtest_cli-1.3.2/tests/unit/file_comparator/__pycache__/test_error_analysis.cpython-312-pytest-7.4.4.pyc +0 -0
  108. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/__pycache__/test_error_analysis.cpython-312-pytest-9.0.3.pyc +0 -0
  109. symtest_cli-1.3.2/tests/unit/file_comparator/__pycache__/test_hourglass_tangent_comparator.cpython-312-pytest-7.4.4.pyc +0 -0
  110. symtest_cli-1.3.2/tests/unit/file_comparator/__pycache__/test_script_comparator.cpython-312-pytest-7.4.4.pyc +0 -0
  111. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/__pycache__/test_script_comparator.cpython-312-pytest-9.0.3.pyc +0 -0
  112. symtest_cli-1.3.2/tests/unit/file_comparator/__pycache__/test_workspace_plugins.cpython-312-pytest-7.4.4.pyc +0 -0
  113. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/__pycache__/test_workspace_plugins.cpython-312-pytest-9.0.3.pyc +0 -0
  114. symtest_cli-1.3.2/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-312-pytest-7.4.4.pyc +0 -0
  115. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-312-pytest-9.0.3.pyc +0 -0
  116. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/runners/__pycache__/test_test_case_filter.cpython-312-pytest-7.4.4.pyc +0 -0
  117. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/runners/__pycache__/test_test_case_filter.cpython-312-pytest-9.0.3.pyc +0 -0
  118. symtest_cli-1.3.2/tests/unit/runners/__pycache__/test_test_case_tag_filter.cpython-312-pytest-7.4.4.pyc +0 -0
  119. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/runners/__pycache__/test_test_case_tag_filter.cpython-312-pytest-9.0.3.pyc +0 -0
  120. symtest_cli-1.3.2/tests/unit/tui/__pycache__/conftest.cpython-312-pytest-7.4.4.pyc +0 -0
  121. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/conftest.cpython-312-pytest-9.0.3.pyc +0 -0
  122. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_app.cpython-312-pytest-7.4.4.pyc +0 -0
  123. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_app.cpython-312-pytest-9.0.3.pyc +0 -0
  124. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_case_controller.cpython-312-pytest-7.4.4.pyc +0 -0
  125. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_case_controller.cpython-312-pytest-9.0.3.pyc +0 -0
  126. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_search_functions.cpython-312-pytest-7.4.4.pyc +0 -0
  127. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_search_functions.cpython-312-pytest-9.0.3.pyc +0 -0
  128. symtest_cli-1.3.2/tests/unit/tui/__pycache__/test_tui_run_test.cpython-312-pytest-7.4.4.pyc +0 -0
  129. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_tui_run_test.cpython-312-pytest-9.0.3.pyc +0 -0
  130. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_widgets_data.cpython-312-pytest-7.4.4.pyc +0 -0
  131. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_widgets_data.cpython-312-pytest-9.0.3.pyc +0 -0
  132. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/utils/__pycache__/test_junit_xml_writer.cpython-312-pytest-7.4.4.pyc +0 -0
  133. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/utils/__pycache__/test_junit_xml_writer.cpython-312-pytest-9.0.3.pyc +0 -0
  134. symtest_cli-1.3.2/tests/unit/utils/__pycache__/test_report_generator.cpython-312-pytest-7.4.4.pyc +0 -0
  135. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/utils/__pycache__/test_report_generator.cpython-312-pytest-9.0.3.pyc +0 -0
  136. symtest_cli-1.3.0/src/symtest/core/parallel_runner.py +0 -251
  137. symtest_cli-1.3.0/tests/integration/file_compare/__pycache__/test_text_compare.cpython-312-pytest-7.4.4.pyc +0 -0
  138. symtest_cli-1.3.0/tests/integration/file_compare/__pycache__/test_text_compare.cpython-312-pytest-9.0.3.pyc +0 -0
  139. symtest_cli-1.3.0/tests/integration/file_compare/test_text_compare.py +0 -40
  140. symtest_cli-1.3.0/tests/unit/__pycache__/test_cli.cpython-312-pytest-7.4.4.pyc +0 -0
  141. symtest_cli-1.3.0/tests/unit/core/__pycache__/test_assertions.cpython-312-pytest-7.4.4.pyc +0 -0
  142. symtest_cli-1.3.0/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-312-pytest-7.4.4.pyc +0 -0
  143. symtest_cli-1.3.0/tests/unit/utils/__pycache__/test_report_generator.cpython-312-pytest-7.4.4.pyc +0 -0
  144. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/LICENSE +0 -0
  145. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/MANIFEST.in +0 -0
  146. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/pyproject.toml +0 -0
  147. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/setup.cfg +0 -0
  148. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/cli.py +0 -0
  149. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/commands/__init__.py +0 -0
  150. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/commands/compare.py +0 -0
  151. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/config/__init__.py +0 -0
  152. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/config/import_expander.py +0 -0
  153. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/config/inheritance_expander.py +0 -0
  154. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/core/__init__.py +0 -0
  155. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/core/setup.py +0 -0
  156. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/file_comparator/__init__.py +0 -0
  157. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/file_comparator/binary_comparator.py +0 -0
  158. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/file_comparator/csv_comparator.py +0 -0
  159. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/file_comparator/factory.py +0 -0
  160. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/file_comparator/h5_comparator.py +0 -0
  161. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/file_comparator/json_comparator.py +0 -0
  162. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/file_comparator/result.py +0 -0
  163. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/file_comparator/script_comparator.py +0 -0
  164. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/file_comparator/xml_comparator.py +0 -0
  165. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/logging_config.py +0 -0
  166. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/runners/__init__.py +0 -0
  167. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/runners/config_runner.py +0 -0
  168. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/runners/json_runner.py +0 -0
  169. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/runners/parallel_json_runner.py +0 -0
  170. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/runners/parallel_yaml_runner.py +0 -0
  171. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/runners/yaml_runner.py +0 -0
  172. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/tui/__init__.py +0 -0
  173. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/tui/controllers/__init__.py +0 -0
  174. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/tui/controllers/case_controller.py +0 -0
  175. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/tui/screens/__init__.py +0 -0
  176. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/tui/screens/case_list.py +0 -0
  177. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/tui/widgets/__init__.py +0 -0
  178. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/tui/widgets/case_table.py +0 -0
  179. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/tui/widgets/expected_editor.py +0 -0
  180. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/tui/widgets/search_bar.py +0 -0
  181. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/tui/widgets/steps_editor.py +0 -0
  182. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/utils/__init__.py +0 -0
  183. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/utils/junit_xml_writer.py +0 -0
  184. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/utils/path_resolver.py +0 -0
  185. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest/utils/report_generator.py +0 -0
  186. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest_cli.egg-info/dependency_links.txt +0 -0
  187. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest_cli.egg-info/entry_points.txt +0 -0
  188. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest_cli.egg-info/requires.txt +0 -0
  189. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/src/symtest_cli.egg-info/top_level.txt +0 -0
  190. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/README.md +0 -0
  191. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/__init__.py +0 -0
  192. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/__pycache__/__init__.cpython-312.pyc +0 -0
  193. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/__pycache__/__init__.cpython-313.pyc +0 -0
  194. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/__pycache__/__init__.cpython-39.pyc +0 -0
  195. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc +0 -0
  196. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/__pycache__/conftest.cpython-39-pytest-8.3.4.pyc +0 -0
  197. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/__pycache__/run_all.cpython-312.pyc +0 -0
  198. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/__pycache__/run_all.cpython-313.pyc +0 -0
  199. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/__pycache__/run_all.cpython-39.pyc +0 -0
  200. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/__pycache__/test_setup_module.cpython-312-pytest-7.4.4.pyc +0 -0
  201. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/conftest.py +0 -0
  202. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/demos/h5_filter_demo.py +0 -0
  203. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/demos/manual_report_example.py +0 -0
  204. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/demos/perf_parallel.py +0 -0
  205. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/e2e/__init__.py +0 -0
  206. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/e2e/__pycache__/__init__.cpython-312.pyc +0 -0
  207. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/e2e/__pycache__/__init__.cpython-313.pyc +0 -0
  208. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/e2e/__pycache__/__init__.cpython-39.pyc +0 -0
  209. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/e2e/__pycache__/test_user_flows.cpython-313-pytest-9.0.2.pyc +0 -0
  210. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/e2e/__pycache__/test_user_flows.cpython-39-pytest-8.3.4.pyc +0 -0
  211. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/e2e/test_user_flows.py +0 -0
  212. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/circular_config_a.json +0 -0
  213. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/circular_config_b.json +0 -0
  214. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/hourglass_stdout_mismatch.txt +0 -0
  215. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/hourglass_stdout_sample.txt +0 -0
  216. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/inheritance_base.json +0 -0
  217. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/inheritance_chain.json +0 -0
  218. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/inheritance_circular.json +0 -0
  219. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/main_config.json +0 -0
  220. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/missing_fields.json +0 -0
  221. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/mock_fail_script.py +0 -0
  222. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/mock_pass_script.py +0 -0
  223. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/setup_main.json +0 -0
  224. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/setup_sub.json +0 -0
  225. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/sub_json_tests.yaml +0 -0
  226. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/sub_text_tests.json +0 -0
  227. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/test_cases.json +0 -0
  228. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/test_cases.yaml +0 -0
  229. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/test_cases1.json +0 -0
  230. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/test_with_setup.json +0 -0
  231. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/fixtures/test_with_setup.yaml +0 -0
  232. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/__pycache__/test_history_feature.cpython-313-pytest-9.0.2.pyc +0 -0
  233. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/__pycache__/test_new_cli_features.cpython-313-pytest-9.0.2.pyc +0 -0
  234. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/__pycache__/test_real_command_execution.cpython-313-pytest-9.0.2.pyc +0 -0
  235. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/__pycache__/test_sequence.cpython-313-pytest-9.0.2.pyc +0 -0
  236. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_binary_compare.cpython-313-pytest-9.0.2.pyc +0 -0
  237. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_binary_compare.cpython-39-pytest-8.3.4.pyc +0 -0
  238. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_csv_compare.cpython-313-pytest-9.0.2.pyc +0 -0
  239. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_h5_compare.cpython-313-pytest-9.0.2.pyc +0 -0
  240. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_h5_compare.cpython-39-pytest-8.3.4.pyc +0 -0
  241. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_json_compare.cpython-313-pytest-9.0.2.pyc +0 -0
  242. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_json_compare.cpython-39-pytest-8.3.4.pyc +0 -0
  243. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_text_compare.cpython-313-pytest-9.0.2.pyc +0 -0
  244. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_text_compare.cpython-39-pytest-8.3.4.pyc +0 -0
  245. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/__pycache__/test_xml_compare.cpython-313-pytest-9.0.2.pyc +0 -0
  246. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/test_binary_compare.py +0 -0
  247. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/test_csv_compare.py +0 -0
  248. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/test_h5_compare.py +0 -0
  249. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/test_json_compare.py +0 -0
  250. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/file_compare/test_xml_compare.py +0 -0
  251. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/parallel/__pycache__/test_parallel_runner.cpython-313-pytest-9.0.2.pyc +0 -0
  252. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/parallel/__pycache__/test_parallel_runner.cpython-39-pytest-8.3.4.pyc +0 -0
  253. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/parallel/test_parallel_runner.py +0 -0
  254. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/path_handling/__pycache__/test_spaces_in_paths.cpython-313-pytest-9.0.2.pyc +0 -0
  255. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/path_handling/__pycache__/test_spaces_in_paths.cpython-39-pytest-8.3.4.pyc +0 -0
  256. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/path_handling/test_spaces_in_paths.py +0 -0
  257. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/test_new_cli_features.py +0 -0
  258. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/test_real_command_execution.py +0 -0
  259. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/integration/test_sequence.py +0 -0
  260. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/run_all.py +0 -0
  261. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_binary_comparator.cpython-313-pytest-9.0.2.pyc +0 -0
  262. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_cli.cpython-313-pytest-9.0.2.pyc +0 -0
  263. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_config_io.cpython-313-pytest-9.0.2.pyc +0 -0
  264. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_h5_comparator.cpython-313-pytest-9.0.2.pyc +0 -0
  265. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_import_expander.cpython-313-pytest-9.0.2.pyc +0 -0
  266. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_inheritance_expander.cpython-313-pytest-9.0.2.pyc +0 -0
  267. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_result.cpython-313-pytest-9.0.2.pyc +0 -0
  268. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_run_all.cpython-312-pytest-7.4.4.pyc +0 -0
  269. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_run_all.cpython-312-pytest-9.0.3.pyc +0 -0
  270. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/__pycache__/test_run_all.cpython-313-pytest-9.0.2.pyc +0 -0
  271. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/commands/__pycache__/test_compare_command.cpython-313-pytest-9.0.2.pyc +0 -0
  272. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/commands/test_compare_command.py +0 -0
  273. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_assertions.cpython-313-pytest-9.0.2.pyc +0 -0
  274. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_config_loader.cpython-313-pytest-9.0.2.pyc +0 -0
  275. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_config_loader_new_features.cpython-313-pytest-9.0.2.pyc +0 -0
  276. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_execution.cpython-312.pyc +0 -0
  277. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_execution.cpython-313-pytest-9.0.2.pyc +0 -0
  278. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_execution_new_features.cpython-313-pytest-9.0.2.pyc +0 -0
  279. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_history_store.cpython-313-pytest-9.0.2.pyc +0 -0
  280. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_last_run_store.cpython-313-pytest-9.0.2.pyc +0 -0
  281. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_process_worker.cpython-313-pytest-9.0.2.pyc +0 -0
  282. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_setup.cpython-313-pytest-9.0.2.pyc +0 -0
  283. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_setup.cpython-39-pytest-8.3.4.pyc +0 -0
  284. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_validation_error.cpython-313-pytest-9.0.2.pyc +0 -0
  285. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/__pycache__/test_xfail.cpython-313-pytest-9.0.2.pyc +0 -0
  286. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/test_assertions.py +0 -0
  287. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/test_config_loader.py +0 -0
  288. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/test_config_loader_new_features.py +0 -0
  289. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/test_execution.py +0 -0
  290. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/test_execution_new_features.py +0 -0
  291. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/test_history_store.py +0 -0
  292. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/test_last_run_store.py +0 -0
  293. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/test_process_worker.py +0 -0
  294. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/test_setup.py +0 -0
  295. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/test_validation_error.py +0 -0
  296. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/core/test_xfail.py +0 -0
  297. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/__pycache__/__init__.cpython-312.pyc +0 -0
  298. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/__pycache__/test_error_analysis.cpython-313-pytest-9.0.2.pyc +0 -0
  299. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/__pycache__/test_hourglass_tangent_comparator.cpython-312-pytest-9.0.3.pyc +0 -0
  300. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/__pycache__/test_hourglass_tangent_comparator.cpython-313-pytest-9.0.2.pyc +0 -0
  301. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/__pycache__/test_script_comparator.cpython-313-pytest-9.0.2.pyc +0 -0
  302. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/__pycache__/test_workspace_plugins.cpython-313-pytest-9.0.2.pyc +0 -0
  303. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/test_error_analysis.py +0 -0
  304. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/test_hourglass_tangent_comparator.py +0 -0
  305. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/test_script_comparator.py +0 -0
  306. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/file_comparator/test_workspace_plugins.py +0 -0
  307. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-312.pyc +0 -0
  308. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-313-pytest-9.0.2.pyc +0 -0
  309. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/runners/__pycache__/test_json_yaml_runner.cpython-39-pytest-8.3.4.pyc +0 -0
  310. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/runners/__pycache__/test_test_case_filter.cpython-313-pytest-9.0.2.pyc +0 -0
  311. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/runners/__pycache__/test_test_case_tag_filter.cpython-313-pytest-9.0.2.pyc +0 -0
  312. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/runners/test_json_yaml_runner.py +0 -0
  313. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/runners/test_test_case_filter.py +0 -0
  314. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/runners/test_test_case_tag_filter.py +0 -0
  315. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/test_binary_comparator.py +0 -0
  316. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/test_cli.py +0 -0
  317. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/test_config_io.py +0 -0
  318. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/test_h5_comparator.py +0 -0
  319. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/test_import_expander.py +0 -0
  320. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/test_inheritance_expander.py +0 -0
  321. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/test_result.py +0 -0
  322. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/test_run_all.py +0 -0
  323. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__init__.py +0 -0
  324. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/__init__.cpython-312.pyc +0 -0
  325. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/__init__.cpython-313.pyc +0 -0
  326. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc +0 -0
  327. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_app.cpython-313-pytest-9.0.2.pyc +0 -0
  328. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_case_controller.cpython-313-pytest-9.0.2.pyc +0 -0
  329. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_search_functions.cpython-313-pytest-9.0.2.pyc +0 -0
  330. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_tui_run_test.cpython-313-pytest-9.0.2.pyc +0 -0
  331. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/__pycache__/test_widgets_data.cpython-313-pytest-9.0.2.pyc +0 -0
  332. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/conftest.py +0 -0
  333. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/test_app.py +0 -0
  334. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/test_case_controller.py +0 -0
  335. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/test_search_functions.py +0 -0
  336. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/test_tui_run_test.py +0 -0
  337. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/tui/test_widgets_data.py +0 -0
  338. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/utils/__pycache__/test_junit_xml_writer.cpython-313-pytest-9.0.2.pyc +0 -0
  339. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/utils/__pycache__/test_report_generator.cpython-313-pytest-9.0.2.pyc +0 -0
  340. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/utils/test_junit_xml_writer.py +0 -0
  341. {symtest_cli-1.3.0 → symtest_cli-1.3.2}/tests/unit/utils/test_report_generator.py +0 -0
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: symtest-cli
3
- Version: 1.3.0
3
+ Version: 1.3.2
4
4
  Summary: Regression testing for CLI applications, with multi-step workflows and numerical file comparison.
5
- Home-page: https://github.com/ozil111/symtest
5
+ Home-page: https://github.com/ozil111/symtest-cli
6
6
  Author: Xiaotong Wang
7
7
  Author-email: xiaotongwang98@gmail.com
8
- Project-URL: Documentation, https://github.com/ozil111/symtest/blob/main/docs/user_manual.md
9
- Project-URL: Source, https://github.com/ozil111/symtest
10
- Project-URL: Tracker, https://github.com/ozil111/symtest/issues
8
+ Project-URL: Documentation, https://github.com/ozil111/symtest-cli/blob/main/docs/user_manual.md
9
+ Project-URL: Source, https://github.com/ozil111/symtest-cli
10
+ Project-URL: Tracker, https://github.com/ozil111/symtest-cli/issues
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: License :: OSI Approved :: MIT License
13
13
  Classifier: Operating System :: OS Independent
@@ -53,11 +53,11 @@ Dynamic: summary
53
53
 
54
54
  > **Note:** This project was formerly known as `cli-test-framework`.
55
55
  > Since version 1.3.0 it is released as
56
- > [`symtest`](https://pypi.org/project/symtest/); the old package name is no
57
- > longer updated. Install with:
56
+ > [`symtest-cli`](https://pypi.org/project/symtest-cli/); the old package name
57
+ > is no longer updated. Install with:
58
58
  >
59
59
  > ```bash
60
- > pip install symtest
60
+ > pip install symtest-cli
61
61
  > ```
62
62
 
63
63
  A feature-focused automated testing framework for command-line applications.
@@ -92,15 +92,15 @@ occur in real CLI and scientific-computing projects.
92
92
  Python 3.9 or newer is required.
93
93
 
94
94
  ```bash
95
- pip install symtest
95
+ pip install symtest-cli
96
96
  ```
97
97
 
98
98
  YAML and the TUI are optional:
99
99
 
100
100
  ```bash
101
- pip install "symtest[yaml]"
102
- pip install "symtest[tui]"
103
- pip install "symtest[all]"
101
+ pip install "symtest-cli[yaml]"
102
+ pip install "symtest-cli[tui]"
103
+ pip install "symtest-cli[all]"
104
104
  ```
105
105
 
106
106
  The default installation includes HDF5 and numerical comparison support.
@@ -298,6 +298,9 @@ requirement for using the framework.
298
298
  - [User manual](docs/user_manual_en.md)
299
299
  - [Design document](docs/design_en.md)
300
300
  - [Plugin examples](examples/plugins/README.md)
301
+ - [AI Skill template](examples/skill/) — import framework knowledge into AI coding
302
+ assistants so they can author test cases, acceptance criteria,
303
+ and TDD workflows directly
301
304
 
302
305
  ## Development
303
306
 
@@ -4,11 +4,11 @@
4
4
 
5
5
  > **Note:** This project was formerly known as `cli-test-framework`.
6
6
  > Since version 1.3.0 it is released as
7
- > [`symtest`](https://pypi.org/project/symtest/); the old package name is no
8
- > longer updated. Install with:
7
+ > [`symtest-cli`](https://pypi.org/project/symtest-cli/); the old package name
8
+ > is no longer updated. Install with:
9
9
  >
10
10
  > ```bash
11
- > pip install symtest
11
+ > pip install symtest-cli
12
12
  > ```
13
13
 
14
14
  A feature-focused automated testing framework for command-line applications.
@@ -43,15 +43,15 @@ occur in real CLI and scientific-computing projects.
43
43
  Python 3.9 or newer is required.
44
44
 
45
45
  ```bash
46
- pip install symtest
46
+ pip install symtest-cli
47
47
  ```
48
48
 
49
49
  YAML and the TUI are optional:
50
50
 
51
51
  ```bash
52
- pip install "symtest[yaml]"
53
- pip install "symtest[tui]"
54
- pip install "symtest[all]"
52
+ pip install "symtest-cli[yaml]"
53
+ pip install "symtest-cli[tui]"
54
+ pip install "symtest-cli[all]"
55
55
  ```
56
56
 
57
57
  The default installation includes HDF5 and numerical comparison support.
@@ -249,6 +249,9 @@ requirement for using the framework.
249
249
  - [User manual](docs/user_manual_en.md)
250
250
  - [Design document](docs/design_en.md)
251
251
  - [Plugin examples](examples/plugins/README.md)
252
+ - [AI Skill template](examples/skill/) — import framework knowledge into AI coding
253
+ assistants so they can author test cases, acceptance criteria,
254
+ and TDD workflows directly
252
255
 
253
256
  ## Development
254
257
 
@@ -259,7 +259,7 @@ load_test_cases() → _apply_test_case_filter() → setup_manager.setup_all()
259
259
  支持三种过滤方式(可组合):
260
260
  - `test_case_filter`:按名称精确匹配
261
261
  - `test_case_tag_filter`:按 tags 匹配(交集逻辑)
262
- - `last_failed`:从 `.cli-test/last_run.json` 读取上次失败的用例名
262
+ - `last_failed`:从 `.symtest/last_run.json` 读取上次失败的用例名
263
263
 
264
264
  **xfail 机制 `_apply_xfail_status()`**:
265
265
 
@@ -318,6 +318,8 @@ class TestCase:
318
318
  expected_failure: bool = False
319
319
  xfail_reason: str = ""
320
320
  xfail_quiet: bool = False
321
+ depends_on: List[str] = field(default_factory=list)
322
+ env: Dict[str, str] = field(default_factory=dict)
321
323
  ```
322
324
 
323
325
  两种模式:
@@ -328,6 +330,8 @@ class TestCase:
328
330
  - `tags`:标签过滤
329
331
  - `retry_count`:失败重试次数
330
332
  - `expected_failure` / `xfail_reason` / `xfail_quiet`:预期失败标记
333
+ - `depends_on`:用例级依赖声明,支持 DAG 拓扑调度
334
+ - `env`:case 级环境变量,注入该 case(序列模式为所有 step)的子进程,优先级高于 `setup` 与调度器注入
331
335
 
332
336
  ### 4.3 Assertions
333
337
 
@@ -426,7 +430,7 @@ class PathResolver:
426
430
  `--last-failed` 状态存储模块(`core/last_run_store.py`):
427
431
 
428
432
  ```python
429
- # 存储位置: <workspace>/.cli-test/last_run.json
433
+ # 存储位置: <workspace>/.symtest/last_run.json
430
434
  # {
431
435
  # "case_name": {"status": "passed"},
432
436
  # ...
@@ -448,8 +452,8 @@ class PathResolver:
448
452
  `--resume` 断点续跑模块(`core/sequence_state.py`):
449
453
 
450
454
  ```python
451
- # 状态文件: <workspace>/.cli-test/sequence_state/<case_name>.json
452
- # 输出缓存: <workspace>/.cli-test/sequence_state/cache/<case_name>.step<N>.log
455
+ # 状态文件: <workspace>/.symtest/sequence_state/<case_name>.json
456
+ # 输出缓存: <workspace>/.symtest/sequence_state/cache/<case_name>.step<N>.log
453
457
  ```
454
458
 
455
459
  核心接口:
@@ -684,7 +688,7 @@ CaseManagerApp (Textual App)
684
688
  _update_history() # 回归检测 + 更新 .symtest
685
689
  │
686
690
  ▼
687
- _save_last_run() # 写入 .cli-test/last_run.json
691
+ _save_last_run() # 写入 .symtest/last_run.json
688
692
  │
689
693
  ▼
690
694
  setup_manager.teardown_all() # 逆序清理
@@ -699,14 +703,14 @@ CaseManagerApp (Textual App)
699
703
  ParallelConfigRunner.run_tests()
700
704
  │
701
705
  ▼
702
- LPT 排序 (历史 avg_duration 优先,fallback 到 estimated_time 降序)
706
+ 拓扑 LPT 排序 (depends_on 约束 + 历史 avg_duration 降序)
703
707
  │
704
708
  ▼
705
709
  _assign_relative_cpu_cores() # 按权重比例分配 CPU 核心
706
710
  │
707
711
  ▼
708
712
  ┌──────────────────────────────────────┐
709
- │ ThreadPoolExecutor.map(): │
713
+ │ DAG 调度 / 或直接并行 (无依赖时) │
710
714
  │ AtomicSemaphore.acquire(cores) │
711
715
  │ 注入 OMP/MKL/NPROC 环境变量 │
712
716
  │ execute_single_test_case() │
@@ -715,7 +719,45 @@ ParallelConfigRunner.run_tests()
715
719
  └──────────────────────────────────────┘
716
720
  ```
717
721
 
718
- ### 7.3 文件比较流
722
+ ### 7.3 DAG 依赖调度流
723
+
724
+ 当 `TestCase.depends_on` 非空时,并行 runner 自动切换为 DAG 拓扑调度:
725
+
726
+ ```
727
+ ParallelRunner.run_tests()
728
+ │
729
+ ▼
730
+ has_deps? ──No──► _run_tests_flat() (fast path)
731
+ │
732
+ Yes
733
+ ▼
734
+ _run_dag()
735
+ │
736
+ ├── 构建 dependents 邻接表 + in_degree 入度表
737
+ ├── 入度=0 的用例 → 就绪队列 → executor.submit()
738
+ │
739
+ ▼
740
+ ┌────────────────────────────────────────┐
741
+ │ as_completed() 循环: │
742
+ │ 完成一个 future │
743
+ │ │ │
744
+ │ ├── passed/xfailed → 后继入度-1 │
745
+ │ │ └── 入度=0 → submit(后继) │
746
+ │ │ │
747
+ │ └── failed/xpassed → cascade_skip │
748
+ │ └── BFS 标记下游全部 skipped │
749
+ └────────────────────────────────────────┘
750
+ ```
751
+
752
+ **调度语义**:
753
+ - 依赖"满足" = 状态为 `passed` 或 `xfailed`
754
+ - 依赖"不满足" = 状态为 `failed` 或 `xpassed` → 下游全部 skip
755
+ - `skipped` 不计入 `failed` 计数,报告中单独列出
756
+ - 级联 skip:若 B 被 skip,则依赖 B 的 C 也自动 skip
757
+
758
+ **顺序 runner**(`BaseRunner.run_tests()`)同样支持拓扑排序:`_topological_order()` 使用 Kahn 算法生成拓扑序列,按序执行,依赖失败时自动跳过下游。
759
+
760
+ ### 7.4 文件比较流
719
761
 
720
762
  ```
721
763
  symtest compare file1 file2 [options]
@@ -737,7 +779,7 @@ symtest compare file1 file2 [options]
737
779
  format_result(result, --output-format) # text / json / html
738
780
  ```
739
781
 
740
- ### 7.4 --resume 断点续跑流
782
+ ### 7.5 --resume 断点续跑流
741
783
 
742
784
  ```
743
785
  序列测试用例执行
@@ -781,14 +823,16 @@ symtest compare file1 file2 [options]
781
823
  | LPT 调度策略 | 长任务先启动,减少尾延迟;优先使用 `.symtest` 历史数据 |
782
824
  | 累计平均更新历史 | 直觉简单,随运行次数增多单次异常自然稀释 |
783
825
  | 回归检测在更新前执行 | 先与旧均值比较再更新,确保对比的是"历史基线" |
784
- | `.symtest` 隐藏文件 + `.cli-test/` 目录 | 不干扰用户目录视图,JSON 格式便于调试;状态文件统一管理 |
826
+ | `.symtest/` 目录 | 不干扰用户目录视图,JSON 格式便于调试;状态文件统一管理 |
785
827
  | 环境变量注入 | 科学计算求解器常忽略 Python 级线程控制 |
828
+ | case 级 env 通过 subprocess 注入 | 不改进程全局 `os.environ`,进程隔离、并行线程安全;优先级 `os.environ` < 调度器 < case env |
786
829
  | Comparator 工厂 + 插件发现 | 按文件类型创建比较器,workspace `comparators/` 目录自动发现插件 |
787
830
  | subprocess 隔离执行 | 每个 test case 独立子进程,保证测试间互不影响 |
788
831
  | xfail 机制 | 支持预期失败的测试(CI 中不阻塞流水线),意外通过时告警 |
789
832
  | --last-failed 覆写策略 | 只覆写本次执行的用例状态,避免子集运行时丢失未执行用例的状态 |
790
833
  | --resume 纯信任模型 | 不验证 artifact,由用户保证 workspace 未被修改,简化实现 |
791
834
  | retry_count 重试机制 | 应对偶发性网络抖动或竞态条件,首次失败后自动重试 |
835
+ | DAG 依赖调度 | 基于 Kahn 拓扑 + 就绪队列,依赖满足后立即提交;依赖失败级联 skip 下游;无依赖时走 fast path 零开销 |
792
836
  | --update-baseline | 比较失败时自动将实际输出覆盖 baseline,适合批量更新基准 |
793
837
  | next_action_hint 结构化建议 | 失败结果附带下一步操作建议(update_baseline / update_expected / increase_timeout / investigate),便于 AI 消费 |
794
838
  | TUI 基于 Textual | 利用成熟的终端 UI 框架,提供交互式用例管理 |
@@ -259,7 +259,7 @@ load_test_cases() → _apply_test_case_filter() → setup_manager.setup_all()
259
259
  Supports three filter modes (combinable):
260
260
  - `test_case_filter`: exact name match
261
261
  - `test_case_tag_filter`: tag-based match (intersection logic)
262
- - `last_failed`: reads previously failed case names from `.cli-test/last_run.json`
262
+ - `last_failed`: reads previously failed case names from `.symtest/last_run.json`
263
263
 
264
264
  **xfail mechanism `_apply_xfail_status()`**:
265
265
 
@@ -318,6 +318,7 @@ class TestCase:
318
318
  expected_failure: bool = False
319
319
  xfail_reason: str = ""
320
320
  xfail_quiet: bool = False
321
+ depends_on: List[str] = field(default_factory=list)
321
322
  ```
322
323
 
323
324
  Two modes:
@@ -426,7 +427,7 @@ Core interfaces:
426
427
  `--last-failed` state storage module (`core/last_run_store.py`):
427
428
 
428
429
  ```python
429
- # Storage location: <workspace>/.cli-test/last_run.json
430
+ # Storage location: <workspace>/.symtest/last_run.json
430
431
  # {
431
432
  # "case_name": {"status": "passed"},
432
433
  # ...
@@ -448,8 +449,8 @@ Each run **overwrites** the status of executed cases; unexecuted cases retain th
448
449
  `--resume` step-level resume module (`core/sequence_state.py`):
449
450
 
450
451
  ```python
451
- # State file: <workspace>/.cli-test/sequence_state/<case_name>.json
452
- # Output cache: <workspace>/.cli-test/sequence_state/cache/<case_name>.step<N>.log
452
+ # State file: <workspace>/.symtest/sequence_state/<case_name>.json
453
+ # Output cache: <workspace>/.symtest/sequence_state/cache/<case_name>.step<N>.log
453
454
  ```
454
455
 
455
456
  Core interfaces:
@@ -684,7 +685,7 @@ Config file (JSON/YAML)
684
685
  _update_history() # Regression detection + update .symtest
685
686
  │
686
687
  ▼
687
- _save_last_run() # Write .cli-test/last_run.json
688
+ _save_last_run() # Write .symtest/last_run.json
688
689
  │
689
690
  ▼
690
691
  setup_manager.teardown_all() # Reverse cleanup
@@ -699,14 +700,14 @@ Config file (JSON/YAML)
699
700
  ParallelConfigRunner.run_tests()
700
701
  │
701
702
  ▼
702
- LPT sort (historical avg_duration preferred, fallback to estimated_time desc)
703
+ Topology-constrained LPT sort (depends_on + historical avg_duration desc)
703
704
  │
704
705
  ▼
705
706
  _assign_relative_cpu_cores() # Proportional CPU core assignment by weight
706
707
  │
707
708
  ▼
708
709
  ┌──────────────────────────────────────┐
709
- │ ThreadPoolExecutor.map(): │
710
+ │ DAG scheduling / flat (no deps) │
710
711
  │ AtomicSemaphore.acquire(cores) │
711
712
  │ Inject OMP/MKL/NPROC env vars │
712
713
  │ execute_single_test_case() │
@@ -715,7 +716,47 @@ ParallelConfigRunner.run_tests()
715
716
  └──────────────────────────────────────┘
716
717
  ```
717
718
 
718
- ### 7.3 File Comparison Flow
719
+ ### 7.3 DAG Dependency Scheduling Flow
720
+
721
+ When `TestCase.depends_on` is non-empty, the parallel runner switches to DAG topology scheduling:
722
+
723
+ ```
724
+ ParallelRunner.run_tests()
725
+ │
726
+ ▼
727
+ has_deps? ──No──► _run_tests_flat() (fast path)
728
+ │
729
+ Yes
730
+ ▼
731
+ _run_dag()
732
+ │
733
+ ├── Build dependents adjacency + in_degree table
734
+ ├── in_degree=0 cases → ready queue → executor.submit()
735
+ │
736
+ ▼
737
+ ┌────────────────────────────────────────┐
738
+ │ as_completed() loop: │
739
+ │ Complete one future │
740
+ │ │ │
741
+ │ ├── passed/xfailed → decrement │
742
+ │ │ successor in-degree │
743
+ │ │ └── in_degree=0 → submit() │
744
+ │ │ │
745
+ │ └── failed/xpassed → cascade_skip │
746
+ │ └── BFS mark all downstream │
747
+ │ as skipped │
748
+ └────────────────────────────────────────┘
749
+ ```
750
+
751
+ **Scheduling semantics**:
752
+ - Dependency "satisfied" = status is `passed` or `xfailed`
753
+ - Dependency "unsatisfied" = status is `failed` or `xpassed` → all downstream skipped
754
+ - `skipped` is NOT counted as `failed`; listed separately in reports
755
+ - Cascade skip: if B is skipped, C (which depends on B) is also skipped
756
+
757
+ **Sequential runner** (`BaseRunner.run_tests()`) also supports topological ordering: `_topological_order()` uses Kahn's algorithm to generate a topological sequence, runs in order, and auto-skips downstream on dependency failure.
758
+
759
+ ### 7.4 File Comparison Flow
719
760
 
720
761
  ```
721
762
  symtest compare file1 file2 [options]
@@ -737,7 +778,7 @@ symtest compare file1 file2 [options]
737
778
  format_result(result, --output-format) # text / json / html
738
779
  ```
739
780
 
740
- ### 7.4 --resume Checkpoint Flow
781
+ ### 7.5 --resume Checkpoint Flow
741
782
 
742
783
  ```
743
784
  Sequence test case execution
@@ -781,7 +822,7 @@ Sequence test case execution
781
822
  | LPT scheduling strategy | Long tasks start first, reducing tail latency; prioritizes `.symtest` historical data |
782
823
  | Cumulative average history update | Simple and intuitive; single anomalies are naturally diluted over many runs |
783
824
  | Regression check before update | Compare against old average first, then update; ensures comparison is against the "historical baseline" |
784
- | `.symtest` hidden file + `.cli-test/` directory | Non-intrusive to the user's directory view; JSON format for easy debugging; state files centrally managed |
825
+ | `.symtest/` directory | Non-intrusive to the user's directory view; JSON format for easy debugging; state files centrally managed |
785
826
  | Environment variable injection | Scientific computing solvers often ignore Python-level thread control |
786
827
  | Comparator factory + plugin discovery | Creates comparators by file type; workspace `comparators/` directory for auto-discovered plugins |
787
828
  | subprocess isolated execution | Each test case runs in an independent subprocess, ensuring tests don't affect each other |
@@ -789,6 +830,7 @@ Sequence test case execution
789
830
  | --last-failed overwrite strategy | Only overwrites status of executed cases; avoids losing state of unexecuted cases during subset runs |
790
831
  | --resume pure trust model | No artifact validation; user guarantees workspace is unchanged, simplifying implementation |
791
832
  | retry_count retry mechanism | Handles transient network glitches or race conditions; auto-retries on first failure |
833
+ | DAG dependency scheduling | Kahn topology + ready queue; submits dependents immediately once deps are satisfied; cascade-skips downstream on dep failure; zero-overhead fast path when no deps declared |
792
834
  | --update-baseline | Automatically overwrites baseline files with actual output on comparison failure; ideal for batch baseline updates |
793
835
  | next_action_hint structured suggestions | Failed results include actionable suggestions (update_baseline / update_expected / increase_timeout / investigate), convenient for AI consumption |
794
836
  | TUI based on Textual | Leverages a mature terminal UI framework for interactive case management |
@@ -683,8 +683,8 @@ tui = ["textual>=0.40.0"]
683
683
  ```
684
684
 
685
685
  ```bash
686
- pip install symtest[tui] # 安装 TUI 依赖
687
- pip install symtest # 核心包,不含 TUI
686
+ pip install symtest-cli[tui] # 安装 TUI 依赖
687
+ pip install symtest-cli # 核心包,不含 TUI
688
688
  ```
689
689
 
690
690
  ### 9.2 优雅降级
@@ -698,7 +698,7 @@ def run_tui(config_file, workspace):
698
698
  except ImportError:
699
699
  print(
700
700
  "TUI 功能需要安装 textual。请运行:\n"
701
- " pip install symtest[tui]\n"
701
+ " pip install symtest-cli[tui]\n"
702
702
  "或:\n"
703
703
  " pip install textual"
704
704
  )
@@ -4,6 +4,7 @@
4
4
 
5
5
  - [安装](#安装)
6
6
  - [测试用例定义](#测试用例定义)
7
+ - [Case 级环境变量](#case-级环境变量env)
7
8
  - [配置拆分机制](#配置拆分机制)
8
9
  - [配置继承](#配置继承)
9
10
  - [配置校验](#配置校验)
@@ -26,7 +27,7 @@
26
27
  ## 安装
27
28
 
28
29
  ```bash
29
- pip install symtest
30
+ pip install symtest-cli
30
31
  ```
31
32
 
32
33
  要求:Python >= 3.9
@@ -34,13 +35,13 @@ pip install symtest
34
35
  YAML 支持需安装可选依赖:
35
36
 
36
37
  ```bash
37
- pip install "symtest[yaml]"
38
+ pip install "symtest-cli[yaml]"
38
39
  ```
39
40
 
40
41
  一次安装 YAML 和 TUI 等全部可选功能:
41
42
 
42
43
  ```bash
43
- pip install "symtest[all]"
44
+ pip install "symtest-cli[all]"
44
45
  ```
45
46
 
46
47
  HDF5 文件比较依赖 `h5py`(已随框架安装)。如需在无 HDF5 环境下使用其他比较功能,可单独卸载,但 HDF5 比较将不可用。
@@ -159,6 +160,78 @@ test_cases:
159
160
  }
160
161
  ```
161
162
 
163
+ ### 测试依赖(depends_on)
164
+
165
+ 当测试用例之间存在先后依赖时(例如 D 需要 A、B、C 先生成数据),通过 `depends_on` 声明依赖关系,框架会自动按 DAG 拓扑顺序调度:
166
+
167
+ **并行模式**:A、B、C 并行执行,全部通过后 D 才被提交。依赖失败的用例会自动 skip 其下游(级联 skip)。
168
+
169
+ **顺序模式**:框架按拓扑序重排用例,保证依赖在前的先执行,依赖失败时同样跳过下游。
170
+
171
+ **JSON 示例**:
172
+
173
+ ```json
174
+ {
175
+ "test_cases": [
176
+ { "name": "A", "command": "python", "args": ["gen_a.py"], "expected": {"return_code": 0} },
177
+ { "name": "B", "command": "python", "args": ["gen_b.py"], "expected": {"return_code": 0} },
178
+ { "name": "C", "command": "python", "args": ["gen_c.py"], "expected": {"return_code": 0} },
179
+ {
180
+ "name": "D", "command": "python", "args": ["merge.py"],
181
+ "depends_on": ["A", "B", "C"],
182
+ "expected": {"return_code": 0, "compare_files": [{"file": "output.h5", "type": "hdf5"}]}
183
+ }
184
+ ]
185
+ }
186
+ ```
187
+
188
+ **YAML 示例**:
189
+
190
+ ```yaml
191
+ test_cases:
192
+ - name: A
193
+ command: python
194
+ args: ["gen_a.py"]
195
+ expected: { return_code: 0 }
196
+
197
+ - name: B
198
+ command: python
199
+ args: ["gen_b.py"]
200
+ expected: { return_code: 0 }
201
+
202
+ - name: C
203
+ command: python
204
+ args: ["gen_c.py"]
205
+ expected: { return_code: 0 }
206
+
207
+ - name: D
208
+ command: python
209
+ args: ["merge.py"]
210
+ depends_on: [A, B, C]
211
+ expected:
212
+ return_code: 0
213
+ compare_files:
214
+ - file: output.h5
215
+ type: hdf5
216
+ ```
217
+
218
+ **调度语义**:
219
+
220
+ | 依赖状态 | 下游行为 |
221
+ |---|---|
222
+ | `passed` 或 `xfailed` | 依赖"满足",下游正常执行 |
223
+ | `failed` 或 `xpassed` | 依赖"不满足",下游标记为 `skipped`,并级联 skip |
224
+ | 存在循环依赖 | 配置校验阶段报错,禁止运行 |
225
+
226
+ `skipped` 不计入 `failed` 计数,在报告摘要中单独显示 `Skipped: N`。
227
+
228
+ **约束**:
229
+ - 依赖名称必须在同配置文件的 `test_cases` 中存在
230
+ - 不允许自依赖(`depends_on: ["self"]`)
231
+ - 不允许循环依赖(A → B → A)
232
+ - 与 `steps` 模式互不影响——`depends_on` 是用例级概念,`steps` 是用例内步骤级概念
233
+ - 无依赖时走 fast path,调度开销为零
234
+
162
235
  ### 字段说明
163
236
 
164
237
  | 字段 | 必填 | 说明 |
@@ -174,11 +247,69 @@ test_cases:
174
247
  | `expected_failure` | 否 | 标记为预期失败(xfail)。设为 `true` 时,失败计为 XFailed(不影响退出码),意外通过计为 XPassed(视作失败) |
175
248
  | `xfail_reason` | 否 | xfail 的原因说明,报告中将展示此文本(如 "Bug #42 尚未修复") |
176
249
  | `xfail_quiet` | 否 | 设为 `true` 时,xfailed 状态下报告中不输出 Command Output(stdout/stderr 大段输出),仅保留命令、返回码、失败原因等元信息 |
250
+ | `depends_on` | 否 | 依赖的测试用例名称列表(如 `["A", "B"]`)。当前用例必须等待所有依赖用例通过后才执行。依赖失败时自动 skip 当前用例及下游。支持并行和顺序两种 runner |
251
+ | `env` | 否 | case 级环境变量字典(如 `{"UEL_SYSID_SCALE": "1.0"}`),仅在执行该 case(序列模式为所有 step)时注入子进程,见 [Case 级环境变量](#case-级环境变量env) |
177
252
  | `expected.return_code` | 否 | 期望返回码 |
178
253
  | `expected.output_contains` | 否 | 输出需包含的字符串列表 |
179
254
  | `expected.output_matches` | 否 | 输出需匹配的正则表达式(单个字符串) |
180
255
  | `expected.compare_files` | 否 | 文件比较断言列表,见下文 |
181
256
 
257
+ ## Case 级环境变量(env)
258
+
259
+ 通过 case 下与 `name` 同级的 `env` 字段,可为单个用例注入环境变量,仅在该用例(序列模式为所有 step)的子进程内生效,不影响其他用例。
260
+
261
+ ### JSON
262
+
263
+ ```json
264
+ {
265
+ "name": "UEL 缩放测试",
266
+ "command": "solver",
267
+ "args": ["-i", "input.dat"],
268
+ "env": {
269
+ "UEL_SYSID_SCALE": "1.0",
270
+ "OMP_NUM_THREADS": "8"
271
+ },
272
+ "expected": { "return_code": 0 }
273
+ }
274
+ ```
275
+
276
+ ### YAML
277
+
278
+ ```yaml
279
+ - name: UEL 缩放测试
280
+ command: solver
281
+ args: ["-i", "input.dat"]
282
+ env:
283
+ UEL_SYSID_SCALE: "1.0"
284
+ expected: { return_code: 0 }
285
+ ```
286
+
287
+ ### 序列模式
288
+
289
+ `env` 定义在 case 级(与 `steps` 同级),对该 case 的**所有 step** 生效:
290
+
291
+ ```json
292
+ {
293
+ "name": "多步骤+环境变量",
294
+ "env": { "UEL_SYSID_SCALE": "1.0" },
295
+ "steps": [
296
+ { "command": "python", "args": ["./step1.py"], "expected": { "return_code": 0 } },
297
+ { "command": "python", "args": ["./step2.py"], "expected": { "return_code": 0 } }
298
+ ]
299
+ }
300
+ ```
301
+
302
+ ### 语义
303
+
304
+ | 决策点 | 行为 |
305
+ |---|---|
306
+ | 生效方式 | 通过子进程 `env` 注入,不修改进程全局 `os.environ`,天然进程隔离、线程安全 |
307
+ | 优先级 | `os.environ`(含 `setup.environment_variables`)< 调度器注入(`OMP/MKL/NPROC`)< **case `env`(最高)**,即 case env 可覆盖调度器的 `OMP_NUM_THREADS` |
308
+ | 作用范围 | 仅当前 case,不污染其他 case(区别于全局 `setup.environment_variables`) |
309
+ | 占位符 | 自动支持,`"env": {"SCALE": "{scale}"}` 会被 `variables`/`--var` 替换 |
310
+ | 继承(extends) | 自动支持,`env` 为 dict,深合并、子类覆盖父类同名 key |
311
+ | 值类型 | 字符串;数字/布尔在解析时自动 `str()` 化 |
312
+
182
313
  ### 文件比较断言(compare_files)
183
314
 
184
315
  在 `expected` 中通过 `compare_files` 可声明一条或多条文件比较规则,框架会在命令执行后自动用对应的比较器对比实际产出文件与基线文件。所有比较通过才算用例通过,可与 `return_code`、`output_contains` 等断言共存。
@@ -515,7 +646,7 @@ TUI 依赖 `textual` 库,并作为按需安装的可选依赖提供:
515
646
 
516
647
  ```bash
517
648
  # 安装时附带 TUI 支持
518
- pip install "symtest[tui]"
649
+ pip install "symtest-cli[tui]"
519
650
 
520
651
  # 或者在已有框架上单独安装 textual
521
652
  pip install textual
@@ -702,7 +833,7 @@ symtest run test_cases.json --error-analysis
702
833
  **xfail 语义**:标记为 `expected_failure` 的用例如果失败(`xfailed`),是预期行为,**不会**被 `--last-failed` 选中重跑。但如果 xfail 标记的用例意外通过(`xpassed`),则被视为真正失败,**会**被选中。
703
834
 
704
835
  **工作原理**:
705
- - 每次运行结束后,框架在 `<workspace>/.cli-test/last_run.json` 中记录每个用例的状态
836
+ - 每次运行结束后,框架在 `<workspace>/.symtest/last_run.json` 中记录每个用例的状态
706
837
  - 记录采用**覆盖式更新**:本次跑到的用例用新结果覆盖旧结果,没跑到的保留原状态
707
838
  - 这意味着修好的 case 在下一次显示中不再是"failed"
708
839
  - 如果文件不存在(首次运行),`--last-failed` 会提示并正常运行全部用例
@@ -725,7 +856,7 @@ symtest run config.json
725
856
  `--resume` 针对**顺序步骤测试(sequence)**,跳过上次运行中已通过的步骤,直接从失败步骤继续执行。适合耗时长的多步骤用例——例如有限元分析中 step 1-3 通过了(各耗时几十秒甚至分钟),只有 step 4 的断言失败,`--resume` 可以跳过 1-3、只重跑 step 4。
726
857
 
727
858
  **工作原理**:
728
- - 每个步骤通过后,框架在 `<workspace>/.cli-test/sequence_state/<case_name>.json` 中记录步骤状态,并将输出缓存到 `cache/` 子目录
859
+ - 每个步骤通过后,框架在 `<workspace>/.symtest/sequence_state/<case_name>.json` 中记录步骤状态,并将输出缓存到 `cache/` 子目录
729
860
  - 下次 `--resume` 时,计算配置哈希(所有步骤的 command/args/expected/timeout/retry_count 及 case 级 expected 的 SHA256)与已保存状态比对
730
861
  - 哈希匹配 → 跳过已通过的步骤,从缓存重建 `combined_output`(确保 case 级 `expected` 断言能正常执行)
731
862
  - 用例全部通过 → 自动删除状态文件和缓存,避免残留影响后续运行