import pytest from agentci.engine.commands import CommandError, parse_command, resolve_job_kind from agentci.engine.model import CommandName, JobKind def test_ignores_non_commands() -> None: assert parse_command("please run /agent plan") is None @pytest.mark.parametrize( ("name", "is_pull_request", "expected_kind"), [ (CommandName.PLAN, False, JobKind.PLAN), (CommandName.DISCUSS, False, JobKind.DISCUSS), (CommandName.IMPLEMENT, False, JobKind.IMPLEMENT), (CommandName.ITERATE, False, JobKind.ITERATE_PLAN), (CommandName.ITERATE, True, JobKind.ITERATE_IMPLEMENT), (CommandName.FIX, True, JobKind.FIX), ], ) def test_supported_commands_parse_and_resolve( name: CommandName, is_pull_request: bool, expected_kind: JobKind, ) -> None: command = parse_command(f"/agent {name.value}\nfocus on the API\nand add tests") assert command is not None assert (command.name, command.message) == ( name, "focus on the API\nand add tests", ) assert resolve_job_kind(command, is_pull_request=is_pull_request) is expected_kind @pytest.mark.parametrize( ("separator", "line_breaks"), [("\n", 1), ("\n", 2), ("\n", 5), ("\r\n", 3)], ) def test_multiline_messages_accept_line_separators( separator: str, line_breaks: int, ) -> None: message = f"focus on the API{separator}and add tests" command = parse_command(f"/agent {CommandName.PLAN.value}{separator * line_breaks}{message}") assert command is not None assert (command.name, command.message) == (CommandName.PLAN, message) def test_discuss_requires_message() -> None: with pytest.raises(CommandError, match="requires a message"): parse_command("/agent discuss") @pytest.mark.parametrize( ("name", "is_pull_request", "error_match"), [ (CommandName.FIX, False, "pull request"), (CommandName.PLAN, True, "issue"), (CommandName.DISCUSS, True, "issue"), (CommandName.IMPLEMENT, True, "issue"), ], ) def test_rejects_wrong_location( name: CommandName, is_pull_request: bool, error_match: str, ) -> None: command = parse_command(f"/agent {name.value} details") assert command is not None with pytest.raises(CommandError, match=error_match): resolve_job_kind(command, is_pull_request=is_pull_request) @pytest.mark.parametrize( ("body", "message"), [ ("/agent iterate", ""), ("/agent iterate refine tests", "refine tests"), ], ) def test_iterate_accepts_optional_message(body: str, message: str) -> None: command = parse_command(body) assert command is not None assert command.name is CommandName.ITERATE assert command.message == message