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 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 self.assertEqual(report_str, expected_report)
115
117 # When content is not normalized, the function writes normalized text and returns 0.
118 rn_text = textwrap.dedent(
119 """\
120 New checks
121 ^^^^^^^^^^
122
123 - New :doc:`readability-redundant-parentheses
124 <clang-tidy/checks/readability/redundant-parentheses>` check.
125
126 Detect redundant parentheses.
127
128 - New :doc:`bugprone-derived-method-shadowing-base-method
129 <clang-tidy/checks/bugprone/derived-method-shadowing-base-method>` check.
130
131 Finds derived class methods that shadow a (non-virtual) base class method.
132
133 """
134 )
135 with tempfile.TemporaryDirectory() as td:
136 rn_doc = os.path.join(td, "ReleaseNotes.rst")
137 out_path = os.path.join(td, "out.rst")
138 with open(rn_doc, "w", encoding="utf-8") as f:
139 f.write(rn_text)
140
141 buf = io.StringIO()
142 with redirect_stderr(buf):
143 rc = _mod.process_release_notes(out_path, rn_doc)
144
145 self.assertEqual(rc, 0)
146 with open(out_path, "r", encoding="utf-8") as f:
147 out = f.read()
148
149 expected_out = textwrap.dedent(
150 """\
151 New checks
152 ^^^^^^^^^^
153
154 - New :doc:`bugprone-derived-method-shadowing-base-method
155 <clang-tidy/checks/bugprone/derived-method-shadowing-base-method>` check.
156
157 Finds derived class methods that shadow a (non-virtual) base class method.
158
159 - New :doc:`readability-redundant-parentheses
160 <clang-tidy/checks/readability/redundant-parentheses>` check.
161
162 Detect redundant parentheses.
163
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 )
235 self.assertEqual(out, expected_out)
236
238 # Sorting is already correct but duplicates exist, should return 3 and report.
239 rn_text = textwrap.dedent(
240 """\
241 Changes in existing checks
242 ^^^^^^^^^^^^^^^^^^^^^^^^^^
243
244 - Improved :doc:`bugprone-easily-swappable-parameters
245 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
246 correcting a spelling mistake on its option
247 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
248
249 - Improved :doc:`bugprone-easily-swappable-parameters
250 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
251 correcting a spelling mistake on its option
252 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
253
254 - Improved :doc:`bugprone-exception-escape
255 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
256 exceptions from captures are now diagnosed, exceptions in the bodies of
257 lambdas that aren't actually invoked are not.
258
259 """
260 )
261 with tempfile.TemporaryDirectory() as td:
262 rn_doc = os.path.join(td, "ReleaseNotes.rst")
263 out_path = os.path.join(td, "out.rst")
264 with open(rn_doc, "w", encoding="utf-8") as f:
265 f.write(rn_text)
266
267 buf = io.StringIO()
268 with redirect_stderr(buf):
269 rc = _mod.process_release_notes(out_path, rn_doc)
270
271 self.assertEqual(rc, 3)
272 expected_report = textwrap.dedent(
273 """\
274 Error: Duplicate entries in 'Changes in existing checks'.
275
276 Please merge these entries into a single bullet point.
277
278 -- Duplicate: - Improved :doc:`bugprone-easily-swappable-parameters
279
280 - At line 4:
281 - Improved :doc:`bugprone-easily-swappable-parameters
282 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
283 correcting a spelling mistake on its option
284 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
285
286 - At line 9:
287 - Improved :doc:`bugprone-easily-swappable-parameters
288 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
289 correcting a spelling mistake on its option
290 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
291
292 """
293 )
294 self.assertEqual(buf.getvalue(), expected_report)
295
296 with open(out_path, "r", encoding="utf-8") as f:
297 out = f.read()
298 self.assertEqual(out, rn_text)
299
301 rn_text = textwrap.dedent(
302 """\
303 Changes in existing checks
304 ^^^^^^^^^^^^^^^^^^^^^^^^^^
305
306 - Improved :doc:`bugprone-easily-swappable-parameters
307 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
308 correcting a spelling mistake on its option
309 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
310
311 - Improved :doc:`llvm-prefer-isa-or-dyn-cast-in-conditionals
312 <clang-tidy/checks/llvm/prefer-isa-or-dyn-cast-in-conditionals>` check:
313
314 - Fix-it handles callees with nested-name-specifier correctly.
315
316 - ``if`` statements with init-statement (``if (auto X = ...; ...)``) are
317 handled correctly.
318
319 - ``for`` loops are supported.
320
321 - Improved :doc:`bugprone-exception-escape
322 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
323 exceptions from captures are now diagnosed, exceptions in the bodies of
324 lambdas that aren't actually invoked are not.
325
326 """
327 )
328
329 out = _mod.normalize_release_notes(rn_text.splitlines(True))
330
331 expected_out = textwrap.dedent(
332 """\
333 Changes in existing checks
334 ^^^^^^^^^^^^^^^^^^^^^^^^^^
335
336 - Improved :doc:`bugprone-easily-swappable-parameters
337 <clang-tidy/checks/bugprone/easily-swappable-parameters>` check by
338 correcting a spelling mistake on its option
339 ``NamePrefixSuffixSilenceDissimilarityTreshold``.
340
341 - Improved :doc:`bugprone-exception-escape
342 <clang-tidy/checks/bugprone/exception-escape>` check's handling of lambdas:
343 exceptions from captures are now diagnosed, exceptions in the bodies of
344 lambdas that aren't actually invoked are not.
345
346 - Improved :doc:`llvm-prefer-isa-or-dyn-cast-in-conditionals
347 <clang-tidy/checks/llvm/prefer-isa-or-dyn-cast-in-conditionals>` check:
348
349 - Fix-it handles callees with nested-name-specifier correctly.
350
351 - ``if`` statements with init-statement (``if (auto X = ...; ...)``) are
352 handled correctly.
353
354 - ``for`` loops are supported.
355
356
357 """
358 )
359 self.assertEqual(out, expected_out)
360
362 list_text = textwrap.dedent(
363 """\
364 .. csv-table:: List
365 :header: "Name", "Redirect", "Offers fixes"
366
367 :doc:`cert-dcl16-c <cert/dcl16-c>`, :doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes"
368 :doc:`cert-con36-c <cert/con36-c>`, :doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`,
369 :doc:`cert-dcl37-c <cert/dcl37-c>`, :doc:`bugprone-reserved-identifier <bugprone/reserved-identifier>`, "Yes"
370 :doc:`cert-arr39-c <cert/arr39-c>`, :doc:`bugprone-sizeof-expression <bugprone/sizeof-expression>`,
371 """
372 )
373 with tempfile.TemporaryDirectory() as td:
374 in_doc = os.path.join(td, "list.rst")
375 out_doc = os.path.join(td, "out.rst")
376 with open(in_doc, "w", encoding="utf-8") as f:
377 f.write(list_text)
378 buf = io.StringIO()
379 with redirect_stderr(buf):
380 rc = _mod.process_checks_list(out_doc, in_doc)
381 self.assertEqual(rc, 0)
382 self.assertIn(
383 "Checks in 'clang-tools-extra/docs/clang-tidy/checks/list.rst' csv-table are not alphabetically sorted.",
384 buf.getvalue(),
385 )
386 self.assertEqual(rc, 0)
387 with open(out_doc, "r", encoding="utf-8") as f:
388 out = f.read()
389
390 expected_out = textwrap.dedent(
391 """\
392 .. csv-table:: List
393 :header: "Name", "Redirect", "Offers fixes"
394
395 :doc:`cert-arr39-c <cert/arr39-c>`, :doc:`bugprone-sizeof-expression <bugprone/sizeof-expression>`,
396 :doc:`cert-con36-c <cert/con36-c>`, :doc:`bugprone-spuriously-wake-up-functions <bugprone/spuriously-wake-up-functions>`,
397 :doc:`cert-dcl16-c <cert/dcl16-c>`, :doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes"
398 :doc:`cert-dcl37-c <cert/dcl37-c>`, :doc:`bugprone-reserved-identifier <bugprone/reserved-identifier>`, "Yes"
399 """
400 )
401 self.assertEqual(out, expected_out)
402
403
404if __name__ == "__main__":
405 unittest.main()