Skip to content

Commit da451c2

Browse files
committed
fix(main): fix incorrect warning, cover main with tests
1 parent 50a1ceb commit da451c2

File tree

5 files changed

+184
-4
lines changed

5 files changed

+184
-4
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ __pycache__
55
.venv
66
.idea
77
.pytest_cache
8+
.coverage

astyle_py/__main__.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@
88
from .files_iter import iterate_files
99

1010

11+
# Called via entry_points
1112
def main():
13+
astyle_py_main(sys.argv[1:])
14+
15+
16+
def astyle_py_main(argv_array):
1217
try:
13-
args = parse_args(sys.argv[1:])
18+
args = parse_args(argv_array)
1419
except ValueError as e:
1520
print(str(e), file=sys.stderr)
1621
raise SystemExit(1)
@@ -20,7 +25,11 @@ def main():
2025
else:
2126
astyle_version = ASTYLE_COMPAT_VERSION
2227

23-
astyle = Astyle(version=astyle_version)
28+
try:
29+
astyle = Astyle(version=astyle_version)
30+
except ValueError as e:
31+
print(str(e), file=sys.stderr)
32+
raise SystemExit(1)
2433

2534
if args.version:
2635
print('astyle-py {} with Astyle v{}'.format(__version__, astyle.version()))
@@ -38,6 +47,7 @@ def diag(*args_):
3847
files_with_errors = 0
3948
files_formatted = 0
4049
for file_item in iterate_files(args):
50+
files_checked += 1
4151
fname = file_item.filename
4252
astyle.set_options(' '.join(file_item.astyle_options))
4353
with open(fname) as f:
@@ -58,6 +68,7 @@ def diag(*args_):
5868
files_with_errors += 1
5969

