aboutsummaryrefslogtreecommitdiff
path: root/lib/project/tests/test_cli.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/project/tests/test_cli.py')
-rw-r--r--lib/project/tests/test_cli.py52
1 files changed, 29 insertions, 23 deletions
diff --git a/lib/project/tests/test_cli.py b/lib/project/tests/test_cli.py
index 05c8292..31eadf9 100644
--- a/lib/project/tests/test_cli.py
+++ b/lib/project/tests/test_cli.py
@@ -19,7 +19,7 @@ def invoke(monkeypatch):
def test_preview_real_audio_preserves_original_and_reports_provenance(
- wav, tmp_path, ffmpeg, invoke, capsys, monkeypatch
+ wav, tmp_path, ffmpeg, invoke, capsys, monkeypatch, report_of
):
time = np.arange(48000 * 7) / 48000
source = wav(0.15 * np.sin(2 * np.pi * 440 * time))
@@ -44,13 +44,15 @@ def test_preview_real_audio_preserves_original_and_reports_provenance(
assert "Preview:" in captured.err
assert source.read_bytes() == original
assert len(modes) == 2
+ # --no-normalize --no-limiter differ from every built-in profile: the
+ # outputs are named 'custom', with the compared profile kept for clarity.
assert {path.name for path in output_dir.iterdir()} == {
- f"input.{profile}.preview.wav"
+ f"input.custom.{profile}.preview.wav"
for profile in ("natural", "radio")
- } | {"logs"}
+ }
for profile, mode in zip(("natural", "radio"), modes):
- target = output_dir / f"input.{profile}.preview.wav"
- report = json.loads(pipeline.report_for(target).read_text())
+ target = output_dir / f"input.custom.{profile}.preview.wav"
+ report = json.loads(report_of(target).read_text())
info = sf.info(target)
assert info.duration == pytest.approx(5, abs=0.02)
assert info.channels == 1
@@ -123,7 +125,7 @@ def test_missing_input_fails_before_tool_setup(tmp_path, invoke, capsys, monkeyp
assert not target.exists()
-def test_existing_output_is_not_overwritten(wav, tmp_path, invoke, capsys, monkeypatch):
+def test_existing_output_is_not_overwritten(wav, tmp_path, invoke, capsys, monkeypatch, logs):
source = wav()
original = source.read_bytes()
target = tmp_path / "master.wav"
@@ -135,7 +137,7 @@ def test_existing_output_is_not_overwritten(wav, tmp_path, invoke, capsys, monke
assert "Output exists" in capsys.readouterr().err
assert target.read_bytes() == b"previous master"
assert source.read_bytes() == original
- assert not pipeline.report_for(target).exists()
+ assert not list(logs.glob("*.report.json"))
def test_overwrite_cannot_replace_input(wav, invoke, capsys, monkeypatch):
@@ -169,19 +171,23 @@ def test_default_outputs_are_written_beside_each_input(wav, tmp_path, ffmpeg, in
sources = [wav(name="a/take.wav"), wav(name="b/take.wav")]
invoke("process", *sources, "--no-denoise")
for source in sources:
+ # --no-denoise differs from the built-in profile, so outputs are named
+ # 'custom'. Report logs never appear beside the outputs.
assert {path.name for path in source.parent.iterdir()} == {
- "take.wav", "take.natural.wav", "logs"}
+ "take.wav", "take.custom.wav"}
captured = capsys.readouterr()
assert captured.out == ""
assert captured.err.count("Written:") == 2
-def test_process_keyword_is_optional(wav, tmp_path, ffmpeg, invoke, capsys):
+def test_process_keyword_is_optional(wav, tmp_path, ffmpeg, invoke, capsys, report_of):
source = wav()
original = source.read_bytes()
invoke(source, "--no-denoise")
assert {path.name for path in tmp_path.iterdir()} == {
- "input.wav", "input.natural.wav", "logs"}
+ "input.wav", "input.custom.wav", "producer-root"}
+ report = json.loads(report_of(tmp_path / "input.custom.wav").read_text())
+ assert report["settings"]["denoiser"] == "none"
assert source.read_bytes() == original
assert capsys.readouterr().err.count("Written:") == 1
@@ -189,7 +195,7 @@ def test_process_keyword_is_optional(wav, tmp_path, ffmpeg, invoke, capsys):
def test_leading_flag_still_selects_process(wav, tmp_path, ffmpeg, invoke, capsys):
source = wav()
invoke("--no-denoise", source)
- assert (tmp_path / "input.natural.wav").exists()
+ assert (tmp_path / "input.custom.wav").exists()
def test_output_and_output_dir_cannot_be_combined(wav, tmp_path, invoke, capsys):
@@ -206,20 +212,20 @@ def test_missing_later_input_fails_before_any_processing(wav, tmp_path, invoke,
invoke("process", source, tmp_path / "missing.wav", "--no-denoise")
assert error.value.code == 1
assert "existing WAV file" in capsys.readouterr().err
- assert not (tmp_path / "input.natural.wav").exists()
+ assert not (tmp_path / "input.custom.wav").exists()
def test_existing_output_in_batch_fails_before_any_processing(wav, tmp_path, invoke, capsys, monkeypatch):
(tmp_path / "a").mkdir()
(tmp_path / "b").mkdir()
sources = [wav(name="a/take.wav"), wav(name="b/take.wav")]
- (tmp_path / "b" / "take.natural.wav").write_bytes(b"previous result")
+ (tmp_path / "b" / "take.custom.wav").write_bytes(b"previous result")
monkeypatch.setattr(cli, "process", lambda *a, **kw: pytest.fail("Preflight must reject the batch"))
with pytest.raises(SystemExit) as error:
invoke("process", *sources, "--no-denoise")
assert error.value.code == 1
assert "Output exists" in capsys.readouterr().err
- assert not (tmp_path / "a" / "take.natural.wav").exists()
+ assert not (tmp_path / "a" / "take.custom.wav").exists()
def test_preview_rejects_duplicate_profiles_and_profile_override(wav, invoke, capsys, monkeypatch):
@@ -237,15 +243,16 @@ def test_preview_rejects_duplicate_profiles_and_profile_override(wav, invoke, ca
assert list(source.parent.iterdir()) == [source]
-def test_preview_default_output_is_written_beside_input(wav, tmp_path, ffmpeg, invoke, capsys):
+def test_preview_default_output_is_written_beside_input(wav, tmp_path, ffmpeg, invoke, capsys, report_of):
source = wav()
original = source.read_bytes()
invoke("preview", source, "--no-denoise", "--start", "1", "--duration", "2",
"--profiles", "natural")
assert {path.name for path in tmp_path.iterdir()} == {
- "input.wav", "input.natural.preview.wav", "logs"}
- report = json.loads(pipeline.report_for(tmp_path / "input.natural.preview.wav").read_text())
+ "input.wav", "input.custom.natural.preview.wav", "producer-root"}
+ report = json.loads(report_of(tmp_path / "input.custom.natural.preview.wav").read_text())
assert report["settings"]["profile"] == "natural"
+ assert report["settings"]["denoiser"] == "none"
assert source.read_bytes() == original
@@ -271,14 +278,16 @@ def test_preview_cancellation_cleans_excerpt(wav, tmp_path, ffmpeg, invoke, caps
assert source.read_bytes() == original
-@pytest.mark.parametrize("suffix", [".wav", ".report.json", ".mp3"])
+@pytest.mark.parametrize("suffix", [".wav", ".mp3"])
def test_nonfile_output_with_overwrite_fails_before_tool_setup(
wav, tmp_path, bypass, progress, monkeypatch, suffix
):
+ # Report logs are timestamped and uniquified in the shared logs directory,
+ # so only audio outputs can collide with a non-file.
source = wav()
original = source.read_bytes()
target = tmp_path / "master.wav"
- nonfile = target.with_suffix(suffix) if suffix != ".report.json" else pipeline.report_for(target)
+ nonfile = target.with_suffix(suffix)
nonfile.parent.mkdir(parents=True, exist_ok=True)
nonfile.mkdir()
bypass.mp3 = True
@@ -287,8 +296,5 @@ def test_nonfile_output_with_overwrite_fails_before_tool_setup(
pipeline.process(source, target, bypass, progress, overwrite=True)
assert nonfile.is_dir()
assert list(nonfile.iterdir()) == []
- if suffix == ".report.json":
- assert {path.name for path in tmp_path.iterdir()} == {source.name, "logs"}
- else:
- assert set(tmp_path.iterdir()) == {source, nonfile}
+ assert set(tmp_path.iterdir()) == {source, nonfile}
assert source.read_bytes() == original