# Copyright 2014 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import os import re import unittest import PRESUBMIT class MockInputApi(object): def __init__(self): self.re = re self.os_path = os.path self.files = [] self.is_committing = False def AffectedFiles(self): return self.files def AffectedSourceFiles(self, fn): # we'll just pretend everything is a source file for the sake of simplicity return self.files def ReadFile(self, f): return f.NewContents() class MockOutputApi(object): class PresubmitResult(object): def __init__(self, message, items=None, long_text=''): self.message = message self.items = items self.long_text = long_text class PresubmitError(PresubmitResult): def __init__(self, message, items, long_text=''): MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) self.type = 'error' class PresubmitPromptWarning(PresubmitResult): def __init__(self, message, items, long_text=''): MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) self.type = 'warning' class PresubmitNotifyResult(PresubmitResult): def __init__(self, message, items, long_text=''): MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) self.type = 'notify' class PresubmitPromptOrNotify(PresubmitResult): def __init__(self, message, items, long_text=''): MockOutputApi.PresubmitResult.__init__(self, message, items, long_text) self.type = 'promptOrNotify' class MockFile(object): def __init__(self, local_path, new_contents): self._local_path = local_path self._new_contents = new_contents self._changed_contents = [(i + 1, l) for i, l in enumerate(new_contents)] def ChangedContents(self): return self._changed_contents def NewContents(self): return self._new_contents def LocalPath(self): return self._local_path class MockChange(object): def __init__(self, changed_files): self._changed_files = changed_files def LocalPaths(self): return self._changed_files class HistogramOffByOneTest(unittest.TestCase): # Take an input and make sure the problems found equals the expectation. def simpleCheck(self, contents, expected_errors): input_api = MockInputApi() input_api.files.append(MockFile('test.cc', contents)) results = PRESUBMIT._CheckForHistogramOffByOne(input_api, MockOutputApi()) if expected_errors: self.assertEqual(1, len(results)) self.assertEqual(expected_errors, len(results[0].items)) else: self.assertEqual(0, len(results)) def testValid(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFooMax + 1);', 0) def testValidComments(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", /*...*/ kFoo, /*...*/' 'kFooMax + 1);', 0) def testValidMultiLine(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test",\n' ' kFoo,\n' ' kFooMax + 1);', 0) def testValidMultiLineComments(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", // This is the name\n' ' kFoo, /* The value */\n' ' kFooMax + 1 /* The max */ );', 0) def testNoPlusOne(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFooMax);', 1) def testInvalidWithIgnore(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFooMax); ' '// PRESUBMIT_IGNORE_UMA_MAX', 0) def testNoMax(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFoo + 1);', 1) def testNoMaxNoPlusOne(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFoo);', 1) def testMultipleErrors(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFoo);\n' 'printf("hello, world!");\n' 'UMA_HISTOGRAM_ENUMERATION("test", kBar, kBarMax);', 2) def testValidAndInvalid(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFoo);\n' 'UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFooMax + 1);' 'UMA_HISTOGRAM_ENUMERATION("test", kBar, kBarMax);', 2) def testInvalidMultiLine(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test",\n' ' kFoo,\n' ' kFooMax + 2);', 1) def testInvalidComments(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", /*...*/, val, /*...*/,' 'Max);\n', 1) def testInvalidMultiLineComments(self): self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", // This is the name\n' ' kFoo, /* The value */\n' ' kFooMax + 2 /* The max */ );', 1) if __name__ == '__main__': unittest.main()