Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 38 additions & 17 deletions tools/check_wave_corpus.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,27 +67,48 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
return parser.parse_args(argv)


def _resolve_compiler_path(candidate: Path | str) -> Path | None:
raw = Path(candidate)
if not str(raw).strip():
return None
if raw.is_file():
return raw
if not raw.is_absolute():
rel = ROOT / raw
if rel.is_file():
return rel
which = shutil.which(str(candidate))
if which:
return Path(which)
return None


def resolve_wavec(explicit: Path | None) -> Path:
candidates = []
if explicit is not None:
candidates.append(explicit)
if os.environ.get("WAVEC"):
candidates.append(Path(os.environ["WAVEC"]))
candidates.extend(
[
ROOT / "target" / "release" / "wavec.exe",
ROOT / "target" / "release" / "wavec",
ROOT / "target" / "debug" / "wavec.exe",
ROOT / "target" / "debug" / "wavec",
ROOT / "target" / "x86_64-pc-windows-gnu" / "release" / "wavec.exe",
ROOT / "target" / "x86_64-pc-windows-gnu" / "debug" / "wavec.exe",
]
)
resolved = _resolve_compiler_path(explicit)
if resolved is not None:
return resolved
raise FileNotFoundError(f"wavec executable not found at {explicit}")

env_wavec = os.environ.get("WAVEC")
if env_wavec and env_wavec.strip():
resolved = _resolve_compiler_path(env_wavec)
if resolved is not None:
return resolved
raise FileNotFoundError(f"wavec executable specified by WAVEC not found: {env_wavec}")

candidates = [
ROOT / "target" / "release" / "wavec.exe",
ROOT / "target" / "release" / "wavec",
ROOT / "target" / "debug" / "wavec.exe",
ROOT / "target" / "debug" / "wavec",
ROOT / "target" / "x86_64-pc-windows-gnu" / "release" / "wavec.exe",
ROOT / "target" / "x86_64-pc-windows-gnu" / "debug" / "wavec.exe",
]

for candidate in candidates:
path = candidate if candidate.is_absolute() else ROOT / candidate
if path.is_file():
return path
if candidate.is_file():
return candidate

raise FileNotFoundError("wavec not found; build it or pass --wavec")

Expand Down
104 changes: 103 additions & 1 deletion tools/test_check_wave_corpus.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import io
import os
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch

from tools.check_wave_corpus import parse_args, main
from tools.check_wave_corpus import parse_args, resolve_wavec, main
import tools.check_wave_corpus as check_wave_corpus


class TestCheckWaveCorpusCLI(unittest.TestCase):
Expand Down Expand Up @@ -92,5 +96,103 @@ def test_help_flag(self):
self.assertIn("per-file timeout in seconds (default: 15)", output)


class TestResolveWavec(unittest.TestCase):
def test_invalid_explicit_path_fails_without_selecting_existing_fallback(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
fallback = root / "target" / "release" / "wavec"
fallback.parent.mkdir(parents=True)
fallback.touch()

with patch.object(check_wave_corpus, "ROOT", root):
with self.assertRaises(FileNotFoundError) as cm:
resolve_wavec(Path("missing/wavec"))

self.assertIn("missing/wavec", str(cm.exception))

def test_invalid_explicit_wavec_env_fails_without_selecting_fallback(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
fallback = root / "target" / "release" / "wavec"
fallback.parent.mkdir(parents=True)
fallback.touch()

with patch.object(check_wave_corpus, "ROOT", root):
with patch.dict(os.environ, {"WAVEC": "missing_env_wavec"}, clear=False):
with self.assertRaises(FileNotFoundError) as cm:
resolve_wavec(None)

self.assertIn("missing_env_wavec", str(cm.exception))

def test_valid_explicit_path_selected(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
custom = root / "bin" / "custom_wavec"
custom.parent.mkdir(parents=True)
custom.touch()

fallback = root / "target" / "release" / "wavec"
fallback.parent.mkdir(parents=True)
fallback.touch()

with patch.object(check_wave_corpus, "ROOT", root):
self.assertEqual(resolve_wavec(custom), custom)
self.assertEqual(
resolve_wavec(Path("bin/custom_wavec")),
custom,
)

def test_valid_wavec_env_selected(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
custom = root / "bin" / "custom_wavec"
custom.parent.mkdir(parents=True)
custom.touch()

fallback = root / "target" / "release" / "wavec"
fallback.parent.mkdir(parents=True)
fallback.touch()

with patch.object(check_wave_corpus, "ROOT", root):
with patch.dict(os.environ, {"WAVEC": str(custom)}, clear=False):
self.assertEqual(resolve_wavec(None), custom)

def test_no_override_falls_back_to_discovery(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
fallback = root / "target" / "release" / "wavec"
fallback.parent.mkdir(parents=True)
fallback.touch()

with patch.object(check_wave_corpus, "ROOT", root):
env = os.environ.copy()
env.pop("WAVEC", None)
with patch.dict(os.environ, env, clear=True):
self.assertEqual(resolve_wavec(None), fallback)

def test_empty_wavec_env_falls_back_to_discovery(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
fallback = root / "target" / "release" / "wavec"
fallback.parent.mkdir(parents=True)
fallback.touch()

with patch.object(check_wave_corpus, "ROOT", root):
with patch.dict(os.environ, {"WAVEC": " "}, clear=False):
self.assertEqual(resolve_wavec(None), fallback)

def test_no_override_and_no_binary_raises_file_not_found(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
with patch.object(check_wave_corpus, "ROOT", root):
env = os.environ.copy()
env.pop("WAVEC", None)
with patch.dict(os.environ, env, clear=True):
with self.assertRaises(FileNotFoundError) as cm:
resolve_wavec(None)

self.assertIn("wavec not found; build it or pass --wavec", str(cm.exception))


if __name__ == "__main__":
unittest.main()
Loading