Completed
Push — master ( 2bc9f2...ef56ad )
by Lambda
01:45
created

test_keymap_harvest_timeout()   F

Complexity

Conditions 15

Size

Total Lines 79

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 15
dl 0
loc 79
rs 2.1217
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A side_effect() 0 5 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like test_keymap_harvest_timeout() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
from curses import ascii
2
from collections import abc
3
4
from datetime import datetime, timedelta
5
from unittest.mock import MagicMock, patch
6
7
import pytest
8
9
from neovim_prompt.keystroke import Keystroke
10
from neovim_prompt.keymap import Keymap
11
12
13
def test_Keymap_property():
14
    keymap = Keymap()
15
16
17 View Code Duplication
def test_keymap_register(nvim):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
18
    lhs = Keystroke.parse(nvim, '<C-H>')
19
    rhs = Keystroke.parse(nvim, '<BS>')
20
    keymap = Keymap()
21
    keymap.register(lhs, rhs)
22
    assert keymap.registry[lhs] == (lhs, rhs, False, False)
23
24
    keymap.register(lhs, rhs, True)
25
    assert keymap.registry[lhs] == (lhs, rhs, True, False)
26
27
    keymap.register(lhs, rhs, True, True)
28
    assert keymap.registry[lhs] == (lhs, rhs, True, True)
29
30
31 View Code Duplication
def test_keymap_register_from_rule(nvim):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
32
    lhs = Keystroke.parse(nvim, '<C-H>')
33
    rhs = Keystroke.parse(nvim, '<BS>')
34
    keymap = Keymap()
35
    keymap.register_from_rule(nvim, ('<C-H>', '<BS>'))
36
    assert keymap.registry[lhs] == (lhs, rhs, False, False)
37
38
    keymap.register_from_rule(nvim, ('<C-H>', '<BS>', True))
39
    assert keymap.registry[lhs] == (lhs, rhs, True, False)
40
41
    keymap.register_from_rule(nvim, ('<C-H>', '<BS>', True, True))
42
    assert keymap.registry[lhs] == (lhs, rhs, True, True)
43
44
45
def test_keymap_register_from_rules(nvim):
46
    lhs1 = Keystroke.parse(nvim, '<C-H>')
47
    lhs2 = Keystroke.parse(nvim, '<C-D>')
48
    lhs3 = Keystroke.parse(nvim, '<C-M>')
49
    rhs1 = Keystroke.parse(nvim, '<BS>')
50
    rhs2 = Keystroke.parse(nvim, '<DEL>')
51
    rhs3 = Keystroke.parse(nvim, '<CR>')
52
53
    keymap = Keymap()
54
    keymap.register_from_rules(nvim, [
55
        ('<C-H>', '<BS>'),
56
        ('<C-D>', '<DEL>', True),
57
        ('<C-M>', '<CR>', True, True),
58
    ])
59
    assert keymap.registry[lhs1] == (lhs1, rhs1, False, False)
60
    assert keymap.registry[lhs2] == (lhs2, rhs2, True, False)
61
    assert keymap.registry[lhs3] == (lhs3, rhs3, True, True)
62
63
    # It can overwrite
64
    keymap.register_from_rules(nvim, [
65
        ('<C-H>', '<BS>', True, True),
66
        ('<C-D>', '<DEL>', False, True),
67
        ('<C-M>', '<CR>', False, False),
68
    ])
69
    assert keymap.registry[lhs1] == (lhs1, rhs1, True, True)
70
    assert keymap.registry[lhs2] == (lhs2, rhs2, False, True)
71
    assert keymap.registry[lhs3] == (lhs3, rhs3, False, False)
72
73
74
def test_keymap_filter(nvim):
75
    lhs1 = Keystroke.parse(nvim, '<C-X><C-F>')
76
    lhs2 = Keystroke.parse(nvim, '<C-X><C-B>')
77
    lhs3 = Keystroke.parse(nvim, '<C-A>')
78
    keymap = Keymap()
79
    keymap.register_from_rule(nvim, ('<C-X><C-F>', '<A>'))
80
    keymap.register_from_rule(nvim, ('<C-X><C-B>', '<B>'))
81
    keymap.register_from_rule(nvim, ('<C-A>', '<C>'))
