Home | History | Annotate | Download | only in media
      1 # Copyright 2014 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 import os
      5 import re
      6 import unittest
      7 
      8 import PRESUBMIT
      9 
     10 class MockInputApi(object):
     11   def __init__(self):
     12     self.re = re
     13     self.os_path = os.path
     14     self.files = []
     15     self.is_committing = False
     16 
     17   def AffectedFiles(self):
     18     return self.files
     19 
     20   def AffectedSourceFiles(self, fn):
     21     # we'll just pretend everything is a source file for the sake of simplicity
     22     return self.files
     23 
     24   def ReadFile(self, f):
     25     return f.NewContents()
     26 
     27 
     28 class MockOutputApi(object):
     29   class PresubmitResult(object):
     30     def __init__(self, message, items=None, long_text=''):
     31       self.message = message
     32       self.items = items
     33       self.long_text = long_text
     34 
     35   class PresubmitError(PresubmitResult):
     36     def __init__(self, message, items, long_text=''):
     37       MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
     38       self.type = 'error'
     39 
     40   class PresubmitPromptWarning(PresubmitResult):
     41     def __init__(self, message, items, long_text=''):
     42       MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
     43       self.type = 'warning'
     44 
     45   class PresubmitNotifyResult(PresubmitResult):
     46     def __init__(self, message, items, long_text=''):
     47       MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
     48       self.type = 'notify'
     49 
     50   class PresubmitPromptOrNotify(PresubmitResult):
     51     def __init__(self, message, items, long_text=''):
     52       MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
     53       self.type = 'promptOrNotify'
     54 
     55 
     56 class MockFile(object):
     57   def __init__(self, local_path, new_contents):
     58     self._local_path = local_path
     59     self._new_contents = new_contents
     60     self._changed_contents = [(i + 1, l) for i, l in enumerate(new_contents)]
     61 
     62   def ChangedContents(self):
     63     return self._changed_contents
     64 
     65   def NewContents(self):
     66     return self._new_contents
     67 
     68   def LocalPath(self):
     69     return self._local_path
     70 
     71 
     72 class MockChange(object):
     73   def __init__(self, changed_files):
     74     self._changed_files = changed_files
     75 
     76   def LocalPaths(self):
     77     return self._changed_files
     78 
     79 
     80 class HistogramOffByOneTest(unittest.TestCase):
     81 
     82   # Take an input and make sure the problems found equals the expectation.
     83   def simpleCheck(self, contents, expected_errors):
     84     input_api = MockInputApi()
     85     input_api.files.append(MockFile('test.cc', contents))
     86     results = PRESUBMIT._CheckForHistogramOffByOne(input_api, MockOutputApi())
     87     if expected_errors:
     88       self.assertEqual(1, len(results))
     89       self.assertEqual(expected_errors, len(results[0].items))
     90     else:
     91       self.assertEqual(0, len(results))
     92 
     93   def testValid(self):
     94     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFooMax + 1);', 0)
     95 
     96   def testValidComments(self):
     97     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", /*...*/ kFoo, /*...*/'
     98                      'kFooMax + 1);', 0)
     99 
    100   def testValidMultiLine(self):
    101     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test",\n'
    102                      '                          kFoo,\n'
    103                      '                          kFooMax + 1);', 0)
    104 
    105   def testValidMultiLineComments(self):
    106     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test",  // This is the name\n'
    107                      '                          kFoo,  /* The value */\n'
    108                      '                          kFooMax + 1 /* The max */ );',
    109                      0)
    110 
    111   def testNoPlusOne(self):
    112     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFooMax);', 1)
    113 
    114   def testInvalidWithIgnore(self):
    115     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFooMax); '
    116                      '// PRESUBMIT_IGNORE_UMA_MAX', 0)
    117 
    118   def testNoMax(self):
    119     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFoo + 1);', 1)
    120 
    121   def testNoMaxNoPlusOne(self):
    122     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFoo);', 1)
    123 
    124   def testMultipleErrors(self):
    125     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFoo);\n'
    126                      'printf("hello, world!");\n'
    127                      'UMA_HISTOGRAM_ENUMERATION("test", kBar, kBarMax);', 2)
    128 
    129   def testValidAndInvalid(self):
    130     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFoo);\n'
    131                      'UMA_HISTOGRAM_ENUMERATION("test", kFoo, kFooMax + 1);'
    132                      'UMA_HISTOGRAM_ENUMERATION("test", kBar, kBarMax);', 2)
    133 
    134   def testInvalidMultiLine(self):
    135     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test",\n'
    136                      '                          kFoo,\n'
    137                      '                          kFooMax + 2);', 1)
    138 
    139   def testInvalidComments(self):
    140     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test", /*...*/, val, /*...*/,'
    141                      'Max);\n', 1)
    142 
    143   def testInvalidMultiLineComments(self):
    144     self.simpleCheck('UMA_HISTOGRAM_ENUMERATION("test",  // This is the name\n'
    145                      '                          kFoo,  /* The value */\n'
    146                      '                          kFooMax + 2 /* The max */ );',
    147                      1)
    148 
    149 if __name__ == '__main__':
    150   unittest.main()
    151