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
)
47 class MockFile(object):
48 def __init__(self
, local_path
, new_contents
):
49 self
._local
_path
= local_path
50 self
._new
_contents
= new_contents
51 self
._changed
_contents
= [(i
+ 1, l
) for i
, l
in enumerate(new_contents
)]
53 def ChangedContents(self
):
54 return self
._changed
_contents
56 def NewContents(self
):
57 return self
._new
_contents
60 return self
._local
_path
63 class MockChange(object):
64 def __init__(self
, changed_files
):
65 self
._changed
_files
= changed_files
68 return self
._changed
_files
71 class IncludeOrderTest(unittest
.TestCase
):
72 def testSystemHeaderOrder(self
):
73 scope
= [(1, '#include <csystem.h>'),
74 (2, '#include <cppsystem>'),
75 (3, '#include "acustom.h"')]
76 all_linenums
= [linenum
for (linenum
, _
) in scope
]
77 mock_input_api
= MockInputApi()
78 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
80 self
.assertEqual(0, len(warnings
))
82 def testSystemHeaderOrderMismatch1(self
):
83 scope
= [(10, '#include <cppsystem>'),
84 (20, '#include <csystem.h>'),
85 (30, '#include "acustom.h"')]
86 all_linenums
= [linenum
for (linenum
, _
) in scope
]
87 mock_input_api
= MockInputApi()
88 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
90 self
.assertEqual(1, len(warnings
))
91 self
.assertTrue('20' in warnings
[0])
93 def testSystemHeaderOrderMismatch2(self
):
94 scope
= [(10, '#include <cppsystem>'),
95 (20, '#include "acustom.h"'),
96 (30, '#include <csystem.h>')]
97 all_linenums
= [linenum
for (linenum
, _
) in scope
]
98 mock_input_api
= MockInputApi()
99 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
101 self
.assertEqual(1, len(warnings
))
102 self
.assertTrue('30' in warnings
[0])
104 def testSystemHeaderOrderMismatch3(self
):
105 scope
= [(10, '#include "acustom.h"'),
106 (20, '#include <csystem.h>'),
107 (30, '#include <cppsystem>')]
108 all_linenums
= [linenum
for (linenum
, _
) in scope
]
109 mock_input_api
= MockInputApi()
110 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
112 self
.assertEqual(2, len(warnings
))
113 self
.assertTrue('20' in warnings
[0])
114 self
.assertTrue('30' in warnings
[1])
116 def testAlphabeticalOrderMismatch(self
):
117 scope
= [(10, '#include <csystem.h>'),
118 (15, '#include <bsystem.h>'),
119 (20, '#include <cppsystem>'),
120 (25, '#include <bppsystem>'),
121 (30, '#include "bcustom.h"'),
122 (35, '#include "acustom.h"')]
123 all_linenums
= [linenum
for (linenum
, _
) in scope
]
124 mock_input_api
= MockInputApi()
125 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
127 self
.assertEqual(3, len(warnings
))
128 self
.assertTrue('15' in warnings
[0])
129 self
.assertTrue('25' in warnings
[1])
130 self
.assertTrue('35' in warnings
[2])
132 def testSpecialFirstInclude1(self
):
133 mock_input_api
= MockInputApi()
134 contents
= ['#include "some/path/foo.h"',
135 '#include "a/header.h"']
136 mock_file
= MockFile('some/path/foo.cc', contents
)
137 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
138 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
139 self
.assertEqual(0, len(warnings
))
141 def testSpecialFirstInclude2(self
):
142 mock_input_api
= MockInputApi()
143 contents
= ['#include "some/other/path/foo.h"',
144 '#include "a/header.h"']
145 mock_file
= MockFile('some/path/foo.cc', contents
)
146 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
147 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
148 self
.assertEqual(0, len(warnings
))
150 def testSpecialFirstInclude3(self
):
151 mock_input_api
= MockInputApi()
152 contents
= ['#include "some/path/foo.h"',
153 '#include "a/header.h"']
154 mock_file
= MockFile('some/path/foo_platform.cc', contents
)
155 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
156 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
157 self
.assertEqual(0, len(warnings
))
159 def testSpecialFirstInclude4(self
):
160 mock_input_api
= MockInputApi()
161 contents
= ['#include "some/path/bar.h"',
162 '#include "a/header.h"']
163 mock_file
= MockFile('some/path/foo_platform.cc', contents
)
164 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
165 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
166 self
.assertEqual(1, len(warnings
))
167 self
.assertTrue('2' in warnings
[0])
169 def testSpecialFirstInclude5(self
):
170 mock_input_api
= MockInputApi()
171 contents
= ['#include "some/other/path/foo.h"',
172 '#include "a/header.h"']
173 mock_file
= MockFile('some/path/foo-suffix.h', contents
)
174 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
175 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
176 self
.assertEqual(0, len(warnings
))
178 def testOrderAlreadyWrong(self
):
179 scope
= [(1, '#include "b.h"'),
180 (2, '#include "a.h"'),
181 (3, '#include "c.h"')]
182 mock_input_api
= MockInputApi()
183 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
185 self
.assertEqual(0, len(warnings
))
187 def testConflictAdded1(self
):
188 scope
= [(1, '#include "a.h"'),
189 (2, '#include "c.h"'),
190 (3, '#include "b.h"')]
191 mock_input_api
= MockInputApi()
192 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
194 self
.assertEqual(1, len(warnings
))
195 self
.assertTrue('3' in warnings
[0])
197 def testConflictAdded2(self
):
198 scope
= [(1, '#include "c.h"'),
199 (2, '#include "b.h"'),
200 (3, '#include "d.h"')]
201 mock_input_api
= MockInputApi()
202 warnings
= PRESUBMIT
._CheckIncludeOrderForScope
(scope
, mock_input_api
,
204 self
.assertEqual(1, len(warnings
))
205 self
.assertTrue('2' in warnings
[0])
207 def testIfElifElseEndif(self
):
208 mock_input_api
= MockInputApi()
209 contents
= ['#include "e.h"',
222 mock_file
= MockFile('', contents
)
223 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
224 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
225 self
.assertEqual(0, len(warnings
))
227 def testSysIncludes(self
):
228 # #include <sys/...>'s can appear in any order.
229 mock_input_api
= MockInputApi()
230 contents
= ['#include <sys/b.h>',
231 '#include <sys/a.h>']
232 mock_file
= MockFile('', contents
)
233 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
234 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
235 self
.assertEqual(0, len(warnings
))
237 def testCheckOnlyCFiles(self
):
238 mock_input_api
= MockInputApi()
239 mock_output_api
= MockOutputApi()
240 contents
= ['#include <b.h>',
242 mock_file_cc
= MockFile('something.cc', contents
)
243 mock_file_h
= MockFile('something.h', contents
)
244 mock_file_other
= MockFile('something.py', contents
)
245 mock_input_api
.files
= [mock_file_cc
, mock_file_h
, mock_file_other
]
246 warnings
= PRESUBMIT
._CheckIncludeOrder
(mock_input_api
, mock_output_api
)
247 self
.assertEqual(1, len(warnings
))
248 self
.assertEqual(2, len(warnings
[0].items
))
249 self
.assertEqual('warning', warnings
[0].type)
251 def testOnlyNotifyOnCommit(self
):
252 mock_input_api
= MockInputApi()
253 mock_input_api
.is_committing
= True
254 mock_output_api
= MockOutputApi()
255 contents
= ['#include <b.h>',
257 mock_input_api
.files
= [MockFile('something.cc', contents
)]
258 warnings
= PRESUBMIT
._CheckIncludeOrder
(mock_input_api
, mock_output_api
)
259 self
.assertEqual(1, len(warnings
))
260 self
.assertEqual(1, len(warnings
[0].items
))
261 self
.assertEqual('notify', warnings
[0].type)
263 def testUncheckableIncludes(self
):
264 mock_input_api
= MockInputApi()
265 contents
= ['#include <windows.h>',
268 mock_file
= MockFile('', contents
)
269 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
270 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
271 self
.assertEqual(0, len(warnings
))
273 contents
= ['#include "gpu/command_buffer/gles_autogen.h"',
276 mock_file
= MockFile('', contents
)
277 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
278 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
279 self
.assertEqual(0, len(warnings
))
281 contents
= ['#include "gl_mock_autogen.h"',
284 mock_file
= MockFile('', contents
)
285 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
286 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
287 self
.assertEqual(0, len(warnings
))
289 contents
= ['#include "ipc/some_macros.h"',
292 mock_file
= MockFile('', contents
)
293 warnings
= PRESUBMIT
._CheckIncludeOrderInFile
(
294 mock_input_api
, mock_file
, range(1, len(contents
) + 1))
295 self
.assertEqual(0, len(warnings
))
298 class VersionControlConflictsTest(unittest
.TestCase
):
299 def testTypicalConflict(self
):
300 lines
= ['<<<<<<< HEAD',
301 ' base::ScopedTempDir temp_dir_;',
303 ' ScopedTempDir temp_dir_;',
305 errors
= PRESUBMIT
._CheckForVersionControlConflictsInFile
(
306 MockInputApi(), MockFile('some/path/foo_platform.cc', lines
))
307 self
.assertEqual(3, len(errors
))
308 self
.assertTrue('1' in errors
[0])
309 self
.assertTrue('3' in errors
[1])
310 self
.assertTrue('5' in errors
[2])
313 class BadExtensionsTest(unittest
.TestCase
):
314 def testBadRejFile(self
):
315 mock_input_api
= MockInputApi()
316 mock_input_api
.files
= [
317 MockFile('some/path/foo.cc', ''),
318 MockFile('some/path/foo.cc.rej', ''),
319 MockFile('some/path2/bar.h.rej', ''),
322 results
= PRESUBMIT
._CheckPatchFiles
(mock_input_api
, MockOutputApi())
323 self
.assertEqual(1, len(results
))
324 self
.assertEqual(2, len(results
[0].items
))
325 self
.assertTrue('foo.cc.rej' in results
[0].items
[0])
326 self
.assertTrue('bar.h.rej' in results
[0].items
[1])
328 def testBadOrigFile(self
):
329 mock_input_api
= MockInputApi()
330 mock_input_api
.files
= [
331 MockFile('other/path/qux.h.orig', ''),
332 MockFile('other/path/qux.h', ''),
333 MockFile('other/path/qux.cc', ''),
336 results
= PRESUBMIT
._CheckPatchFiles
(mock_input_api
, MockOutputApi())
337 self
.assertEqual(1, len(results
))
338 self
.assertEqual(1, len(results
[0].items
))
339 self
.assertTrue('qux.h.orig' in results
[0].items
[0])
341 def testGoodFiles(self
):
342 mock_input_api
= MockInputApi()
343 mock_input_api
.files
= [
344 MockFile('other/path/qux.h', ''),
345 MockFile('other/path/qux.cc', ''),
347 results
= PRESUBMIT
._CheckPatchFiles
(mock_input_api
, MockOutputApi())
348 self
.assertEqual(0, len(results
))
350 def testOnlyOwnersFiles(self
):
351 mock_change
= MockChange([
353 'A\Windows\Path\OWNERS',
355 results
= PRESUBMIT
.GetPreferredTrySlaves(None, mock_change
)
356 self
.assertEqual(0, len(results
))
359 class InvalidOSMacroNamesTest(unittest
.TestCase
):
360 def testInvalidOSMacroNames(self
):
361 lines
= ['#if defined(OS_WINDOWS)',
362 ' #elif defined(OS_WINDOW)',
363 ' # if defined(OS_MACOSX) || defined(OS_CHROME)',
364 '# else // defined(OS_MAC)',
365 '#endif // defined(OS_MACOS)']
366 errors
= PRESUBMIT
._CheckForInvalidOSMacrosInFile
(
367 MockInputApi(), MockFile('some/path/foo_platform.cc', lines
))
368 self
.assertEqual(len(lines
), len(errors
))
369 self
.assertTrue(':1 OS_WINDOWS' in errors
[0])
370 self
.assertTrue('(did you mean OS_WIN?)' in errors
[0])
372 def testValidOSMacroNames(self
):
373 lines
= ['#if defined(%s)' % m
for m
in PRESUBMIT
._VALID
_OS
_MACROS
]
374 errors
= PRESUBMIT
._CheckForInvalidOSMacrosInFile
(
375 MockInputApi(), MockFile('some/path/foo_platform.cc', lines
))
376 self
.assertEqual(0, len(errors
))
379 if __name__
== '__main__':