82
83
    assert keymap.filter(Keystroke.parse(nvim, '')) == sorted((
84
        (lhs3, Keystroke.parse(nvim, '<C>'), False, False),
85
        (lhs1, Keystroke.parse(nvim, '<A>'), False, False),
86
        (lhs2, Keystroke.parse(nvim, '<B>'), False, False),
87
    ))
88
89
    assert keymap.filter(Keystroke.parse(nvim, '<C-X>')) == sorted((
90
        (lhs1, Keystroke.parse(nvim, '<A>'), False, False),
91
        (lhs2, Keystroke.parse(nvim, '<B>'), False, False),
92
    ))
93
94
    assert keymap.filter(Keystroke.parse(nvim, '<C-X><C-F>')) == sorted((
95
        (lhs1, Keystroke.parse(nvim, '<A>'), False, False),
96
    ))
97
98
99
def test_keymap_resolve(nvim):
100
    lhs1 = Keystroke.parse(nvim, '<C-X><C-F>')
101
    lhs2 = Keystroke.parse(nvim, '<C-X><C-B>')
102
    lhs3 = Keystroke.parse(nvim, '<C-A>')
103
    keymap = Keymap()
104
    keymap.register_from_rule(nvim, ('<C-X><C-F>', '<A>'))
105
    keymap.register_from_rule(nvim, ('<C-X><C-B>', '<B>'))
106
    keymap.register_from_rule(nvim, ('<C-A>', '<C>'))
107
108
    assert keymap.resolve(Keystroke.parse(nvim, '')) is None
109
    assert keymap.resolve(Keystroke.parse(nvim, '<C-A>')) == \
110
        Keystroke.parse(nvim, '<C>')
111
    assert keymap.resolve(Keystroke.parse(nvim, '<C-X>')) is None
112
    assert keymap.resolve(Keystroke.parse(nvim, '<C-X><C-F>')) == \
113
        Keystroke.parse(nvim, '<A>')
114
115
    # remap
116
    keymap.register_from_rule(nvim, ('<B>', '<D>'))
117
    assert keymap.resolve(Keystroke.parse(nvim, '<C-X><C-B>')) == \
118
        Keystroke.parse(nvim, '<D>')
119
    # noremap
120
    keymap.register_from_rule(nvim, ('<C-X><C-B>', '<B>', True))
121
    assert keymap.resolve(Keystroke.parse(nvim, '<C-X><C-B>')) == \
122
        Keystroke.parse(nvim, '<B>')
123
124
    keymap.register_from_rule(nvim, ('<C-Y><C-K>', '<E>'))
125
    assert keymap.resolve(Keystroke.parse(nvim, '<C-Y>')) is None
126
127
128
def test_keymap_harvest_timeout(nvim):
129
    nvim.options = {
130
        'timeout': True,
131
        'timeoutlen': 1000,
132
        'encoding': 'utf-8',
133
    }
134
135
    now = datetime.now()
136
    with patch('neovim_prompt.keymap.datetime') as m1:
137
        keymap = Keymap()
138
        keymap.register_from_rules(nvim, [
139
            ('<C-H>', '<prompt:CH>', True),
140
            ('<C-H><C-H>', '<prompt:CHCH>', True),
141
        ])
142
143
        # Keypress within timeoutlen
144
        def side_effect(*args):
145
            yield ord('\x08')   # ^H
146
            m1.now.return_value += timedelta(milliseconds=999)
147
            yield 0
148
            yield ord('\x08')   # ^H
149
150
        m1.now.return_value = now
151
        nvim.call = MagicMock()
152
        nvim.call.side_effect = side_effect()
153
154
        keystroke = keymap.harvest(nvim)
155
        assert keystroke == Keystroke.parse(nvim, '<prompt:CHCH>')
156
        with pytest.raises(StopIteration):
157
            nvim.call()
158
159
        # Keypress after timeoutlen
160
        def side_effect(*args):
161
            yield ord('\x08')   # ^H
162
            m1.now.return_value += timedelta(milliseconds=1000)
163
            yield 0
164
            yield ord('\x08')   # ^H
165
166
        m1.now.return_value = now
167
        nvim.call.side_effect = side_effect()
168
169
        keystroke = keymap.harvest(nvim)
170
        assert keystroke == Keystroke.parse(nvim, '<prompt:CH>')
171
        assert nvim.call() == ord('\x08')   # residual
172
173
        # Timeout without keypress
174
        def side_effect(*args):
