blob: 6d0e20845b71dcfcbc86281c2301469b030aa8b9 [file] [log] [blame]
Vaclav Brozekcdc7defb2018-03-20 09:54:351#!/usr/bin/env python
Avi Drissmanea1be232022-09-14 23:29:062# Copyright 2017 The Chromium Authors
Sylvain Defresnefcda19f2017-06-27 10:14:013# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6import os
7import sys
8import unittest
9
10import PRESUBMIT
11
12sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
13import PRESUBMIT_test_mocks
14
Sylvain Defresnefcda19f2017-06-27 10:14:0115class CheckTODOFormatTest(unittest.TestCase):
Gauthier Ambard1981d622022-09-13 09:34:4916 """Test the _CheckBugInToDo presubmit check."""
Sylvain Defresnefcda19f2017-06-27 10:14:0117
Gauthier Ambard1981d622022-09-13 09:34:4918 def testTODOs(self):
Mark Cogancc4c1ea2024-03-07 09:31:2919 # All instances of the "TO DO" string in the following test cases are
20 # broken by line breaks, because this file is run through the PRESUBIT
21 # that it tests, so incorrectly formatted items in the test fixture
22 # will trigger errors.
Gauthier Ambard1981d622022-09-13 09:34:4923 bad_lines = [
24 'TO'
25 'DO(ldap): fix this', 'TO'
26 'DO(ladp): see crbug.com/8675309', 'TO'
27 'DO(8675309): fix this', 'TO'
28 'DO(http://crbug.com/8675309): fix this', 'TO'
29 'DO( crbug.com/8675309): fix this', 'TO'
30 'DO(crbug/8675309): fix this', 'TO'
Mark Cogancc4c1ea2024-03-07 09:31:2931 'DO(crbug.com): fix this', 'TO'
32 'DO(inccrbug.com): fix this',
33 ]
34 deprecated_lines = [
35 'TO'
36 'DO(b/12345): fix this'
Gauthier Ambard1981d622022-09-13 09:34:4937 ]
38 good_lines = [
39 'TO'
40 'DO(crbug.com/8675309): fix this', 'TO'
Mark Cogancc4c1ea2024-03-07 09:31:2941 'DO(crbug.com/8675309): fix this (please)'
Gauthier Ambard1981d622022-09-13 09:34:4942 ]
43 mock_input = PRESUBMIT_test_mocks.MockInputApi()
Mark Cogancc4c1ea2024-03-07 09:31:2944 lines = bad_lines + deprecated_lines + good_lines
Gauthier Ambard1981d622022-09-13 09:34:4945 mock_input.files = [
Mark Cogancc4c1ea2024-03-07 09:31:2946 PRESUBMIT_test_mocks.MockFile('ios/path/foo_controller.mm', lines)
Gauthier Ambard1981d622022-09-13 09:34:4947 ]
48 mock_output = PRESUBMIT_test_mocks.MockOutputApi()
Mark Cogancc4c1ea2024-03-07 09:31:2949 results = PRESUBMIT._CheckBugInToDo(mock_input, mock_output)
50 # Expect one error result and one warning result.
51 self.assertEqual(len(results), 2)
52 self.assertEqual('error', results[0].type)
53 self.assertEqual('warning', results[1].type)
54 self.assertTrue('without bug numbers' in results[0].message)
55 self.assertTrue('with a deprecated bug link' in results[1].message)
56 error_lines = results[0].message.split('\n')
Gauthier Ambard1981d622022-09-13 09:34:4957 self.assertEqual(len(error_lines), len(bad_lines) + 2)
Mark Cogancc4c1ea2024-03-07 09:31:2958 warning_lines = results[1].message.split('\n')
59 self.assertEqual(len(warning_lines), len(deprecated_lines) + 2)
Sylvain Defresnefcda19f2017-06-27 10:14:0160
Petro Akzhygitovdb9b351622022-07-01 08:21:5061class CheckHasNoIncludeDirectivesTest(unittest.TestCase):
Gauthier Ambard1981d622022-09-13 09:34:4962 """Test the _CheckHasNoIncludeDirectives presubmit check."""
Petro Akzhygitovdb9b351622022-07-01 08:21:5063
Gauthier Ambard1981d622022-09-13 09:34:4964 def testFindsIncludeDirectives(self):
65 good_lines = [
66 '#import <system>', '#import "my/path/my/header.h"',
67 '#import "my/path/my/source.mm"', '#import "my/path/my/source.m"'
68 ]
69 bad_lines = [
70 '#include <system>', '#import <system>',
71 '#include "my/path/my/header.h"',
72 '#include "my/path/my/source.mm"', '#import "my/path/my/header.h"'
73 '#include "my/path/my/source.m"'
74 ]
75 mock_input = PRESUBMIT_test_mocks.MockInputApi()
76 mock_input.files = [
77 PRESUBMIT_test_mocks.MockFile('ios/path/foo_controller.mm',
78 bad_lines),
79 PRESUBMIT_test_mocks.MockFile('ios/path/foo_controller_2.mm',
80 good_lines),
81 PRESUBMIT_test_mocks.MockFile('ios/path/bar_controller.h',
82 bad_lines),
83 PRESUBMIT_test_mocks.MockFile('ios/path/bar_controller.m',
84 bad_lines),
85 PRESUBMIT_test_mocks.MockFile('ios/path/bar_controller.cc',
86 bad_lines),
87 PRESUBMIT_test_mocks.MockFile('chrome/path/foo_controller.mm',
88 bad_lines),
89 ]
90 mock_output = PRESUBMIT_test_mocks.MockOutputApi()
91 errors = PRESUBMIT._CheckHasNoIncludeDirectives(
92 mock_input, mock_output)
93 self.assertEqual(len(errors), 1)
94 self.assertEqual('error', errors[0].type)
95 self.assertTrue('ios/path/foo_controller.mm:1' in errors[0].message)
96 self.assertTrue('ios/path/foo_controller.mm:3' in errors[0].message)
97 self.assertTrue('ios/path/foo_controller.mm:4' in errors[0].message)
98
Petro Akzhygitovdb9b351622022-07-01 08:21:5099
Gauthier Ambardf85c5f12022-09-14 11:26:54100class CheckHasNoPipeInCommentTest(unittest.TestCase):
101 """Test the _CheckHasNoPipeInComment presubmit check."""
102
103 def testFindsIncludeDirectives(self):
104 good_lines = [
Peter Kasting06d48312023-12-20 22:26:14105 '#if !defined(a) || !defined(b)',
Gauthier Ambardf85c5f12022-09-14 11:26:54106 '// This does A || B', '// `MySymbol` is correct',
107 'bitVariable1 | bitVariable2'
108 ]
109 bad_lines = [
110 '// |MySymbol| is wrong', '// What is wrong is: |MySymbol|'
111 ]
112 mock_input = PRESUBMIT_test_mocks.MockInputApi()
113 mock_input.files = [
114 PRESUBMIT_test_mocks.MockFile('ios/path/foo_controller.mm',
115 good_lines + bad_lines),
116 PRESUBMIT_test_mocks.MockFile('ios/path/foo_controller.h',
117 bad_lines + good_lines),
118 ]
119 mock_output = PRESUBMIT_test_mocks.MockOutputApi()
120 errors = PRESUBMIT._CheckHasNoPipeInComment(mock_input, mock_output)
121 self.assertEqual(len(errors), 1)
122 self.assertEqual('warning', errors[0].type)
123 self.assertTrue('ios/path/foo_controller.mm:5' in errors[0].message)
124 self.assertTrue('ios/path/foo_controller.mm:6' in errors[0].message)
125 self.assertTrue('ios/path/foo_controller.h:1' in errors[0].message)
126 self.assertTrue('ios/path/foo_controller.h:2' in errors[0].message)
127 error_lines = errors[0].message.split('\n')
128 self.assertEqual(len(error_lines), len(bad_lines) * 2 + 3)
129
Federica Germinario6aeebd42024-09-17 11:59:15130class _CheckCanImproveTestUsingExpectNSEQ(unittest.TestCase):
131 """Test the _CheckCanImproveTestUsingExpectNSEQ presubmit. """
132
133 def testFindImprovableTestUsingExpectNSEQ(self):
134 good_lines = [
135 'EXPECT_TRUE(a == b);',
136 'if (a isEqualToString:b) {',
137 'if (a isEqualToData:b) {'
138 ]
139 bad_lines = [
140 'EXPECT_TRUE(a ',
141 ' isEqualToString:b);',
142 'EXPECT_TRUE(@"example" isEqualToString:@"example");',
143 'EXPECT_FALSE(@"example" isEqualToData:@"example");',
144 'EXPECT_TRUE(@"example" isEqualToArray:@"example");'
145 ]
146 mock_input = PRESUBMIT_test_mocks.MockInputApi()
147 mock_input.files = [
148 PRESUBMIT_test_mocks.MockFile('ios/path/foo_unittest.mm',
149 good_lines + bad_lines),
150 ]
151 mock_output = PRESUBMIT_test_mocks.MockOutputApi()
152 errors = PRESUBMIT._CheckCanImproveTestUsingExpectNSEQ(
153 mock_input, mock_output)
154 self.assertEqual(len(errors), 1)
155 self.assertEqual('warning', errors[0].type)
156 self.assertFalse('ios/path/foo_unittest.mm:1' in errors[0].message)
157 self.assertFalse('ios/path/foo_unittest.mm:2' in errors[0].message)
158 self.assertFalse('ios/path/foo_unittest.mm:3' in errors[0].message)
159 self.assertTrue('ios/path/foo_unittest.mm:4' in errors[0].message)
160 self.assertFalse('ios/path/foo_unittest.mm:5' in errors[0].message)
161 self.assertTrue('ios/path/foo_unittest.mm:6' in errors[0].message)
162 self.assertTrue('ios/path/foo_unittest.mm:7' in errors[0].message)
163 self.assertTrue('ios/path/foo_unittest.mm:8' in errors[0].message)
164
Federica Germinario2ce51a82025-01-27 14:44:10165class _CheckNotUsingNSUserDefaults(unittest.TestCase):
166 """Test the _CheckNotUsingNSUserDefaults presubmit. """
167
168 def testFindImprovableTestUsingExpectNSEQ(self):
169 good_lines = [
170 '[defaults dictionaryForKey:key_name];',
171 ]
172 bad_lines = [
173 '[[NSUserDefaults standardUserDefaults]',
174 'NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];',
175 '[[NSUserDefaults standardUserDefaults] setObject:object_name',
176 ]
177
178 mock_input = PRESUBMIT_test_mocks.MockInputApi()
179 mock_input.files = [
180 PRESUBMIT_test_mocks.MockFile('ios/path/defaults_unittest.mm',
181 good_lines + bad_lines),
182 ]
183 mock_output = PRESUBMIT_test_mocks.MockOutputApi()
184 errors = PRESUBMIT._CheckNotUsingNSUserDefaults(
185 mock_input, mock_output)
186 self.assertEqual(len(errors), 1)
187 self.assertEqual('warning', errors[0].type)
188 self.assertFalse('ios/path/defaults_unittest.mm:1' in errors[0].message)
189 self.assertTrue('ios/path/defaults_unittest.mm:2' in errors[0].message)
190 self.assertTrue('ios/path/defaults_unittest.mm:3' in errors[0].message)
191 self.assertTrue('ios/path/defaults_unittest.mm:4' in errors[0].message)
Federica Germinario6aeebd42024-09-17 11:59:15192
Benjamin Williams715f0232025-02-20 12:44:09193
194class CheckNewColorIntroductionTest(unittest.TestCase):
195 """Test the _CheckNewColorIntroduction presubmit check."""
196
197 def setUp(self):
198 self.mock_input = PRESUBMIT_test_mocks.MockInputApi()
199 self.mock_output = PRESUBMIT_test_mocks.MockOutputApi()
200
201 def testNoColorChanges(self):
202 """Test when there are no color file changes."""
203 self.mock_input.files = [
204 PRESUBMIT_test_mocks.MockFile('ios/path/some_controller.mm', [])
205 ]
206 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
207 self.mock_output)
208 self.assertEqual(len(results), 0)
209
210 def testNewColorInSharedDirectory(self):
211 """Test adding a new color in the shared directory."""
212 self.mock_input.files = [
213 PRESUBMIT_test_mocks.MockFile(
214 'ios/chrome/common/ui/colors/resources/Assets.xcassets/'
215 'test_color.colorset/Contents.json', [],
216 action='A')
217 ]
218 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
219 self.mock_output)
220 self.assertEqual(len(results), 1)
221 self.assertEqual('warning', results[0].type)
222 self.assertTrue('New color(s) added in' in results[0].message)
223 self.assertTrue(
224 'ensure the color does not already exist' in results[0].message)
225
226 def testNewColorOutsideSharedDirectory(self):
227 """Test adding a new color outside the shared directory."""
228 self.mock_input.files = [
229 PRESUBMIT_test_mocks.MockFile(
230 'ios/chrome/browser/safety_check/resources/Assets.xcassets/'
231 'test_color.colorset/Contents.json', [],
232 action='A')
233 ]
234 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
235 self.mock_output)
236 self.assertEqual(len(results), 1)
237 self.assertEqual('error', results[0].type)
238 self.assertTrue(
239 'New color(s) must be added to the' in results[0].message)
240 self.assertTrue('ios/chrome/common/ui/colors' in results[0].message)
241
242 def testModifiedColorInSharedDirectory(self):
243 """Test modifying an existing color in the shared directory."""
244 self.mock_input.files = [
245 PRESUBMIT_test_mocks.MockFile(
246 'ios/chrome/common/ui/colors/resources/Assets.xcassets/'
247 'test_color.colorset/Contents.json', [],
248 action='M')
249 ]
250 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
251 self.mock_output)
252 self.assertEqual(len(results), 1)
253 self.assertEqual('warning', results[0].type)
254 self.assertTrue('Color(s) modified in' in results[0].message)
255 self.assertTrue(
256 'ensure the color does not already exist' in results[0].message)
257
258 def testModifiedColorOutsideSharedDirectory(self):
259 """Test modifying an existing color outside the shared directory."""
260 self.mock_input.files = [
261 PRESUBMIT_test_mocks.MockFile(
262 'ios/chrome/browser/safety_check/resources/Assets.xcassets/'
263 'test_color.colorset/Contents.json', [],
264 action='M')
265 ]
266 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
267 self.mock_output)
268 self.assertEqual(len(results), 1)
269 self.assertEqual('warning', results[0].type)
270 self.assertTrue('Color(s) modified' in results[0].message)
271 self.assertTrue(
272 'ensure the color does not already exist' in results[0].message)
273
274 def testMultipleColorChanges(self):
275 """Test multiple color changes in different locations."""
276 self.mock_input.files = [
277 PRESUBMIT_test_mocks.MockFile(
278 'ios/chrome/common/ui/colors/resources/Assets.xcassets/'
279 'color1.colorset/Contents.json', [],
280 action='A'),
281 PRESUBMIT_test_mocks.MockFile(
282 'ios/chrome/browser/safety_check/resources/Assets.xcassets/'
283 'color2.colorset/Contents.json', [],
284 action='A'),
285 PRESUBMIT_test_mocks.MockFile(
286 'ios/chrome/common/ui/colors/resources/Assets.xcassets/'
287 'color3.colorset/Contents.json', [],
288 action='M'),
289 PRESUBMIT_test_mocks.MockFile(
290 'ios/chrome/browser/safety_check/resources/Assets.xcassets/'
291 'color4.colorset/Contents.json', [],
292 action='M')
293 ]
294 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
295 self.mock_output)
296 self.assertEqual(len(results), 4)
297 # Check for error about new color outside shared directory
298 self.assertEqual('error', results[0].type)
299 self.assertTrue(
300 'New color(s) must be added to the' in results[0].message)
301 # Check for warning about new color in shared directory
302 self.assertEqual('warning', results[1].type)
303 self.assertTrue('New color(s) added in' in results[1].message)
304 # Check for warning about modified color in shared directory
305 self.assertEqual('warning', results[2].type)
306 self.assertTrue('Color(s) modified in' in results[2].message)
307 # Check for warning about modified color outside shared directory
308 self.assertEqual('warning', results[3].type)
309 self.assertTrue('Color(s) modified' in results[3].message)
310
311 def testNonColorsetFiles(self):
312 """Test that non-colorset files are ignored."""
313 self.mock_input.files = [
314 PRESUBMIT_test_mocks.MockFile(
315 'ios/chrome/common/ui/colors/resources/Assets.xcassets/'
316 'test_file.json', [],
317 action='A'),
318 PRESUBMIT_test_mocks.MockFile(
319 'ios/chrome/browser/ui/colors/test_file.mm', [], action='M')
320 ]
321 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
322 self.mock_output)
323 self.assertEqual(len(results), 0)
324
Sylvain Defresnefcda19f2017-06-27 10:14:01325if __name__ == '__main__':
Gauthier Ambard1981d622022-09-13 09:34:49326 unittest.main()