-
-
Notifications
You must be signed in to change notification settings - Fork 80
Expand file tree
/
Copy pathtest_cli_pyproject.py
More file actions
107 lines (83 loc) · 3.43 KB
/
test_cli_pyproject.py
File metadata and controls
107 lines (83 loc) · 3.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from pathlib import Path
from unittest.mock import patch
import uvicorn
from typer.testing import CliRunner
from fastapi_cli.cli import app
from tests.utils import changing_dir
runner = CliRunner()
assets_path = Path(__file__).parent / "assets"
def test_dev_with_pyproject_app_config_uses() -> None:
with (
changing_dir(assets_path / "pyproject_config"),
patch.object(uvicorn, "run") as mock_run,
):
result = runner.invoke(app, ["dev"])
assert result.exit_code == 0, result.output
assert mock_run.call_args.kwargs["app"] == "my_module:app"
assert mock_run.call_args.kwargs["host"] == "127.0.0.1"
assert mock_run.call_args.kwargs["port"] == 8000
assert mock_run.call_args.kwargs["reload"] is True
assert "Using import string: my_module:app" in result.output
assert "Configuration sources:" in result.output
assert "Import string: entrypoint in pyproject.toml" in result.output
def test_run_with_pyproject_app_config() -> None:
with (
changing_dir(assets_path / "pyproject_config"),
patch.object(uvicorn, "run") as mock_run,
):
result = runner.invoke(app, ["run"])
assert result.exit_code == 0, result.output
assert mock_run.call_args.kwargs["app"] == "my_module:app"
assert mock_run.call_args.kwargs["host"] == "0.0.0.0"
assert mock_run.call_args.kwargs["port"] == 8000
assert mock_run.call_args.kwargs["reload"] is False
assert "Using import string: my_module:app" in result.output
assert "Configuration sources:" in result.output
assert "Import string: entrypoint in pyproject.toml" in result.output
def test_cli_arg_overrides_pyproject_config() -> None:
with (
changing_dir(assets_path / "pyproject_config"),
patch.object(uvicorn, "run") as mock_run,
):
result = runner.invoke(app, ["dev", "another_module.py"])
assert result.exit_code == 0, result.output
assert mock_run.call_args.kwargs["app"] == "another_module:app"
assert "Configuration sources:" in result.output
assert "Module: path CLI argument" in result.output
assert "App name: auto-discovery" in result.output
def test_pyproject_app_config_invalid_format() -> None:
test_dir = assets_path / "pyproject_invalid_config"
test_dir.mkdir(exist_ok=True)
pyproject_file = test_dir / "pyproject.toml"
pyproject_file.write_text("""
[tool.fastapi]
entrypoint = "invalid_format_without_colon"
""")
try:
with changing_dir(test_dir):
result = runner.invoke(app, ["dev"])
assert result.exit_code == 1
assert (
"Import string must be in the format module.submodule:app_name"
in result.output
)
finally:
pyproject_file.unlink()
test_dir.rmdir()
def test_pyproject_validation_error() -> None:
test_dir = assets_path / "pyproject_validation_error"
test_dir.mkdir(exist_ok=True)
pyproject_file = test_dir / "pyproject.toml"
pyproject_file.write_text("""
[tool.fastapi]
entrypoint = 123
""")
try:
with changing_dir(test_dir):
result = runner.invoke(app, ["dev"])
assert result.exit_code == 1
assert "Invalid configuration in pyproject.toml:" in result.output
assert "entrypoint" in result.output.lower()
finally:
pyproject_file.unlink()
test_dir.rmdir()