2 # Copyright 2014 The Chromium Authors
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
11 class MockInputApi(object):
14 self.os_path = os.path
16 self.is_committing = False
18 def AffectedFiles(self):
21 def AffectedSourceFiles(self, fn):
22 # we'll just pretend everything is a source file for the sake of simplicity
25 def ReadFile(self, f):
26 return f.NewContents()
29 class MockOutputApi(object):
30 class PresubmitResult(object):
31 def __init__(self, message, items=None, long_text=''):
32 self.message = message
34 self.long_text = long_text
36 class PresubmitError(PresubmitResult):
37 def __init__(self, message, items, long_text=''):
38 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
41 class PresubmitPromptWarning(PresubmitResult):
42 def __init__(self, message, items, long_text=''):
43 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
46 class PresubmitNotifyResult(PresubmitResult):
47 def __init__(self, message, items, long_text=''):
48 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
51 class PresubmitPromptOrNotify(PresubmitResult):
52 def __init__(self, message, items, long_text=''):
53 MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
54 self.type = 'promptOrNotify'
57 class MockFile(object):
58 def __init__(self, local_path, new_contents):
59 self._local_path = local_path
60 self._new_contents = new_contents
61 self._changed_contents = [(i + 1, l) for i, l in enumerate(new_contents)]
63 def ChangedContents(self):
64 return self._changed_contents
66 def NewContents(self):
67 return self._new_contents
70 return self._local_path
73 class MockChange(object):
74 def __init__(self, changed_files):
75 self._changed_files = changed_files
78 return self._changed_files
81 class HistogramOffByOneTest(unittest.TestCase):
83 # Take an input and make sure the problems found equals the expectation.
84 def simpleCheck(self, contents, expected_errors):
85 input_api = MockInputApi()
86 input_api.files.append(MockFile('test.cc', contents))
87 results = PRESUBMIT._CheckForHistogramOffByOne(input_api, MockOutputApi())
89 self.assertEqual(1, len(results))
90 self.assertEqual(expected_errors, len(results[0].items))
92 self.assertEqual(0, len(results))
95 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFooMax + 1);', 0)
97 def testValidComments(self):
98 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", /*...*/ kFoo, /*...*/'
101 def testValidMultiLine(self):
102 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test",\n'
106 def testValidMultiLineComments(self):
107 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", // This is the name\n'
108 ' kFoo, /* The value */\n'
109 ' kFooMax + 1 /* The max */ );',
112 def testNoPlusOne(self):
113 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFooMax);', 1)
115 def testInvalidWithIgnore(self):
116 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFooMax); '
117 '// PRESUBMIT_IGNORE_UMA_MAX', 0)
120 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFoo + 1);', 1)
122 def testNoMaxNoPlusOne(self):
123 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFoo);', 1)
125 def testMultipleErrors(self):
126 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFoo);\n'
127 'printf("hello, world!");\n'
128 'UMA_HISTOGRAM_ENUMERATION("test", kBar, kBarMax);', 2)
130 def testValidAndInvalid(self):
131 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFoo);\n'
132 'UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFooMax + 1);'
133 'UMA_HISTOGRAM_ENUMERATION("test", kBar, kBarMax);', 2)
135 def testInvalidMultiLine(self):
136 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test",\n'
140 def testInvalidComments(self):
141 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", /*...*/, val, /*...*/,'
144 def testInvalidMultiLineComments(self):
145 self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", // This is the name\n'
146 ' kFoo, /* The value */\n'
147 ' kFooMax + 2 /* The max */ );',
150 class NoV4L2AggregateInitializationTest(unittest.TestCase):
153 self._testChange(['struct v4l2_format_ format;'], 0)
155 def testInvalid(self):
156 self._testChange(['struct v4l2_format format = {};'], 1)
157 self._testChange([' struct v4l2_format format = {};'], 1)
158 self._testChange([' struct std::vector<v4l2_format> format[] = {};'], 1)
159 self._testChange([' struct std::vector<v4l2_format> format[] = {{}};'], 1)
161 def _testChange(self, content, expected_warnings):
162 mock_input_api = MockInputApi()
163 mock_input_api.files.append(MockFile('test.cc', content))
164 results = PRESUBMIT._CheckForNoV4L2AggregateInitialization(mock_input_api,
166 if expected_warnings:
167 self.assertEqual(1, len(results))
168 self.assertEqual(expected_warnings, len(results[0].items))
170 self.assertEqual(0, len(results))
173 if __name__ == '__main__':