Coverage for tests / unit / parsers / pydoclint_parser / test_field_extraction.py: 100%
39 statements
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2026-04-03 18:53 +0000
1"""Tests for pydoclint parser field extraction."""
3from __future__ import annotations
5import pytest
6from assertpy import assert_that
8from lintro.parsers.pydoclint.pydoclint_parser import parse_pydoclint_output
10from .conftest import make_issue, make_pydoclint_output
13@pytest.mark.parametrize(
14 ("code", "message"),
15 [
16 ("DOC101", "Function `foo` has 1 argument(s) in signature: ['x']"),
17 ("DOC102", "Function `foo` has 2 argument(s) in docstring"),
18 ("DOC103", "Argument `y` does not exist in `foo`'s signature"),
19 ("DOC201", "Function `foo` does not have a return section"),
20 ("DOC202", "Function `foo` has return type, but no return section"),
21 ("DOC301", "Function `foo` does not have a Raises section"),
22 ("DOC401", "Class `Foo` has 1 attribute(s) in docstring"),
23 ("DOC501", "Function `foo` has raises section but no raises in body"),
24 ("DOC502", "Function `foo` raises ValueError but does not document it"),
25 ],
26 ids=[
27 "DOC101_missing_arg",
28 "DOC102_extra_arg",
29 "DOC103_nonexistent_arg",
30 "DOC201_no_return_section",
31 "DOC202_return_type_no_section",
32 "DOC301_no_raises_section",
33 "DOC401_class_attributes",
34 "DOC501_raises_section_no_raises",
35 "DOC502_undocumented_raises",
36 ],
37)
38def test_parse_doc_codes(code: str, message: str) -> None:
39 """Parse issues with different DOC codes.
41 Args:
42 code: The expected DOC code.
43 message: The expected message.
44 """
45 output = make_pydoclint_output([make_issue(code=code, message=message)])
46 result = parse_pydoclint_output(output=output)
48 assert_that(result).is_length(1)
49 assert_that(result[0].code).is_equal_to(code)
50 assert_that(result[0].message).is_equal_to(message)
53def test_parse_extracts_all_fields() -> None:
54 """Parse issue extracts all fields correctly.
56 Note: pydoclint doesn't report column information, so column is always 0.
57 """
58 output = make_pydoclint_output(
59 [
60 make_issue(
61 file="src/module.py",
62 line=42,
63 column=0, # pydoclint doesn't report columns
64 code="DOC101",
65 message="Function `calculate` has 2 argument(s) in signature",
66 ),
67 ],
68 )
69 result = parse_pydoclint_output(output=output)
71 assert_that(result).is_length(1)
72 issue = result[0]
73 assert_that(issue.file).is_equal_to("src/module.py")
74 assert_that(issue.line).is_equal_to(42)
75 assert_that(issue.column).is_equal_to(0) # pydoclint doesn't report columns
76 assert_that(issue.code).is_equal_to("DOC101")
77 assert_that(issue.message).is_equal_to(
78 "Function `calculate` has 2 argument(s) in signature",
79 )
82def test_parse_multiple_issues() -> None:
83 """Parse multiple issues from output."""
84 output = make_pydoclint_output(
85 [
86 make_issue(file="test1.py", line=10, code="DOC101"),
87 make_issue(file="test2.py", line=20, code="DOC201"),
88 make_issue(file="test3.py", line=30, code="DOC301"),
89 ],
90 )
91 result = parse_pydoclint_output(output=output)
93 assert_that(result).is_length(3)
94 assert_that(result[0].file).is_equal_to("test1.py")
95 assert_that(result[0].code).is_equal_to("DOC101")
96 assert_that(result[1].file).is_equal_to("test2.py")
97 assert_that(result[1].code).is_equal_to("DOC201")
98 assert_that(result[2].file).is_equal_to("test3.py")
99 assert_that(result[2].code).is_equal_to("DOC301")
102def test_parse_nested_path() -> None:
103 """Parse issue with nested file path."""
104 output = """src/utils/helpers/formatter.py
105 100: DOC101: Test message"""
106 result = parse_pydoclint_output(output=output)
108 assert_that(result).is_length(1)
109 assert_that(result[0].file).is_equal_to("src/utils/helpers/formatter.py")
110 assert_that(result[0].line).is_equal_to(100)
111 assert_that(result[0].column).is_equal_to(0) # pydoclint doesn't report columns