Coverage for tests / test_types.py: 100%
109 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-11-09 00:15 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-11-09 00:15 +0000
1from enum import Enum 1abcdefg
3import pytest 1abcdefg
4import typer 1abcdefg
5from typer import _click 1abcdefg
6from typer.testing import CliRunner 1abcdefg
8app = typer.Typer(context_settings={"token_normalize_func": str.lower}) 1abcdefg
11class User(str, Enum): 1abcdefg
12 rick = "Rick" 1abcdefg
13 morty = "Morty" 1abcdefg
16@app.command() 1abcdefg
17def hello_option(name: User = User.rick) -> None: 1abcdefg
18 print(f"Hello {name.value}!") 1abcdefg
21@app.command() 1abcdefg
22def hello_argument(name: User) -> None: 1abcdefg
23 print(f"Hello {name.value}!") 1abcdefg
26@app.command() 1abcdefg
27def hello_no_choices( 1abcdefg
28 name: User = typer.Option(..., "--name", show_choices=False),
29):
30 print(f"Hello {name.value}!") 1abcdefg
33@app.command() 1abcdefg
34def hello_all_options(name: list[str] = typer.Option(["World"])) -> None: 1abcdefg
35 for n in name: 1abcdefg
36 print(f"Hello {n}!") 1abcdefg
39@app.command() 1abcdefg
40def hello_all_args(names: list[str] = typer.Argument(["World"])) -> None: 1abcdefg
41 for name in names: 1abcdefg
42 print(f"Hello {name}!") 1abcdefg
45@app.command() 1abcdefg
46def hello_all_envvar( 1abcdefg
47 names: list[str] = typer.Argument(["World"], envvar="NAMES"),
48) -> None:
49 for name in names: 1abcdefg
50 print(f"Hello {name}!") 1abcdefg
53@app.command() 1abcdefg
54def split_variadic_and_pair(items: list[str], pair: tuple[str, str]) -> None: 1abcdefg
55 print(f"items={items}") 1abcdefg
56 print(f"pair={pair}") 1abcdefg
59runner = CliRunner() 1abcdefg
62def test_enum_choice() -> None: 1abcdefg
63 result = runner.invoke( 1abcdefg
64 app, ["hello-option", "--name", "morty"], catch_exceptions=False
65 )
66 assert result.exit_code == 0 1abcdefg
67 assert "Hello Morty!" in result.output 1abcdefg
69 result = runner.invoke(app, ["hello-option", "--name", "Rick"]) 1abcdefg
70 assert result.exit_code == 0 1abcdefg
71 assert "Hello Rick!" in result.output 1abcdefg
73 result = runner.invoke(app, ["hello-option", "--name", "RICK"]) 1abcdefg
74 assert result.exit_code == 0 1abcdefg
75 assert "Hello Rick!" in result.output 1abcdefg
77 result = runner.invoke(app, ["hello-no-choices", "--name", "RICK"]) 1abcdefg
78 assert result.exit_code == 0 1abcdefg
79 assert "Hello Rick!" in result.output 1abcdefg
81 result = runner.invoke(app, ["hello-argument", "RICK"]) 1abcdefg
82 assert result.exit_code == 0 1abcdefg
83 assert "Hello Rick!" in result.output 1abcdefg
86def test_enum_choice_repr() -> None: 1abcdefg
87 root_command = typer.main.get_command(app) 1abcdefg
88 command = root_command.commands["hello-option"] 1abcdefg
89 name_param = next(param for param in command.params if param.name == "name") 1abcdefg
90 assert repr(name_param.type).startswith("Choice([") 1abcdefg
93def test_enum_choice_help() -> None: 1abcdefg
94 result = runner.invoke(app, ["hello-argument", "--help"]) 1abcdefg
95 assert result.exit_code == 0 1abcdefg
96 assert "<rick|morty>" in result.output 1abcdefg
98 result = runner.invoke(app, ["hello-option", "--help"]) 1abcdefg
99 assert result.exit_code == 0 1abcdefg
100 assert "<rick|morty>" in result.output 1abcdefg
102 result = runner.invoke(app, ["hello-no-choices", "--help"]) 1abcdefg
103 assert result.exit_code == 0 1abcdefg
104 assert "--name" in result.output 1abcdefg
105 assert "rick|morty" not in result.output 1abcdefg
108def test_enum_choice_missing_message() -> None: 1abcdefg
109 result = runner.invoke(app, ["hello-argument"]) 1abcdefg
110 assert result.exit_code != 0 1abcdefg
111 assert "Missing argument" in result.output 1abcdefg
112 assert "Choose from:" in result.output 1abcdefg
113 assert "rick" in result.output 1abcdefg
114 assert "morty" in result.output 1abcdefg
117def test_list() -> None: 1abcdefg
118 result = runner.invoke( 1abcdefg
119 app, ["hello-all-options", "--name", "Rick", "--name", "Morty"]
120 )
121 assert result.exit_code == 0 1abcdefg
122 assert "Hello World!" not in result.output 1abcdefg
123 assert "Hello Rick!" in result.output 1abcdefg
124 assert "Hello Morty!" in result.output 1abcdefg
126 result = runner.invoke(app, ["hello-all-args", "Rick", "Morty"]) 1abcdefg
127 assert result.exit_code == 0 1abcdefg
128 assert "Hello World!" not in result.output 1abcdefg
129 assert "Hello Rick!" in result.output 1abcdefg
130 assert "Hello Morty!" in result.output 1abcdefg
133def test_list_empty() -> None: 1abcdefg
134 result = runner.invoke(app, ["hello-all-args"]) 1abcdefg
135 assert result.exit_code == 0 1abcdefg
136 assert "Hello World!" in result.output 1abcdefg
138 result = runner.invoke(app, ["hello-all-options"]) 1abcdefg
139 assert result.exit_code == 0 1abcdefg
140 assert "Hello World!" in result.output 1abcdefg
142 result = runner.invoke(app, ["hello-all-envvar"]) 1abcdefg
143 assert result.exit_code == 0 1abcdefg
144 assert "Hello World!" in result.output 1abcdefg
147def test_split_envvar_value(monkeypatch) -> None: 1abcdefg
148 # This will use split_envvar_value to produce two strings from the envvar
149 monkeypatch.setenv("NAMES", "Rick Morty") 1abcdefg
150 result = runner.invoke(app, ["hello-all-envvar"]) 1abcdefg
151 assert result.exit_code == 0 1abcdefg
152 assert "Hello Rick!" in result.output 1abcdefg
153 assert "Hello Morty!" in result.output 1abcdefg
156def test_list_pair() -> None: 1abcdefg
157 result = runner.invoke(app, ["split-variadic-and-pair", "a", "b", "c", "x", "y"]) 1abcdefg
158 assert result.exit_code == 0 1abcdefg
159 assert "items=['a', 'b', 'c']" in result.output 1abcdefg
160 assert "pair=('x', 'y')" in result.output 1abcdefg
163def test_float_range_open_bounds_with_clamp_not_allowed(): 1abcdefg
164 with pytest.raises(TypeError, match="Clamping is not supported for open bounds."): 1abcdefg
165 _click.types.FloatRange(min=0.0, min_open=True, clamp=True) 1abcdefg