- add sources.
[platform/framework/web/crosswalk.git] / src / PRESUBMIT_test.py
1 #!/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
6 import os
7 import re
8 import unittest
9
10 import PRESUBMIT
11
12
13 class MockInputApi(object):
14   def __init__(self):
15     self.re = re
16     self.os_path = os.path
17     self.files = []
18     self.is_committing = False
19
20   def AffectedFiles(self):
21     return self.files
22
23
24 class MockOutputApi(object):
25   class PresubmitResult(object):
26     def __init__(self, message, items=None, long_text=''):
27       self.message = message
28       self.items = items
29       self.long_text = long_text
30
31   class PresubmitError(PresubmitResult):
32     def __init__(self, message, items, long_text=''):
33       MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
34       self.type = 'error'
35
36   class PresubmitPromptWarning(PresubmitResult):
37     def __init__(self, message, items, long_text=''):
38       MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
39       self.type = 'warning'
40
41   class PresubmitNotifyResult(PresubmitResult):
42     def __init__(self, message, items, long_text=''):
43       MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
44       self.type = 'notify'
45
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'
50
51
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)]
57
58   def ChangedContents(self):
59     return self._changed_contents
60
61   def NewContents(self):
62     return self._new_contents
63
64   def LocalPath(self):
65     return self._local_path
66
67
68 class MockChange(object):
69   def __init__(self, changed_files):
70     self._changed_files = changed_files
71
72   def LocalPaths(self):
73     return self._changed_files
74
75
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,
84                                                     '', all_linenums)
85     self.assertEqual(0, len(warnings))
86
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,
94                                                     '', all_linenums)
95     self.assertEqual(1, len(warnings))
96     self.assertTrue('20' in warnings[0])
97
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,
105                                                     '', all_linenums)
106     self.assertEqual(1, len(warnings))
107     self.assertTrue('30' in warnings[0])
108
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,
116                                                     '', all_linenums)
117     self.assertEqual(2, len(warnings))
118     self.assertTrue('20' in warnings[0])
119     self.assertTrue('30' in warnings[1])
120
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,
131                                                     '', all_linenums)
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])
136
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))
145
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))
154
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))
163
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])
173
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))
182
183   def testSpecialFirstInclude6(self):
184     mock_input_api = MockInputApi()
185     contents = ['#include "some/other/path/foo_win.h"',
186                 '#include <set>',
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))
192
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,
199                                                     '', [3])
200     self.assertEqual(0, len(warnings))
201
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,
208                                                     '', [2])
209     self.assertEqual(1, len(warnings))
210     self.assertTrue('3' in warnings[0])
211
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,
218                                                     '', [2])
219     self.assertEqual(1, len(warnings))
220     self.assertTrue('2' in warnings[0])
221
222   def testIfElifElseEndif(self):
223     mock_input_api = MockInputApi()
224     contents = ['#include "e.h"',
225                 '#define foo',
226                 '#include "f.h"',
227                 '#undef foo',
228                 '#include "e.h"',
229                 '#if foo',
230                 '#include "d.h"',
231                 '#elif bar',
232                 '#include "c.h"',
233                 '#else',
234                 '#include "b.h"',
235                 '#endif',
236                 '#include "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))
241
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))
251
252     contents = ['#include <atlbase.h>',
253                 '#include <aaa.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))
258
259     contents = ['#include "build/build_config.h"',
260                 '#include "aaa.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))
265
266   def testCheckOnlyCFiles(self):
267     mock_input_api = MockInputApi()
268     mock_output_api = MockOutputApi()
269     contents = ['#include <b.h>',
270                 '#include <a.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)
279
280   def testUncheckableIncludes(self):
281     mock_input_api = MockInputApi()
282     contents = ['#include <windows.h>',
283                 '#include "b.h"'
284                 '#include "a.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))
289
290     contents = ['#include "gpu/command_buffer/gles_autogen.h"',
291                 '#include "b.h"'
292                 '#include "a.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))
297
298     contents = ['#include "gl_mock_autogen.h"',
299                 '#include "b.h"'
300                 '#include "a.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))
305
306     contents = ['#include "ipc/some_macros.h"',
307                 '#include "b.h"'
308                 '#include "a.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))
313
314
315 class VersionControlConflictsTest(unittest.TestCase):
316   def testTypicalConflict(self):
317     lines = ['<<<<<<< HEAD',
318              '  base::ScopedTempDir temp_dir_;',
319              '=======',
320              '  ScopedTempDir temp_dir_;',
321              '>>>>>>> master']
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])
328
329
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', ''),
337     ]
338
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])
344
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', ''),
351     ]
352
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])
357
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', ''),
363     ]
364     results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
365     self.assertEqual(0, len(results))
366
367   def testOnlyOwnersFiles(self):
368     mock_change = MockChange([
369       'some/path/OWNERS',
370       'A\Windows\Path\OWNERS',
371     ])
372     results = PRESUBMIT.GetPreferredTrySlaves(None, mock_change)
373     self.assertEqual(0, len(results))
374
375
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])
388
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))
394
395
396 class CheckAddedDepsHaveTetsApprovalsTest(unittest.TestCase):
397   def testDepsFilesToCheck(self):
398     changed_lines = [
399       '"+breakpad",',
400       '"+chrome/installer",',
401       '"+chrome/plugin/chrome_content_plugin_client.h",',
402       '"+chrome/utility/chrome_content_utility_client.h",',
403       '"+chromeos/chromeos_paths.h",',
404       '"+components/breakpad",',
405       '"+components/nacl/common",',
406       '"+content/public/browser/render_process_host.h",',
407       '"+grit",  # For generated headers',
408       '"+grit/generated_resources.h",',
409       '"+grit/",',
410       '"+policy",  # For generated headers and source',
411       '"+sandbox",',
412       '"+tools/memory_watcher",',
413       '"+third_party/lss/linux_syscall_support.h",',
414     ]
415     files_to_check = PRESUBMIT._DepsFilesToCheck(re, changed_lines)
416     expected = set([
417       'breakpad/DEPS',
418       'chrome/installer/DEPS',
419       'chrome/plugin/DEPS',
420       'chrome/utility/DEPS',
421       'chromeos/DEPS',
422       'components/breakpad/DEPS',
423       'components/nacl/common/DEPS',
424       'content/public/browser/DEPS',
425       'policy/DEPS',
426       'sandbox/DEPS',
427       'tools/memory_watcher/DEPS',
428       'third_party/lss/DEPS',
429     ])
430     self.assertEqual(expected, files_to_check);
431
432
433 if __name__ == '__main__':
434   unittest.main()