| Index: media/PRESUBMIT_test.py | 
| diff --git a/media/PRESUBMIT_test.py b/media/PRESUBMIT_test.py | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..6ca6687ab43d42d13c85d1ac6768f516eccf1ffd | 
| --- /dev/null | 
| +++ b/media/PRESUBMIT_test.py | 
| @@ -0,0 +1,151 @@ | 
| +#!/usr/bin/env python | 
| +# 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() | 
|  |