clang-tools 23.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 Please merge these entries into a single bullet point.
98
99 -- Duplicate: - Improved :doc:`bugprone-easily-swappable-parameters
100
101 - At line 4:
102 - Improved :doc:`bugprone-easily-swappable-parameters
103 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
104 correcting a spelling mistake on its option
105 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
106
107 - At line 14:
108 - Improved :doc:`bugprone-easily-swappable-parameters
109 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
110 correcting a spelling mistake on its option
111 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
112
113 """
114 )
115 self.assertEqual(report_str, expected_report)
116
118 # When content is not normalized, the function writes normalized text and returns 0.
119 rn_text = textwrap.dedent(
120 """\
121 New checks
122 ^^^^^^^^^^
123
124 - New :doc:`readability-redundant-parentheses
125 <clang-tidy/checks/readability/redundant-parentheses>` check.
126
127 Detect redundant parentheses.
128
129 - New :doc:`bugprone-derived-method-shadowing-base-method
130 <clang-tidy/checks/bugprone/derived-method-shadowing-base-method>` check.
131
132 Finds derived class methods that shadow a (non-virtual) base class method.
133
134 """
135 )
136 with tempfile.TemporaryDirectory() as td:
137 rn_doc = os.path.join(td, "ReleaseNotes.rst")
138 out_path = os.path.join(td, "out.rst")
139 with open(rn_doc, "w", encoding="utf-8") as f:
140 f.write(rn_text)
141
142 buf = io.StringIO()
143 with redirect_stderr(buf):
144 rc = _mod.process_release_notes(out_path, rn_doc)
145
146 self.assertEqual(rc, 0)
147 with open(out_path, "r", encoding="utf-8") as f:
148 out = f.read()
149
150 expected_out = textwrap.dedent(
151 """\
152 New checks
153 ^^^^^^^^^^
154
155 - New :doc:`bugprone-derived-method-shadowing-base-method
156 <clang-tidy/checks/bugprone/derived-method-shadowing-base-method>` check.
157
158 Finds derived class methods that shadow a (non-virtual) base class method.
159
160 - New :doc:`readability-redundant-parentheses
161 <clang-tidy/checks/readability/redundant-parentheses>` check.
162
163 Detect redundant parentheses.
164
165 """
166 )
167
168 self.assertEqual(out, expected_out)
169 self.assertIn("not alphabetically sorted", buf.getvalue())
170
172 # Sorting is incorrect and duplicates exist, should report ordering issues first.
173 rn_text = textwrap.dedent(
174 """\
175 Changes in existing checks
176 ^^^^^^^^^^^^^^^^^^^^^^^^^^
177
178 - Improved :doc:`bugprone-easily-swappable-parameters
179 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
180 correcting a spelling mistake on its option
181 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
182
183 - Improved :doc:`bugprone-exception-escape
184 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
185 exceptions from captures are now diagnosed, exceptions in the bodies of
186 lambdas that aren't actually invoked are not.
187
188 - Improved :doc:`bugprone-easily-swappable-parameters
189 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
190 correcting a spelling mistake on its option
191 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
192
193 """
194 )
195 with tempfile.TemporaryDirectory() as td:
196 rn_doc = os.path.join(td, "ReleaseNotes.rst")
197 out_path = os.path.join(td, "out.rst")
198 with open(rn_doc, "w", encoding="utf-8") as f:
199 f.write(rn_text)
200
201 buf = io.StringIO()
202 with redirect_stderr(buf):
203 rc = _mod.process_release_notes(out_path, rn_doc)
204 self.assertEqual(rc, 0)
205 self.assertIn(
206 "Entries in 'clang-tools-extra/docs/ReleaseNotes.rst' are not alphabetically sorted.",
207 buf.getvalue(),
208 )
209
210 with open(out_path, "r", encoding="utf-8") as f:
211 out = f.read()
212 expected_out = textwrap.dedent(
213 """\
214 Changes in existing checks
215 ^^^^^^^^^^^^^^^^^^^^^^^^^^
216
217 - Improved :doc:`bugprone-easily-swappable-parameters
218 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
219 correcting a spelling mistake on its option
220 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
221
222 - Improved :doc:`bugprone-easily-swappable-parameters
223 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
224 correcting a spelling mistake on its option
225 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
226
227 - Improved :doc:`bugprone-exception-escape
228 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
229 exceptions from captures are now diagnosed, exceptions in the bodies of
230 lambdas that aren't actually invoked are not.
231
232 """
233 )
234 self.assertEqual(out, expected_out)
235
237 # Sorting is already correct but duplicates exist, should return 3 and report.
238 rn_text = textwrap.dedent(
239 """\
240 Changes in existing checks
241 ^^^^^^^^^^^^^^^^^^^^^^^^^^
242
243 - Improved :doc:`bugprone-easily-swappable-parameters
244 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
245 correcting a spelling mistake on its option
246 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
247
248 - Improved :doc:`bugprone-easily-swappable-parameters
249 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
250 correcting a spelling mistake on its option
251 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
252
253 - Improved :doc:`bugprone-exception-escape
254 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
255 exceptions from captures are now diagnosed, exceptions in the bodies of
256 lambdas that aren't actually invoked are not.
257
258 """
259 )
260 with tempfile.TemporaryDirectory() as td:
261 rn_doc = os.path.join(td, "ReleaseNotes.rst")
262 out_path = os.path.join(td, "out.rst")
263 with open(rn_doc, "w", encoding="utf-8") as f:
264 f.write(rn_text)
265
266 buf = io.StringIO()
267 with redirect_stderr(buf):
268 rc = _mod.process_release_notes(out_path, rn_doc)
269
270 self.assertEqual(rc, 3)
271 expected_report = textwrap.dedent(
272 """\
273 Error: Duplicate entries in 'Changes in existing checks'.
274
275 Please merge these entries into a single bullet point.
276
277 -- Duplicate: - Improved :doc:`bugprone-easily-swappable-parameters
278
279 - At line 4:
280 - Improved :doc:`bugprone-easily-swappable-parameters
281 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
282 correcting a spelling mistake on its option
283 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
284
285 - At line 9:
286 - Improved :doc:`bugprone-easily-swappable-parameters
287 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
288 correcting a spelling mistake on its option
289 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
290
291 """
292 )
293 self.assertEqual(buf.getvalue(), expected_report)
294
295 with open(out_path, "r", encoding="utf-8") as f:
296 out = f.read()
297 self.assertEqual(out, rn_text)
298
300 rn_text = textwrap.dedent(
301 """\
302 Changes in existing checks
303 ^^^^^^^^^^^^^^^^^^^^^^^^^^
304
305 - Improved :doc:`bugprone-easily-swappable-parameters
306 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
307 correcting a spelling mistake on its option
308 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
309
310 - Improved :doc:`llvm-prefer-isa-or-dyn-cast-in-conditionals
311 <clang-tidy/checks/llvm/prefer-isa-or-dyn-cast-in-conditionals>` check:
312
313 - Fix-it handles callees with nested-name-specifier correctly.
314
315 - ``if`` statements with init-statement (``if (auto X = ...; ...)``) are
316 handled correctly.
317
318 - ``for`` loops are supported.
319
320 - Improved :doc:`bugprone-exception-escape
321 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
322 exceptions from captures are now diagnosed, exceptions in the bodies of
323 lambdas that aren't actually invoked are not.
324
325 """
326 )
327
328 out = _mod.normalize_release_notes(rn_text.splitlines(True))
329
330 expected_out = textwrap.dedent(
331 """\
332 Changes in existing checks
333 ^^^^^^^^^^^^^^^^^^^^^^^^^^
334
335 - Improved :doc:`bugprone-easily-swappable-parameters
336 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
337 correcting a spelling mistake on its option
338 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
339
340 - Improved :doc:`bugprone-exception-escape
341 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
342 exceptions from captures are now diagnosed, exceptions in the bodies of
343 lambdas that aren't actually invoked are not.
344
345 - Improved :doc:`llvm-prefer-isa-or-dyn-cast-in-conditionals
346 <clang-tidy/checks/llvm/prefer-isa-or-dyn-cast-in-conditionals>` check:
347
348 - Fix-it handles callees with nested-name-specifier correctly.
349
350 - ``if`` statements with init-statement (``if (auto X = ...; ...)``) are
351 handled correctly.
352
353 - ``for`` loops are supported.
354
355 """
356 )
357 self.assertEqual(out, expected_out)
358
360 rn_text = textwrap.dedent(
361 """\
362 Changes in existing checks
363 ^^^^^^^^^^^^^^^^^^^^^^^^^^
364
365 - Renamed :doc:`performance-faster-string-find
366 <clang-tidy/checks/performance/faster-string-find>` to
367 :doc:`performance-faster-string-operation
368 <clang-tidy/checks/performance/faster-string-operation>`.
369 The `performance-faster-string-find` name is kept as an alias.
370
371 - Renamed :doc:`hicpp-no-assembler <clang-tidy/checks/hicpp/no-assembler>`
372 to :doc:`portability-no-assembler
373 <clang-tidy/checks/portability/no-assembler>`. The `hicpp-no-assembler`
374 name is kept as an alias.
375
376 """
377 )
378
379 out = _mod.normalize_release_notes(rn_text.splitlines(True))
380
381 expected_out = textwrap.dedent(
382 """\
383 Changes in existing checks
384 ^^^^^^^^^^^^^^^^^^^^^^^^^^
385
386 - Renamed :doc:`hicpp-no-assembler <clang-tidy/checks/hicpp/no-assembler>`
387 to :doc:`portability-no-assembler
388 <clang-tidy/checks/portability/no-assembler>`. The `hicpp-no-assembler`
389 name is kept as an alias.
390
391 - Renamed :doc:`performance-faster-string-find
392 <clang-tidy/checks/performance/faster-string-find>` to
393 :doc:`performance-faster-string-operation
394 <clang-tidy/checks/performance/faster-string-operation>`.
395 The `performance-faster-string-find` name is kept as an alias.
396
397 """
398 )
399 self.assertEqual(out, expected_out)
400
402 list_text = textwrap.dedent(
403 """\
404 .. csv-table:: List
405 :header: "Name", "Redirect", "Offers fixes"
406
407 :doc:`cert-dcl16-c <cert/dcl16-c>`, :doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes"
408 :doc:`cert-con36-c <cert/con36-c>`, :doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`,
409 :doc:`cert-dcl37-c <cert/dcl37-c>`, :doc:`bugprone-reserved-identifier <bugprone/reserved-identifier>`, "Yes"
410 :doc:`cert-arr39-c <cert/arr39-c>`, :doc:`bugprone-sizeof-expression <bugprone/sizeof-expression>`,
411 """
412 )
413 with tempfile.TemporaryDirectory() as td:
414 in_doc = os.path.join(td, "list.rst")
415 out_doc = os.path.join(td, "out.rst")
416 with open(in_doc, "w", encoding="utf-8") as f:
417 f.write(list_text)
418 buf = io.StringIO()
419 with redirect_stderr(buf):
420 rc = _mod.process_checks_list(out_doc, in_doc)
421 self.assertEqual(rc, 0)
422 self.assertIn(
423 "Checks in 'clang-tools-extra/docs/clang-tidy/checks/list.rst' csv-table are not alphabetically sorted.",
424 buf.getvalue(),
425 )
426 self.assertEqual(rc, 0)
427 with open(out_doc, "r", encoding="utf-8") as f:
428 out = f.read()
429
430 expected_out = textwrap.dedent(
431 """\
432 .. csv-table:: List
433 :header: "Name", "Redirect", "Offers fixes"
434
435 :doc:`cert-arr39-c <cert/arr39-c>`, :doc:`bugprone-sizeof-expression <bugprone/sizeof-expression>`,
436 :doc:`cert-con36-c <cert/con36-c>`, :doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`,
437 :doc:`cert-dcl16-c <cert/dcl16-c>`, :doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes"
438 :doc:`cert-dcl37-c <cert/dcl37-c>`, :doc:`bugprone-reserved-identifier <bugprone/reserved-identifier>`, "Yes"
439 """
440 )
441 self.assertEqual(out, expected_out)
442
443
444if __name__ == "__main__":
445 unittest.main()