xref: /aosp_15_r20/external/pigweed/pw_toolchain/py/clang_tidy_test.py (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1#!/usr/bin/env python3
2# Copyright 2020 The Pigweed Authors
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may not
5# use this file except in compliance with the License. You may obtain a copy of
6# the License at
7#
8#     https://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations under
14# the License.
15"""Tests for clang_tidy."""
16
17import pathlib
18import unittest
19from unittest import mock
20
21from pw_toolchain import clang_tidy
22
23
24class ClangTidyTest(unittest.TestCase):
25    """Unit tests for the clang-tidy wrapper."""
26
27    @mock.patch('subprocess.run', autospec=True)
28    def test_source_exclude_filters(self, mock_run):
29        # Build the path using joinpath to use OS-appropriate separators on both
30        # Windows and Linux.
31        source_file = (
32            pathlib.Path('..').joinpath('third_party').joinpath('somefile.cc')
33        )
34        source_root = pathlib.Path('..')
35        source_exclude = ['third_party.*']
36        extra_args = ['END_OF_INVOKER']
37        got = clang_tidy.main(
38            False,
39            'clang-tidy',
40            source_file,
41            source_root,
42            None,
43            source_exclude,
44            list(),
45            extra_args,
46        )
47
48        # Return code is zero.
49        self.assertEqual(got, 0)
50        # No calls to subprocess: we filtered out the source file.
51        self.assertEqual(len(mock_run.mock_calls), 0)
52
53    @mock.patch('subprocess.run', autospec=True)
54    def test_source_exclude_does_not_filter(self, mock_run):
55        mock_run.return_value.returncode = 0
56        source_file = (
57            pathlib.Path('..').joinpath('third_party').joinpath('somefile.cc')
58        )
59        source_root = pathlib.Path('..')
60        source_exclude = ['someotherdir.*']
61        extra_args = ['END_OF_INVOKER']
62        got = clang_tidy.main(
63            False,
64            'clang-tidy',
65            source_file,
66            source_root,
67            None,
68            source_exclude,
69            list(),
70            extra_args,
71        )
72
73        # Return code is zero.
74        self.assertEqual(got, 0)
75        # One call to subprocess: we did not filter out the source file.
76        # There will be more than one mock call because accessing return value
77        # attributes also produces mock_calls.
78        self.assertGreater(len(mock_run.mock_calls), 0)
79
80
81if __name__ == '__main__':
82    unittest.main()
83