"""Tests for scripts/compose.py render CLI flags.""" import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).parents[1])) import pytest import argparse from unittest.mock import patch, MagicMock from scripts.compose import main as compose_main class TestRenderFlag: """Test --render and --render-output CLI arguments.""" def test_render_flag_defaults_to_false(self): """Without --render, the render flag should be False.""" parser = argparse.ArgumentParser() parser.add_argument("--render", action="store_true") parser.add_argument("--render-output", default=None) args = parser.parse_args([]) assert args.render is False def test_render_flag_true_when_provided(self): """With --render, the flag should be True.""" parser = argparse.ArgumentParser() parser.add_argument("--render", action="store_true") parser.add_argument("--render-output", default=None) args = parser.parse_args(["--render"]) assert args.render is True def test_render_output_defaults_to_none(self): """--render-output defaults to None when not provided.""" parser = argparse.ArgumentParser() parser.add_argument("--render", action="store_true") parser.add_argument("--render-output", default=None) args = parser.parse_args([]) assert args.render_output is None @patch("scripts.compose.render_project") @patch("scripts.compose.RPPBuilder") def test_render_triggers_render_project_call(self, mock_builder_cls, mock_render): """Calling main with --render invokes render_project.""" mock_builder = MagicMock() mock_builder_cls.return_value = mock_builder with patch("scripts.compose.SampleSelector") as mock_selector: mock_sel_instance = MagicMock() mock_sel_instance.select_one.return_value = None mock_selector.return_value = mock_sel_instance with patch("sys.argv", ["compose.py", "--genre", "reggaeton", "--render"]): compose_main() mock_render.assert_called_once() call_args = mock_render.call_args # First arg should be the .rpp path, second should be .wav path rpp_path = call_args[0][0] wav_path = call_args[0][1] assert rpp_path.endswith(".rpp") assert wav_path.endswith(".wav") @patch("scripts.compose.render_project") @patch("scripts.compose.RPPBuilder") def test_without_render_does_not_call_render_project(self, mock_builder_cls, mock_render): """Calling main without --render does NOT invoke render_project.""" mock_builder = MagicMock() mock_builder_cls.return_value = mock_builder with patch("scripts.compose.SampleSelector") as mock_selector: mock_sel_instance = MagicMock() mock_sel_instance.select_one.return_value = None mock_selector.return_value = mock_sel_instance with patch("sys.argv", ["compose.py", "--genre", "reggaeton"]): compose_main() mock_render.assert_not_called() @patch("scripts.compose.render_project") @patch("scripts.compose.RPPBuilder") def test_render_output_overrides_default_wav_path(self, mock_builder_cls, mock_render): """--render-output sets the WAV path explicitly.""" mock_builder = MagicMock() mock_builder_cls.return_value = mock_builder with patch("scripts.compose.SampleSelector") as mock_selector: mock_sel_instance = MagicMock() mock_sel_instance.select_one.return_value = None mock_selector.return_value = mock_sel_instance with patch("sys.argv", [ "compose.py", "--genre", "reggaeton", "--render", "--render-output", "output/my_render.wav" ]): compose_main() mock_render.assert_called_once() wav_path = mock_render.call_args[0][1] assert wav_path == "output/my_render.wav" @patch("scripts.compose.render_project") @patch("scripts.compose.RPPBuilder") def test_render_project_propagates_file_not_found_error(self, mock_builder_cls, mock_render): """FileNotFoundError from render_project is propagated to caller.""" mock_builder = MagicMock() mock_builder_cls.return_value = mock_builder mock_render.side_effect = FileNotFoundError("reaper.exe not found") with patch("scripts.compose.SampleSelector") as mock_selector: mock_sel_instance = MagicMock() mock_sel_instance.select_one.return_value = None mock_selector.return_value = mock_sel_instance with patch("sys.argv", [ "compose.py", "--genre", "reggaeton", "--render", ]): with pytest.raises(FileNotFoundError): compose_main()