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 MockLogging(object):
17 def info(self
, message
):
18 self
.lines
.append(message
)
20 def debug(self
, message
):
21 self
.lines
.append(message
)
23 class MockInputApi(object):
26 self
.os_path
= os
.path
28 self
.is_committing
= False
29 self
.logging
= MockLogging()
31 def AffectedFiles(self
, include_deletes
=None):
35 class MockOutputApi(object):
36 class PresubmitResult(object):
37 def __init__(self
, message
, items
=None, long_text
=''):
38 self
.message
= message
40 self
.long_text
= long_text
42 class PresubmitError(PresubmitResult
):
43 def __init__(self
, message
, items
, long_text
=''):
44 MockOutputApi
.PresubmitResult
.__init
__(self
, message
, items
, long_text
)
47 class PresubmitPromptWarning(PresubmitResult
):
48 def __init__(self
, message
, items
, long_text
=''):
49 MockOutputApi
.PresubmitResult
.__init
__(self
, message
, items
, long_text
)
52 class PresubmitNotifyResult(PresubmitResult
):
53 def __init__(self
, message
, items
, long_text
=''):
54 MockOutputApi
.PresubmitResult
.__init
__(self
, message
, items
, long_text
)
58 class MockFile(object):
59 def __init__(self
, local_path
, old_contents
, new_contents
):
60 self
._local
_path
= local_path
61 self
._new
_contents
= new_contents
62 self
._old
_contents
= old_contents
63 self
._cached
_changed
_contents
= None
65 def ChangedContents(self
):
66 return self
._changed
_contents
68 def NewContents(self
):
69 return self
._new
_contents
72 return self
._local
_path
74 def IsDirectory(self
):
77 def GenerateScmDiff(self
):
79 for line
in difflib
.unified_diff(self
._old
_contents
, self
._new
_contents
,
80 self
._local
_path
, self
._local
_path
):
84 # NOTE: This method is a copy of ChangeContents method of AffectedFile in
85 # presubmit_support.py
86 def ChangedContents(self
):
87 """Returns a list of tuples (line number, line text) of all new lines.
89 This relies on the scm diff output describing each changed code section
90 with a line of the form
92 ^@@ <old line num>,<old size> <new line num>,<new size> @@$
94 if self
._cached
_changed
_contents
is not None:
95 return self
._cached
_changed
_contents
[:]
96 self
._cached
_changed
_contents
= []
99 if self
.IsDirectory():
102 for line
in self
.GenerateScmDiff().splitlines():
103 m
= re
.match(r
'^@@ [0-9\,\+\-]+ \+([0-9]+)\,[0-9]+ @@', line
)
105 line_num
= int(m
.groups(1)[0])
107 if line
.startswith('+') and not line
.startswith('++'):
108 self
._cached
_changed
_contents
.append((line_num
, line
[1:]))
109 if not line
.startswith('-'):
111 return self
._cached
_changed
_contents
[:]
114 class MockChange(object):
115 def __init__(self
, changed_files
):
116 self
._changed
_files
= changed_files
118 def LocalPaths(self
):
119 return self
._changed
_files
122 class HistogramValueCheckerTest(unittest
.TestCase
):
123 TEST_FILE_PATTERN
= "PRESUBMIT_test_new_file_%s.txt"
125 def _ReadTextFileContents(self
, path
):
126 """Given a path, returns a list of strings corresponding to the text lines
127 in the file. Reads files in text format.
132 contents
= fo
.readlines()
137 def _ReadInputFile(self
):
138 return self
._ReadTextFileContents
("PRESUBMIT_test_old_file.txt")
140 def _PrepareTest(self
, new_file_path
):
141 old_contents
= self
._ReadInputFile
()
142 if not new_file_path
:
145 new_contents
= self
._ReadTextFileContents
(new_file_path
)
146 input_api
= MockInputApi()
147 mock_file
= MockFile(PRESUBMIT
.HistogramValueChecker
.LOCAL_PATH
,
150 input_api
.files
.append(mock_file
)
151 output_api
= MockOutputApi()
152 return input_api
, output_api
154 def _RunTest(self
, new_file_path
):
155 input_api
, output_api
= self
._PrepareTest
(new_file_path
)
156 checker
= PRESUBMIT
.HistogramValueChecker(input_api
, output_api
)
157 results
= checker
.Run()
160 def testDeleteFile(self
):
161 results
= self
._RunTest
(new_file_path
=None)
162 # TODO(rpaquay) How to check it's the expected warning?'
163 self
.assertEquals(1, len(results
),
164 "We hould get a single warning about file deletion.")
166 def testSimpleValidEdit(self
):
167 results
= self
._RunTest
(self
.TEST_FILE_PATTERN
% "1")
168 # TODO(rpaquay) How to check it's the expected warning?'
169 self
.assertEquals(0, len(results
),
170 "We should get no warning for simple edits.")
172 def testSingleDeletionOfEntry(self
):
173 results
= self
._RunTest
(self
.TEST_FILE_PATTERN
% "2")
174 # TODO(rpaquay) How to check it's the expected warning?'
175 self
.assertEquals(1, len(results
),
176 "We should get a warning for an entry deletion.")
178 def testSingleRenameOfEntry(self
):
179 results
= self
._RunTest
(self
.TEST_FILE_PATTERN
% "3")
180 # TODO(rpaquay) How to check it's the expected warning?'
181 self
.assertEquals(1, len(results
),
182 "We should get a warning for an entry rename, even "
183 "though it is not optimal.")
185 def testMissingEnumStartOfEntry(self
):
186 results
= self
._RunTest
(self
.TEST_FILE_PATTERN
% "4")
187 # TODO(rpaquay) How to check it's the expected warning?'
188 self
.assertEquals(1, len(results
),
189 "We should get a warning for a missing enum marker.")
191 def testMissingEnumEndOfEntry(self
):
192 results
= self
._RunTest
(self
.TEST_FILE_PATTERN
% "5")
193 # TODO(rpaquay) How to check it's the expected warning?'
194 self
.assertEquals(1, len(results
),
195 "We should get a warning for a missing enum marker.")
197 def testInvertedEnumMarkersOfEntry(self
):
198 results
= self
._RunTest
(self
.TEST_FILE_PATTERN
% "6")
199 # TODO(rpaquay) How to check it's the expected warning?'
200 self
.assertEquals(1, len(results
),
201 "We should get a warning for inverted enum markers.")
203 def testMultipleInvalidEdits(self
):
204 results
= self
._RunTest
(self
.TEST_FILE_PATTERN
% "7")
205 # TODO(rpaquay) How to check it's the expected warning?'
206 self
.assertEquals(3, len(results
),
207 "We should get 3 warnings (one per edit).")
209 def testSingleInvalidInserts(self
):
210 results
= self
._RunTest
(self
.TEST_FILE_PATTERN
% "8")
211 # TODO(rpaquay) How to check it's the expected warning?'
212 self
.assertEquals(1, len(results
),
213 "We should get a warning for a single invalid "
214 "insertion inside the enum.")
216 def testMulitpleValidInserts(self
):
217 results
= self
._RunTest
(self
.TEST_FILE_PATTERN
% "9")
218 # TODO(rpaquay) How to check it's the expected warning?'
219 self
.assertEquals(0, len(results
),
220 "We should not get a warning mulitple valid edits")
222 def testSingleValidDeleteOutsideOfEnum(self
):
223 results
= self
._RunTest
(self
.TEST_FILE_PATTERN
% "10")
224 # TODO(rpaquay) How to check it's the expected warning?'
225 self
.assertEquals(0, len(results
),
226 "We should not get a warning for a deletion outside of "
230 if __name__
== '__main__':