| #!/usr/bin/env vpython3 | |
| # 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 | |
| from __future__ import absolute_import | |
| import os.path | |
| import re | |
| class MockInputApi: | |
| """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__) | |
| self.re = re # pylint: disable=invalid-name | |
| def AffectedSourceFiles(self, file_filter=None): | |
| return self.AffectedFiles(file_filter=file_filter) | |
| def AffectedFiles(self, file_filter=None, include_deletes=False): | |
| for f in self.files: | |
| if file_filter and not file_filter(f): | |
| continue | |
| if not include_deletes and f.Action() == 'D': | |
| continue | |
| yield f | |
| @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='r'): | |
| 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: | |
| """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: | |
| 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: | |
| """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: | |
| """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 |