Spaces:
Sleeping
Sleeping
| import io | |
| import json | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parents[1])) | |
| import numpy as np | |
| import soundfile as sf | |
| from fastapi.testclient import TestClient | |
| from app import app | |
| from pipeline_runner import PipelineParams | |
| def wav_bytes() -> io.BytesIO: | |
| sr = 22050 | |
| t = np.arange(int(sr * 0.25)) / sr | |
| y = 0.15 * np.sin(2 * np.pi * 220 * t) * np.exp(-t * 10) | |
| buf = io.BytesIO() | |
| sf.write(buf, y, sr, format="WAV") | |
| buf.seek(0) | |
| return buf | |
| def test_mapping_coerces_browser_form_values() -> None: | |
| params = PipelineParams.from_mapping({ | |
| "stem": "all", | |
| "subdivision": "16", | |
| "demucs_shifts": "0", | |
| "demucs_overlap": "0.25", | |
| "target_min": "2", | |
| "target_max": "6", | |
| "synthesize": "false", | |
| "quantize_midi": "true", | |
| "use_disk_cache": "1", | |
| }) | |
| assert params.subdivision == 16 | |
| assert params.demucs_shifts == 0 | |
| assert params.demucs_overlap == 0.25 | |
| assert params.target_min == 2 | |
| assert params.target_max == 6 | |
| assert params.synthesize is False | |
| assert params.quantize_midi is True | |
| assert params.use_disk_cache is True | |
| def test_invalid_subdivision_is_actionable() -> None: | |
| try: | |
| PipelineParams.from_mapping({"subdivision": "12"}) | |
| except ValueError as exc: | |
| assert "subdivision must be one of 4, 8, 16, 32, 64" in str(exc) | |
| else: | |
| raise AssertionError("invalid subdivision was accepted") | |
| def test_jobs_endpoint_accepts_string_subdivision_from_browser_select() -> None: | |
| client = TestClient(app) | |
| params = { | |
| "stem": "all", | |
| "subdivision": "16", | |
| "demucs_shifts": "0", | |
| "synthesize": "false", | |
| "use_disk_cache": "false", | |
| } | |
| response = client.post( | |
| "/api/jobs", | |
| files={"file": ("tiny.wav", wav_bytes(), "audio/wav")}, | |
| data={"params": json.dumps(params)}, | |
| ) | |
| assert response.status_code == 202, response.text | |
| payload = response.json() | |
| assert payload["params"]["subdivision"] == 16 | |
| assert payload["params"]["demucs_shifts"] == 0 | |
| assert payload["params"]["synthesize"] is False | |
| assert payload["params"]["use_disk_cache"] is False | |
| def test_jobs_endpoint_reports_bad_parameter_as_visible_detail() -> None: | |
| client = TestClient(app) | |
| response = client.post( | |
| "/api/jobs", | |
| files={"file": ("tiny.wav", wav_bytes(), "audio/wav")}, | |
| data={"params": json.dumps({"subdivision": "12"})}, | |
| ) | |
| assert response.status_code == 400 | |
| payload = response.json() | |
| assert "Invalid extraction parameter" in payload["detail"] | |
| assert "subdivision must be one of 4, 8, 16, 32, 64" in payload["detail"] | |
| if __name__ == "__main__": | |
| test_mapping_coerces_browser_form_values() | |
| test_invalid_subdivision_is_actionable() | |
| test_jobs_endpoint_accepts_string_subdivision_from_browser_select() | |
| test_jobs_endpoint_reports_bad_parameter_as_visible_detail() | |
| print("parameter validation and API error visibility contract passed") | |