[docs] 1# @Test suite for needextend RST generation from extracted markers, TEST_WRITE_1, test, [IMPL_CLI_WRITE]
2from pathlib import Path
3
4import pytest
5
6from sphinx_codelinks.analyse.analyse import SourceAnalyse
7from sphinx_codelinks.analyse.models import MarkedContentType
8from sphinx_codelinks.config import SourceAnalyseConfig
9from sphinx_codelinks.needextend_write import (
10 MarkedContentSchema,
11 convert_marked_content,
12)
13
14
15@pytest.mark.parametrize(
16 ("markers", "texts"),
17 [
18 (
19 [
20 {
21 "filepath": "/home/jui-wen/git_repo/ub/sphinx-codelinks/tests/data/need_id_refs/dummy_1.cpp",
22 "remote_url": "https://github.com/useblocks/sphinx-codelinks/blob/main/tests/data/need_id_refs/dummy_1.cpp#L3",
23 "source_map": {
24 "start": {"row": 2, "column": 13},
25 "end": {"row": 2, "column": 51},
26 },
27 "tagged_scope": "void dummy_func1(){\n //...\n }",
28 "need_ids": ["NEED_001", "NEED_002", "NEED_003", "NEED_004"],
29 "marker": "@need-ids:",
30 "type": "need-id-refs",
31 },
32 ],
33 [
34 ".. needextend:: NEED_001\n :remote-url: https://github.com/useblocks/sphinx-codelinks/blob/main/tests/data/need_id_refs/dummy_1.cpp#L3\n\n",
35 ".. needextend:: NEED_002\n :remote-url: https://github.com/useblocks/sphinx-codelinks/blob/main/tests/data/need_id_refs/dummy_1.cpp#L3\n\n",
36 ".. needextend:: NEED_003\n :remote-url: https://github.com/useblocks/sphinx-codelinks/blob/main/tests/data/need_id_refs/dummy_1.cpp#L3\n\n",
37 ".. needextend:: NEED_004\n :remote-url: https://github.com/useblocks/sphinx-codelinks/blob/main/tests/data/need_id_refs/dummy_1.cpp#L3\n\n",
38 ],
39 ),
40 (
41 [
42 {
43 "filepath": "/home/jui-wen/git_repo/ub/sphinx-codelinks/tests/data/need_id_refs/dummy_1.cpp",
44 "remote_url": "https://github.com/useblocks/sphinx-codelinks/blob/main/tests/data/need_id_refs/dummy_1.cpp#L3",
45 "source_map": {
46 "start": {"row": 2, "column": 13},
47 "end": {"row": 2, "column": 51},
48 },
49 "tagged_scope": "void dummy_func1(){\n //...\n }",
50 "need_ids": ["NEED_001"],
51 "marker": "@need-ids:",
52 "type": "need-id-refs",
53 },
54 {
55 "filepath": "/home/jui-wen/git_repo/ub/sphinx-codelinks/tests/data/need_id_refs/dummy_1.cpp",
56 "remote_url": "https://github.com/useblocks/sphinx-codelinks/blob/main/tests/data/need_id_refs/dummy_1.cpp#L10",
57 "source_map": {
58 "start": {"row": 2, "column": 13},
59 "end": {"row": 2, "column": 51},
60 },
61 "tagged_scope": "void dummy_func1(){\n //...\n }",
62 "need_ids": ["NEED_001"],
63 "marker": "@need-ids:",
64 "type": "need-id-refs",
65 },
66 ],
67 [
68 ".. needextend:: NEED_001\n :remote-url: https://github.com/useblocks/sphinx-codelinks/blob/main/tests/data/need_id_refs/dummy_1.cpp#L3,https://github.com/useblocks/sphinx-codelinks/blob/main/tests/data/need_id_refs/dummy_1.cpp#L10\n\n"
69 ],
70 ),
71 ],
72)
73def test_convert_marked_content(markers, texts):
74 # Normalize line endings
75 texts = [line.replace("\r\n", "\n").replace("\r", "\n") for line in texts]
76 needextend_texts, errors = convert_marked_content(markers)
77
78 assert not errors
79
80 assert needextend_texts == texts
81
82
83def test_convert_marked_content_ignores_multiline_needs() -> None:
84 """``write rst`` converts the references only: a multi-line need record is valid
85 input and yields nothing."""
86 markers = [
87 {
88 "filepath": "src/demo.cpp",
89 "remote_url": None,
90 "source_map": {
91 "start": {"row": 0, "column": 3},
92 "end": {"row": 5, "column": 11},
93 },
94 "tagged_scope": None,
95 "type": "multiline-need",
96 "need": {"type": "impl", "title": "Demo", "content": "", "doctype": ".rst"},
97 "markup": "rst",
98 "source": {"project": "p", "path": "src/demo.cpp", "root": "git"},
99 },
100 {
101 "filepath": "src/demo.cpp",
102 "remote_url": "https://example.com/src/demo.cpp#L8",
103 "source_map": {
104 "start": {"row": 7, "column": 13},
105 "end": {"row": 7, "column": 21},
106 },
107 "tagged_scope": None,
108 "need_ids": ["NEED_001"],
109 "marker": "@need-ids:",
110 "type": "need-id-refs",
111 },
112 ]
113
114 needextend_texts, errors = convert_marked_content(markers)
115
116 assert not errors
117 assert needextend_texts == [
118 ".. needextend:: NEED_001\n :remote-url: https://example.com/src/demo.cpp#L8\n\n"
119 ]
120
121
122def test_a_multiline_need_record_needs_its_need() -> None:
123 schema = MarkedContentSchema(
124 filepath="src/demo.cpp",
125 remote_url=None,
126 source_map={"start": {"row": 0, "column": 0}, "end": {"row": 1, "column": 0}},
127 tagged_scope=None,
128 type=MarkedContentType.multiline_need,
129 )
130
131 assert schema.check_conditional_required_fields() == [
132 "Need definition is required for marked content of type 'multiline-need'"
133 ]
134
135
136def test_convert_marked_content_reads_the_records_analyse_writes(
137 tmp_path: Path,
138) -> None:
139 """Every key ``codelinks analyse`` writes for a reference is one ``write rst``
140 accepts: a key the schema lacks makes it drop the record with an error. The records
141 carry the attached entity, ``scope``, since the analysis names it."""
142 source = tmp_path / "demo.cpp"
143 source.write_text(
144 "// @need-ids: NEED_001\nvoid demo() {}\n// @need-ids: NEED_002\n",
145 encoding="utf-8",
146 )
147 analyse = SourceAnalyse(
148 SourceAnalyseConfig(src_files=[source], src_dir=tmp_path, get_need_id_refs=True)
149 )
150 analyse.git_remote_url = None
151 analyse.git_commit_rev = None
152 analyse.run()
153 records = [item.to_dict() for item in analyse.all_marked_content]
154 assert [record["scope"] for record in records] == [
155 {
156 "kind": "function_definition",
157 "start": 2,
158 "end": 2,
159 "language": "cpp",
160 "entity_kind": "function",
161 "qualified_name": "demo",
162 "semantic": [{"kind": "function", "name": "demo"}],
163 "mechanism": "leading",
164 },
165 None,
166 ]
167 for record in records:
168 record["remote_url"] = (
169 f"https://example.com/demo.cpp#L{record['source_map']['start']['row'] + 1}"
170 )
171
172 needextend_texts, errors = convert_marked_content(records)
173
174 assert not errors
175 assert needextend_texts == [
176 ".. needextend:: NEED_001\n :remote-url: https://example.com/demo.cpp#L1\n\n",
177 ".. needextend:: NEED_002\n :remote-url: https://example.com/demo.cpp#L3\n\n",
178 ]