blob: 9bc7db5dd2f1e4e4a5d3d936dea2f227e47646dc [file] [log] [blame]
[email protected]2299dcf2012-11-15 19:56:241#!/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
6import os
7import re
8import unittest
9
10import PRESUBMIT
11
12
13class MockInputApi(object):
14 def __init__(self):
15 self.re = re
16 self.os_path = os.path
[email protected]b8079ae4a2012-12-05 19:56:4917 self.files = []
18
19 def AffectedFiles(self):
20 return self.files
21
22
23class MockOutputApi(object):
24 class PresubmitResult(object):
25 def __init__(self, message, items=None, long_text=''):
26 self.message = message
27 self.items = items
28 self.long_text = long_text
29
30 class PresubmitError(PresubmitResult):
[email protected]ac294a12012-12-06 16:38:4331 def __init__(self, message, items, long_text=''):
32 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
[email protected]b8079ae4a2012-12-05 19:56:4933
34 class PresubmitPromptWarning(PresubmitResult):
[email protected]ac294a12012-12-06 16:38:4335 def __init__(self, message, items, long_text=''):
36 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
[email protected]b8079ae4a2012-12-05 19:56:4937
38 class PresubmitNotifyResult(PresubmitResult):
[email protected]ac294a12012-12-06 16:38:4339 def __init__(self, message, items, long_text=''):
40 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
[email protected]2299dcf2012-11-15 19:56:2441
42
43class MockFile(object):
44 def __init__(self, local_path, new_contents):
45 self._local_path = local_path
46 self._new_contents = new_contents
[email protected]70ca77752012-11-20 03:45:0347 self._changed_contents = [(i + 1, l) for i, l in enumerate(new_contents)]
48
49 def ChangedContents(self):
50 return self._changed_contents
[email protected]2299dcf2012-11-15 19:56:2451
52 def NewContents(self):
53 return self._new_contents
54
55 def LocalPath(self):
56 return self._local_path
57
58
59class IncludeOrderTest(unittest.TestCase):
60 def testSystemHeaderOrder(self):
61 scope = [(1, '#include <csystem.h>'),
62 (2, '#include <cppsystem>'),
63 (3, '#include "acustom.h"')]
64 all_linenums = [linenum for (linenum, _) in scope]
65 mock_input_api = MockInputApi()
66 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
67 '', all_linenums)
68 self.assertEqual(0, len(warnings))
69
70 def testSystemHeaderOrderMismatch1(self):
71 scope = [(10, '#include <cppsystem>'),
72 (20, '#include <csystem.h>'),
73 (30, '#include "acustom.h"')]
74 all_linenums = [linenum for (linenum, _) in scope]
75 mock_input_api = MockInputApi()
76 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
77 '', all_linenums)
78 self.assertEqual(1, len(warnings))
79 self.assertTrue('20' in warnings[0])
80
81 def testSystemHeaderOrderMismatch2(self):
82 scope = [(10, '#include <cppsystem>'),
83 (20, '#include "acustom.h"'),
84 (30, '#include <csystem.h>')]
85 all_linenums = [linenum for (linenum, _) in scope]
86 mock_input_api = MockInputApi()
87 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
88 '', all_linenums)
89 self.assertEqual(1, len(warnings))
90 self.assertTrue('30' in warnings[0])
91
92 def testSystemHeaderOrderMismatch3(self):
93 scope = [(10, '#include "acustom.h"'),
94 (20, '#include <csystem.h>'),
95 (30, '#include <cppsystem>')]
96 all_linenums = [linenum for (linenum, _) in scope]
97 mock_input_api = MockInputApi()
98 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
99 '', all_linenums)
100 self.assertEqual(2, len(warnings))
101 self.assertTrue('20' in warnings[0])
102 self.assertTrue('30' in warnings[1])
103
104 def testAlphabeticalOrderMismatch(self):
105 scope = [(10, '#include <csystem.h>'),
106 (15, '#include <bsystem.h>'),
107 (20, '#include <cppsystem>'),
108 (25, '#include <bppsystem>'),
109 (30, '#include "bcustom.h"'),
110 (35, '#include "acustom.h"')]
111 all_linenums = [linenum for (linenum, _) in scope]
112 mock_input_api = MockInputApi()
113 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
114 '', all_linenums)
115 self.assertEqual(3, len(warnings))
116 self.assertTrue('15' in warnings[0])
117 self.assertTrue('25' in warnings[1])
118 self.assertTrue('35' in warnings[2])
119
120 def testSpecialFirstInclude1(self):
121 mock_input_api = MockInputApi()
122 contents = ['#include "some/path/foo.h"',
123 '#include "a/header.h"']
124 mock_file = MockFile('some/path/foo.cc', contents)
125 warnings = PRESUBMIT._CheckIncludeOrderInFile(
[email protected]ac294a12012-12-06 16:38:43126 mock_input_api, mock_file, range(1, len(contents) + 1))
[email protected]2299dcf2012-11-15 19:56:24127 self.assertEqual(0, len(warnings))
128
129 def testSpecialFirstInclude2(self):
130 mock_input_api = MockInputApi()
131 contents = ['#include "some/other/path/foo.h"',
132 '#include "a/header.h"']
133 mock_file = MockFile('some/path/foo.cc', contents)
134 warnings = PRESUBMIT._CheckIncludeOrderInFile(
[email protected]ac294a12012-12-06 16:38:43135 mock_input_api, mock_file, range(1, len(contents) + 1))
[email protected]2299dcf2012-11-15 19:56:24136 self.assertEqual(0, len(warnings))
137
138 def testSpecialFirstInclude3(self):
139 mock_input_api = MockInputApi()
140 contents = ['#include "some/path/foo.h"',
141 '#include "a/header.h"']
142 mock_file = MockFile('some/path/foo_platform.cc', contents)
143 warnings = PRESUBMIT._CheckIncludeOrderInFile(
[email protected]ac294a12012-12-06 16:38:43144 mock_input_api, mock_file, range(1, len(contents) + 1))
[email protected]2299dcf2012-11-15 19:56:24145 self.assertEqual(0, len(warnings))
146
147 def testSpecialFirstInclude4(self):
148 mock_input_api = MockInputApi()
149 contents = ['#include "some/path/bar.h"',
150 '#include "a/header.h"']
151 mock_file = MockFile('some/path/foo_platform.cc', contents)
152 warnings = PRESUBMIT._CheckIncludeOrderInFile(
[email protected]ac294a12012-12-06 16:38:43153 mock_input_api, mock_file, range(1, len(contents) + 1))
[email protected]2299dcf2012-11-15 19:56:24154 self.assertEqual(1, len(warnings))
155 self.assertTrue('2' in warnings[0])
156
[email protected]ac294a12012-12-06 16:38:43157 def testSpecialFirstInclude5(self):
158 mock_input_api = MockInputApi()
159 contents = ['#include "some/other/path/foo.h"',
160 '#include "a/header.h"']
161 mock_file = MockFile('some/path/foo-suffix.h', contents)
162 warnings = PRESUBMIT._CheckIncludeOrderInFile(
163 mock_input_api, mock_file, range(1, len(contents) + 1))
164 self.assertEqual(0, len(warnings))
165
[email protected]2299dcf2012-11-15 19:56:24166 def testOrderAlreadyWrong(self):
167 scope = [(1, '#include "b.h"'),
168 (2, '#include "a.h"'),
169 (3, '#include "c.h"')]
170 mock_input_api = MockInputApi()
171 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
172 '', [3])
173 self.assertEqual(0, len(warnings))
174
175 def testConflictAdded1(self):
176 scope = [(1, '#include "a.h"'),
177 (2, '#include "c.h"'),
178 (3, '#include "b.h"')]
179 mock_input_api = MockInputApi()
180 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
181 '', [2])
182 self.assertEqual(1, len(warnings))
183 self.assertTrue('3' in warnings[0])
184
185 def testConflictAdded2(self):
186 scope = [(1, '#include "c.h"'),
187 (2, '#include "b.h"'),
188 (3, '#include "d.h"')]
189 mock_input_api = MockInputApi()
190 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
191 '', [2])
192 self.assertEqual(1, len(warnings))
193 self.assertTrue('2' in warnings[0])
194
[email protected]2309b0fa02012-11-16 12:18:27195 def testIfElifElseEndif(self):
196 mock_input_api = MockInputApi()
197 contents = ['#include "e.h"',
[email protected]ac294a12012-12-06 16:38:43198 '#define foo',
199 '#include "f.h"',
200 '#undef foo',
201 '#include "e.h"',
[email protected]2309b0fa02012-11-16 12:18:27202 '#if foo',
203 '#include "d.h"',
204 '#elif bar',
205 '#include "c.h"',
206 '#else',
207 '#include "b.h"',
208 '#endif',
209 '#include "a.h"']
210 mock_file = MockFile('', contents)
211 warnings = PRESUBMIT._CheckIncludeOrderInFile(
[email protected]ac294a12012-12-06 16:38:43212 mock_input_api, mock_file, range(1, len(contents) + 1))
[email protected]2309b0fa02012-11-16 12:18:27213 self.assertEqual(0, len(warnings))
214
[email protected]962f117e2012-11-22 18:11:56215 def testSysIncludes(self):
216 # #include <sys/...>'s can appear in any order.
217 mock_input_api = MockInputApi()
218 contents = ['#include <sys/b.h>',
219 '#include <sys/a.h>']
220 mock_file = MockFile('', contents)
221 warnings = PRESUBMIT._CheckIncludeOrderInFile(
[email protected]ac294a12012-12-06 16:38:43222 mock_input_api, mock_file, range(1, len(contents) + 1))
[email protected]962f117e2012-11-22 18:11:56223 self.assertEqual(0, len(warnings))
224
[email protected]ac294a12012-12-06 16:38:43225 def testCheckOnlyCFiles(self):
226 mock_input_api = MockInputApi()
227 mock_output_api = MockOutputApi()
228 contents = ['#include <b.h>',
229 '#include <a.h>']
230 mock_file_cc = MockFile('something.cc', contents)
231 mock_file_h = MockFile('something.h', contents)
232 mock_file_other = MockFile('something.py', contents)
233 mock_input_api.files = [mock_file_cc, mock_file_h, mock_file_other]
234 warnings = PRESUBMIT._CheckIncludeOrder(mock_input_api, mock_output_api)
235 self.assertEqual(1, len(warnings))
236 self.assertEqual(2, len(warnings[0].items))
237
[email protected]2299dcf2012-11-15 19:56:24238
[email protected]70ca77752012-11-20 03:45:03239class VersionControlerConflictsTest(unittest.TestCase):
240 def testTypicalConflict(self):
241 lines = ['<<<<<<< HEAD',
242 ' base::ScopedTempDir temp_dir_;',
243 '=======',
244 ' ScopedTempDir temp_dir_;',
245 '>>>>>>> master']
246 errors = PRESUBMIT._CheckForVersionControlConflictsInFile(
247 MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
248 self.assertEqual(3, len(errors))
249 self.assertTrue('1' in errors[0])
250 self.assertTrue('3' in errors[1])
251 self.assertTrue('5' in errors[2])
252
253
[email protected]b8079ae4a2012-12-05 19:56:49254class BadExtensionsTest(unittest.TestCase):
255 def testBadRejFile(self):
256 mock_input_api = MockInputApi()
257 mock_input_api.files = [
258 MockFile('some/path/foo.cc', ''),
259 MockFile('some/path/foo.cc.rej', ''),
260 MockFile('some/path2/bar.h.rej', ''),
261 ]
262
263 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
264 self.assertEqual(1, len(results))
265 self.assertEqual(2, len(results[0].items))
266 self.assertTrue('foo.cc.rej' in results[0].items[0])
267 self.assertTrue('bar.h.rej' in results[0].items[1])
268
269 def testBadOrigFile(self):
270 mock_input_api = MockInputApi()
271 mock_input_api.files = [
272 MockFile('other/path/qux.h.orig', ''),
273 MockFile('other/path/qux.h', ''),
274 MockFile('other/path/qux.cc', ''),
275 ]
276
277 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
278 self.assertEqual(1, len(results))
279 self.assertEqual(1, len(results[0].items))
280 self.assertTrue('qux.h.orig' in results[0].items[0])
281
282 def testGoodFiles(self):
283 mock_input_api = MockInputApi()
284 mock_input_api.files = [
285 MockFile('other/path/qux.h', ''),
286 MockFile('other/path/qux.cc', ''),
287 ]
288 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
289 self.assertEqual(0, len(results))
290
291
[email protected]2299dcf2012-11-15 19:56:24292if __name__ == '__main__':
293 unittest.main()