from pathlib import Path import pytest from scripts.export_experimental_yolo_train_shard import ( is_canonical_train_window, validate_experimental_request, ) from scripts.train_experimental_yolo_candidate import validate_paths from scripts.train_experimental_building_proposal_filter import validate_inputs from scripts.compose_experimental_yolo_rehearsal_dataset import validate_sources def test_export_refuses_non_experimental_output(tmp_path: Path) -> None: manifest = tmp_path / "manifest.json" manifest.write_text("{}", encoding="utf-8") with pytest.raises(ValueError, match="output must remain"): validate_experimental_request(manifest, tmp_path / "output") def test_training_refuses_paths_outside_experimental_root(tmp_path: Path) -> None: with pytest.raises(ValueError, match="must remain"): validate_paths(tmp_path / "dataset", tmp_path / "output") def test_train_shard_rejects_near_duplicate_edge_cover_windows() -> None: canonical = {"row_off": 512, "col_off": 0, "height": 512, "width": 512} edge_cover = {"row_off": 513, "col_off": 0, "height": 512, "width": 512} assert is_canonical_train_window(canonical, 512) assert not is_canonical_train_window(edge_cover, 512) def test_proposal_filter_refuses_non_experimental_paths(tmp_path: Path) -> None: with pytest.raises(ValueError, match="must remain"): validate_inputs(tmp_path / "summary.json", tmp_path / "output") def test_rehearsal_composer_refuses_non_experimental_output(tmp_path: Path) -> None: with pytest.raises(ValueError, match="output must remain"): validate_sources(tmp_path / "old.json", tmp_path / "new.json", tmp_path / "out")