Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Cargo.lock
*.dylib
.claude/
site/
.coverage
website/.astro/
website/dist/
website/node_modules/
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,5 @@ testpaths = ["tests"]
[dependency-groups]
dev = [
"pre-commit>=4.6.0",
"pytest-cov>=7.1.0",
]
89 changes: 89 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,92 @@ def test_split_invalid_test_ratio(tmp_path: Path) -> None:
_write_manifest(staging, n=50)
result = runner.invoke(app, ["split", str(staging), "--test-ratio", "1.5"])
assert result.exit_code != 0


def test_split_config_error(tmp_path: Path) -> None:
# Trigger the except Exception block in split command
staging = tmp_path / "staging"
_write_manifest(staging, n=50)
# providing an invalid strategy to trigger validation error
result = runner.invoke(app, ["split", str(staging), "--strategy", "invalid_strategy"])
assert result.exit_code != 0
assert "Config error" in result.output


# ---------------------------------------------------------------------------
# generate command
# ---------------------------------------------------------------------------


def test_generate_missing_file(tmp_path: Path) -> None:
result = runner.invoke(app, ["generate", str(tmp_path / "no_file.yaml")])
assert result.exit_code != 0
assert "not found" in result.output.lower()


def test_generate_bad_config(tmp_path: Path) -> None:
bad = tmp_path / "bad.yaml"
bad.write_text("region:\n west: 0\n")
result = runner.invoke(app, ["generate", str(bad)])
assert result.exit_code != 0
assert "Config error" in result.output


def test_generate_unreadable_config(tmp_path: Path, monkeypatch) -> None:
cfg = _write_config(tmp_path)

def mock_read_text(*args, **kwargs):
raise OSError("Permission denied")

monkeypatch.setattr(Path, "read_text", mock_read_text)

result = runner.invoke(app, ["generate", str(cfg)])
assert result.exit_code != 0
assert "Config error" in result.output
assert "Permission denied" in result.output


def test_generate_calls_run_generate(tmp_path: Path, monkeypatch) -> None:
cfg = _write_config(tmp_path)
called = False

def mock_run_generate(config):
nonlocal called
called = True

monkeypatch.setattr("mapcv.cli.run_generate", mock_run_generate)

result = runner.invoke(app, ["generate", str(cfg)])
assert result.exit_code == 0
assert called


# ---------------------------------------------------------------------------
# Error handling in validate
# ---------------------------------------------------------------------------


def test_validate_unreadable_config(tmp_path: Path, monkeypatch) -> None:
cfg = _write_config(tmp_path)

def mock_read_text(*args, **kwargs):
raise OSError("Permission denied")

monkeypatch.setattr(Path, "read_text", mock_read_text)

result = runner.invoke(app, ["validate", str(cfg)])
assert result.exit_code != 0
assert "Config error" in result.output
assert "Permission denied" in result.output


def test_validate_shows_split_info(tmp_path: Path) -> None:
cfg = tmp_path / "config.yaml"
staging = tmp_path / "output"
cfg.write_text(
_VALID_CONFIG.format(staging_dir=staging) + "split:\n test_ratio: 0.2\n strategy: random\n"
)
result = runner.invoke(app, ["validate", str(cfg)])
assert result.exit_code == 0
assert "split" in result.output
assert "0.2" in result.output
Loading
Loading