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
160
161
162
163
164
165
166
167
168
169
170
|
# coding=utf-8
"""
Cmd2 unit/functional testing
Copyright 2016 Federico Ceratto <federico.ceratto@gmail.com>
Released under MIT license, see LICENSE file
"""
import sys
from typing import Optional
from unittest import mock
from pytest import fixture
import cmd2
from cmd2.utils import StdSim
# Prefer statically linked gnureadline if available (for macOS compatibility due to issues with libedit)
try:
import gnureadline as readline
except ImportError:
# Try to import readline, but allow failure for convenience in Windows unit testing
# Note: If this actually fails, you should install readline on Linux or Mac or pyreadline on Windows
try:
# noinspection PyUnresolvedReferences
import readline
except ImportError:
pass
# Help text for base cmd2.Cmd application
BASE_HELP = """Documented commands (type help <topic>):
========================================
alias help load py quit shell
edit history macro pyscript set shortcuts
"""
BASE_HELP_VERBOSE = """
Documented commands (type help <topic>):
================================================================================
alias Manage aliases
edit Edit a file in a text editor
help List available commands with "help" or detailed help with "help cmd"
history View, run, edit, save, or clear previously entered commands
load Run commands in script file that is encoded as either ASCII or UTF-8 text
macro Manage macros
py Invoke Python command or shell
pyscript Run a Python script file inside the console
quit Exit this application
set Set a settable parameter or show current settings of parameters
shell Execute a command as if at the OS prompt
shortcuts List available shortcuts
"""
# Help text for the history command
HELP_HISTORY = """Usage: history [-h] [-r | -e | -s | -o FILE | -t TRANSCRIPT | -c] [arg]
View, run, edit, save, or clear previously entered commands
positional arguments:
arg empty all history items
a one history item by number
a..b, a:b, a:, ..b items by indices (inclusive)
[string] items containing string
/regex/ items matching regular expression
optional arguments:
-h, --help show this help message and exit
-r, --run run selected history items
-e, --edit edit and then run selected history items
-s, --script output commands in script format
-o, --output-file FILE
output commands to a script file
-t, --transcript TRANSCRIPT
output commands and results to a transcript file
-c, --clear clear all history
"""
# Output from the shortcuts command with default built-in shortcuts
SHORTCUTS_TXT = """Shortcuts for other commands:
!: shell
?: help
@: load
@@: _relative_load
"""
# Output from the show command with default settings
SHOW_TXT = """colors: Terminal
continuation_prompt: >
debug: False
echo: False
editor: vim
feedback_to_output: False
locals_in_py: False
prompt: (Cmd)
quiet: False
timing: False
"""
SHOW_LONG = """
colors: Terminal # Allow colorized output (valid values: Terminal, Always, Never)
continuation_prompt: > # On 2nd+ line of input
debug: False # Show full error stack on error
echo: False # Echo command issued into output
editor: vim # Program used by ``edit``
feedback_to_output: False # Include nonessentials in `|`, `>` results
locals_in_py: False # Allow access to your application in py via self
prompt: (Cmd) # The prompt issued to solicit input
quiet: False # Don't print nonessential feedback
timing: False # Report execution times
"""
def normalize(block):
""" Normalize a block of text to perform comparison.
Strip newlines from the very beginning and very end Then split into separate lines and strip trailing whitespace
from each line.
"""
assert isinstance(block, str)
block = block.strip('\n')
return [line.rstrip() for line in block.splitlines()]
def run_cmd(app, cmd):
""" Clear StdSim buffer, run the command, extract the buffer contents, """
app.stdout.clear()
app.onecmd_plus_hooks(cmd)
out = app.stdout.getvalue()
app.stdout.clear()
return normalize(out)
@fixture
def base_app():
c = cmd2.Cmd()
c.stdout = StdSim(c.stdout)
return c
def complete_tester(text: str, line: str, begidx: int, endidx: int, app) -> Optional[str]:
"""
This is a convenience function to test cmd2.complete() since
in a unit test environment there is no actual console readline
is monitoring. Therefore we use mock to provide readline data
to complete().
:param text: the string prefix we are attempting to match
:param line: the current input line with leading whitespace removed
:param begidx: the beginning index of the prefix text
:param endidx: the ending index of the prefix text
:param app: the cmd2 app that will run completions
:return: The first matched string or None if there are no matches
Matches are stored in app.completion_matches
These matches also have been sorted by complete()
"""
def get_line():
return line
def get_begidx():
return begidx
def get_endidx():
return endidx
first_match = None
with mock.patch.object(readline, 'get_line_buffer', get_line):
with mock.patch.object(readline, 'get_begidx', get_begidx):
with mock.patch.object(readline, 'get_endidx', get_endidx):
# Run the readline tab-completion function with readline mocks in place
first_match = app.complete(text, 0)
return first_match
|