diff --git a/src/clipstick/_clipstick.py b/src/clipstick/_clipstick.py index e4005b1..1705b91 100644 --- a/src/clipstick/_clipstick.py +++ b/src/clipstick/_clipstick.py @@ -9,7 +9,11 @@ DUMMY_ENTRY_POINT: Final[str] = "my-cli-app" -def parse(model: type[TPydanticModel], args: list[str] | None = None) -> TPydanticModel: +def parse( + model: type[TPydanticModel], + args: list[str] | None = None, + entry_point: str | None = None, +) -> TPydanticModel: """Create an instance of the provided model. Leave `args` to None in production. Only use it for testing. @@ -19,6 +23,9 @@ def parse(model: type[TPydanticModel], args: list[str] | None = None) -> TPydant args: The list of arguments. This is useful for testing. Provide a list and check if your model is parsed correctly. If not provided clipstick will evaluate the arguments from `sys.argv`. + entry_point: Entry point name. This is useful for testing. + Provide an entry point name and check for value in help output. + If not provided clipstick will evaluate an entry point from `sys.argv`. Returns: An instance of the pydantic class we provided as argument populated with the provided args. @@ -30,7 +37,7 @@ def parse(model: type[TPydanticModel], args: list[str] | None = None) -> TPydant sys.exit(1) if args is None: entry_point, args = sys.argv[0], sys.argv[1:] - else: + elif entry_point is None: # Normally the first item in your sys.argv is the command/entrypoint you've entered. # During testing you don't provide that (only the actual arguments you enter after that). entry_point = DUMMY_ENTRY_POINT diff --git a/tests/conftest.py b/tests/conftest.py index e8a7a64..7d3e4f4 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -17,11 +17,13 @@ def __init__(self, fixture_request) -> None: self.captured_output: str | None = None self._fixture_request = fixture_request - def __call__(self, model: type[BaseModel], args: list[str]) -> None: + def __call__( + self, model: type[BaseModel], args: list[str], entry_point: str | None = None + ) -> None: try: console.width = 1000 console.record = True - parse(model, args) + parse(model, args, entry_point) finally: self.captured_output = console.export_text(clear=False) diff --git a/tests/help_output/test_help_command_name/test_command_name_from_args.png b/tests/help_output/test_help_command_name/test_command_name_from_args.png new file mode 100644 index 0000000..4e15920 Binary files /dev/null and b/tests/help_output/test_help_command_name/test_command_name_from_args.png differ diff --git a/tests/help_output/test_help_command_name/test_command_name_from_args.txt b/tests/help_output/test_help_command_name/test_command_name_from_args.txt new file mode 100644 index 0000000..eff844b --- /dev/null +++ b/tests/help_output/test_help_command_name/test_command_name_from_args.txt @@ -0,0 +1,7 @@ + +Usage: my-app [Arguments] + +A simple model. Main description. + +Arguments: + my-name A snake cased argument. [str] diff --git a/tests/test_help_command_name.py b/tests/test_help_command_name.py index baec24f..0213736 100644 --- a/tests/test_help_command_name.py +++ b/tests/test_help_command_name.py @@ -18,3 +18,11 @@ def test_command_name(entrypoint, monkeypatch, capture_output): capture_output(SimpleModel, ["-h"]) assert "Usage: my-app [Arguments]" in capture_output.captured_output + + +@pytest.mark.parametrize("entrypoint", ["/test/my-app", "\\test\\my-app", "my-app"]) +def test_command_name_from_args(entrypoint, monkeypatch, capture_output): + with pytest.raises(SystemExit): + capture_output(SimpleModel, ["-h"], entrypoint) + + assert "Usage: my-app [Arguments]" in capture_output.captured_output