blob: debe33b899bae74da065b2f5d14e5e875127cd01 [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):
31 pass
32
33 class PresubmitPromptWarning(PresubmitResult):
34 pass
35
36 class PresubmitNotifyResult(PresubmitResult):
37 pass
[email protected]2299dcf2012-11-15 19:56:2438
39
40class MockFile(object):
41 def __init__(self, local_path, new_contents):
42 self._local_path = local_path
43 self._new_contents = new_contents
[email protected]70ca77752012-11-20 03:45:0344 self._changed_contents = [(i + 1, l) for i, l in enumerate(new_contents)]
45
46 def ChangedContents(self):
47 return self._changed_contents
[email protected]2299dcf2012-11-15 19:56:2448
49 def NewContents(self):
50 return self._new_contents
51
52 def LocalPath(self):
53 return self._local_path
54
55
56class IncludeOrderTest(unittest.TestCase):
57 def testSystemHeaderOrder(self):
58 scope = [(1, '#include <csystem.h>'),
59 (2, '#include <cppsystem>'),
60 (3, '#include "acustom.h"')]
61 all_linenums = [linenum for (linenum, _) in scope]
62 mock_input_api = MockInputApi()
63 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
64 '', all_linenums)
65 self.assertEqual(0, len(warnings))
66
67 def testSystemHeaderOrderMismatch1(self):
68 scope = [(10, '#include <cppsystem>'),
69 (20, '#include <csystem.h>'),
70 (30, '#include "acustom.h"')]
71 all_linenums = [linenum for (linenum, _) in scope]
72 mock_input_api = MockInputApi()
73 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
74 '', all_linenums)
75 self.assertEqual(1, len(warnings))
76 self.assertTrue('20' in warnings[0])
77
78 def testSystemHeaderOrderMismatch2(self):
79 scope = [(10, '#include <cppsystem>'),
80 (20, '#include "acustom.h"'),
81 (30, '#include <csystem.h>')]
82 all_linenums = [linenum for (linenum, _) in scope]
83 mock_input_api = MockInputApi()
84 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
85 '', all_linenums)
86 self.assertEqual(1, len(warnings))
87 self.assertTrue('30' in warnings[0])
88
89 def testSystemHeaderOrderMismatch3(self):
90 scope = [(10, '#include "acustom.h"'),
91 (20, '#include <csystem.h>'),
92 (30, '#include <cppsystem>')]
93 all_linenums = [linenum for (linenum, _) in scope]
94 mock_input_api = MockInputApi()
95 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
96 '', all_linenums)
97 self.assertEqual(2, len(warnings))
98 self.assertTrue('20' in warnings[0])
99 self.assertTrue('30' in warnings[1])
100
101 def testAlphabeticalOrderMismatch(self):
102 scope = [(10, '#include <csystem.h>'),
103 (15, '#include <bsystem.h>'),
104 (20, '#include <cppsystem>'),
105 (25, '#include <bppsystem>'),
106 (30, '#include "bcustom.h"'),
107 (35, '#include "acustom.h"')]
108 all_linenums = [linenum for (linenum, _) in scope]
109 mock_input_api = MockInputApi()
110 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
111 '', all_linenums)
112 self.assertEqual(3, len(warnings))
113 self.assertTrue('15' in warnings[0])
114 self.assertTrue('25' in warnings[1])
115 self.assertTrue('35' in warnings[2])
116
117 def testSpecialFirstInclude1(self):
118 mock_input_api = MockInputApi()
119 contents = ['#include "some/path/foo.h"',
120 '#include "a/header.h"']
121 mock_file = MockFile('some/path/foo.cc', contents)
122 warnings = PRESUBMIT._CheckIncludeOrderInFile(
123 mock_input_api, mock_file, True, range(1, len(contents) + 1))
124 self.assertEqual(0, len(warnings))
125
126 def testSpecialFirstInclude2(self):
127 mock_input_api = MockInputApi()
128 contents = ['#include "some/other/path/foo.h"',
129 '#include "a/header.h"']
130 mock_file = MockFile('some/path/foo.cc', contents)
131 warnings = PRESUBMIT._CheckIncludeOrderInFile(
132 mock_input_api, mock_file, True, range(1, len(contents) + 1))
133 self.assertEqual(0, len(warnings))
134
135 def testSpecialFirstInclude3(self):
136 mock_input_api = MockInputApi()
137 contents = ['#include "some/path/foo.h"',
138 '#include "a/header.h"']
139 mock_file = MockFile('some/path/foo_platform.cc', contents)
140 warnings = PRESUBMIT._CheckIncludeOrderInFile(
141 mock_input_api, mock_file, True, range(1, len(contents) + 1))
142 self.assertEqual(0, len(warnings))
143
144 def testSpecialFirstInclude4(self):
145 mock_input_api = MockInputApi()
146 contents = ['#include "some/path/bar.h"',
147 '#include "a/header.h"']
148 mock_file = MockFile('some/path/foo_platform.cc', contents)
149 warnings = PRESUBMIT._CheckIncludeOrderInFile(
150 mock_input_api, mock_file, True, range(1, len(contents) + 1))
151 self.assertEqual(1, len(warnings))
152 self.assertTrue('2' in warnings[0])
153
154 def testOrderAlreadyWrong(self):
155 scope = [(1, '#include "b.h"'),
156 (2, '#include "a.h"'),
157 (3, '#include "c.h"')]
158 mock_input_api = MockInputApi()
159 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
160 '', [3])
161 self.assertEqual(0, len(warnings))
162
163 def testConflictAdded1(self):
164 scope = [(1, '#include "a.h"'),
165 (2, '#include "c.h"'),
166 (3, '#include "b.h"')]
167 mock_input_api = MockInputApi()
168 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
169 '', [2])
170 self.assertEqual(1, len(warnings))
171 self.assertTrue('3' in warnings[0])
172
173 def testConflictAdded2(self):
174 scope = [(1, '#include "c.h"'),
175 (2, '#include "b.h"'),
176 (3, '#include "d.h"')]
177 mock_input_api = MockInputApi()
178 warnings = PRESUBMIT._CheckIncludeOrderForScope(scope, mock_input_api,
179 '', [2])
180 self.assertEqual(1, len(warnings))
181 self.assertTrue('2' in warnings[0])
182
[email protected]2309b0fa02012-11-16 12:18:27183 def testIfElifElseEndif(self):
184 mock_input_api = MockInputApi()
185 contents = ['#include "e.h"',
186 '#if foo',
187 '#include "d.h"',
188 '#elif bar',
189 '#include "c.h"',
190 '#else',
191 '#include "b.h"',
192 '#endif',
193 '#include "a.h"']
194 mock_file = MockFile('', contents)
195 warnings = PRESUBMIT._CheckIncludeOrderInFile(
196 mock_input_api, mock_file, True, range(1, len(contents) + 1))
197 self.assertEqual(0, len(warnings))
198
[email protected]962f117e2012-11-22 18:11:56199 def testSysIncludes(self):
200 # #include <sys/...>'s can appear in any order.
201 mock_input_api = MockInputApi()
202 contents = ['#include <sys/b.h>',
203 '#include <sys/a.h>']
204 mock_file = MockFile('', contents)
205 warnings = PRESUBMIT._CheckIncludeOrderInFile(
206 mock_input_api, mock_file, True, range(1, len(contents) + 1))
207 self.assertEqual(0, len(warnings))
208
[email protected]2299dcf2012-11-15 19:56:24209
[email protected]70ca77752012-11-20 03:45:03210class VersionControlerConflictsTest(unittest.TestCase):
211 def testTypicalConflict(self):
212 lines = ['<<<<<<< HEAD',
213 ' base::ScopedTempDir temp_dir_;',
214 '=======',
215 ' ScopedTempDir temp_dir_;',
216 '>>>>>>> master']
217 errors = PRESUBMIT._CheckForVersionControlConflictsInFile(
218 MockInputApi(), MockFile('some/path/foo_platform.cc', lines))
219 self.assertEqual(3, len(errors))
220 self.assertTrue('1' in errors[0])
221 self.assertTrue('3' in errors[1])
222 self.assertTrue('5' in errors[2])
223
224
[email protected]b8079ae4a2012-12-05 19:56:49225class BadExtensionsTest(unittest.TestCase):
226 def testBadRejFile(self):
227 mock_input_api = MockInputApi()
228 mock_input_api.files = [
229 MockFile('some/path/foo.cc', ''),
230 MockFile('some/path/foo.cc.rej', ''),
231 MockFile('some/path2/bar.h.rej', ''),
232 ]
233
234 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
235 self.assertEqual(1, len(results))
236 self.assertEqual(2, len(results[0].items))
237 self.assertTrue('foo.cc.rej' in results[0].items[0])
238 self.assertTrue('bar.h.rej' in results[0].items[1])
239
240 def testBadOrigFile(self):
241 mock_input_api = MockInputApi()
242 mock_input_api.files = [
243 MockFile('other/path/qux.h.orig', ''),
244 MockFile('other/path/qux.h', ''),
245 MockFile('other/path/qux.cc', ''),
246 ]
247
248 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
249 self.assertEqual(1, len(results))
250 self.assertEqual(1, len(results[0].items))
251 self.assertTrue('qux.h.orig' in results[0].items[0])
252
253 def testGoodFiles(self):
254 mock_input_api = MockInputApi()
255 mock_input_api.files = [
256 MockFile('other/path/qux.h', ''),
257 MockFile('other/path/qux.cc', ''),
258 ]
259 results = PRESUBMIT._CheckPatchFiles(mock_input_api, MockOutputApi())
260 self.assertEqual(0, len(results))
261
262
[email protected]2299dcf2012-11-15 19:56:24263if __name__ == '__main__':
264 unittest.main()