clang-tools 22.0.0git
check_alphabetical_order_test.py
Go to the documentation of this file.
1# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2# See https://llvm.org/LICENSE.txt for license information.
3# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5# To run these tests:
6# python3 check_alphabetical_order_test.py -v
7
8import check_alphabetical_order as _mod
9from contextlib import redirect_stderr
10import io
11import os
12import tempfile
13import textwrap
14from typing import cast
15import unittest
16
17
18class TestAlphabeticalOrderCheck(unittest.TestCase):
20 input_text = textwrap.dedent(
21 """\
22 .. csv-table:: Clang-Tidy checks
23 :header: "Name", "Offers fixes"
24
25 :doc:`bugprone-virtual-near-miss <bugprone/virtual-near-miss>`, "Yes"
26 :doc:`cert-flp30-c <cert/flp30-c>`,
27 :doc:`abseil-cleanup-ctad <abseil/cleanup-ctad>`, "Yes"
28 A non-doc row that should stay after docs
29 """
30 )
31
32 expected_text = textwrap.dedent(
33 """\
34 .. csv-table:: Clang-Tidy checks
35 :header: "Name", "Offers fixes"
36
37 :doc:`abseil-cleanup-ctad <abseil/cleanup-ctad>`, "Yes"
38 :doc:`bugprone-virtual-near-miss <bugprone/virtual-near-miss>`, "Yes"
39 :doc:`cert-flp30-c <cert/flp30-c>`,
40 A non-doc row that should stay after docs
41 """
42 )
43
44 out_str = _mod.normalize_list_rst(input_text)
45 self.assertEqual(out_str, expected_text)
46
47 def test_find_heading(self) -> None:
48 text = textwrap.dedent(
49 """\
50 - Deprecated the :program:`clang-tidy` ``zircon`` module. All checks have been
51 moved to the ``fuchsia`` module instead. The ``zircon`` module will be removed
52 in the 24th release.
53
54 New checks
55 ^^^^^^^^^^
56 - New :doc:`bugprone-derived-method-shadowing-base-method
57 <clang-tidy/checks/bugprone/derived-method-shadowing-base-method>` check.
58 """
59 )
60 lines = text.splitlines(True)
61 idx = _mod.find_heading(lines, "New checks")
62 self.assertEqual(idx, 4)
63
65 # Ensure duplicate detection works properly when sorting is incorrect.
66 text = textwrap.dedent(
67 """\
68 Changes in existing checks
69 ^^^^^^^^^^^^^^^^^^^^^^^^^^
70
71 - Improved :doc:`bugprone-easily-swappable-parameters
72 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
73 correcting a spelling mistake on its option
74 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
75
76 - Improved :doc:`bugprone-exception-escape
77 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
78 exceptions from captures are now diagnosed, exceptions in the bodies of
79 lambdas that aren't actually invoked are not.
80
81 - Improved :doc:`bugprone-easily-swappable-parameters
82 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
83 correcting a spelling mistake on its option
84 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
85
86 """
87 )
88 lines = text.splitlines(True)
89 report = _mod._emit_duplicate_report(lines, "Changes in existing checks")
90 self.assertIsNotNone(report)
91 report_str = cast(str, report)
92
93 expected_report = textwrap.dedent(
94 """\
95 Error: Duplicate entries in 'Changes in existing checks':
96
97 -- Duplicate: - Improved :doc:`bugprone-easily-swappable-parameters
98
99 - At line 4:
100 - Improved :doc:`bugprone-easily-swappable-parameters
101 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
102 correcting a spelling mistake on its option
103 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
104
105 - At line 14:
106 - Improved :doc:`bugprone-easily-swappable-parameters
107 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
108 correcting a spelling mistake on its option
109 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
110 """
111 )
112 self.assertEqual(report_str, expected_report)
113
115 # When content is not normalized, the function writes normalized text and returns 0.
116 rn_text = textwrap.dedent(
117 """\
118 New checks
119 ^^^^^^^^^^
120
121 - New :doc:`readability-redundant-parentheses
122 <clang-tidy/checks/readability/redundant-parentheses>` check.
123
124 Detect redundant parentheses.
125
126 - New :doc:`bugprone-derived-method-shadowing-base-method
127 <clang-tidy/checks/bugprone/derived-method-shadowing-base-method>` check.
128
129 Finds derived class methods that shadow a (non-virtual) base class method.
130
131 """
132 )
133 with tempfile.TemporaryDirectory() as td:
134 rn_doc = os.path.join(td, "ReleaseNotes.rst")
135 out_path = os.path.join(td, "out.rst")
136 with open(rn_doc, "w", encoding="utf-8") as f:
137 f.write(rn_text)
138
139 buf = io.StringIO()
140 with redirect_stderr(buf):
141 rc = _mod.process_release_notes(out_path, rn_doc)
142
143 self.assertEqual(rc, 0)
144 with open(out_path, "r", encoding="utf-8") as f:
145 out = f.read()
146
147 expected_out = textwrap.dedent(
148 """\
149 New checks
150 ^^^^^^^^^^
151
152 - New :doc:`bugprone-derived-method-shadowing-base-method
153 <clang-tidy/checks/bugprone/derived-method-shadowing-base-method>` check.
154
155 Finds derived class methods that shadow a (non-virtual) base class method.
156
157 - New :doc:`readability-redundant-parentheses
158 <clang-tidy/checks/readability/redundant-parentheses>` check.
159
160 Detect redundant parentheses.
161
162
163 """
164 )
165
166 self.assertEqual(out, expected_out)
167 self.assertIn("not alphabetically sorted", buf.getvalue())
168
170 # Sorting is incorrect and duplicates exist, should report ordering issues first.
171 rn_text = textwrap.dedent(
172 """\
173 Changes in existing checks
174 ^^^^^^^^^^^^^^^^^^^^^^^^^^
175
176 - Improved :doc:`bugprone-easily-swappable-parameters
177 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
178 correcting a spelling mistake on its option
179 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
180
181 - Improved :doc:`bugprone-exception-escape
182 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
183 exceptions from captures are now diagnosed, exceptions in the bodies of
184 lambdas that aren't actually invoked are not.
185
186 - Improved :doc:`bugprone-easily-swappable-parameters
187 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
188 correcting a spelling mistake on its option
189 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
190
191 """
192 )
193 with tempfile.TemporaryDirectory() as td:
194 rn_doc = os.path.join(td, "ReleaseNotes.rst")
195 out_path = os.path.join(td, "out.rst")
196 with open(rn_doc, "w", encoding="utf-8") as f:
197 f.write(rn_text)
198
199 buf = io.StringIO()
200 with redirect_stderr(buf):
201 rc = _mod.process_release_notes(out_path, rn_doc)
202 self.assertEqual(rc, 0)
203 self.assertIn(
204 "Entries in 'clang-tools-extra/docs/ReleaseNotes.rst' are not alphabetically sorted.",
205 buf.getvalue(),
206 )
207
208 with open(out_path, "r", encoding="utf-8") as f:
209 out = f.read()
210 expected_out = textwrap.dedent(
211 """\
212 Changes in existing checks
213 ^^^^^^^^^^^^^^^^^^^^^^^^^^
214
215 - Improved :doc:`bugprone-easily-swappable-parameters
216 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
217 correcting a spelling mistake on its option
218 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
219
220 - Improved :doc:`bugprone-easily-swappable-parameters
221 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
222 correcting a spelling mistake on its option
223 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
224
225 - Improved :doc:`bugprone-exception-escape
226 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
227 exceptions from captures are now diagnosed, exceptions in the bodies of
228 lambdas that aren't actually invoked are not.
229
230
231 """
232 )
233 self.assertEqual(out, expected_out)
234
236 # Sorting is already correct but duplicates exist, should return 3 and report.
237 rn_text = textwrap.dedent(
238 """\
239 Changes in existing checks
240 ^^^^^^^^^^^^^^^^^^^^^^^^^^
241
242 - Improved :doc:`bugprone-easily-swappable-parameters
243 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
244 correcting a spelling mistake on its option
245 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
246
247 - Improved :doc:`bugprone-easily-swappable-parameters
248 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
249 correcting a spelling mistake on its option
250 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
251
252 - Improved :doc:`bugprone-exception-escape
253 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
254 exceptions from captures are now diagnosed, exceptions in the bodies of
255 lambdas that aren't actually invoked are not.
256
257 """
258 )
259 with tempfile.TemporaryDirectory() as td:
260 rn_doc = os.path.join(td, "ReleaseNotes.rst")
261 out_path = os.path.join(td, "out.rst")
262 with open(rn_doc, "w", encoding="utf-8") as f:
263 f.write(rn_text)
264
265 buf = io.StringIO()
266 with redirect_stderr(buf):
267 rc = _mod.process_release_notes(out_path, rn_doc)
268
269 self.assertEqual(rc, 3)
270 expected_report = textwrap.dedent(
271 """\
272 Error: Duplicate entries in 'Changes in existing checks':
273
274 -- Duplicate: - Improved :doc:`bugprone-easily-swappable-parameters
275
276 - At line 4:
277 - Improved :doc:`bugprone-easily-swappable-parameters
278 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
279 correcting a spelling mistake on its option
280 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
281
282 - At line 9:
283 - Improved :doc:`bugprone-easily-swappable-parameters
284 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
285 correcting a spelling mistake on its option
286 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
287
288 """
289 )
290 self.assertEqual(buf.getvalue(), expected_report)
291
292 with open(out_path, "r", encoding="utf-8") as f:
293 out = f.read()
294 self.assertEqual(out, rn_text)
295
297 rn_text = textwrap.dedent(
298 """\
299 Changes in existing checks
300 ^^^^^^^^^^^^^^^^^^^^^^^^^^
301
302 - Improved :doc:`bugprone-easily-swappable-parameters
303 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
304 correcting a spelling mistake on its option
305 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
306
307 - Improved :doc:`llvm-prefer-isa-or-dyn-cast-in-conditionals
308 <clang-tidy/checks/llvm/prefer-isa-or-dyn-cast-in-conditionals>` check:
309
310 - Fix-it handles callees with nested-name-specifier correctly.
311
312 - ``if`` statements with init-statement (``if (auto X = ...; ...)``) are
313 handled correctly.
314
315 - ``for`` loops are supported.
316
317 - Improved :doc:`bugprone-exception-escape
318 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
319 exceptions from captures are now diagnosed, exceptions in the bodies of
320 lambdas that aren't actually invoked are not.
321
322 """
323 )
324
325 out = _mod.normalize_release_notes(rn_text.splitlines(True))
326
327 expected_out = textwrap.dedent(
328 """\
329 Changes in existing checks
330 ^^^^^^^^^^^^^^^^^^^^^^^^^^
331
332 - Improved :doc:`bugprone-easily-swappable-parameters
333 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
334 correcting a spelling mistake on its option
335 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
336
337 - Improved :doc:`bugprone-exception-escape
338 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
339 exceptions from captures are now diagnosed, exceptions in the bodies of
340 lambdas that aren't actually invoked are not.
341
342 - Improved :doc:`llvm-prefer-isa-or-dyn-cast-in-conditionals
343 <clang-tidy/checks/llvm/prefer-isa-or-dyn-cast-in-conditionals>` check:
344
345 - Fix-it handles callees with nested-name-specifier correctly.
346
347 - ``if`` statements with init-statement (``if (auto X = ...; ...)``) are
348 handled correctly.
349
350 - ``for`` loops are supported.
351
352
353 """
354 )
355 self.assertEqual(out, expected_out)
356
358 list_text = textwrap.dedent(
359 """\
360 .. csv-table:: List
361 :header: "Name", "Redirect", "Offers fixes"
362
363 :doc:`cert-dcl16-c <cert/dcl16-c>`, :doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes"
364 :doc:`cert-con36-c <cert/con36-c>`, :doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`,
365 :doc:`cert-dcl37-c <cert/dcl37-c>`, :doc:`bugprone-reserved-identifier <bugprone/reserved-identifier>`, "Yes"
366 :doc:`cert-arr39-c <cert/arr39-c>`, :doc:`bugprone-sizeof-expression <bugprone/sizeof-expression>`,
367 """
368 )
369 with tempfile.TemporaryDirectory() as td:
370 in_doc = os.path.join(td, "list.rst")
371 out_doc = os.path.join(td, "out.rst")
372 with open(in_doc, "w", encoding="utf-8") as f:
373 f.write(list_text)
374 buf = io.StringIO()
375 with redirect_stderr(buf):
376 rc = _mod.process_checks_list(out_doc, in_doc)
377 self.assertEqual(rc, 0)
378 self.assertIn(
379 "Checks in 'clang-tools-extra/docs/clang-tidy/checks/list.rst' csv-table are not alphabetically sorted.",
380 buf.getvalue(),
381 )
382 self.assertEqual(rc, 0)
383 with open(out_doc, "r", encoding="utf-8") as f:
384 out = f.read()
385
386 expected_out = textwrap.dedent(
387 """\
388 .. csv-table:: List
389 :header: "Name", "Redirect", "Offers fixes"
390
391 :doc:`cert-arr39-c <cert/arr39-c>`, :doc:`bugprone-sizeof-expression <bugprone/sizeof-expression>`,
392 :doc:`cert-con36-c <cert/con36-c>`, :doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`,
393 :doc:`cert-dcl16-c <cert/dcl16-c>`, :doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes"
394 :doc:`cert-dcl37-c <cert/dcl37-c>`, :doc:`bugprone-reserved-identifier <bugprone/reserved-identifier>`, "Yes"
395 """
396 )
397 self.assertEqual(out, expected_out)
398
399
400if __name__ == "__main__":
401 unittest.main()