File: test_autocommand.py

package info (click to toggle)
python-autocommand 2.2.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 236 kB
  • sloc: python: 1,052; sh: 15; makefile: 3
file content (159 lines) | stat: -rw-r--r-- 4,604 bytes parent folder | download | duplicates (2)
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