testing-conventions 0.0.44__tar.gz → 0.0.45__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.
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/PKG-INFO +1 -1
- testing_conventions-0.0.45/python/testing_conventions/mutation/baseline.py +32 -0
- testing_conventions-0.0.45/python/testing_conventions/mutation/cli.py +35 -0
- testing_conventions-0.0.45/python/testing_conventions/mutation/config.py +39 -0
- testing_conventions-0.0.45/python/testing_conventions/mutation/conftest.py +68 -0
- testing_conventions-0.0.45/python/testing_conventions/mutation/main.py +9 -0
- testing_conventions-0.0.45/python/testing_conventions/mutation/normalize.py +30 -0
- testing_conventions-0.0.45/python/testing_conventions/mutation/parse_args.py +28 -0
- testing_conventions-0.0.45/python/testing_conventions/mutation/session.py +35 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/CHANGELOG.md +15 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/Cargo.lock +1 -1
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/Cargo.toml +1 -1
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/MIGRATIONS.md +23 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/mutation.rs +81 -280
- testing_conventions-0.0.45/rust/tests/fixtures/colocated_test/python_exempt/__init__.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/mutation_base_py.rs +9 -8
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/mutation_python.rs +6 -3
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/mutation_python_e2e.rs +5 -3
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/README.md +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/pyproject.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/python/testing_conventions/__init__.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/python/testing_conventions/config/__init__.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/python/testing_conventions/config/detect.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/python/testing_conventions/config/tomlcompat.py +0 -0
- {testing_conventions-0.0.44/python/testing_conventions/pytest_plugin → testing_conventions-0.0.45/python/testing_conventions/mutation}/__init__.py +0 -0
- {testing_conventions-0.0.44/rust/tests/fixtures/colocated_test/python_exempt → testing_conventions-0.0.45/python/testing_conventions/pytest_plugin}/__init__.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/python/testing_conventions/pytest_plugin/hooks.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/python/testing_conventions/pytest_plugin/plan.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/co_change.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/colocated_test.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/config.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/coverage.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/isolation.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/lib.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/lint.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/main.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/packaging.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/patch_coverage.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/ts.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/violation.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/src/workflow.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/co_change.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/co_change_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/colocated_test.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/colocated_test_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/common/mod.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/config_lines.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/config_loader.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage_base.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage_base_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage_base_rust.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage_base_rust_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage_base_ts.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage_base_ts_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage_line_exempt_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage_rust.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage_rust_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage_ts.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/coverage_ts_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/e2e_attest.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/e2e_attest_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/e2e_verify.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/e2e_verify_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/bad_exempt/cli.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/bad_exempt/testing-conventions.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/clean/pkg/helper.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/clean/widget.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/python_conftest/conftest.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/python_conftest/widget.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/python_exempt/cli.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/python_exempt/core.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/python_exempt/pkg/__init__.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/python_exempt/testing-conventions.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/red/lonely.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/red/pkg/orphan.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/red/pkg/paired.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/red/widget.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/stale_exempt/core.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/stale_exempt/testing-conventions.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/clean/ambient.d.mts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/clean/button.test.tsx +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/clean/button.tsx +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/clean/legacy.cts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/clean/legacy.test.cts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/clean/pkg/helper.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/clean/pkg/helper.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/clean/service.mts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/clean/service.test.mts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/clean/types.d.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/clean/widget.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/clean/widget.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/exempt/index.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/exempt/testing-conventions.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/exempt/widget.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/exempt/widget.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/red/bridge.cts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/red/lonely.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/red/pkg/orphan.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/red/shapes.d.cts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/red/shapes.d.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/red/solo.mts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/red/widget.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/colocated_test/typescript/red/widget.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/exempt.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/exempt_empty_reason.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/exempt_lines.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/exempt_lines_bad_rule.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/exempt_no_reason.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/python/constant_patch/waived/testing-conventions.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/python/environ/waived/testing-conventions.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/python/inline_patch/waived/testing-conventions.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/python/legacy_prefix/test_widget.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/python/monkeypatch/waived/testing-conventions.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/python/no_first_party_patch/clean/pyproject.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/python/no_first_party_patch/red/pyproject.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/python/no_first_party_patch/waived/pyproject.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/python/no_first_party_patch/waived/testing-conventions.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/typescript/no_first_party_mock/clean/charge.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/typescript/no_first_party_mock/clean/views/report.test.tsx +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/typescript/no_first_party_mock/red/charge.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/integration_lint/typescript/no_first_party_mock/red/notify.test.mts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/isolation/unit/stale_exempt.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/malformed.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/python_clean/widget.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/python_red/widget.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/python_sdist/clean-0.1.0.tar.gz +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/python_sdist/make_sdist.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/python_sdist/widget-0.1.0.tar.gz +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/python_wheel/clean.whl +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/python_wheel/make_wheels.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/python_wheel/red.whl +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/rust_crate/clean-0.1.0.crate +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/rust_crate/make_crates.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/rust_crate/widget-0.1.0.crate +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/typescript_clean/button.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/typescript_npm/clean.tgz +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/typescript_npm/make_tarballs.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/typescript_npm/red.tgz +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/typescript_red/button.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/packaging/typescript_red/button.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/partial_coverage.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/floor100.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/floor100_exempt_shim.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/floor85.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/lines_py_shim_ok.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/lines_py_shim_over.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/lines_py_shim_under.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/lines_rust_over.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/lines_rust_shim_ok.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/lines_ts_over.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/lines_ts_shim_ok.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/python/above_85/router.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/python/below_85/grade.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/python/conftest_omit/conftest.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/python/conftest_omit/widget.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/python/exempt_cov/core.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/python/exempt_cov/shim.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/python/full/widget.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/rust_full.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/rust_full_exempt_shim.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/rust_mid.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/above/router.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/above/router.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/below/grade.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/below/grade.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/exempt_cov/core.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/exempt_cov/core.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/exempt_cov/shim.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/exempt_cov/shim.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/full/widget.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/full/widget.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/package-lock.json +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/package.json +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/ts_full.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/ts_full_exempt_shim.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_coverage/typescript/ts_mid.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/python/clean/pyproject.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/python/external/clean/pyproject.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/python/external/red/pyproject.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/python/external/waived/pyproject.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/python/external/waived/testing-conventions.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/python/legacy_prefix/pyproject.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/python/legacy_prefix/test_widget.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/python/red/pyproject.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/python/waived/pyproject.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/python/waived/testing-conventions.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/typescript/clean/widget.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/typescript/red/widget.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/typescript/untyped_mock/clean/widget.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/typescript/untyped_mock/red/widget.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_isolation/typescript/untyped_mock/spy_clean/widget.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/lines_mut_py_ok.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/lines_mut_py_over.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/lines_mut_rust_ok.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/lines_mut_rust_over.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/lines_mut_ts_ok.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/lines_mut_ts_over.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/lines_mut_ts_under.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/mutation_exempt.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/mutation_exempt_py.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/mutation_exempt_ts.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/python/killed/calc.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/python/survivors/calc.py +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/typescript/killed/index.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/typescript/killed/index.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/typescript/killed/stryker.conf.json +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/typescript/package-lock.json +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/typescript/package.json +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/typescript/survivors/index.test.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/typescript/survivors/index.ts +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unit_mutation/typescript/survivors/stryker.conf.json +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unknown_coverage_field.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/unknown_key.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/valid.toml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/workflow/clean/conventions.yml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/fixtures/workflow/red/conventions.yml +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/integration_lint.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/integration_lint_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/isolation.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/isolation_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/mutation_base_rust.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/mutation_base_ts.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/mutation_line_exempt_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/mutation_rust.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/mutation_rust_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/mutation_typescript.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/mutation_typescript_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/packaging.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/packaging_crate.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/packaging_crate_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/packaging_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/packaging_npm.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/packaging_npm_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/packaging_sdist.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/packaging_sdist_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/packaging_wheel.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/packaging_wheel_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/py_unit_isolation.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/py_unit_isolation_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/rust_integration_lint.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/rust_integration_lint_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/ts_integration_lint.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/ts_integration_lint_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/unit_isolation.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/unit_isolation_e2e.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/workflow.rs +0 -0
- {testing_conventions-0.0.44 → testing_conventions-0.0.45}/rust/tests/workflow_e2e.rs +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""The baseline check: the unit suite must pass over unmutated code.
|
|
2
|
+
|
|
3
|
+
``cosmic_ray`` is imported lazily (the module imports without the engine; the check itself
|
|
4
|
+
is unit-tested with a fake ``cosmic_ray`` injected).
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def check_baseline(config):
|
|
10
|
+
"""Run the suite once with no mutation, raising ``RuntimeError`` if it fails. cosmic-ray
|
|
11
|
+
reports the unmutated baseline ``killed`` when the tests fail on their own — without this
|
|
12
|
+
guard every mutant would falsely ``die`` on the already-failing suite and we'd report a
|
|
13
|
+
clean pass."""
|
|
14
|
+
import tempfile
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
from cosmic_ray.commands import execute
|
|
18
|
+
from cosmic_ray.work_db import WorkDB, use_db
|
|
19
|
+
from cosmic_ray.work_item import WorkItem
|
|
20
|
+
|
|
21
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
22
|
+
with use_db(Path(tmp) / "baseline.sqlite", mode=WorkDB.Mode.create) as database:
|
|
23
|
+
database.clear()
|
|
24
|
+
database.add_work_item(WorkItem(mutations=[], job_id="baseline"))
|
|
25
|
+
execute(database, config)
|
|
26
|
+
_, result = next(database.results)
|
|
27
|
+
outcome = getattr(result.test_outcome, "value", result.test_outcome)
|
|
28
|
+
if outcome == "killed":
|
|
29
|
+
raise RuntimeError(
|
|
30
|
+
"the Python unit suite did not pass unmutated (cosmic-ray baseline failed):\n"
|
|
31
|
+
+ (result.output or "")
|
|
32
|
+
)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""The mutation adapter's orchestrator (#248), the Python counterpart of the TypeScript
|
|
2
|
+
``mutationCLI``: parse args, drive cosmic-ray in-process, and emit the normalized-results
|
|
3
|
+
JSON the rust core gates on. A pure, importable function; ``main.py`` is the executable that
|
|
4
|
+
runs it.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
from testing_conventions.mutation.baseline import check_baseline
|
|
12
|
+
from testing_conventions.mutation.config import build_config
|
|
13
|
+
from testing_conventions.mutation.normalize import normalize
|
|
14
|
+
from testing_conventions.mutation.parse_args import parse_args
|
|
15
|
+
from testing_conventions.mutation.session import run_session
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def mutation_cli(argv):
|
|
19
|
+
"""Run the adapter over ``argv``: build the cosmic-ray config, check the baseline, run the
|
|
20
|
+
session, and write the normalized results to ``--out``. Any failure is printed to stderr
|
|
21
|
+
and turned into a non-zero exit code."""
|
|
22
|
+
try:
|
|
23
|
+
args = parse_args(argv)
|
|
24
|
+
config = build_config(args.modules)
|
|
25
|
+
check_baseline(config)
|
|
26
|
+
results = [
|
|
27
|
+
mutant
|
|
28
|
+
for mutation, result in run_session(config)
|
|
29
|
+
if (mutant := normalize(mutation, result)) is not None
|
|
30
|
+
]
|
|
31
|
+
with open(args.out, "w", encoding="utf-8") as handle:
|
|
32
|
+
json.dump(results, handle)
|
|
33
|
+
except Exception as error: # surface any adapter failure as a clean non-zero exit
|
|
34
|
+
sys.stderr.write(f"{error}\n")
|
|
35
|
+
sys.exit(1)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Build the cosmic-ray configuration the adapter drives.
|
|
2
|
+
|
|
3
|
+
[`render_config`] is the pure TOML-rendering half; [`build_config`] parses it into
|
|
4
|
+
cosmic-ray's ``ConfigDict`` (the object ``init`` / ``execute`` consume). ``cosmic_ray`` is
|
|
5
|
+
imported lazily so the module imports without the engine installed — the pure renderer stays
|
|
6
|
+
testable anywhere, and the dogfood coverage job (which installs only coverage + pytest) can
|
|
7
|
+
collect this package.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
# Test files cosmic-ray must never mutate (it would mutate the suite itself). Mirrors the
|
|
12
|
+
# excludes the CLI-driven Rust arm used.
|
|
13
|
+
EXCLUDES = ["*_test.py", "test_*.py", "conftest.py"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def render_config(modules):
|
|
17
|
+
"""Render the ``cosmic-ray`` TOML for a run over ``modules`` (a list of source-file
|
|
18
|
+
paths; empty ⇒ the whole project, ``"."``). ``pytest`` runs the suite; the ``local``
|
|
19
|
+
distributor runs each mutant in this adapter's own process tree."""
|
|
20
|
+
paths = modules or ["."]
|
|
21
|
+
module_path = ", ".join(f'"{p}"' for p in paths)
|
|
22
|
+
excludes = ", ".join(f'"{glob}"' for glob in EXCLUDES)
|
|
23
|
+
return (
|
|
24
|
+
"[cosmic-ray]\n"
|
|
25
|
+
f"module-path = [{module_path}]\n"
|
|
26
|
+
"timeout = 30.0\n"
|
|
27
|
+
f"excluded-modules = [{excludes}]\n"
|
|
28
|
+
'test-command = "python3 -m pytest -q -p no:cacheprovider"\n'
|
|
29
|
+
"\n"
|
|
30
|
+
"[cosmic-ray.distributor]\n"
|
|
31
|
+
'name = "local"\n'
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def build_config(modules):
|
|
36
|
+
"""The parsed cosmic-ray ``ConfigDict`` for a run over ``modules``."""
|
|
37
|
+
from cosmic_ray.config import deserialize_config
|
|
38
|
+
|
|
39
|
+
return deserialize_config(render_config(modules))
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"""Shared fakes for the mutation adapter's unit tests.
|
|
2
|
+
|
|
3
|
+
The adapter imports ``cosmic_ray`` lazily (inside the functions), so the engine need not be
|
|
4
|
+
installed to unit-test it. This fixture installs a fake ``cosmic_ray`` package tree in
|
|
5
|
+
``sys.modules`` for the duration of a test, and the lazy imports resolve to it — injecting the
|
|
6
|
+
dependency via ``sys.modules`` (never ``monkeypatch`` or an inline ``patch``, which the
|
|
7
|
+
isolation lint forbids), the same technique the version-conditional ``tomlcompat`` test uses.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import contextlib
|
|
12
|
+
import sys
|
|
13
|
+
from types import ModuleType, SimpleNamespace
|
|
14
|
+
from unittest.mock import MagicMock
|
|
15
|
+
|
|
16
|
+
import pytest
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@pytest.fixture
|
|
20
|
+
def cosmic_ray():
|
|
21
|
+
"""Yield the adapter's cosmic-ray seams as configurable mocks. ``db`` is the fake
|
|
22
|
+
``WorkDB`` a test configures (``db.results`` for the baseline, ``db.completed_work_items``
|
|
23
|
+
for the session); the rest are the ``find_modules`` / ``init`` / ``execute`` / ... calls."""
|
|
24
|
+
saved = {
|
|
25
|
+
name: mod
|
|
26
|
+
for name, mod in sys.modules.items()
|
|
27
|
+
if name == "cosmic_ray" or name.startswith("cosmic_ray.")
|
|
28
|
+
}
|
|
29
|
+
for name in saved:
|
|
30
|
+
del sys.modules[name]
|
|
31
|
+
|
|
32
|
+
seams = SimpleNamespace(
|
|
33
|
+
db=MagicMock(name="WorkDB"),
|
|
34
|
+
deserialize_config=MagicMock(name="deserialize_config"),
|
|
35
|
+
find_modules=MagicMock(name="find_modules", return_value=[]),
|
|
36
|
+
filter_paths=MagicMock(name="filter_paths", side_effect=lambda mods, excl: list(mods)),
|
|
37
|
+
init=MagicMock(name="init"),
|
|
38
|
+
execute=MagicMock(name="execute"),
|
|
39
|
+
WorkItem=MagicMock(name="WorkItem"),
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
@contextlib.contextmanager
|
|
43
|
+
def use_db(path, mode=None):
|
|
44
|
+
yield seams.db
|
|
45
|
+
|
|
46
|
+
def module(name, **attrs):
|
|
47
|
+
mod = ModuleType(name)
|
|
48
|
+
for key, value in attrs.items():
|
|
49
|
+
setattr(mod, key, value)
|
|
50
|
+
sys.modules[name] = mod
|
|
51
|
+
return mod
|
|
52
|
+
|
|
53
|
+
root = module("cosmic_ray")
|
|
54
|
+
root.commands = module("cosmic_ray.commands", init=seams.init, execute=seams.execute)
|
|
55
|
+
root.modules = module(
|
|
56
|
+
"cosmic_ray.modules", find_modules=seams.find_modules, filter_paths=seams.filter_paths
|
|
57
|
+
)
|
|
58
|
+
root.config = module("cosmic_ray.config", deserialize_config=seams.deserialize_config)
|
|
59
|
+
root.work_db = module(
|
|
60
|
+
"cosmic_ray.work_db", use_db=use_db, WorkDB=SimpleNamespace(Mode=SimpleNamespace(create=1))
|
|
61
|
+
)
|
|
62
|
+
root.work_item = module("cosmic_ray.work_item", WorkItem=seams.WorkItem)
|
|
63
|
+
|
|
64
|
+
yield seams
|
|
65
|
+
|
|
66
|
+
for name in [n for n in sys.modules if n == "cosmic_ray" or n.startswith("cosmic_ray.")]:
|
|
67
|
+
del sys.modules[name]
|
|
68
|
+
sys.modules.update(saved)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Executable entry for the Python mutation arm (#248): the rust binary spawns
|
|
2
|
+
``python -m testing_conventions.mutation.main`` and this runs [`mutation_cli`] over the
|
|
3
|
+
process arguments. Kept thin so the orchestration stays a pure, importable function.
|
|
4
|
+
"""
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
from testing_conventions.mutation.cli import mutation_cli
|
|
8
|
+
|
|
9
|
+
mutation_cli(sys.argv[1:])
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Map a cosmic-ray work item + result onto the normalized mutation schema (#245).
|
|
2
|
+
|
|
3
|
+
The rust core gates over one engine-agnostic representation
|
|
4
|
+
(``{file, line, status, mutator}``); this turns cosmic-ray's per-mutant outcome into it,
|
|
5
|
+
the Python counterpart of the TypeScript adapter's ``to-normalized``. It reads only plain
|
|
6
|
+
attributes off the passed objects, so it needs no ``cosmic_ray`` import.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
# cosmic-ray's ``TestOutcome`` values → the normalized ``MutantStatus`` vocabulary.
|
|
11
|
+
# ``survived`` / ``killed`` map straight across; ``incompetent`` (the mutation produced code
|
|
12
|
+
# the interpreter rejected — a syntax / import error, never a viable mutant) is
|
|
13
|
+
# ``compile_error``. cosmic-ray has no distinct no-coverage outcome: an uncovered mutant's
|
|
14
|
+
# suite still passes, so it reports ``survived``.
|
|
15
|
+
STATUS = {"survived": "survived", "killed": "killed", "incompetent": "compile_error"}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def normalize(mutation, result):
|
|
19
|
+
"""Return the normalized mutant dict for one completed work item, or ``None`` to skip a
|
|
20
|
+
work item with no usable outcome (the worker never judged it — abnormal / no test)."""
|
|
21
|
+
outcome = result.test_outcome
|
|
22
|
+
status = STATUS.get(getattr(outcome, "value", outcome))
|
|
23
|
+
if status is None:
|
|
24
|
+
return None
|
|
25
|
+
return {
|
|
26
|
+
"file": str(mutation.module_path).replace("\\", "/"),
|
|
27
|
+
"line": mutation.start_pos[0],
|
|
28
|
+
"status": status,
|
|
29
|
+
"mutator": mutation.operator_name,
|
|
30
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Parse the mutation adapter's CLI arguments.
|
|
2
|
+
|
|
3
|
+
The rust binary spawns ``python -m testing_conventions.mutation.main`` and passes these:
|
|
4
|
+
``--out <path>`` (where to write the normalized-results JSON — the rule passes a temp file)
|
|
5
|
+
and ``--module <path>`` (repeatable; the source files to mutate, for a diff-scoped run).
|
|
6
|
+
Without any ``--module`` the whole project is mutated.
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import argparse
|
|
11
|
+
from dataclasses import dataclass, field
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class Args:
|
|
16
|
+
"""The adapter's parsed arguments."""
|
|
17
|
+
|
|
18
|
+
out: str
|
|
19
|
+
modules: list[str] = field(default_factory=list)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def parse_args(argv):
|
|
23
|
+
"""Parse ``argv`` (a list of strings) into [`Args`]."""
|
|
24
|
+
parser = argparse.ArgumentParser(prog="testing-conventions-mutation")
|
|
25
|
+
parser.add_argument("--out", required=True)
|
|
26
|
+
parser.add_argument("--module", action="append", default=[], dest="modules")
|
|
27
|
+
ns = parser.parse_args(argv)
|
|
28
|
+
return Args(out=ns.out, modules=ns.modules)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Run a cosmic-ray session over the configured modules.
|
|
2
|
+
|
|
3
|
+
``cosmic_ray`` is imported lazily (the module imports without the engine; the session is
|
|
4
|
+
unit-tested with a fake ``cosmic_ray`` injected).
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def run_session(config):
|
|
10
|
+
"""Init + execute cosmic-ray over ``config``'s ``module-path`` and return a list of
|
|
11
|
+
``(MutationSpec, WorkResult)`` — the first mutation of each completed work item paired
|
|
12
|
+
with its outcome. The session DB lives in an out-of-tree temp dir; cosmic-ray mutates
|
|
13
|
+
each source file in place and reverts it, so the scanned tree is left as it was."""
|
|
14
|
+
import tempfile
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
import cosmic_ray.commands
|
|
18
|
+
import cosmic_ray.modules
|
|
19
|
+
from cosmic_ray.work_db import WorkDB, use_db
|
|
20
|
+
|
|
21
|
+
module_path = config["module-path"]
|
|
22
|
+
paths = (
|
|
23
|
+
[Path(module_path)]
|
|
24
|
+
if isinstance(module_path, str)
|
|
25
|
+
else [Path(entry) for entry in module_path]
|
|
26
|
+
)
|
|
27
|
+
modules = cosmic_ray.modules.find_modules(paths)
|
|
28
|
+
modules = cosmic_ray.modules.filter_paths(modules, config.get("excluded-modules", ()))
|
|
29
|
+
with tempfile.TemporaryDirectory() as tmp:
|
|
30
|
+
with use_db(Path(tmp) / "session.sqlite", mode=WorkDB.Mode.create) as database:
|
|
31
|
+
cosmic_ray.commands.init(modules, database, config.operators_config)
|
|
32
|
+
cosmic_ray.commands.execute(database, config)
|
|
33
|
+
return [
|
|
34
|
+
(item.mutations[0], result) for item, result in database.completed_work_items
|
|
35
|
+
]
|
|
@@ -31,6 +31,16 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
31
31
|
`testing-conventions` launcher passes the adapter's path to the binary as a `--ts-mutation-adapter`
|
|
32
32
|
argument on a `unit mutation` invocation; the SDK `measure_typescript` takes it as a trailing
|
|
33
33
|
`adapter: &Path`. See [MIGRATIONS](./MIGRATIONS.md).
|
|
34
|
+
- **`unit mutation --language python` drives cosmic-ray in-process through a bundled adapter** (#248,
|
|
35
|
+
epic #239). The Python arm now spawns a Python adapter shipped in the wheel (`python3 -m
|
|
36
|
+
testing_conventions.mutation.main`) that drives cosmic-ray via its `WorkDB` library API and emits
|
|
37
|
+
the normalized `NormalizedMutant` schema (#239) the gate consumes — replacing the `cosmic-ray` CLI
|
|
38
|
+
orchestration (baseline/init/exec/dump spawns + JSONL dump parse). The tool drives the engine; the
|
|
39
|
+
project supplies its own test runner (pytest). maturin ships the binary directly as the wheel's
|
|
40
|
+
script, so — unlike the TS arm's launcher-injected path — the binary resolves the adapter as an
|
|
41
|
+
installed module (from the wheel's site-packages; the diff-scoped run passes the changed `.py`
|
|
42
|
+
files as `--module` and the core filters survivors to the changed lines). `measure_python`'s
|
|
43
|
+
signature is unchanged. See [MIGRATIONS](./MIGRATIONS.md).
|
|
34
44
|
|
|
35
45
|
### Removed
|
|
36
46
|
|
|
@@ -39,6 +49,11 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
39
49
|
the TS arm no longer parses a Stryker report file; the bundled adapter emits the normalized schema
|
|
40
50
|
(#239) directly. Consume `parse_normalized_results` + `evaluate_normalized` instead. See
|
|
41
51
|
[MIGRATIONS](./MIGRATIONS.md).
|
|
52
|
+
- **BREAKING: the cosmic-ray `dump` types are gone** (#248). `mutation::{parse_cosmic_ray_dump,
|
|
53
|
+
cosmic_ray_mutated_lines, CosmicRayLine, CrWorkItem, CrMutation, CrResult}` are removed — the Python
|
|
54
|
+
arm no longer parses a `cosmic-ray dump`; the bundled adapter emits the normalized schema (#239)
|
|
55
|
+
directly. Consume `parse_normalized_results` + `evaluate_normalized` instead. See
|
|
56
|
+
[MIGRATIONS](./MIGRATIONS.md).
|
|
42
57
|
|
|
43
58
|
### Fixed
|
|
44
59
|
|
|
@@ -15,6 +15,16 @@ Each entry has five sections, in order:
|
|
|
15
15
|
|
|
16
16
|
### Summary
|
|
17
17
|
|
|
18
|
+
Wires the Python arm to drive cosmic-ray in-process through a **bundled Python adapter** (#248,
|
|
19
|
+
building on the #239 core). `unit mutation --language python` now spawns a Python adapter shipped in
|
|
20
|
+
the wheel (`python3 -m testing_conventions.mutation.main`) that drives cosmic-ray via its `WorkDB`
|
|
21
|
+
library API and emits the normalized `NormalizedMutant` schema (#239) the gate consumes — replacing
|
|
22
|
+
the `cosmic-ray` CLI orchestration. maturin ships the rust binary directly as the wheel's script (no
|
|
23
|
+
Python launcher to inject a path, unlike the TS arm), so the binary invokes the adapter as an
|
|
24
|
+
installed module, resolved from the wheel's environment alongside cosmic-ray. One breaking SDK change:
|
|
25
|
+
the cosmic-ray `dump` types are removed (see **Required changes**); `measure_python`'s signature is
|
|
26
|
+
unchanged.
|
|
27
|
+
|
|
18
28
|
Wires the TypeScript arm to drive Stryker through a **bundled Node adapter** (#246, building on the
|
|
19
29
|
#239 core). `unit mutation --language typescript` now spawns a Node adapter shipped with the npm
|
|
20
30
|
package that drives Stryker via its own Node API and emits the normalized `NormalizedMutant` schema
|
|
@@ -569,6 +579,19 @@ core (#239) — the same types the bundled adapter emits and the Rust/Python arm
|
|
|
569
579
|
| `mutation::parse_stryker_report`, `mutation::stryker_survivors` | `mutation::parse_normalized_results` + `mutation::evaluate_normalized` |
|
|
570
580
|
| `mutation::{StrykerReport, StrykerFile, StrykerMutant, StrykerLocation}` | `mutation::NormalizedMutant` |
|
|
571
581
|
|
|
582
|
+
The cosmic-ray `dump` types are removed the same way (#248): the Python arm no longer parses a
|
|
583
|
+
`cosmic-ray dump`. Switch to the normalized core:
|
|
584
|
+
|
|
585
|
+
| Removed | Replacement |
|
|
586
|
+
| --- | --- |
|
|
587
|
+
| `mutation::parse_cosmic_ray_dump`, `mutation::cosmic_ray_mutated_lines` | `mutation::parse_normalized_results` + `mutation::evaluate_normalized` |
|
|
588
|
+
| `mutation::{CosmicRayLine, CrWorkItem, CrMutation, CrResult}` | `mutation::NormalizedMutant` |
|
|
589
|
+
|
|
590
|
+
`measure_python`'s signature is unchanged; it now spawns the bundled Python adapter (`python3 -m
|
|
591
|
+
testing_conventions.mutation.main`) rather than the `cosmic-ray` CLI. In production the wheel makes
|
|
592
|
+
`testing_conventions` importable (site-packages); the rust integration tests set
|
|
593
|
+
`PYTHONPATH=packages/python/python` for their staged fixtures.
|
|
594
|
+
|
|
572
595
|
`measure_typescript` takes a trailing `adapter: &Path` — the path to the bundled Node adapter
|
|
573
596
|
(`packages/node/dist/mutation/main.js`):
|
|
574
597
|
|