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.
13 class MockInputApi(object):
16 self
.os_path
= os
.path
18 self
.is_committing
= False
20 def AffectedFiles(self
):
24 class MockOutputApi(object):
25 class PresubmitResult(object):
26 def __init__(self
, message
, items
=None, long_text
=''):
27 self
.message
= message
29 self
.long_text
= long_text
31 class PresubmitError(PresubmitResult
):
32 def __init__(self
, message
, items
, long_text
=''):
33 MockOutputApi
.PresubmitResult
.__init
__(self
, message
, items
, long_text
)
36 class PresubmitPromptWarning(PresubmitResult
):
37 def __init__(self
, message
, items
, long_text
=''):
38 MockOutputApi
.PresubmitResult
.__init
__(self
, message
, items
, long_text
)
41 class PresubmitNotifyResult(PresubmitResult
):
42 def __init__(self
, message
, items
, long_text
=''):
43 MockOutputApi
.PresubmitResult
.__init
__(self
, message
, items
, long_text
)
46 class PresubmitPromptOrNotify(PresubmitResult
):
47 def __init__(self
, message
, items
, long_text
=''):
48 MockOutputApi
.PresubmitResult
.__init
__(self
, message
, items
, long_text
)
49 self
.type = 'promptOrNotify'
52 class MockFile(object):
53 def __init__(self
, local_path
, new_contents
):
54 self
._local
_path
= local_path
55 self
._new
_contents
= new_contents
56 self
._changed
_contents
= [(i
+ 1, l
) for i
, l
in enumerate(new_contents
)]
58 def ChangedContents(self
):
59 return self
._changed
_contents
61 def NewContents(self
):
62 return self
._new
_contents
65 return self
._local
_path
68 class MockChange(object):
69 def __init__(self
, changed_files
):
70 self
._changed
_files
= changed_files
73 return self
._changed
_files
76 class IncludeOrderTest(unittest
.TestCase
):
77 def testSystemHeaderOrder(self
):
78 scope
= [(1, '#include <csystem.h>'),
79 (2, '#include <cppsystem>'),
80 (3, '#include "acustom.h"')]
81 all_linenums
= [linenum
for (linenum
, _
) in scope
]
82 mock_input_api
= MockInputApi()
83 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
85 self
.assertEqual(0, len(warnings
))
87 def testSystemHeaderOrderMismatch1(self
):
88 scope
= [(10, '#include <cppsystem>'),
89 (20, '#include <csystem.h>'),
90 (30, '#include "acustom.h"')]
91 all_linenums
= [linenum
for (linenum
, _
) in scope
]
92 mock_input_api
= MockInputApi()
93 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
95 self
.assertEqual(1, len(warnings
))
96 self
.assertTrue('20' in warnings
[0])
98 def testSystemHeaderOrderMismatch2(self
):
99 scope
= [(10, '#include <cppsystem>'),
100 (20, '#include "acustom.h"'),
101 (30, '#include <csystem.h>')]
102 all_linenums
= [linenum
for (linenum
, _
) in scope
]
103 mock_input_api
= MockInputApi()
104 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
106 self
.assertEqual(1, len(warnings
))
107 self
.assertTrue('30' in warnings
[0])
109 def testSystemHeaderOrderMismatch3(self
):
110 scope
= [(10, '#include "acustom.h"'),
111 (20, '#include <csystem.h>'),
112 (30, '#include <cppsystem>')]
113 all_linenums
= [linenum
for (linenum
, _
) in scope
]
114 mock_input_api
= MockInputApi()
115 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
117 self
.assertEqual(2, len(warnings
))
118 self
.assertTrue('20' in warnings
[0])
119 self
.assertTrue('30' in warnings
[1])
121 def testAlphabeticalOrderMismatch(self
):
122 scope
= [(10, '#include <csystem.h>'),
123 (15, '#include <bsystem.h>'),
124 (20, '#include <cppsystem>'),
125 (25, '#include <bppsystem>'),
126 (30, '#include "bcustom.h"'),
127 (35, '#include "acustom.h"')]
128 all_linenums
= [linenum
for (linenum
, _
) in scope
]
129 mock_input_api
= MockInputApi()
130 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
132 self
.assertEqual(3, len(warnings
))
133 self
.assertTrue('15' in warnings
[0])
134 self
.assertTrue('25' in warnings
[1])
135 self
.assertTrue('35' in warnings
[2])
137 def testSpecialFirstInclude1(self
):
138 mock_input_api
= MockInputApi()
139 contents
= ['#include "some/path/foo.h"',
140 '#include "a/header.h"']
141 mock_file
= MockFile('some/path/foo.cc', contents
)
142 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
143 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
144 self
.assertEqual(0, len(warnings
))
146 def testSpecialFirstInclude2(self
):
147 mock_input_api
= MockInputApi()
148 contents
= ['#include "some/other/path/foo.h"',
149 '#include "a/header.h"']
150 mock_file
= MockFile('some/path/foo.cc', contents
)
151 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
152 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
153 self
.assertEqual(0, len(warnings
))
155 def testSpecialFirstInclude3(self
):
156 mock_input_api
= MockInputApi()
157 contents
= ['#include "some/path/foo.h"',
158 '#include "a/header.h"']
159 mock_file
= MockFile('some/path/foo_platform.cc', contents
)
160 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
161 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
162 self
.assertEqual(0, len(warnings
))
164 def testSpecialFirstInclude4(self
):
165 mock_input_api
= MockInputApi()
166 contents
= ['#include "some/path/bar.h"',
167 '#include "a/header.h"']
168 mock_file
= MockFile('some/path/foo_platform.cc', contents
)
169 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
170 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
171 self
.assertEqual(1, len(warnings
))
172 self
.assertTrue('2' in warnings
[0])
174 def testSpecialFirstInclude5(self
):
175 mock_input_api
= MockInputApi()
176 contents
= ['#include "some/other/path/foo.h"',
177 '#include "a/header.h"']
178 mock_file
= MockFile('some/path/foo-suffix.h', contents
)
179 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
180 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
181 self
.assertEqual(0, len(warnings
))
183 def testSpecialFirstInclude6(self
):
184 mock_input_api
= MockInputApi()
185 contents
= ['#include "some/other/path/foo_win.h"',
187 '#include "a/header.h"']
188 mock_file
= MockFile('some/path/foo_unittest_win.h', contents
)
189 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
190 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
191 self
.assertEqual(0, len(warnings
))
193 def testOrderAlreadyWrong(self
):
194 scope
= [(1, '#include "b.h"'),
195 (2, '#include "a.h"'),
196 (3, '#include "c.h"')]
197 mock_input_api
= MockInputApi()
198 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
200 self
.assertEqual(0, len(warnings
))
202 def testConflictAdded1(self
):
203 scope
= [(1, '#include "a.h"'),
204 (2, '#include "c.h"'),
205 (3, '#include "b.h"')]
206 mock_input_api
= MockInputApi()
207 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
209 self
.assertEqual(1, len(warnings
))
210 self
.assertTrue('3' in warnings
[0])
212 def testConflictAdded2(self
):
213 scope
= [(1, '#include "c.h"'),
214 (2, '#include "b.h"'),
215 (3, '#include "d.h"')]
216 mock_input_api
= MockInputApi()
217 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
219 self
.assertEqual(1, len(warnings
))
220 self
.assertTrue('2' in warnings
[0])
222 def testIfElifElseEndif(self
):
223 mock_input_api
= MockInputApi()
224 contents
= ['#include "e.h"',
237 mock_file
= MockFile('', contents
)
238 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
239 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
240 self
.assertEqual(0, len(warnings
))
242 def testExcludedIncludes(self
):
243 # #include <sys/...>'s can appear in any order.
244 mock_input_api
= MockInputApi()
245 contents
= ['#include <sys/b.h>',
246 '#include <sys/a.h>']
247 mock_file
= MockFile('', contents
)
248 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
249 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
250 self
.assertEqual(0, len(warnings
))
252 contents
= ['#include <atlbase.h>',
254 mock_file
= MockFile('', contents
)
255 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
256 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
257 self
.assertEqual(0, len(warnings
))
259 contents
= ['#include "build/build_config.h"',
261 mock_file
= MockFile('', contents
)
262 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
263 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
264 self
.assertEqual(0, len(warnings
))
266 def testCheckOnlyCFiles(self
):
267 mock_input_api
= MockInputApi()
268 mock_output_api
= MockOutputApi()
269 contents
= ['#include <b.h>',
271 mock_file_cc
= MockFile('something.cc', contents
)
272 mock_file_h
= MockFile('something.h', contents
)
273 mock_file_other
= MockFile('something.py', contents
)
274 mock_input_api
.files
= [mock_file_cc
, mock_file_h
, mock_file_other
]
275 warnings
= PRESUBMIT
._CheckIncludeOrder
(mock_input_api
, mock_output_api
)
276 self
.assertEqual(1, len(warnings
))
277 self
.assertEqual(2, len(warnings
[0].items
))
278 self
.assertEqual('promptOrNotify', warnings
[0].type)
280 def testUncheckableIncludes(self
):
281 mock_input_api
= MockInputApi()
282 contents
= ['#include <windows.h>',
285 mock_file
= MockFile('', contents
)
286 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
287 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
288 self
.assertEqual(0, len(warnings
))
290 contents
= ['#include "gpu/command_buffer/gles_autogen.h"',
293 mock_file
= MockFile('', contents
)
294 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
295 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
296 self
.assertEqual(0, len(warnings
))
298 contents
= ['#include "gl_mock_autogen.h"',
301 mock_file
= MockFile('', contents
)
302 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
303 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
304 self
.assertEqual(0, len(warnings
))
306 contents
= ['#include "ipc/some_macros.h"',
309 mock_file
= MockFile('', contents
)
310 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
311 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
312 self
.assertEqual(0, len(warnings
))
315 class VersionControlConflictsTest(unittest
.TestCase
):
316 def testTypicalConflict(self
):
317 lines
= ['<<<<<<< HEAD',
318 ' base::ScopedTempDir temp_dir_;',
320 ' ScopedTempDir temp_dir_;',
322 errors
= PRESUBMIT
._CheckForVersionControlConflictsInFile
(
323 MockInputApi(), MockFile('some/path/foo_platform.cc', lines
))
324 self
.assertEqual(3, len(errors
))
325 self
.assertTrue('1' in errors
[0])
326 self
.assertTrue('3' in errors
[1])
327 self
.assertTrue('5' in errors
[2])
330 class BadExtensionsTest(unittest
.TestCase
):
331 def testBadRejFile(self
):
332 mock_input_api
= MockInputApi()
333 mock_input_api
.files
= [
334 MockFile('some/path/foo.cc', ''),
335 MockFile('some/path/foo.cc.rej', ''),
336 MockFile('some/path2/bar.h.rej', ''),
339 results
= PRESUBMIT
._CheckPatchFiles
(mock_input_api
, MockOutputApi())
340 self
.assertEqual(1, len(results
))
341 self
.assertEqual(2, len(results
[0].items
))
342 self
.assertTrue('foo.cc.rej' in results
[0].items
[0])
343 self
.assertTrue('bar.h.rej' in results
[0].items
[1])
345 def testBadOrigFile(self
):
346 mock_input_api
= MockInputApi()
347 mock_input_api
.files
= [
348 MockFile('other/path/qux.h.orig', ''),
349 MockFile('other/path/qux.h', ''),
350 MockFile('other/path/qux.cc', ''),
353 results
= PRESUBMIT
._CheckPatchFiles
(mock_input_api
, MockOutputApi())
354 self
.assertEqual(1, len(results
))
355 self
.assertEqual(1, len(results
[0].items
))
356 self
.assertTrue('qux.h.orig' in results
[0].items
[0])
358 def testGoodFiles(self
):
359 mock_input_api
= MockInputApi()
360 mock_input_api
.files
= [
361 MockFile('other/path/qux.h', ''),
362 MockFile('other/path/qux.cc', ''),
364 results
= PRESUBMIT
._CheckPatchFiles
(mock_input_api
, MockOutputApi())
365 self
.assertEqual(0, len(results
))
367 def testOnlyOwnersFiles(self
):
368 mock_change
= MockChange([
370 'A\Windows\Path\OWNERS',
372 results
= PRESUBMIT
.GetPreferredTrySlaves(None, mock_change
)
373 self
.assertEqual(0, len(results
))
376 class InvalidOSMacroNamesTest(unittest
.TestCase
):
377 def testInvalidOSMacroNames(self
):
378 lines
= ['#if defined(OS_WINDOWS)',
379 ' #elif defined(OS_WINDOW)',
380 ' # if defined(OS_MACOSX) || defined(OS_CHROME)',
381 '# else // defined(OS_MAC)',
382 '#endif // defined(OS_MACOS)']
383 errors
= PRESUBMIT
._CheckForInvalidOSMacrosInFile
(
384 MockInputApi(), MockFile('some/path/foo_platform.cc', lines
))
385 self
.assertEqual(len(lines
), len(errors
))
386 self
.assertTrue(':1 OS_WINDOWS' in errors
[0])
387 self
.assertTrue('(did you mean OS_WIN?)' in errors
[0])
389 def testValidOSMacroNames(self
):
390 lines
= ['#if defined(%s)' % m
for m
in PRESUBMIT
._VALID
_OS
_MACROS
]
391 errors
= PRESUBMIT
._CheckForInvalidOSMacrosInFile
(
392 MockInputApi(), MockFile('some/path/foo_platform.cc', lines
))
393 self
.assertEqual(0, len(errors
))
396 class String16Test(unittest
.TestCase
):
397 def testUnprefixedGivesWarnings(self
):
398 lines
= ['string16 GetName() const;',
399 'void SetName(const string16& name) OVERRIDE {}',
400 'const string16& GetNameRef() const = 0;',
402 'string16 foo = ASCIIToUTF16("bar");',
403 'string16 blah(ASCIIToUTF16("blee"));',
404 'std::vector<string16> names;',
405 'string16 var_with_string16_in_name;']
406 warnings
= PRESUBMIT
._CheckForString
16InFile
(
407 MockInputApi(), MockFile('chrome/browser/name_getter_bad.cc', lines
))
408 self
.assertEqual(len(lines
), len(warnings
))
410 def testPrefixedSkipped(self
):
411 lines
= ['#include "base/strings/string16.h"',
412 'void SetName(const base::string16& name) OVERRIDE {}',
413 'const base::string16& GetNameRef() const = 0;',
414 'base::string16 name;',
415 'base::string16 foo = ASCIIToUTF16("bar");',
416 'base::string16 blah(ASCIIToUTF16("blee"));',
417 'std::vector<base::string16> names;',
418 'base::string16 var_with_string16_in_name;']
419 warnings
= PRESUBMIT
._CheckForString
16InFile
(
420 MockInputApi(), MockFile('chrome/browser/name_getter_good.cc', lines
))
421 self
.assertEqual(0, len(warnings
))
423 def testUsingYieldsNoWarnings(self
):
424 lines
= ['#include "base/strings/string16.h',
426 'using base::string16;',
427 'string16 SayHiOnlyToEd(const string16& name) {',
428 ' string16 first = name.substr(0, 2); // Only "Ed" gets a "Hi".',
429 ' return first == "Ed" ? first : string16();',
431 warnings
= PRESUBMIT
._CheckForString
16InFile
(
432 MockInputApi(), MockFile('chrome/browser/say_hi_to_ed.cc', lines
))
433 self
.assertEqual(0, len(warnings
))
436 class CheckAddedDepsHaveTetsApprovalsTest(unittest
.TestCase
):
437 def testDepsFilesToCheck(self
):
440 '"+chrome/installer",',
441 '"+chrome/plugin/chrome_content_plugin_client.h",',
442 '"+chrome/utility/chrome_content_utility_client.h",',
443 '"+chromeos/chromeos_paths.h",',
444 '"+components/breakpad",',
445 '"+components/nacl/common",',
446 '"+content/public/browser/render_process_host.h",',
447 '"+grit", # For generated headers',
448 '"+grit/generated_resources.h",',
450 '"+policy", # For generated headers and source',
452 '"+tools/memory_watcher",',
453 '"+third_party/lss/linux_syscall_support.h",',
455 files_to_check
= PRESUBMIT
._DepsFilesToCheck
(re
, changed_lines
)
458 'chrome/installer/DEPS',
459 'chrome/plugin/DEPS',
460 'chrome/utility/DEPS',
462 'components/breakpad/DEPS',
463 'components/nacl/common/DEPS',
464 'content/public/browser/DEPS',
467 'tools/memory_watcher/DEPS',
468 'third_party/lss/DEPS',
470 self
.assertEqual(expected
, files_to_check
);
473 if __name__
== '__main__':