"""Tests for scripts/generate.py — E2E song generation and RPP validator.""" from __future__ import annotations import subprocess import sys from pathlib import Path import pytest sys.path.insert(0, str(Path(__file__).parents[1])) class TestGenerateCLI: """Smoke and integration tests for the generate.py CLI.""" def test_generate_cli_smoke(self, tmp_path): """CLI produces a non-empty .rpp file at the expected path.""" output = tmp_path / "song.rpp" result = subprocess.run( [ sys.executable, "scripts/generate.py", "--bpm", "95", "--key", "Am", "--output", str(output), "--seed", "42", ], capture_output=True, text=True, timeout=60, ) assert result.returncode == 0, f"stderr: {result.stderr}" assert output.exists(), f"File not created: {output}" assert output.stat().st_size > 0, "File is empty" def test_validate_passes_for_valid_output(self, tmp_path): """With --validate, CLI returns 0 when validator sees no errors.""" output = tmp_path / "song.rpp" result = subprocess.run( [ sys.executable, "scripts/generate.py", "--bpm", "95", "--key", "Am", "--output", str(output), "--seed", "42", "--validate", ], capture_output=True, text=True, timeout=60, ) assert result.returncode == 0, f"stderr: {result.stderr}\nstdout: {result.stdout}" def test_validate_detects_track_count_violation(self, tmp_path): """Validator flags a project with fewer than 9 tracks.""" from src.validator.rpp_validator import validate_rpp_output rpp_path = tmp_path / "bad.rpp" # Write a minimal .rpp with only 5 blocks content = ( "\n" + " \n" + " \n" + " \n" + " \n" + ">" ) rpp_path.write_text(content, encoding="utf-8") errors = validate_rpp_output(str(rpp_path)) assert any("Expected 9" in e for e in errors), f"Got: {errors}" def test_reproducibility_same_seed(self, tmp_path): """Two runs with the same seed produce byte-identical output.""" output_a = tmp_path / "song_a.rpp" output_b = tmp_path / "song_b.rpp" for out_path in (output_a, output_b): result = subprocess.run( [ sys.executable, "scripts/generate.py", "--bpm", "95", "--key", "Am", "--output", str(out_path), "--seed", "42", ], capture_output=True, text=True, timeout=60, ) assert result.returncode == 0, f"stderr: {result.stderr}" assert output_a.read_bytes() == output_b.read_bytes(), ( "Outputs differ — seed does not guarantee reproducibility" )