blob: 22380f62e47b32ec89658c4b60d7613badf55fd8 [file] [log] [blame]
yzshen2e936f42014-10-27 09:13:22 -07001#!/usr/bin/env python
2# Copyright (c) 2012 The Chromium Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
yzshen2e936f42014-10-27 09:13:22 -07006import re
yzshen2e936f42014-10-27 09:13:22 -07007import unittest
8
9import PRESUBMIT
Colin Blundell8e4e30a2014-12-12 07:26:05 +010010from PRESUBMIT_test_mocks import MockChange, MockFile
11from PRESUBMIT_test_mocks import MockInputApi, MockOutputApi
yzshen2e936f42014-10-27 09:13:22 -070012
13
14_TEST_DATA_DIR = 'base/test/data/presubmit'
15
16
yzshen2e936f42014-10-27 09:13:22 -070017class IncludeOrderTest(unittest.TestCase):
18 def testSystemHeaderOrder(self):
19 scope = [(1, '#include <csystem.h>'),
20 (2, '#include <cppsystem>'),
21 (3, '#include "acustom.h"')]
22 all_linenums = [linenum for (linenum, _) in scope]
23 mock_input_api = MockInputApi()
24 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
25 '', all_linenums)
26 self.assertEqual(0, len(warnings))
27
28 def testSystemHeaderOrderMismatch1(self):
29 scope = [(10, '#include <cppsystem>'),
30 (20, '#include <csystem.h>'),
31 (30, '#include "acustom.h"')]
32 all_linenums = [linenum for (linenum, _) in scope]
33 mock_input_api = MockInputApi()
34 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
35 '', all_linenums)
36 self.assertEqual(1, len(warnings))
37 self.assertTrue('20' in warnings[0])
38
39 def testSystemHeaderOrderMismatch2(self):
40 scope = [(10, '#include <cppsystem>'),
41 (20, '#include "acustom.h"'),
42 (30, '#include <csystem.h>')]
43 all_linenums = [linenum for (linenum, _) in scope]
44 mock_input_api = MockInputApi()
45 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
46 '', all_linenums)
47 self.assertEqual(1, len(warnings))
48 self.assertTrue('30' in warnings[0])
49
50 def testSystemHeaderOrderMismatch3(self):
51 scope = [(10, '#include "acustom.h"'),
52 (20, '#include <csystem.h>'),
53 (30, '#include <cppsystem>')]
54 all_linenums = [linenum for (linenum, _) in scope]
55 mock_input_api = MockInputApi()
56 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
57 '', all_linenums)
58 self.assertEqual(2, len(warnings))
59 self.assertTrue('20' in warnings[0])
60 self.assertTrue('30' in warnings[1])
61
62 def testAlphabeticalOrderMismatch(self):
63 scope = [(10, '#include <csystem.h>'),
64 (15, '#include <bsystem.h>'),
65 (20, '#include <cppsystem>'),
66 (25, '#include <bppsystem>'),
67 (30, '#include "bcustom.h"'),
68 (35, '#include "acustom.h"')]
69 all_linenums = [linenum for (linenum, _) in scope]
70 mock_input_api = MockInputApi()
71 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
72 '', all_linenums)
73 self.assertEqual(3, len(warnings))
74 self.assertTrue('15' in warnings[0])
75 self.assertTrue('25' in warnings[1])
76 self.assertTrue('35' in warnings[2])
77
78 def testSpecialFirstInclude1(self):
79 mock_input_api = MockInputApi()
80 contents = ['#include "some/path/foo.h"',
81 '#include "a/header.h"']
82 mock_file = MockFile('some/path/foo.cc', contents)
83 warnings = PRESUBMIT._CheckIncludeOrderInFile(
84 mock_input_api, mock_file, range(1, len(contents) + 1))
85 self.assertEqual(0, len(warnings))
86
87 def testSpecialFirstInclude2(self):
88 mock_input_api = MockInputApi()
89 contents = ['#include "some/other/path/foo.h"',
90 '#include "a/header.h"']
91 mock_file = MockFile('some/path/foo.cc', contents)
92 warnings = PRESUBMIT._CheckIncludeOrderInFile(
93 mock_input_api, mock_file, range(1, len(contents) + 1))
94 self.assertEqual(0, len(warnings))
95
96 def testSpecialFirstInclude3(self):
97 mock_input_api = MockInputApi()
98 contents = ['#include "some/path/foo.h"',
99 '#include "a/header.h"']
100 mock_file = MockFile('some/path/foo_platform.cc', contents)
101 warnings = PRESUBMIT._CheckIncludeOrderInFile(
102 mock_input_api, mock_file, range(1, len(contents) + 1))
103 self.assertEqual(0, len(warnings))
104
105 def testSpecialFirstInclude4(self):
106 mock_input_api = MockInputApi()
107 contents = ['#include "some/path/bar.h"',
108 '#include "a/header.h"']
109 mock_file = MockFile('some/path/foo_platform.cc', contents)
110 warnings = PRESUBMIT._CheckIncludeOrderInFile(
111 mock_input_api, mock_file, range(1, len(contents) + 1))
112 self.assertEqual(1, len(warnings))
113 self.assertTrue('2' in warnings[0])
114
115 def testSpecialFirstInclude5(self):
116 mock_input_api = MockInputApi()
117 contents = ['#include "some/other/path/foo.h"',
118 '#include "a/header.h"']
119 mock_file = MockFile('some/path/foo-suffix.h', contents)
120 warnings = PRESUBMIT._CheckIncludeOrderInFile(
121 mock_input_api, mock_file, range(1, len(contents) + 1))
122 self.assertEqual(0, len(warnings))
123
124 def testSpecialFirstInclude6(self):
125 mock_input_api = MockInputApi()
126 contents = ['#include "some/other/path/foo_win.h"',
127 '#include <set>',
128 '#include "a/header.h"']
129 mock_file = MockFile('some/path/foo_unittest_win.h', contents)
130 warnings = PRESUBMIT._CheckIncludeOrderInFile(
131 mock_input_api, mock_file, range(1, len(contents) + 1))
132 self.assertEqual(0, len(warnings))
133
134 def testOrderAlreadyWrong(self):
135 scope = [(1, '#include "b.h"'),
136 (2, '#include "a.h"'),
137 (3, '#include "c.h"')]
138 mock_input_api = MockInputApi()
139 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
140 '', [3])
141 self.assertEqual(0, len(warnings))
142
143 def testConflictAdded1(self):
144 scope = [(1, '#include "a.h"'),
145 (2, '#include "c.h"'),
146 (3, '#include "b.h"')]
147 mock_input_api = MockInputApi()
148 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
149 '', [2])
150 self.assertEqual(1, len(warnings))
151 self.assertTrue('3' in warnings[0])
152
153 def testConflictAdded2(self):
154 scope = [(1, '#include "c.h"'),
155 (2, '#include "b.h"'),
156 (3, '#include "d.h"')]
157 mock_input_api = MockInputApi()
158 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
159 '', [2])
160 self.assertEqual(1, len(warnings))
161 self.assertTrue('2' in warnings[0])
162
163 def testIfElifElseEndif(self):
164 mock_input_api = MockInputApi()
165 contents = ['#include "e.h"',
166 '#define foo',
167 '#include "f.h"',
168 '#undef foo',
169 '#include "e.h"',
170 '#if foo',
171 '#include "d.h"',
172 '#elif bar',
173 '#include "c.h"',
174 '#else',
175 '#include "b.h"',
176 '#endif',
177 '#include "a.h"']
178 mock_file = MockFile('', contents)
179 warnings = PRESUBMIT._CheckIncludeOrderInFile(
180 mock_input_api, mock_file, range(1, len(contents) + 1))
181 self.assertEqual(0, len(warnings))
182
183 def testExcludedIncludes(self):
184 # #include <sys/...>'s can appear in any order.
185 mock_input_api = MockInputApi()
186 contents = ['#include <sys/b.h>',
187 '#include <sys/a.h>']
188 mock_file = MockFile('', contents)
189 warnings = PRESUBMIT._CheckIncludeOrderInFile(
190 mock_input_api, mock_file, range(1, len(contents) + 1))
191 self.assertEqual(0, len(warnings))
192
yzshen2e936f42014-10-27 09:13:22 -0700193 contents = ['#include "build/build_config.h"',
194 '#include "aaa.h"']
195 mock_file = MockFile('', contents)
196 warnings = PRESUBMIT._CheckIncludeOrderInFile(
197 mock_input_api, mock_file, range(1, len(contents) + 1))
198 self.assertEqual(0, len(warnings))
199
200 def testCheckOnlyCFiles(self):
201 mock_input_api = MockInputApi()
202 mock_output_api = MockOutputApi()
203 contents = ['#include <b.h>',
204 '#include <a.h>']
205 mock_file_cc = MockFile('something.cc', contents)
206 mock_file_h = MockFile('something.h', contents)
207 mock_file_other = MockFile('something.py', contents)
208 mock_input_api.files = [mock_file_cc, mock_file_h, mock_file_other]
209 warnings = PRESUBMIT._CheckIncludeOrder(mock_input_api, mock_output_api)
210 self.assertEqual(1, len(warnings))
211 self.assertEqual(2, len(warnings[0].items))
212 self.assertEqual('promptOrNotify', warnings[0].type)
213
214 def testUncheckableIncludes(self):
215 mock_input_api = MockInputApi()
216 contents = ['#include <windows.h>',
217 '#include "b.h"',
218 '#include "a.h"']
219 mock_file = MockFile('', contents)
220 warnings = PRESUBMIT._CheckIncludeOrderInFile(
221 mock_input_api, mock_file, range(1, len(contents) + 1))
222 self.assertEqual(1, len(warnings))
223
224 contents = ['#include "gpu/command_buffer/gles_autogen.h"',
225 '#include "b.h"',
226 '#include "a.h"']
227 mock_file = MockFile('', contents)
228 warnings = PRESUBMIT._CheckIncludeOrderInFile(
229 mock_input_api, mock_file, range(1, len(contents) + 1))
230 self.assertEqual(1, len(warnings))
231
232 contents = ['#include "gl_mock_autogen.h"',
233 '#include "b.h"',
234 '#include "a.h"']
235 mock_file = MockFile('', contents)
236 warnings = PRESUBMIT._CheckIncludeOrderInFile(
237 mock_input_api, mock_file, range(1, len(contents) + 1))
238 self.assertEqual(1, len(warnings))
239
240 contents = ['#include "ipc/some_macros.h"',
241 '#include "b.h"',
242 '#include "a.h"']
243 mock_file = MockFile('', contents)
244 warnings = PRESUBMIT._CheckIncludeOrderInFile(
245 mock_input_api, mock_file, range(1, len(contents) + 1))
246 self.assertEqual(1, len(warnings))
247
248
249class VersionControlConflictsTest(unittest.TestCase):
250 def testTypicalConflict(self):
251 lines = ['<<<<<<< HEAD',
252 ' base::ScopedTempDir temp_dir_;',
253 '=======',
254 ' ScopedTempDir temp_dir_;',
255 '>>>>>>> master']
256 errors = PRESUBMIT._CheckForVersionControlConflictsInFile(
257 MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
258 self.assertEqual(3, len(errors))
259 self.assertTrue('1' in errors[0])
260 self.assertTrue('3' in errors[1])
261 self.assertTrue('5' in errors[2])
262
263
264class BadExtensionsTest(unittest.TestCase):
265 def testBadRejFile(self):
266 mock_input_api = MockInputApi()
267 mock_input_api.files = [
268 MockFile('some/path/foo.cc', ''),
269 MockFile('some/path/foo.cc.rej', ''),
270 MockFile('some/path2/bar.h.rej', ''),
271 ]
272
273 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
274 self.assertEqual(1, len(results))
275 self.assertEqual(2, len(results[0].items))
276 self.assertTrue('foo.cc.rej' in results[0].items[0])
277 self.assertTrue('bar.h.rej' in results[0].items[1])
278
279 def testBadOrigFile(self):
280 mock_input_api = MockInputApi()
281 mock_input_api.files = [
282 MockFile('other/path/qux.h.orig', ''),
283 MockFile('other/path/qux.h', ''),
284 MockFile('other/path/qux.cc', ''),
285 ]
286
287 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
288 self.assertEqual(1, len(results))
289 self.assertEqual(1, len(results[0].items))
290 self.assertTrue('qux.h.orig' in results[0].items[0])
291
292 def testGoodFiles(self):
293 mock_input_api = MockInputApi()
294 mock_input_api.files = [
295 MockFile('other/path/qux.h', ''),
296 MockFile('other/path/qux.cc', ''),
297 ]
298 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
299 self.assertEqual(0, len(results))
300
Viet-Trung Luu0d4fef62015-04-09 15:45:05 -0700301 def testNoFiles(self):
302 mock_change = MockChange([])
yzshen2e936f42014-10-27 09:13:22 -0700303 results = PRESUBMIT.GetPreferredTryMasters(None, mock_change)
304 self.assertEqual({}, results)
305
306
307class InvalidOSMacroNamesTest(unittest.TestCase):
308 def testInvalidOSMacroNames(self):
309 lines = ['#if defined(OS_WINDOWS)',
310 ' #elif defined(OS_WINDOW)',
311 ' # if defined(OS_MACOSX) || defined(OS_CHROME)',
312 '# else // defined(OS_MAC)',
313 '#endif // defined(OS_MACOS)']
314 errors = PRESUBMIT._CheckForInvalidOSMacrosInFile(
315 MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
316 self.assertEqual(len(lines), len(errors))
317 self.assertTrue(':1 OS_WINDOWS' in errors[0])
318 self.assertTrue('(did you mean OS_WIN?)' in errors[0])
319
320 def testValidOSMacroNames(self):
321 lines = ['#if defined(%s)' % m for m in PRESUBMIT._VALID_OS_MACROS]
322 errors = PRESUBMIT._CheckForInvalidOSMacrosInFile(
323 MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
324 self.assertEqual(0, len(errors))
325
326
327class InvalidIfDefinedMacroNamesTest(unittest.TestCase):
328 def testInvalidIfDefinedMacroNames(self):
329 lines = ['#if defined(TARGET_IPHONE_SIMULATOR)',
330 '#if !defined(TARGET_IPHONE_SIMULATOR)',
331 '#elif defined(TARGET_IPHONE_SIMULATOR)',
332 '#ifdef TARGET_IPHONE_SIMULATOR',
333 ' # ifdef TARGET_IPHONE_SIMULATOR',
334 '# if defined(VALID) || defined(TARGET_IPHONE_SIMULATOR)',
335 '# else // defined(TARGET_IPHONE_SIMULATOR)',
336 '#endif // defined(TARGET_IPHONE_SIMULATOR)',]
337 errors = PRESUBMIT._CheckForInvalidIfDefinedMacrosInFile(
338 MockInputApi(), MockFile('some/path/source.mm', lines))
339 self.assertEqual(len(lines), len(errors))
340
341 def testValidIfDefinedMacroNames(self):
342 lines = ['#if defined(FOO)',
343 '#ifdef BAR',]
344 errors = PRESUBMIT._CheckForInvalidIfDefinedMacrosInFile(
345 MockInputApi(), MockFile('some/path/source.cc', lines))
346 self.assertEqual(0, len(errors))
347
348
yzshen2e936f42014-10-27 09:13:22 -0700349if __name__ == '__main__':
350 unittest.main()