From 5212607599e6dd5463196f99d6e5a23ea9aded78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Gait=C3=A1n-Villamizar?= Date: Mon, 11 May 2026 11:54:02 +0200 Subject: [PATCH 1/2] test(check): probe --changed scope boundaries with named gate assertions Add two targeted e2e scenarios that prove the --changed contract in full: - each graph-wide gate (test, deps, attribution) is skipped with its explicit named message (not just the generic "skipped under --changed" fragment) - file-level gates (fix, typecheck) DO run on the scoped file set Extract _stage_combined() helper in the step defs to deduplicate the stdout+stderr combination shared by both output assertion steps. --- tests/features/interlock_stages.feature | 19 +++++++++++++++++++ tests/step_defs/test_interlock_stages.py | 6 +++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/features/interlock_stages.feature b/tests/features/interlock_stages.feature index b7dd6b3..793f550 100644 --- a/tests/features/interlock_stages.feature +++ b/tests/features/interlock_stages.feature @@ -70,6 +70,25 @@ Feature: interlocks stage commands on a minimal inline project And the stage output contains "changed vs HEAD" And the stage output contains "skipped under --changed" + # req: stage-check + Scenario: `interlocks check --changed` skips each graph-wide gate with a named reason + Given a minimal tmp project initialized as a git repo + And the tmp project has a changed Python file + When I run "interlocks check --changed=HEAD" in the tmp project + Then the stage exits 0 + And the stage output contains "test: skipped under --changed" + And the stage output contains "deps: skipped under --changed" + And the stage output contains "attribution: skipped under --changed" + + # req: stage-check + Scenario: `interlocks check --changed` runs file-level gates on changed Python files + Given a minimal tmp project initialized as a git repo + And the tmp project has a changed Python file + When I run "interlocks check --changed=HEAD" in the tmp project + Then the stage exits 0 + And the stage output contains "[fix]" + And the stage output contains "[typecheck]" + # req: stage-check Scenario: `interlocks check --changed` honors changed_ref from pyproject Given a minimal tmp project initialized as a git repo diff --git a/tests/step_defs/test_interlock_stages.py b/tests/step_defs/test_interlock_stages.py index e0de514..7399d76 100644 --- a/tests/step_defs/test_interlock_stages.py +++ b/tests/step_defs/test_interlock_stages.py @@ -138,7 +138,11 @@ def _stage_exits(stage_result: subprocess.CompletedProcess[str], code: int) -> N ) +def _stage_combined(result: subprocess.CompletedProcess[str]) -> str: + return result.stdout + result.stderr + + @then(parsers.parse('the stage output contains "{fragment}"')) def _stage_output_contains(stage_result: subprocess.CompletedProcess[str], fragment: str) -> None: - combined = stage_result.stdout + stage_result.stderr + combined = _stage_combined(stage_result) assert fragment in combined, f"expected {fragment!r} in stage output; got:\n{combined}" From 4228c8afefa115e1b1750f4de6f3fa2cb8a629c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Gait=C3=A1n-Villamizar?= Date: Mon, 11 May 2026 12:44:15 +0200 Subject: [PATCH 2/2] test(check): consolidate --changed scenarios and add format/crap assertions Merges two separate --changed scenarios that had identical setup into one, reducing redundant E2E subprocess + git-init overhead. Adds [format] and [crap] assertions to fully cover all four file-level gates under --changed scope. --- tests/features/interlock_stages.feature | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/features/interlock_stages.feature b/tests/features/interlock_stages.feature index 793f550..4c4740f 100644 --- a/tests/features/interlock_stages.feature +++ b/tests/features/interlock_stages.feature @@ -71,7 +71,7 @@ Feature: interlocks stage commands on a minimal inline project And the stage output contains "skipped under --changed" # req: stage-check - Scenario: `interlocks check --changed` skips each graph-wide gate with a named reason + Scenario: `interlocks check --changed` skips graph-wide gates and runs file-level gates Given a minimal tmp project initialized as a git repo And the tmp project has a changed Python file When I run "interlocks check --changed=HEAD" in the tmp project @@ -79,15 +79,10 @@ Feature: interlocks stage commands on a minimal inline project And the stage output contains "test: skipped under --changed" And the stage output contains "deps: skipped under --changed" And the stage output contains "attribution: skipped under --changed" - - # req: stage-check - Scenario: `interlocks check --changed` runs file-level gates on changed Python files - Given a minimal tmp project initialized as a git repo - And the tmp project has a changed Python file - When I run "interlocks check --changed=HEAD" in the tmp project - Then the stage exits 0 And the stage output contains "[fix]" + And the stage output contains "[format]" And the stage output contains "[typecheck]" + And the stage output contains "[crap]" # req: stage-check Scenario: `interlocks check --changed` honors changed_ref from pyproject