Skip to content

Commit f17220b

Browse files
authored
Merge pull request #137 from mdevolde/tests
docs: separated tests in files, added doc and typing, moved cli tests from bash to python
2 parents 22551c8 + 21efc19 commit f17220b

18 files changed

+757
-497
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,7 @@ jobs:
5252
5353
- name: Test with pytest
5454
run: |
55-
pytest -vx --dist=loadfile -n auto
56-
57-
- name: Run additional tests in bash scripts for Ubuntu
58-
run: |
59-
bash tests/test_local.bash
60-
bash tests/test_remote.bash
55+
pytest --dist=loadfile -n auto
6156
6257
lint:
6358
name: Lint with Ruff

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ check:
1111

1212
test:
1313
pytest
14-
14+
uvx --with defusedxml genbadge coverage --input-file coverage.xml --silent
1515
doc:
1616
source ./.venv/bin/activate && uv run sphinx-apidoc -o docs/source/references language_tool_python
1717
source ./.venv/bin/activate && cd ./docs && make html

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
[![language tool python on pypi](https://badge.fury.io/py/language-tool-python.svg)](https://pypi.org/project/language-tool-python/)
44
[![Documentation Status](https://readthedocs.org/projects/language-tool-python/badge/?version=latest)](https://language-tool-python.readthedocs.io/en/latest/)
55
[![Test with PyTest](https://github.com/jxmorris12/language_tool_python/workflows/Test%20with%20PyTest/badge.svg)](https://github.com/jxmorris12/language_tool_python/actions)
6+
[![Coverage Status](./coverage-badge.svg)](https://github.com/jxmorris12/language_tool_python/actions)
67
[![Downloads](https://static.pepy.tech/badge/language-tool-python)](https://pepy.tech/project/language-tool-python)
78
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](LICENSE)
89
[![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/jxmorris12/language_tool_python/pulls)

coverage-badge.svg

Lines changed: 1 addition & 0 deletions
Loading

language_tool_python/__main__.py

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from importlib.metadata import PackageNotFoundError, version
1111
from logging.config import dictConfig
1212
from pathlib import Path
13-
from typing import Any, Optional, Set, Union
13+
from typing import Any, Optional, Sequence, Set, Union
1414

1515
import toml
1616

@@ -37,7 +37,7 @@
3737
dictConfig(log_config)
3838

3939

40-
def parse_args() -> argparse.Namespace:
40+
def parse_args(argv: Optional[Sequence[str]] = None) -> argparse.Namespace:
4141
"""
4242
Parse command line arguments.
4343
@@ -121,7 +121,7 @@ def parse_args() -> argparse.Namespace:
121121
parser.add_argument("--remote-port", help="port of the remote LanguageTool server")
122122
parser.add_argument("--verbose", action="store_true", help="enable verbose output")
123123

124-
args = parser.parse_args()
124+
args = parser.parse_args(argv)
125125

126126
if args.enabled_only:
127127
if args.disable:
@@ -219,14 +219,14 @@ def print_exception(exc: Exception, debug: bool) -> None:
219219
print(exc, file=sys.stderr)
220220

221221

222-
def main() -> int:
222+
def main(argv: Optional[Sequence[str]] = None) -> int:
223223
"""
224224
Main function to parse arguments, process files, and check text using LanguageTool.
225225
226226
:return: Exit status code
227227
:rtype: int
228228
"""
229-
args = parse_args()
229+
args = parse_args(argv)
230230

231231
if args.verbose:
232232
logging.getLogger().setLevel(logging.DEBUG)
@@ -237,16 +237,6 @@ def main() -> int:
237237
if len(args.files) > 1:
238238
print(filename, file=sys.stderr)
239239

240-
if filename == "-":
241-
filename = sys.stdin.fileno()
242-
encoding = args.encoding or (
243-
sys.stdin.encoding
244-
if sys.stdin.isatty()
245-
else locale.getpreferredencoding()
246-
)
247-
else:
248-
encoding = args.encoding or "utf-8"
249-
250240
remote_server = None
251241
if args.remote_host is not None:
252242
remote_server = args.remote_host
@@ -257,11 +247,27 @@ def main() -> int:
257247
mother_tongue=args.mother_tongue,
258248
remote_server=remote_server,
259249
) as lang_tool:
260-
try:
261-
text = get_text(filename, encoding, ignore=args.ignore_lines)
262-
except (UnicodeError, FileNotFoundError) as exception:
263-
print_exception(exception, args.verbose)
264-
continue
250+
if filename == "-":
251+
encoding = args.encoding or (
252+
sys.stdin.encoding
253+
if sys.stdin.isatty()
254+
else locale.getpreferredencoding()
255+
)
256+
raw = sys.stdin.read()
257+
if args.ignore_lines:
258+
text = "".join(
259+
"\n" if re.match(args.ignore_lines, line) else line
260+
for line in raw.splitlines(keepends=True)
261+
)
262+
else:
263+
text = raw
264+
else:
265+
encoding = args.encoding or "utf-8"
266+
try:
267+
text = get_text(filename, encoding, ignore=args.ignore_lines)
268+
except (UnicodeError, FileNotFoundError) as exception:
269+
print_exception(exception, args.verbose)
270+
continue
265271

266272
if not args.spell_check:
267273
lang_tool.disable_spellchecking()
@@ -302,4 +308,5 @@ def main() -> int:
302308
return status
303309

304310

305-
sys.exit(main())
311+
if __name__ == "__main__":
312+
raise SystemExit(main())

make.bat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ exit /b %errorlevel%
1919

2020
:test
2121
pytest
22+
uvx --with defusedxml genbadge coverage --input-file coverage.xml --silent
2223
exit /b %errorlevel%
2324

2425
:doc

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ select = ["F", "W", "I", "B", "SIM", "RET", "Q", "N", "S", "BLE"]
8080
"tests/*.py" = ["S101"]
8181

8282
[tool.mypy]
83-
files = ["language_tool_python"]
83+
files = ["language_tool_python", "tests"]
8484
strict = true
8585
warn_unused_ignores = true
8686
warn_redundant_casts = true

pytest.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[pytest]
2-
addopts = -ra --cov=language_tool_python --cov-report=html --cov-report=xml
2+
addopts = -vra --cov=language_tool_python --cov-report=html --cov-report=xml
33
testpaths = tests
44

55
[coverage:run]

tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Tests for language_tool_python package."""

tests/test_api_public.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""Tests for the public API functionality."""
2+
3+
from language_tool_python.exceptions import RateLimitError
4+
5+
6+
def test_remote_es() -> None:
7+
"""
8+
Test the public API with Spanish language text.
9+
This test verifies that the LanguageToolPublicAPI correctly identifies
10+
various errors in a Spanish text sample.
11+
12+
:raises AssertionError: If the detected matches do not match the expected output.
13+
"""
14+
import language_tool_python
15+
16+
try:
17+
with language_tool_python.LanguageToolPublicAPI("es") as tool:
18+
es_text = "Escriba un texto aquí. LanguageTool le ayudará a afrentar algunas dificultades propias de la escritura. Se a hecho un esfuerzo para detectar errores tipográficos, ortograficos y incluso gramaticales. También algunos errores de estilo, a grosso modo."
19+
matches = tool.check(es_text)
20+
assert (
21+
str(matches)
22+
== """[Match({'rule_id': 'AFRENTAR_DIFICULTADES', 'message': 'Confusión entre «afrontar» y «afrentar».', 'replacements': ['afrontar'], 'offset_in_context': 43, 'context': '...n texto aquí. LanguageTool le ayudará a afrentar algunas dificultades propias de la escr...', 'offset': 49, 'error_length': 8, 'category': 'INCORRECT_EXPRESSIONS', 'rule_issue_type': 'grammar', 'sentence': 'LanguageTool le ayudará a afrentar algunas dificultades propias de la escritura.'}), Match({'rule_id': 'PRON_HABER_PARTICIPIO', 'message': 'El v. ‘haber’ se escribe con hache.', 'replacements': ['ha'], 'offset_in_context': 43, 'context': '...ificultades propias de la escritura. Se a hecho un esfuerzo para detectar errores...', 'offset': 107, 'error_length': 1, 'category': 'MISSPELLING', 'rule_issue_type': 'misspelling', 'sentence': 'Se a hecho un esfuerzo para detectar errores tipográficos, ortograficos y incluso gramaticales.'}), Match({'rule_id': 'MORFOLOGIK_RULE_ES', 'message': 'Se ha encontrado un posible error ortográfico.', 'replacements': ['ortográficos', 'ortográficas', 'ortográfico', 'orográficos', 'ortografiaos', 'ortografíeos'], 'offset_in_context': 43, 'context': '...rzo para detectar errores tipográficos, ortograficos y incluso gramaticales. También algunos...', 'offset': 163, 'error_length': 12, 'category': 'TYPOS', 'rule_issue_type': 'misspelling', 'sentence': 'Se a hecho un esfuerzo para detectar errores tipográficos, ortograficos y incluso gramaticales.'}), Match({'rule_id': 'Y_E_O_U', 'message': 'Cuando precede a palabras que comienzan por ‘i’, la conjunción ‘y’ se transforma en ‘e’.', 'replacements': ['e'], 'offset_in_context': 43, 'context': '...ctar errores tipográficos, ortograficos y incluso gramaticales. También algunos e...', 'offset': 176, 'error_length': 1, 'category': 'GRAMMAR', 'rule_issue_type': 'grammar', 'sentence': 'Se a hecho un esfuerzo para detectar errores tipográficos, ortograficos y incluso gramaticales.'}), Match({'rule_id': 'GROSSO_MODO', 'message': 'Esta expresión latina se usa sin preposición.', 'replacements': ['grosso modo'], 'offset_in_context': 43, 'context': '...les. También algunos errores de estilo, a grosso modo.', 'offset': 235, 'error_length': 13, 'category': 'GRAMMAR', 'rule_issue_type': 'grammar', 'sentence': 'También algunos errores de estilo, a grosso modo.'})]"""
23+
)
24+
except RateLimitError:
25+
print("Rate limit error: skipping test about public API.")
26+
return

0 commit comments

Comments
 (0)