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 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
|
# coding=utf-8
# flake8: noqa E302
"""
Unit/functional testing for run_pytest in cmd2
"""
import builtins
import os
from unittest import (
mock,
)
import pytest
from cmd2 import (
plugin,
utils,
)
from .conftest import (
odd_file_names,
run_cmd,
)
HOOK_OUTPUT = "TEST_OUTPUT"
def cmdfinalization_hook(data: plugin.CommandFinalizationData) -> plugin.CommandFinalizationData:
"""A cmdfinalization_hook hook which requests application exit"""
print(HOOK_OUTPUT)
return data
def test_run_pyscript(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
python_script = os.path.join(test_dir, 'script.py')
expected = 'This is a python script running ...'
out, err = run_cmd(base_app, "run_pyscript {}".format(python_script))
assert expected in out
assert base_app.last_result is True
def test_run_pyscript_recursive_not_allowed(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
python_script = os.path.join(test_dir, 'pyscript', 'recursive.py')
expected = 'Recursively entering interactive Python shells is not allowed'
out, err = run_cmd(base_app, "run_pyscript {}".format(python_script))
assert err[0] == expected
assert base_app.last_result is False
def test_run_pyscript_with_nonexist_file(base_app):
python_script = 'does_not_exist.py'
out, err = run_cmd(base_app, "run_pyscript {}".format(python_script))
assert "Error reading script file" in err[0]
assert base_app.last_result is False
def test_run_pyscript_with_non_python_file(base_app, request):
m = mock.MagicMock(name='input', return_value='2')
builtins.input = m
test_dir = os.path.dirname(request.module.__file__)
filename = os.path.join(test_dir, 'scripts', 'help.txt')
out, err = run_cmd(base_app, 'run_pyscript {}'.format(filename))
assert "does not have a .py extension" in err[0]
assert base_app.last_result is False
@pytest.mark.parametrize('python_script', odd_file_names)
def test_run_pyscript_with_odd_file_names(base_app, python_script):
"""
Pass in file names with various patterns. Since these files don't exist, we will rely
on the error text to make sure the file names were processed correctly.
"""
# Mock input to get us passed the warning about not ending in .py
input_mock = mock.MagicMock(name='input', return_value='1')
builtins.input = input_mock
out, err = run_cmd(base_app, "run_pyscript {}".format(utils.quote_string(python_script)))
err = ''.join(err)
assert "Error reading script file '{}'".format(python_script) in err
assert base_app.last_result is False
def test_run_pyscript_with_exception(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
python_script = os.path.join(test_dir, 'pyscript', 'raises_exception.py')
out, err = run_cmd(base_app, "run_pyscript {}".format(python_script))
assert err[0].startswith('Traceback')
assert "TypeError: unsupported operand type(s) for +: 'int' and 'str'" in err[-1]
assert base_app.last_result is True
def test_run_pyscript_requires_an_argument(base_app):
out, err = run_cmd(base_app, "run_pyscript")
assert "the following arguments are required: script_path" in err[1]
assert base_app.last_result is None
def test_run_pyscript_help(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
python_script = os.path.join(test_dir, 'pyscript', 'help.py')
out1, err1 = run_cmd(base_app, 'help')
out2, err2 = run_cmd(base_app, 'run_pyscript {}'.format(python_script))
assert out1 and out1 == out2
def test_scripts_add_to_history(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
python_script = os.path.join(test_dir, 'pyscript', 'help.py')
command = f'run_pyscript {python_script}'
# Add to history
base_app.scripts_add_to_history = True
base_app.history.clear()
run_cmd(base_app, command)
assert len(base_app.history) == 2
assert base_app.history.get(1).raw == command
assert base_app.history.get(2).raw == 'help'
# Do not add to history
base_app.scripts_add_to_history = False
base_app.history.clear()
run_cmd(base_app, command)
assert len(base_app.history) == 1
assert base_app.history.get(1).raw == command
def test_run_pyscript_dir(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
python_script = os.path.join(test_dir, 'pyscript', 'pyscript_dir.py')
out, err = run_cmd(base_app, 'run_pyscript {}'.format(python_script))
assert out[0] == "['cmd_echo']"
def test_run_pyscript_stdout_capture(base_app, request):
base_app.register_cmdfinalization_hook(cmdfinalization_hook)
test_dir = os.path.dirname(request.module.__file__)
python_script = os.path.join(test_dir, 'pyscript', 'stdout_capture.py')
out, err = run_cmd(base_app, 'run_pyscript {} {}'.format(python_script, HOOK_OUTPUT))
assert out[0] == "PASSED"
assert out[1] == "PASSED"
def test_run_pyscript_stop(base_app, request):
# Verify onecmd_plus_hooks() returns True if any commands in a pyscript return True for stop
test_dir = os.path.dirname(request.module.__file__)
# help.py doesn't run any commands that return True for stop
python_script = os.path.join(test_dir, 'pyscript', 'help.py')
stop = base_app.onecmd_plus_hooks('run_pyscript {}'.format(python_script))
assert not stop
# stop.py runs the quit command which does return True for stop
python_script = os.path.join(test_dir, 'pyscript', 'stop.py')
stop = base_app.onecmd_plus_hooks('run_pyscript {}'.format(python_script))
assert stop
def test_run_pyscript_environment(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
python_script = os.path.join(test_dir, 'pyscript', 'environment.py')
out, err = run_cmd(base_app, 'run_pyscript {}'.format(python_script))
assert out[0] == "PASSED"
def test_run_pyscript_self_in_py(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
python_script = os.path.join(test_dir, 'pyscript', 'self_in_py.py')
# Set self_in_py to True and make sure we see self
base_app.self_in_py = True
out, err = run_cmd(base_app, 'run_pyscript {}'.format(python_script))
assert 'I see self' in out[0]
# Set self_in_py to False and make sure we can't see self
base_app.self_in_py = False
out, err = run_cmd(base_app, 'run_pyscript {}'.format(python_script))
assert 'I do not see self' in out[0]
def test_run_pyscript_py_locals(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
python_script = os.path.join(test_dir, 'pyscript', 'py_locals.py')
# Make sure pyscripts can't edit Cmd.py_locals. It used to be that cmd2 was passing its py_locals
# dictionary to the py environment instead of a shallow copy.
base_app.py_locals['test_var'] = 5
# Place an editable object in py_locals. Since we make a shallow copy of py_locals,
# this object should be editable from the py environment.
base_app.py_locals['my_list'] = []
run_cmd(base_app, 'run_pyscript {}'.format(python_script))
# test_var should still exist
assert base_app.py_locals['test_var'] == 5
# my_list should be edited
assert base_app.py_locals['my_list'][0] == 2
def test_run_pyscript_app_echo(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
python_script = os.path.join(test_dir, 'pyscript', 'echo.py')
out, err = run_cmd(base_app, 'run_pyscript {}'.format(python_script))
# Only the edit help text should have been echoed to pytest's stdout
assert out[0] == "Usage: edit [-h] [file_path]"
|