6070
if files_checked == 0:
71+
assert args.exclude_list or args.rules # otherwise we would have exited earlier
6172
diag(
6273
'No files checked, excluded by {}'.format(
6374
'--exclude/--exclude-list option'
@@ -74,6 +85,7 @@ def diag(*args_):
7485
if files_with_errors:
7586
diag('Formatting errors found in {} files'.format(files_with_errors))
7687
raise SystemExit(1)
88+
raise SystemExit(0)
7789

7890

7991
if __name__ == '__main__':

sample.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77

88

99
def main():
10-
# Create the formatter
11-
formatter = Astyle()
10+
# Create the formatter, optionally specifying the version of Astyle
11+
formatter = Astyle(version='3.4.7')
1212

1313
# Get the version of Astyle
1414
version: str = formatter.version()

setup.cfg

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ dev =
2929
pytest
3030
types-PyYAML
3131
pre-commit
32+
coverage
3233

3334
[options.package_data]
3435
astyle_py = lib/*/libastyle.wasm

test/test_main.py

+166
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# SPDX-FileCopyrightText: 2023 Ivan Grokhotkov <[email protected]>
2+
# SPDX-License-Identifier: MIT
3+
import pathlib
4+
5+
import pytest
6+
from test_files_iter import chdir_ctx
7+
8+
from astyle_py import __version__
9+
from astyle_py.__main__ import astyle_py_main
10+
11+
# tmp_path: pathlib.Path
12+
13+
14+
def test_main_version(capfd: pytest.CaptureFixture[str]):
15+
with pytest.raises(SystemExit) as e:
16+
astyle_py_main(['--version'])
17+
assert e.value.code == 0
18+
out, err = capfd.readouterr()
19+
assert out == f'astyle-py {__version__} with Astyle v3.1\n'
20+
assert err == ''
21+
22+
23+
def test_main_specific_version(capfd: pytest.CaptureFixture[str]):
24+
ver = '3.4.7'
25+
with pytest.raises(SystemExit) as e:
26+
astyle_py_main([f'--astyle-version={ver}', '--version'])
27+
assert e.value.code == 0
28+
out, err = capfd.readouterr()
29+
assert out == f'astyle-py {__version__} with Astyle v{ver}\n'
30+
assert err == ''
31+
32+
33+
def test_main_invalid_version(capfd: pytest.CaptureFixture[str]):
34+
ver = '1.2.3'
35+
with pytest.raises(SystemExit) as e:
36+
astyle_py_main([f'--astyle-version={ver}'])
37+
assert e.value.code == 1
38+
out, err = capfd.readouterr()
39+
assert out == ''
40+
assert f'Unsupported astyle version: {ver}. Available versions:' in err
41+
42+
43+
def test_main_option_requires_value(capfd: pytest.CaptureFixture[str]):
44+
with pytest.raises(SystemExit) as e:
45+
astyle_py_main(['--exclude'])
46+
assert e.value.code == 1
47+
out, err = capfd.readouterr()
48+
assert out == ''
49+
assert 'Option --exclude requires a value' in err
50+
51+
52+
def test_main_no_files(capfd: pytest.CaptureFixture[str]):
53+
with pytest.raises(SystemExit) as e:
54+
astyle_py_main([])
55+
assert e.value.code == 0
56+
out, err = capfd.readouterr()
57+
assert out == ''
58+
assert err == 'No files specified\n'
59+
60+
61+
def test_main_formatting_error_invalid_arg(
62+
capfd: pytest.CaptureFixture[str], tmp_path: pathlib.Path
63+
):
64+
base = str(tmp_path.absolute())
65+
(tmp_path / 'file_a.c').touch()
66+
67+
with chdir_ctx(base):
68+
with pytest.raises(SystemExit) as e:
69+
astyle_py_main(['--invalid-arg', 'file_a.c'])
70+
assert e.value.code == 1
71+
out, err = capfd.readouterr()
72+
assert out == ''
73+
assert (
74+
'Error formatting file_a.c: error: Invalid Artistic Style options:\n\tinvalid-arg\n'
75+
in err
76+
)
77+
78+
79+
def test_formatted_quiet(capfd: pytest.CaptureFixture[str], tmp_path: pathlib.Path):
80+
# Check in formatting mode (no --dry-run)
81+
base = str(tmp_path.absolute())
82+
(tmp_path / 'file_a.c').write_text('int main() { foo(); }\n')
83+
(tmp_path / 'file_b.c').write_text('int main()\n{\n foo();\n}\n')
84+
85+
with chdir_ctx(base):
86+
with pytest.raises(SystemExit) as e:
87+
astyle_py_main(['--style=otbs', '--quiet', 'file_a.c', 'file_b.c'])
88+
assert e.value.code == 0
89+
out, err = capfd.readouterr()
90+
assert out == ''
91+
assert err == ''
92+
93+
# first file formatted, 2nd unchanged
94+
assert (tmp_path / 'file_a.c').read_text() == 'int main()\n{\n foo();\n}\n'
95+
assert (tmp_path / 'file_b.c').read_text() == 'int main()\n{\n foo();\n}\n'
96+
97+
# Now check in --dry-run mode (no formatting)
98+
(tmp_path / 'file_a.c').write_text('int main() { foo(); }\n')
99+
(tmp_path / 'file_b.c').write_text('int main()\n{\n foo();\n}\n')
100+
101+
with chdir_ctx(base):
102+
with pytest.raises(SystemExit) as e:
103+
astyle_py_main(
104+
['--style=otbs', '--quiet', '--dry-run', 'file_a.c', 'file_b.c']
105+
)
106+
assert e.value.code == 1
107+
out, err = capfd.readouterr()
108+
assert out == ''
109+
assert err == ''
110+
111+
# Files should not be modified in dry-run mode
112+
assert (tmp_path / 'file_a.c').read_text() == 'int main() { foo(); }\n'
113+
assert (tmp_path / 'file_b.c').read_text() == 'int main()\n{\n foo();\n}\n'
114+
115+
116+
def test_formatted_verbose(capfd: pytest.CaptureFixture[str], tmp_path: pathlib.Path):
117+
base = str(tmp_path.absolute())
118+
(tmp_path / 'file_a.c').write_text('int main() { foo(); }\n')
119+
(tmp_path / 'file_b.c').write_text('int main()\n{\n foo();\n}\n')
120+
121+
with chdir_ctx(base):
122+
with pytest.raises(SystemExit) as e:
123+
astyle_py_main(['--style=otbs', 'file_a.c', 'file_b.c'])
124+
assert e.value.code == 0
125+
out, err = capfd.readouterr()
126+
assert out == ''
127+
assert 'Formatting file_a.c' in err
128+
assert 'Formatted 1 files' in err
129+
130+
assert (tmp_path / 'file_a.c').read_text() == 'int main()\n{\n foo();\n}\n'
131+
assert (tmp_path / 'file_b.c').read_text() == 'int main()\n{\n foo();\n}\n'
132+
133+
134+
def test_formatted_verbose_dry_run(
135+
capfd: pytest.CaptureFixture[str], tmp_path: pathlib.Path
136+
):
137+
base = str(tmp_path.absolute())
138+
(tmp_path / 'file_a.c').write_text('int main() { foo(); }\n')
139+
(tmp_path / 'file_b.c').write_text('int main()\n{\n foo();\n}\n')
140+
141+
with chdir_ctx(base):
142+
with pytest.raises(SystemExit) as e:
143+
astyle_py_main(['--style=otbs', '--dry-run', 'file_a.c', 'file_b.c'])
144+
assert e.value.code == 1
145+
out, err = capfd.readouterr()
146+
assert out == ''
147+
assert 'Formatting error in file_a.c' in err
148+
assert 'Formatting errors found in 1 files' in err
149+
150+
assert (tmp_path / 'file_a.c').read_text() == 'int main() { foo(); }\n'
151+
assert (tmp_path / 'file_b.c').read_text() == 'int main()\n{\n foo();\n}\n'
152+
153+
154+
def test_all_files_excluded_warning(
155+
capfd: pytest.CaptureFixture[str], tmp_path: pathlib.Path
156+
):
157+
base = str(tmp_path.absolute())
158+
(tmp_path / 'file_a.c').touch()
159+
160+
with chdir_ctx(base):
161+
with pytest.raises(SystemExit) as e:
162+
astyle_py_main(['--exclude=*.c', 'file_a.c'])
163+
assert e.value.code == 0
164+
out, err = capfd.readouterr()
165+
assert out == ''
166+
assert 'No files checked, excluded by --exclude/--exclude-list option' in err

0 commit comments

Comments
 (0)