From 3463331171ae7d8ee68a97dccf550c18dd6880a5 Mon Sep 17 00:00:00 2001 From: Gracy769 <169199616+Gracy769@users.noreply.github.com> Date: Sun, 30 Aug 2026 14:08:19 +0530 Subject: [PATCH] test: fix windows test compatibility --- tests/test_pre_push_hook_contract.py | 13 ++++++++++++ tests/test_roadmap_helpers.py | 31 +++++++++++++++++++++------- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/tests/test_pre_push_hook_contract.py b/tests/test_pre_push_hook_contract.py index b38a5d45..7a958a05 100644 --- a/tests/test_pre_push_hook_contract.py +++ b/tests/test_pre_push_hook_contract.py @@ -1,5 +1,16 @@ from __future__ import annotations +import unittest +import os + +def require_bash() -> bool: + import shutil + bash = shutil.which('bash') + if os.name == 'nt': + return False + return bash is not None + + import os import subprocess import unittest @@ -11,6 +22,7 @@ PRE_PUSH_HOOK = REPO_ROOT / '.github' / 'hooks' / 'pre-push' class PrePushHookContractTests(unittest.TestCase): + @unittest.skipUnless(require_bash(), 'Requires bash') def test_skip_escape_hatch_exits_successfully_with_stderr_notice(self) -> None: env = os.environ.copy() env['SKIP_CLAW_PRE_PUSH_BUILD'] = '1' @@ -28,6 +40,7 @@ class PrePushHookContractTests(unittest.TestCase): self.assertIn('SKIP_CLAW_PRE_PUSH_BUILD=1', result.stderr) self.assertIn('skipping cargo workspace build', result.stderr) + @unittest.skipUnless(require_bash(), 'Requires bash') def test_default_build_gate_uses_workspace_locked_cargo_build(self) -> None: hook = PRE_PUSH_HOOK.read_text() diff --git a/tests/test_roadmap_helpers.py b/tests/test_roadmap_helpers.py index 3c875198..27031c5d 100644 --- a/tests/test_roadmap_helpers.py +++ b/tests/test_roadmap_helpers.py @@ -14,6 +14,17 @@ DOGFOOD_PROBE = REPO_ROOT / 'scripts' / 'dogfood-probe.py' +import sys + +def require_bash() -> bool: + import os + import shutil + bash = shutil.which('bash') + if os.name == 'nt': + # On Windows, 'bash' often resolves to WSL which fails if not configured + return False + return bash is not None + def run_next_id(roadmap: Path, script: Path = NEXT_ID) -> subprocess.CompletedProcess[str]: return subprocess.run( ['bash', str(script), str(roadmap)], @@ -25,8 +36,9 @@ def run_next_id(roadmap: Path, script: Path = NEXT_ID) -> subprocess.CompletedPr def run_dogfood_probe(args: list[str]) -> subprocess.CompletedProcess[str]: + import sys return subprocess.run( - ['python3', str(DOGFOOD_PROBE), *args], + [sys.executable, str(DOGFOOD_PROBE), *args], cwd=REPO_ROOT, capture_output=True, text=True, @@ -35,6 +47,7 @@ def run_dogfood_probe(args: list[str]) -> subprocess.CompletedProcess[str]: class RoadmapHelperTests(unittest.TestCase): + @unittest.skipUnless(require_bash(), 'Requires bash') def test_roadmap_next_id_prints_only_next_id_after_duplicate_check(self) -> None: with tempfile.TemporaryDirectory() as temp_dir: roadmap = Path(temp_dir) / 'ROADMAP.md' @@ -46,6 +59,7 @@ class RoadmapHelperTests(unittest.TestCase): self.assertEqual('725\n', result.stdout) self.assertEqual('', result.stderr) + @unittest.skipUnless(require_bash(), 'Requires bash') def test_roadmap_next_id_fails_fast_on_helper_era_duplicate(self) -> None: with tempfile.TemporaryDirectory() as temp_dir: roadmap = Path(temp_dir) / 'ROADMAP.md' @@ -59,6 +73,7 @@ class RoadmapHelperTests(unittest.TestCase): self.assertIn('999', result.stderr) self.assertNotIn('1000', result.stdout) + @unittest.skipUnless(require_bash(), 'Requires bash') def test_roadmap_next_id_fails_when_explicit_roadmap_path_is_missing(self) -> None: with tempfile.TemporaryDirectory() as temp_dir: roadmap = Path(temp_dir) / 'missing-ROADMAP.md' @@ -70,6 +85,7 @@ class RoadmapHelperTests(unittest.TestCase): self.assertIn('ROADMAP not found', result.stderr) self.assertIn(str(roadmap), result.stderr) + @unittest.skipUnless(require_bash(), 'Requires bash') def test_roadmap_next_id_fails_closed_when_checker_is_unavailable(self) -> None: with tempfile.TemporaryDirectory() as temp_dir: script_dir = Path(temp_dir) / 'scripts' @@ -100,7 +116,7 @@ class RoadmapHelperTests(unittest.TestCase): result = run_dogfood_probe([ '--stdout-json-byte0', '--', - 'python3', + sys.executable, str(fixture), '--output-format', 'json', @@ -112,7 +128,7 @@ class RoadmapHelperTests(unittest.TestCase): payload = __import__('json').loads(result.stdout) self.assertEqual('ok', payload['kind']) self.assertEqual([ - 'python3', + sys.executable, str(fixture), '--output-format', 'json', @@ -120,15 +136,16 @@ class RoadmapHelperTests(unittest.TestCase): '--help', ], payload['argv']) self.assertEqual(0, payload['returncode']) - self.assertEqual('{"argv": ["--output-format", "json", "doctor", "--help"]}\n', payload['stdout']) - self.assertEqual('diagnostic\n', payload['stderr']) + self.assertEqual('{"argv": ["--output-format", "json", "doctor", "--help"]}\n', payload['stdout'].replace('\r\n', '\n')) + self.assertEqual('diagnostic\n', payload['stderr'].replace('\r\n', '\n')) def test_dogfood_probe_labels_timeout_separately_from_product_error(self) -> None: with tempfile.TemporaryDirectory() as temp_dir: fixture = Path(temp_dir) / 'sleep.py' fixture.write_text('import time\ntime.sleep(2)\n') - result = run_dogfood_probe(['--timeout', '0.1', '--', 'python3', str(fixture)]) + import sys + result = run_dogfood_probe(['--timeout', '0.1', '--', sys.executable, str(fixture)]) self.assertEqual(1, result.returncode) payload = __import__('json').loads(result.stdout) @@ -151,7 +168,7 @@ class RoadmapHelperTests(unittest.TestCase): fixture = Path(temp_dir) / 'prefixed.py' fixture.write_text('print("warning before json")\nprint("{}")\n') - result = run_dogfood_probe(['--stdout-json-byte0', '--', 'python3', str(fixture)]) + result = run_dogfood_probe(['--stdout-json-byte0', '--', sys.executable, str(fixture)]) self.assertEqual(1, result.returncode) payload = __import__('json').loads(result.stdout)