# (c) 2014, Toshio Kuratomi <[email protected]> | |
# | |
# This file is part of Ansible | |
# | |
# Ansible is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# | |
# Ansible is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with Ansible. If not, see <http://www.gnu.org/licenses/>. | |
# Make coding more python3-ish | |
from __future__ import absolute_import, division, print_function | |
__metaclass__ = type | |
""" | |
Compat module for Python3.x's unittest.mock module | |
""" | |
import sys | |
# Python 2.7 | |
# Note: Could use the pypi mock library on python3.x as well as python2.x. It | |
# is the same as the python3 stdlib mock library | |
try: | |
# Allow wildcard import because we really do want to import all of mock's | |
# symbols into this compat shim | |
# pylint: disable=wildcard-import,unused-wildcard-import | |
from unittest.mock import * | |
except ImportError: | |
# Python 2 | |
# pylint: disable=wildcard-import,unused-wildcard-import | |
try: | |
from mock import * | |
except ImportError: | |
print("You need the mock library installed on python2.x to run tests") | |
# Prior to 3.4.4, mock_open cannot handle binary read_data | |
if sys.version_info >= (3,) and sys.version_info < (3, 4, 4): | |
file_spec = None | |
def _iterate_read_data(read_data): | |
# Helper for mock_open: | |
# Retrieve lines from read_data via a generator so that separate calls to | |
# readline, read, and readlines are properly interleaved | |
sep = b"\n" if isinstance(read_data, bytes) else "\n" | |
data_as_list = [l + sep for l in read_data.split(sep)] | |
if data_as_list[-1] == sep: | |
# If the last line ended in a newline, the list comprehension will have an | |
# extra entry that's just a newline. Remove this. | |
data_as_list = data_as_list[:-1] | |
else: | |
# If there wasn't an extra newline by itself, then the file being | |
# emulated doesn't have a newline to end the last line remove the | |
# newline that our naive format() added | |
data_as_list[-1] = data_as_list[-1][:-1] | |
for line in data_as_list: | |
yield line | |
def mock_open(mock=None, read_data=""): | |
""" | |
A helper function to create a mock to replace the use of `open`. It works | |
for `open` called directly or used as a context manager. | |
The `mock` argument is the mock object to configure. If `None` (the | |
default) then a `MagicMock` will be created for you, with the API limited | |
to methods or attributes available on standard file handles. | |
`read_data` is a string for the `read` methoddline`, and `readlines` of the | |
file handle to return. This is an empty string by default. | |
""" | |
def _readlines_side_effect(*args, **kwargs): | |
if handle.readlines.return_value is not None: | |
return handle.readlines.return_value | |
return list(_data) | |
def _read_side_effect(*args, **kwargs): | |
if handle.read.return_value is not None: | |
return handle.read.return_value | |
return type(read_data)().join(_data) | |
def _readline_side_effect(): | |
if handle.readline.return_value is not None: | |
while True: | |
yield handle.readline.return_value | |
for line in _data: | |
yield line | |
global file_spec | |
if file_spec is None: | |
import _io | |
file_spec = list( | |
set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO))) | |
) | |
if mock is None: | |
mock = MagicMock(name="open", spec=open) | |
handle = MagicMock(spec=file_spec) | |
handle.__enter__.return_value = handle | |
_data = _iterate_read_data(read_data) | |
handle.write.return_value = None | |
handle.read.return_value = None | |
handle.readline.return_value = None | |
handle.readlines.return_value = None | |
handle.read.side_effect = _read_side_effect | |
handle.readline.side_effect = _readline_side_effect() | |
handle.readlines.side_effect = _readlines_side_effect | |
mock.return_value = handle | |
return mock |
File Metadata
File Metadata
- Mime Type
- text/x-script.python
- Expires
- Thu, Oct 31, 10:38 PM (1 d, 19 h)
- Storage Engine
- blob
- Storage Format
- Raw Data
- Storage Handle
- 886420
- Default Alt Text
- mock.py (4 KB)