| # Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 
 | # | 
 | # Use of this source code is governed by a BSD-style license | 
 | # that can be found in the LICENSE file in the root of the source | 
 | # tree. An additional intellectual property rights grant can be found | 
 | # in the file PATENTS.  All contributing project authors may | 
 | # be found in the AUTHORS file in the root of the source tree. | 
 |  | 
 | # This file is inspired to [1]. | 
 | # [1] - https://cs.chromium.org/chromium/src/PRESUBMIT_test_mocks.py | 
 |  | 
 | import os.path | 
 | import re | 
 |  | 
 |  | 
 | class MockInputApi(object): | 
 |     """Mock class for the InputApi class. | 
 |  | 
 |   This class can be used for unittests for presubmit by initializing the files | 
 |   attribute as the list of changed files. | 
 |   """ | 
 |  | 
 |     def __init__(self): | 
 |         self.change = MockChange([], []) | 
 |         self.files = [] | 
 |         self.presubmit_local_path = os.path.dirname(__file__) | 
 |  | 
 |     def AffectedSourceFiles(self, file_filter=None): | 
 |         return self.AffectedFiles(file_filter=file_filter) | 
 |  | 
 |     def AffectedFiles(self, file_filter=None, include_deletes=False): | 
 |         # pylint: disable=unused-argument | 
 |         return self.files | 
 |  | 
 |     @classmethod | 
 |     def FilterSourceFile(cls, | 
 |                          affected_file, | 
 |                          files_to_check=(), | 
 |                          files_to_skip=()): | 
 |         # pylint: disable=unused-argument | 
 |         return True | 
 |  | 
 |     def PresubmitLocalPath(self): | 
 |         return self.presubmit_local_path | 
 |  | 
 |     def ReadFile(self, affected_file, mode='rU'): | 
 |         filename = affected_file.AbsoluteLocalPath() | 
 |         for f in self.files: | 
 |             if f.LocalPath() == filename: | 
 |                 with open(filename, mode) as f: | 
 |                     return f.read() | 
 |         # Otherwise, file is not in our mock API. | 
 |         raise IOError, "No such file or directory: '%s'" % filename | 
 |  | 
 |  | 
 | class MockOutputApi(object): | 
 |     """Mock class for the OutputApi class. | 
 |  | 
 |   An instance of this class can be passed to presubmit unittests for outputing | 
 |   various types of results. | 
 |   """ | 
 |  | 
 |     class PresubmitResult(object): | 
 |         def __init__(self, message, items=None, long_text=''): | 
 |             self.message = message | 
 |             self.items = items | 
 |             self.long_text = long_text | 
 |  | 
 |         def __repr__(self): | 
 |             return self.message | 
 |  | 
 |     class PresubmitError(PresubmitResult): | 
 |         def __init__(self, message, items=None, long_text=''): | 
 |             MockOutputApi.PresubmitResult.__init__(self, message, items, | 
 |                                                    long_text) | 
 |             self.type = 'error' | 
 |  | 
 |  | 
 | class MockChange(object): | 
 |     """Mock class for Change class. | 
 |  | 
 |   This class can be used in presubmit unittests to mock the query of the | 
 |   current change. | 
 |   """ | 
 |  | 
 |     def __init__(self, changed_files, bugs_from_description, tags=None): | 
 |         self._changed_files = changed_files | 
 |         self._bugs_from_description = bugs_from_description | 
 |         self.tags = dict() if not tags else tags | 
 |  | 
 |     def BugsFromDescription(self): | 
 |         return self._bugs_from_description | 
 |  | 
 |     def __getattr__(self, attr): | 
 |         """Return tags directly as attributes on the object.""" | 
 |         if not re.match(r"^[A-Z_]*$", attr): | 
 |             raise AttributeError(self, attr) | 
 |         return self.tags.get(attr) | 
 |  | 
 |  | 
 | class MockFile(object): | 
 |     """Mock class for the File class. | 
 |  | 
 |   This class can be used to form the mock list of changed files in | 
 |   MockInputApi for presubmit unittests. | 
 |   """ | 
 |  | 
 |     def __init__(self, | 
 |                  local_path, | 
 |                  new_contents=None, | 
 |                  old_contents=None, | 
 |                  action='A'): | 
 |         if new_contents is None: | 
 |             new_contents = ["Data"] | 
 |         self._local_path = local_path | 
 |         self._new_contents = new_contents | 
 |         self._changed_contents = [(i + 1, l) | 
 |                                   for i, l in enumerate(new_contents)] | 
 |         self._action = action | 
 |         self._old_contents = old_contents | 
 |  | 
 |     def Action(self): | 
 |         return self._action | 
 |  | 
 |     def ChangedContents(self): | 
 |         return self._changed_contents | 
 |  | 
 |     def NewContents(self): | 
 |         return self._new_contents | 
 |  | 
 |     def LocalPath(self): | 
 |         return self._local_path | 
 |  | 
 |     def AbsoluteLocalPath(self): | 
 |         return self._local_path | 
 |  | 
 |     def OldContents(self): | 
 |         return self._old_contents |