Skip to content

Commit c1a7ee0

Browse files
author
Andreas Ritter
committed
Add test for new formatting option.
1 parent 40f0e78 commit c1a7ee0

File tree

3 files changed

+95
-19
lines changed

3 files changed

+95
-19
lines changed

src/openapi_python_generator/common.py

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ class Formatter(str, Enum):
2828
BLACK = "black"
2929
NONE = "none"
3030

31+
class FormatOptions:
32+
skip_validation: bool = False
33+
line_length: int = 120
34+
3135

3236
library_config_dict: Dict[Optional[HTTPLibrary], LibraryConfig] = {
3337
HTTPLibrary.httpx: LibraryConfig(

src/openapi_python_generator/generate_data.py

+11-16
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from openapi_pydantic.v3.v3_0 import OpenAPI
1616
from pydantic import ValidationError
1717

18-
from .common import Formatter, HTTPLibrary, PydanticVersion
18+
from .common import FormatOptions, Formatter, HTTPLibrary, PydanticVersion
1919
from .common import library_config_dict
2020
from .language_converters.python.generator import generator
2121
from .language_converters.python.jinja_config import SERVICE_TEMPLATE
@@ -30,29 +30,24 @@ def write_code(path: Path, content: str, formatter: Formatter) -> None:
3030
:param content: The content to write.
3131
:param formatter: The formatter applied to the code written.
3232
"""
33-
try:
34-
with open(path, "w") as f:
35-
if formatter == Formatter.BLACK:
36-
formatted_contend = format_using_black(content)
37-
elif formatter == Formatter.NONE:
38-
formatted_contend = content
39-
else:
40-
raise NotImplementedError(
41-
f"Missing implementation for formatter {formatter!r}."
42-
)
43-
f.write(formatted_contend)
44-
except Exception as e:
45-
raise e
33+
if formatter == Formatter.BLACK:
34+
formatted_contend = format_using_black(content)
35+
elif formatter == Formatter.NONE:
36+
formatted_contend = content
37+
else:
38+
raise NotImplementedError(f"Missing implementation for formatter {formatter!r}.")
39+
with open(path, "w") as f:
40+
f.write(formatted_contend)
4641

4742

4843
def format_using_black(content: str) -> str:
4944
try:
5045
formatted_contend = black.format_file_contents(
51-
content, fast=False, mode=black.FileMode(line_length=120)
46+
content, fast=FormatOptions.skip_validation, mode=black.FileMode(line_length=FormatOptions.line_length)
5247
)
5348
except NothingChanged:
5449
return content
55-
return isort.code(formatted_contend, line_length=120)
50+
return isort.code(formatted_contend, line_length=FormatOptions.line_length)
5651

5752

5853
def get_open_api(source: Union[str, Path]) -> OpenAPI:

tests/test_generate_data.py

+80-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
from pathlib import Path
12
import shutil
3+
import subprocess
24

35
import pytest
46
import yaml
57
from httpx import ConnectError
68
from orjson import orjson
79
from pydantic import ValidationError
810

9-
from openapi_python_generator.common import HTTPLibrary
11+
from openapi_python_generator.common import FormatOptions, Formatter, HTTPLibrary
1012
from openapi_python_generator.common import library_config_dict
1113
from openapi_python_generator.generate_data import generate_data
1214
from openapi_python_generator.generate_data import get_open_api
@@ -66,7 +68,7 @@ def test_generate_data(model_data_with_cleanup):
6668

6769
def test_write_data(model_data_with_cleanup):
6870
result = generator(model_data_with_cleanup, library_config_dict[HTTPLibrary.httpx])
69-
write_data(result, test_result_path)
71+
write_data(result, test_result_path, Formatter.BLACK)
7072

7173
assert test_result_path.exists()
7274
assert test_result_path.is_dir()
@@ -90,7 +92,7 @@ def test_write_data(model_data_with_cleanup):
9092
model_data_copy.paths = None
9193

9294
result = generator(model_data_copy, library_config_dict[HTTPLibrary.httpx])
93-
write_data(result, test_result_path)
95+
write_data(result, test_result_path, Formatter.BLACK)
9496

9597
assert test_result_path.exists()
9698
assert test_result_path.is_dir()
@@ -105,3 +107,78 @@ def test_write_data(model_data_with_cleanup):
105107
assert (test_result_path / "models" / "__init__.py").is_file()
106108
assert (test_result_path / "__init__.py").exists()
107109
assert (test_result_path / "__init__.py").is_file()
110+
111+
def test_write_formatted_data(model_data_with_cleanup):
112+
result = generator(model_data_with_cleanup, library_config_dict[HTTPLibrary.httpx])
113+
114+
# First write code without formatter
115+
write_data(result, test_result_path, Formatter.NONE)
116+
117+
assert test_result_path.exists()
118+
assert test_result_path.is_dir()
119+
assert (test_result_path / "api_config.py").exists()
120+
assert (test_result_path / "models").exists()
121+
assert (test_result_path / "models").is_dir()
122+
assert (test_result_path / "services").exists()
123+
assert (test_result_path / "services").is_dir()
124+
assert (test_result_path / "models" / "__init__.py").exists()
125+
assert (test_result_path / "services" / "__init__.py").exists()
126+
assert (test_result_path / "services" / "__init__.py").is_file()
127+
assert (test_result_path / "models" / "__init__.py").is_file()
128+
assert (test_result_path / "__init__.py").exists()
129+
assert (test_result_path / "__init__.py").is_file()
130+
131+
assert not files_are_black_formatted(test_result_path)
132+
133+
# delete test_result_path folder
134+
shutil.rmtree(test_result_path)
135+
136+
model_data_copy = model_data_with_cleanup.copy()
137+
model_data_copy.components = None
138+
model_data_copy.paths = None
139+
140+
result = generator(model_data_copy, library_config_dict[HTTPLibrary.httpx])
141+
write_data(result, test_result_path, Formatter.BLACK)
142+
143+
assert test_result_path.exists()
144+
assert test_result_path.is_dir()
145+
assert (test_result_path / "api_config.py").exists()
146+
assert (test_result_path / "models").exists()
147+
assert (test_result_path / "models").is_dir()
148+
assert (test_result_path / "services").exists()
149+
assert (test_result_path / "services").is_dir()
150+
assert (test_result_path / "models" / "__init__.py").exists()
151+
assert (test_result_path / "services" / "__init__.py").exists()
152+
assert (test_result_path / "services" / "__init__.py").is_file()
153+
assert (test_result_path / "models" / "__init__.py").is_file()
154+
assert (test_result_path / "__init__.py").exists()
155+
assert (test_result_path / "__init__.py").is_file()
156+
157+
assert files_are_black_formatted(test_result_path)
158+
159+
def files_are_black_formatted(test_result_path: Path) -> bool:
160+
# Run the `black --check` command on all files. This does not write any file.
161+
result = subprocess.run([
162+
"black",
163+
"--check",
164+
# Overwrite any exclusion due to a .gitignore.
165+
"--exclude", "''",
166+
# Settings also used when formatting the code when writing it
167+
"--fast" if FormatOptions.skip_validation else "--safe",
168+
"--line-length", str(FormatOptions.line_length),
169+
# The source directory
170+
str(test_result_path.absolute())
171+
],
172+
capture_output=True,
173+
text=True
174+
)
175+
176+
# With `--check` the return status has the following meaning:
177+
# - Return code 0 means nothing would change.
178+
# - Return code 1 means some files would be reformatted.
179+
# - Return code 123 means there was an internal error.
180+
181+
if result.returncode == 123:
182+
result.check_returncode # raise the error
183+
184+
return result.returncode == 0

0 commit comments

Comments
 (0)