175
            m1.now.return_value += timedelta(milliseconds=1000)
176
            yield 0
177
            yield ord('\x08')   # ^H
178
            yield ord('\x08')   # ^H
179
180
        m1.now.return_value = now
181
        nvim.call.side_effect = side_effect()
182
183
        keystroke = keymap.harvest(nvim)
184
        assert keystroke == Keystroke.parse(nvim, '<prompt:CHCH>')
185
        with pytest.raises(StopIteration):
186
            nvim.call()
187
188
        # Keypress within timeoutlen but with nowait
189
        keymap.register_from_rules(nvim, [
190
            ('<C-H>', '<prompt:CH>', True, True),
191
            ('<C-H><C-H>', '<prompt:CHCH>', True),
192
        ])
193
        def side_effect(*args):
194
            yield ord('\x08')   # ^H
195
            m1.now.return_value += timedelta(milliseconds=999)
196
            yield 0
197
            yield ord('\x08')   # ^H
198
199
        m1.now.return_value = now
200
        nvim.call = MagicMock()
201
        nvim.call.side_effect = side_effect()
202
203
        keystroke = keymap.harvest(nvim)
204
        assert keystroke == Keystroke.parse(nvim, '<prompt:CH>')
205
        assert nvim.call() == 0   # residual
206
        assert nvim.call() == ord('\x08')   # residual
207
208
209
def test_keymap_harvest_notimeout(nvim):
210
    nvim.options = {
211
        'timeout': False,
212
        'timeoutlen': 1000,
213
        'encoding': 'utf-8',
214
    }
215
216
    now = datetime.now()
217
    with patch('neovim_prompt.keymap.datetime') as m1:
218
        keymap = Keymap()
219
        keymap.register_from_rules(nvim, [
220
            ('<C-H>', '<prompt:CH>', True),
221
            ('<C-H><C-H>', '<prompt:CHCH>', True),
222
        ])
223
224
        # Keypress after timeoutlen
225
        def side_effect(*args):
226
            yield ord('\x08')   # ^H
227
            m1.now.return_value += timedelta(milliseconds=1000)
228
            yield 0
229
            yield ord('\x08')   # ^H
230
231
        m1.now.return_value = now
232
        nvim.call = MagicMock()
233
        nvim.call.side_effect = side_effect()
234
235
        keystroke = keymap.harvest(nvim)
236
        assert keystroke == Keystroke.parse(nvim, '<prompt:CHCH>')
237
        with pytest.raises(StopIteration):
238
            nvim.call()
239
240
        # Keypress within timeoutlen but with nowait
241
        keymap.register_from_rules(nvim, [
242
            ('<C-H>', '<prompt:CH>', True, True),
243
            ('<C-H><C-H>', '<prompt:CHCH>', True),
244
        ])
245
        def side_effect(*args):
246
            yield ord('\x08')   # ^H
247
            m1.now.return_value += timedelta(milliseconds=999)
248
            yield 0
249
            yield ord('\x08')   # ^H
250
251
        m1.now.return_value = now
252
        nvim.call = MagicMock()
253
        nvim.call.side_effect = side_effect()
254
255
        keystroke = keymap.harvest(nvim)
256
        assert keystroke == Keystroke.parse(nvim, '<prompt:CH>')
257
        assert nvim.call() == 0   # residual
258
        assert nvim.call() == ord('\x08')   # residual
259
260
261
def test_Keymap_from_rules(nvim):
262
    lhs1 = Keystroke.parse(nvim, '<C-H>')
263
    lhs2 = Keystroke.parse(nvim, '<C-D>')
264
    lhs3 = Keystroke.parse(nvim, '<C-M>')
265
    rhs1 = Keystroke.parse(nvim, '<BS>')
266
    rhs2 = Keystroke.parse(nvim, '<DEL>')
267
    rhs3 = Keystroke.parse(nvim, '<CR>')
268
269
    keymap = Keymap.from_rules(nvim, [
270
        ('<C-H>', '<BS>'),
271
        ('<C-D>', '<DEL>', True),
272
        ('<C-M>', '<CR>', True, True),
273
    ])
274
    assert keymap.registry[lhs1] == (lhs1, rhs1, False, False)
275
    assert keymap.registry[lhs2] == (lhs2, rhs2, True, False)
276
    assert keymap.registry[lhs3] == (lhs3, rhs3, True, True)
277