fix(coverage): resolve fail-under from pyproject in threshold-enforcement step (WS5)
CI / lint (pull_request) Successful in 42s
CI / typecheck (pull_request) Successful in 55s
CI / quality (pull_request) Successful in 59s
CI / security (pull_request) Successful in 1m16s
CI / helm (pull_request) Successful in 40s
CI / build (pull_request) Successful in 43s
CI / push-validation (pull_request) Successful in 20s
CI / unit_tests (pull_request) Successful in 4m26s
CI / docker (pull_request) Successful in 1m25s
CI / coverage (pull_request) Successful in 9m34s
CI / integration_tests (pull_request) Failing after 21m41s
CI / status-check (pull_request) Failing after 3s
CI / lint (pull_request) Successful in 42s
CI / typecheck (pull_request) Successful in 55s
CI / quality (pull_request) Successful in 59s
CI / security (pull_request) Successful in 1m16s
CI / helm (pull_request) Successful in 40s
CI / build (pull_request) Successful in 43s
CI / push-validation (pull_request) Successful in 20s
CI / unit_tests (pull_request) Successful in 4m26s
CI / docker (pull_request) Successful in 1m25s
CI / coverage (pull_request) Successful in 9m34s
CI / integration_tests (pull_request) Failing after 21m41s
CI / status-check (pull_request) Failing after 3s
The coverage_report noxfile session now delegates COVERAGE_THRESHOLD to the pyproject single source (`COVERAGE_THRESHOLD = _read_coverage_fail_under()`), so the AST value is a Call, not a Constant. The coverage_threshold_enforcement.feature step "I parse the COVERAGE_THRESHOLD constant from noxfile.py" raised ValueError (errored scenario) because it only handled a literal constant — this was the missed third WS5 step file (the config + consolidated steps were already reconciled). Add the same pyproject `[tool.coverage.report].fail_under` fallback used by coverage_threshold_config_steps.py, and fix the phantom-97 in the feature description prose. Verified: the four coverage feature files now pass (136 scenarios, 0 errored); previously unit_tests errored on coverage_threshold_enforcement.feature:7. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
Feature: Coverage threshold enforcement
|
||||
The project enforces a minimum 97% code coverage threshold.
|
||||
The project enforces a minimum 96.5% code coverage threshold.
|
||||
This feature validates that the coverage configuration and nox session
|
||||
are properly set up to enforce this requirement.
|
||||
|
||||
|
||||
@@ -41,6 +41,18 @@ def step_ci_workflow_exists(context: Any) -> None:
|
||||
context.ci_file_content = ci_file.read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def _pyproject_fail_under() -> float | None:
|
||||
"""The canonical coverage floor: pyproject ``[tool.coverage.report]``
|
||||
``fail_under`` (the single source the noxfile delegates to via
|
||||
``_read_coverage_fail_under()``). None if absent/unreadable."""
|
||||
pyproject = PROJECT_ROOT / "pyproject.toml"
|
||||
try:
|
||||
data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
|
||||
return float(data["tool"]["coverage"]["report"]["fail_under"])
|
||||
except (OSError, KeyError, TypeError, ValueError, tomllib.TOMLDecodeError):
|
||||
return None
|
||||
|
||||
|
||||
@when("I parse the COVERAGE_THRESHOLD constant from noxfile.py")
|
||||
def step_parse_threshold(context: Any) -> None:
|
||||
content = context.noxfile_content
|
||||
@@ -55,8 +67,16 @@ def step_parse_threshold(context: Any) -> None:
|
||||
and isinstance(node.value, ast.Constant)
|
||||
):
|
||||
threshold = node.value.value
|
||||
# WS5: the noxfile now delegates the constant to pyproject's single source
|
||||
# (``COVERAGE_THRESHOLD = _read_coverage_fail_under()``), so the AST value is
|
||||
# a Call, not a Constant. Resolve the effective floor from pyproject.
|
||||
if threshold is None:
|
||||
raise ValueError("COVERAGE_THRESHOLD constant not found in noxfile.py")
|
||||
threshold = _pyproject_fail_under()
|
||||
if threshold is None:
|
||||
raise ValueError(
|
||||
"COVERAGE_THRESHOLD not found in noxfile.py and pyproject "
|
||||
"[tool.coverage.report].fail_under is unreadable"
|
||||
)
|
||||
context.coverage_threshold = threshold
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user