xref: /aosp_15_r20/external/pigweed/pw_presubmit/py/cpp_format_test.py (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1# Copyright 2024 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14"""Tests for the clang-format formatter."""
15
16import importlib.resources
17from pathlib import Path
18from tempfile import TemporaryDirectory
19from typing import Final, Sequence
20import unittest
21
22from format_testing_utils import CapturingToolRunner
23from pw_presubmit.format.cpp import ClangFormatFormatter
24
25_TEST_DATA_FILES = importlib.resources.files('pw_presubmit.format.test_data')
26
27_TEST_SRC_FILE = _TEST_DATA_FILES / 'cpp_test_data.cc'
28_TEST_GOLDEN = _TEST_DATA_FILES / 'cpp_test_data_golden.cc'
29
30_CLANG_FORMAT_CONFIG_PATH = _TEST_DATA_FILES / 'clang_format_config'
31_CLANG_FORMAT_ARGS: Final[Sequence[str]] = (
32    f'--style=file:{_CLANG_FORMAT_CONFIG_PATH}',
33)
34
35
36class TestClangFormatFormatter(unittest.TestCase):
37    """Tests for the ClangFormatFormatter."""
38
39    def test_check_file(self):
40        tool_runner = CapturingToolRunner()
41        formatter = ClangFormatFormatter(_CLANG_FORMAT_ARGS)
42        formatter.run_tool = tool_runner
43
44        result = formatter.format_file_in_memory(
45            _TEST_SRC_FILE, _TEST_SRC_FILE.read_bytes()
46        )
47        self.assertTrue(result.ok)
48        self.assertEqual(result.error_message, None)
49
50        self.assertEqual(
51            tool_runner.command_history.pop(0),
52            ' '.join(
53                (
54                    'clang-format',
55                    f'--style=file:{_CLANG_FORMAT_CONFIG_PATH}',
56                    str(_TEST_SRC_FILE),
57                )
58            ),
59        )
60
61        self.assertMultiLineEqual(
62            result.formatted_file_contents.decode(), _TEST_GOLDEN.read_text()
63        )
64
65    def test_fix_file(self):
66        tool_runner = CapturingToolRunner()
67        formatter = ClangFormatFormatter(_CLANG_FORMAT_ARGS)
68        formatter.run_tool = tool_runner
69
70        with TemporaryDirectory() as temp_dir:
71            file_to_fix = Path(temp_dir) / _TEST_SRC_FILE.name
72            file_to_fix.write_bytes(_TEST_SRC_FILE.read_bytes())
73
74            errors = formatter.format_files([file_to_fix])
75
76            # Error dictionary should be empty.
77            self.assertFalse(list(errors))
78
79            self.assertEqual(
80                tool_runner.command_history.pop(0),
81                ' '.join(
82                    (
83                        'clang-format',
84                        '-i',
85                        f'--style=file:{_CLANG_FORMAT_CONFIG_PATH}',
86                        str(file_to_fix),
87                    )
88                ),
89            )
90
91            self.assertMultiLineEqual(
92                file_to_fix.read_text(), _TEST_GOLDEN.read_text()
93            )
94
95
96if __name__ == '__main__':
97    unittest.main()
98