blob: 875030eadb15b03111018c48dac99bf8a3ba8f6d [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
Federica Germinario94204012025-04-16 18:20:59193class _CheckUIGraphicsBeginImageContextWithOptions(unittest.TestCase):
194 """Test the _CheckUIGraphicsBeginImageContextWithOptions presubmit."""
195
196 def testFindUsesOfDeprecatedAPIs(self):
197 good_lines = [
198 '// Update UIGraphicsBeginImageContextWithOptions',
199 ]
200 bad_lines = [
201 'UIGraphicsBeginImageContextWithOptions(',
202 ]
203
204 mock_input = PRESUBMIT_test_mocks.MockInputApi()
205 mock_input.files = [
206 PRESUBMIT_test_mocks.MockFile('ios/path/deprecated.mm',
207 good_lines + bad_lines),
208 ]
209 mock_output = PRESUBMIT_test_mocks.MockOutputApi()
210 errors = PRESUBMIT._CheckUIGraphicsBeginImageContextWithOptions(
211 mock_input, mock_output)
212 self.assertEqual(len(errors), 1)
213 self.assertEqual('error', errors[0].type)
214 self.assertFalse('ios/path/deprecated.mm:1' in errors[0].message)
215 self.assertTrue('ios/path/deprecated.mm:2' in errors[0].message)
216
Benjamin Williams715f0232025-02-20 12:44:09217
218class CheckNewColorIntroductionTest(unittest.TestCase):
219 """Test the _CheckNewColorIntroduction presubmit check."""
220
221 def setUp(self):
222 self.mock_input = PRESUBMIT_test_mocks.MockInputApi()
223 self.mock_output = PRESUBMIT_test_mocks.MockOutputApi()
224
225 def testNoColorChanges(self):
226 """Test when there are no color file changes."""
227 self.mock_input.files = [
228 PRESUBMIT_test_mocks.MockFile('ios/path/some_controller.mm', [])
229 ]
230 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
231 self.mock_output)
232 self.assertEqual(len(results), 0)
233
234 def testNewColorInSharedDirectory(self):
235 """Test adding a new color in the shared directory."""
236 self.mock_input.files = [
237 PRESUBMIT_test_mocks.MockFile(
238 'ios/chrome/common/ui/colors/resources/Assets.xcassets/'
239 'test_color.colorset/Contents.json', [],
240 action='A')
241 ]
242 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
243 self.mock_output)
244 self.assertEqual(len(results), 1)
245 self.assertEqual('warning', results[0].type)
246 self.assertTrue('New color(s) added in' in results[0].message)
247 self.assertTrue(
248 'ensure the color does not already exist' in results[0].message)
249
250 def testNewColorOutsideSharedDirectory(self):
251 """Test adding a new color outside the shared directory."""
252 self.mock_input.files = [
253 PRESUBMIT_test_mocks.MockFile(
254 'ios/chrome/browser/safety_check/resources/Assets.xcassets/'
255 'test_color.colorset/Contents.json', [],
256 action='A')
257 ]
258 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
259 self.mock_output)
260 self.assertEqual(len(results), 1)
261 self.assertEqual('error', results[0].type)
262 self.assertTrue(
263 'New color(s) must be added to the' in results[0].message)
264 self.assertTrue('ios/chrome/common/ui/colors' in results[0].message)
265
266 def testModifiedColorInSharedDirectory(self):
267 """Test modifying an existing color in the shared directory."""
268 self.mock_input.files = [
269 PRESUBMIT_test_mocks.MockFile(
270 'ios/chrome/common/ui/colors/resources/Assets.xcassets/'
271 'test_color.colorset/Contents.json', [],
272 action='M')
273 ]
274 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
275 self.mock_output)
276 self.assertEqual(len(results), 1)
277 self.assertEqual('warning', results[0].type)
278 self.assertTrue('Color(s) modified in' in results[0].message)
279 self.assertTrue(
280 'ensure the color does not already exist' in results[0].message)
281
282 def testModifiedColorOutsideSharedDirectory(self):
283 """Test modifying an existing color outside the shared directory."""
284 self.mock_input.files = [
285 PRESUBMIT_test_mocks.MockFile(
286 'ios/chrome/browser/safety_check/resources/Assets.xcassets/'
287 'test_color.colorset/Contents.json', [],
288 action='M')
289 ]
290 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
291 self.mock_output)
292 self.assertEqual(len(results), 1)
293 self.assertEqual('warning', results[0].type)
294 self.assertTrue('Color(s) modified' in results[0].message)
295 self.assertTrue(
296 'ensure the color does not already exist' in results[0].message)
297
298 def testMultipleColorChanges(self):
299 """Test multiple color changes in different locations."""
300 self.mock_input.files = [
301 PRESUBMIT_test_mocks.MockFile(
302 'ios/chrome/common/ui/colors/resources/Assets.xcassets/'
303 'color1.colorset/Contents.json', [],
304 action='A'),
305 PRESUBMIT_test_mocks.MockFile(
306 'ios/chrome/browser/safety_check/resources/Assets.xcassets/'
307 'color2.colorset/Contents.json', [],
308 action='A'),
309 PRESUBMIT_test_mocks.MockFile(
310 'ios/chrome/common/ui/colors/resources/Assets.xcassets/'
311 'color3.colorset/Contents.json', [],
312 action='M'),
313 PRESUBMIT_test_mocks.MockFile(
314 'ios/chrome/browser/safety_check/resources/Assets.xcassets/'
315 'color4.colorset/Contents.json', [],
316 action='M')
317 ]
318 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
319 self.mock_output)
320 self.assertEqual(len(results), 4)
321 # Check for error about new color outside shared directory
322 self.assertEqual('error', results[0].type)
323 self.assertTrue(
324 'New color(s) must be added to the' in results[0].message)
325 # Check for warning about new color in shared directory
326 self.assertEqual('warning', results[1].type)
327 self.assertTrue('New color(s) added in' in results[1].message)
328 # Check for warning about modified color in shared directory
329 self.assertEqual('warning', results[2].type)
330 self.assertTrue('Color(s) modified in' in results[2].message)
331 # Check for warning about modified color outside shared directory
332 self.assertEqual('warning', results[3].type)
333 self.assertTrue('Color(s) modified' in results[3].message)
334
335 def testNonColorsetFiles(self):
336 """Test that non-colorset files are ignored."""
337 self.mock_input.files = [
338 PRESUBMIT_test_mocks.MockFile(
339 'ios/chrome/common/ui/colors/resources/Assets.xcassets/'
340 'test_file.json', [],
341 action='A'),
342 PRESUBMIT_test_mocks.MockFile(
Gauthier Ambard7bb67f072025-03-28 08:31:22343 'ios/chrome/browser/colors/ui_bundled/test_file.mm', [],
344 action='M')
Benjamin Williams715f0232025-02-20 12:44:09345 ]
346 results = PRESUBMIT._CheckNewColorIntroduction(self.mock_input,
347 self.mock_output)
348 self.assertEqual(len(results), 0)
349
Sylvain Defresnefcda19f2017-06-27 10:14:01350if __name__ == '__main__':
Gauthier Ambard1981d622022-09-13 09:34:49351 unittest.main()