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