xref: /aosp_15_r20/external/pigweed/pw_presubmit/py/inclusive_language_test.py (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1#!/usr/bin/env python3
2# Copyright 2022 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 inclusive_language."""
16
17from pathlib import Path
18import tempfile
19import unittest
20
21from pw_presubmit import inclusive_language
22
23# pylint: disable=attribute-defined-outside-init
24# pylint: disable=too-many-public-methods
25
26IGNORE = inclusive_language.IGNORE
27DISABLE = inclusive_language.DISABLE
28ENABLE = inclusive_language.ENABLE
29
30# inclusive-language: disable
31
32
33class TestInclusiveLanguage(unittest.TestCase):
34    """Test inclusive language check."""
35
36    def _run(self, *contents: str, filename: str | None = None) -> None:
37        with tempfile.TemporaryDirectory() as tempdir:
38            path = Path(tempdir) / (filename or 'foo')
39
40            with path.open('w') as outs:
41                outs.write('\n'.join(contents))
42
43            self.found_words: dict[
44                Path,
45                list[
46                    inclusive_language.PathMatch | inclusive_language.LineMatch
47                ],
48            ] = {}
49
50            inclusive_language.check_file(
51                path,
52                self.found_words,
53                check_path=bool(filename),
54            )
55            self.success = True
56
57    def assert_success(self):
58        self.assertFalse(self.found_words)
59
60    def assert_failures(self, num_expected_failures):
61        num_actual_failures = sum(len(x) for x in self.found_words.values())
62        self.assertEqual(num_expected_failures, num_actual_failures)
63
64    def test_no_objectionable_language(self) -> None:
65        self._run('no objectionable language')
66        self.assert_success()
67
68    def test_slave(self) -> None:
69        self._run('slave')
70        self.assert_failures(1)
71
72    def test_multiline_slave(self) -> None:
73        self._run('prefix', 'slave', 'suffix')
74        self.assert_failures(1)
75
76    def test_plural(self) -> None:
77        self._run('slaves')
78        self.assert_failures(1)
79
80    def test_past_tense(self) -> None:
81        self._run('slaved')
82        self.assert_failures(1)
83
84    def test_ignore_same_line(self) -> None:
85        self._run(f'slave {IGNORE}')
86        self.assert_success()
87
88    def test_ignore_next_line(self) -> None:
89        self._run(IGNORE, 'slave')
90        self.assert_success()
91
92    def test_ignore_same_and_next_line(self) -> None:
93        self._run(f'slave {IGNORE}', 'slave')
94        self.assert_success()
95
96    def test_ignore_prev_line(self) -> None:
97        self._run('slave', IGNORE)
98        self.assert_failures(1)
99
100    def test_one_ignored_one_not(self) -> None:
101        self._run(IGNORE, 'slave', 'slave')
102        self.assert_failures(1)
103
104    def test_two_ignored_one_not(self) -> None:
105        self._run(f'slave {IGNORE}', 'slave', 'slave')
106        self.assert_failures(1)
107
108    def test_disable_next_line(self) -> None:
109        self._run(DISABLE, 'slave')
110        self.assert_success()
111
112    def test_disable_prev_line(self) -> None:
113        self._run('slave', DISABLE)
114        self.assert_failures(1)
115
116    def test_disable_line_enable(self) -> None:
117        self._run(DISABLE, 'slave', ENABLE)
118        self.assert_success()
119
120    def test_line_disable_enable(self) -> None:
121        self._run('slave', DISABLE, ENABLE)
122        self.assert_failures(1)
123
124    def test_disable_enable_line(self) -> None:
125        self._run(DISABLE, ENABLE, 'slave')
126        self.assert_failures(1)
127
128    def test_one_enabled_one_disabled_one_enabled(self) -> None:
129        self._run('slave', DISABLE, 'slave', ENABLE, 'slave')
130        self.assert_failures(2)
131
132    def test_repeated_disable_noop(self) -> None:
133        self._run(DISABLE, DISABLE, 'slave', ENABLE, 'slave')
134        self.assert_failures(1)
135
136    def test_repeated_enable_noop(self) -> None:
137        self._run(DISABLE, 'slave', ENABLE, ENABLE, 'slave')
138        self.assert_failures(1)
139
140    def test_camel_case(self) -> None:
141        self._run('FooSlaveBar')
142        self.assert_failures(1)
143
144    def test_underscores(self) -> None:
145        self._run('foo_slave_bar')
146        self.assert_failures(1)
147
148    def test_init_camel_case(self) -> None:
149        self._run('SlaveBar')
150        self.assert_failures(1)
151
152    def test_init_underscores(self) -> None:
153        self._run('slave_bar')
154        self.assert_failures(1)
155
156    def test_underscore_camel_case(self) -> None:
157        self._run('foo_SlaveBar')
158        self.assert_failures(1)
159
160    def test_camel_case_underscore(self) -> None:
161        self._run('FooSlave_bar')
162        self.assert_failures(1)
163
164    def test_number_prefix(self) -> None:
165        self._run('5slave')
166        self.assert_failures(1)
167
168    def test_number_suffix(self) -> None:
169        self._run('slave5')
170        self.assert_failures(1)
171
172    def test_konstant(self) -> None:
173        self._run('kSLAVE')
174        self.assert_failures(1)
175
176    def test_command_line_argument(self) -> None:
177        self._run('--master-disable')
178        self.assert_failures(1)
179
180    def test_multiple(self) -> None:
181        self._run('master', 'slave')
182        self.assert_failures(2)
183
184    def test_bad_filename(self) -> None:
185        self._run(filename='slave')
186        self.assert_failures(1)
187
188
189if __name__ == '__main__':
190    unittest.main()
191
192# inclusive-language: enable
193