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 testOrderAlreadyWrong(self
):
184 scope
= [(1, '#include "b.h"'),
185 (2, '#include "a.h"'),
186 (3, '#include "c.h"')]
187 mock_input_api
= MockInputApi()
188 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
190 self
.assertEqual(0, len(warnings
))
192 def testConflictAdded1(self
):
193 scope
= [(1, '#include "a.h"'),
194 (2, '#include "c.h"'),
195 (3, '#include "b.h"')]
196 mock_input_api
= MockInputApi()
197 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
199 self
.assertEqual(1, len(warnings
))
200 self
.assertTrue('3' in warnings
[0])
202 def testConflictAdded2(self
):
203 scope
= [(1, '#include "c.h"'),
204 (2, '#include "b.h"'),
205 (3, '#include "d.h"')]
206 mock_input_api
= MockInputApi()
207 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
209 self
.assertEqual(1, len(warnings
))
210 self
.assertTrue('2' in warnings
[0])
212 def testIfElifElseEndif(self
):
213 mock_input_api
= MockInputApi()
214 contents
= ['#include "e.h"',
227 mock_file
= MockFile('', contents
)
228 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
229 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
230 self
.assertEqual(0, len(warnings
))
232 def testSysIncludes(self
):
233 # #include <sys/...>'s can appear in any order.
234 mock_input_api
= MockInputApi()
235 contents
= ['#include <sys/b.h>',
236 '#include <sys/a.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 testCheckOnlyCFiles(self
):
243 mock_input_api
= MockInputApi()
244 mock_output_api
= MockOutputApi()
245 contents
= ['#include <b.h>',
247 mock_file_cc
= MockFile('something.cc', contents
)
248 mock_file_h
= MockFile('something.h', contents
)
249 mock_file_other
= MockFile('something.py', contents
)
250 mock_input_api
.files
= [mock_file_cc
, mock_file_h
, mock_file_other
]
251 warnings
= PRESUBMIT
._CheckIncludeOrder
(mock_input_api
, mock_output_api
)
252 self
.assertEqual(1, len(warnings
))
253 self
.assertEqual(2, len(warnings
[0].items
))
254 self
.assertEqual('promptOrNotify', warnings
[0].type)
256 def testUncheckableIncludes(self
):
257 mock_input_api
= MockInputApi()
258 contents
= ['#include <windows.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 contents
= ['#include "gpu/command_buffer/gles_autogen.h"',
269 mock_file
= MockFile('', contents
)
270 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
271 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
272 self
.assertEqual(0, len(warnings
))
274 contents
= ['#include "gl_mock_autogen.h"',
277 mock_file
= MockFile('', contents
)
278 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
279 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
280 self
.assertEqual(0, len(warnings
))
282 contents
= ['#include "ipc/some_macros.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
))
291 class VersionControlConflictsTest(unittest
.TestCase
):
292 def testTypicalConflict(self
):
293 lines
= ['<<<<<<< HEAD',
294 ' base::ScopedTempDir temp_dir_;',
296 ' ScopedTempDir temp_dir_;',
298 errors
= PRESUBMIT
._CheckForVersionControlConflictsInFile
(
299 MockInputApi(), MockFile('some/path/foo_platform.cc', lines
))
300 self
.assertEqual(3, len(errors
))
301 self
.assertTrue('1' in errors
[0])
302 self
.assertTrue('3' in errors
[1])
303 self
.assertTrue('5' in errors
[2])
306 class BadExtensionsTest(unittest
.TestCase
):
307 def testBadRejFile(self
):
308 mock_input_api
= MockInputApi()
309 mock_input_api
.files
= [
310 MockFile('some/path/foo.cc', ''),
311 MockFile('some/path/foo.cc.rej', ''),
312 MockFile('some/path2/bar.h.rej', ''),
315 results
= PRESUBMIT
._CheckPatchFiles
(mock_input_api
, MockOutputApi())
316 self
.assertEqual(1, len(results
))
317 self
.assertEqual(2, len(results
[0].items
))
318 self
.assertTrue('foo.cc.rej' in results
[0].items
[0])
319 self
.assertTrue('bar.h.rej' in results
[0].items
[1])
321 def testBadOrigFile(self
):
322 mock_input_api
= MockInputApi()
323 mock_input_api
.files
= [
324 MockFile('other/path/qux.h.orig', ''),
325 MockFile('other/path/qux.h', ''),
326 MockFile('other/path/qux.cc', ''),
329 results
= PRESUBMIT
._CheckPatchFiles
(mock_input_api
, MockOutputApi())
330 self
.assertEqual(1, len(results
))
331 self
.assertEqual(1, len(results
[0].items
))
332 self
.assertTrue('qux.h.orig' in results
[0].items
[0])
334 def testGoodFiles(self
):
335 mock_input_api
= MockInputApi()
336 mock_input_api
.files
= [
337 MockFile('other/path/qux.h', ''),
338 MockFile('other/path/qux.cc', ''),
340 results
= PRESUBMIT
._CheckPatchFiles
(mock_input_api
, MockOutputApi())
341 self
.assertEqual(0, len(results
))
343 def testOnlyOwnersFiles(self
):
344 mock_change
= MockChange([
346 'A\Windows\Path\OWNERS',
348 results
= PRESUBMIT
.GetPreferredTrySlaves(None, mock_change
)
349 self
.assertEqual(0, len(results
))
352 class InvalidOSMacroNamesTest(unittest
.TestCase
):
353 def testInvalidOSMacroNames(self
):
354 lines
= ['#if defined(OS_WINDOWS)',
355 ' #elif defined(OS_WINDOW)',
356 ' # if defined(OS_MACOSX) || defined(OS_CHROME)',
357 '# else // defined(OS_MAC)',
358 '#endif // defined(OS_MACOS)']
359 errors
= PRESUBMIT
._CheckForInvalidOSMacrosInFile
(
360 MockInputApi(), MockFile('some/path/foo_platform.cc', lines
))
361 self
.assertEqual(len(lines
), len(errors
))
362 self
.assertTrue(':1 OS_WINDOWS' in errors
[0])
363 self
.assertTrue('(did you mean OS_WIN?)' in errors
[0])
365 def testValidOSMacroNames(self
):
366 lines
= ['#if defined(%s)' % m
for m
in PRESUBMIT
._VALID
_OS
_MACROS
]
367 errors
= PRESUBMIT
._CheckForInvalidOSMacrosInFile
(
368 MockInputApi(), MockFile('some/path/foo_platform.cc', lines
))
369 self
.assertEqual(0, len(errors
))
372 if __name__
== '__main__':