1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
# Copyright 2014-2016 Nathan West
#
# This file is part of autocommand.
#
# autocommand is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# autocommand 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with autocommand. If not, see <http://www.gnu.org/licenses/>.
import pytest
import sys
from unittest.mock import patch, sentinel
from autocommand import autocommand
autocommand_module = sys.modules['autocommand.autocommand']
def _asyncio_unavailable():
try:
import asyncio
# This is here to silence flake8 complaining about "unused import"
assert asyncio
except ImportError:
return True
else:
return False
skip_if_async_unavailable = pytest.mark.skipif(
_asyncio_unavailable(),
reason="async tests require asyncio (python3.4+)")
@pytest.fixture
def patched_autoparse():
with patch.object(
autocommand_module,
'autoparse',
autospec=True) as autoparse:
yield autoparse
@pytest.fixture
def patched_autoasync():
with patch.object(
autocommand_module,
'autoasync',
create=True) as autoasync:
if sys.version_info < (3, 4):
autoasync.side_effect = NameError('autoasync')
yield autoasync
@pytest.fixture
def patched_automain():
with patch.object(
autocommand_module,
'automain',
autospec=True) as automain:
yield automain
def test_autocommand_no_async(
patched_automain,
patched_autoasync,
patched_autoparse):
autocommand_wrapped = autocommand(
sentinel.module,
description=sentinel.description,
epilog=sentinel.epilog,
add_nos=sentinel.add_nos,
parser=sentinel.parser)(sentinel.original_function)
assert not patched_autoasync.called
patched_autoparse.assert_called_once_with(
sentinel.original_function,
description=sentinel.description,
epilog=sentinel.epilog,
add_nos=sentinel.add_nos,
parser=sentinel.parser)
autoparse_wrapped = patched_autoparse.return_value
patched_automain.assert_called_once_with(sentinel.module)
patched_automain.return_value.assert_called_once_with(autoparse_wrapped)
automain_wrapped = patched_automain.return_value.return_value
assert automain_wrapped is autocommand_wrapped
@pytest.mark.parametrize(
'input_loop, output_loop',
[(sentinel.loop, sentinel.loop),
(True, None)])
@skip_if_async_unavailable
def test_autocommand_with_async(
patched_automain,
patched_autoasync,
patched_autoparse,
input_loop, output_loop):
autocommand_wrapped = autocommand(
sentinel.module,
description=sentinel.description,
epilog=sentinel.epilog,
add_nos=sentinel.add_nos,
parser=sentinel.parser,
loop=input_loop,
forever=sentinel.forever,
pass_loop=sentinel.pass_loop)(sentinel.original_function)
patched_autoasync.assert_called_once_with(
sentinel.original_function,
loop=output_loop,
forever=sentinel.forever,
pass_loop=sentinel.pass_loop)
autoasync_wrapped = patched_autoasync.return_value
patched_autoparse.assert_called_once_with(
autoasync_wrapped,
description=sentinel.description,
epilog=sentinel.epilog,
add_nos=sentinel.add_nos,
parser=sentinel.parser)
autoparse_wrapped = patched_autoparse.return_value
patched_automain.assert_called_once_with(sentinel.module)
patched_automain.return_value.assert_called_once_with(autoparse_wrapped)
automain_wrapped = patched_automain.return_value.return_value
assert automain_wrapped is autocommand_wrapped
def test_autocommand_incorrect_invocation_no_parenthesis(
patched_automain,
patched_autoparse,
patched_autoasync):
'''
Test that an exception is raised if the autocommand decorator is called
without parenthesis by accident
'''
with pytest.raises(TypeError):
@autocommand
def original_function():
pass
|