summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorKevin Van Brunt <kmvanbrunt@gmail.com>2019-06-14 17:36:44 -0400
committerGitHub <noreply@github.com>2019-06-14 17:36:44 -0400
commitddd07f9cd6d72baca1232ae98856cf3b3d564706 (patch)
tree8e03d435730baf1cc16ccc016e594d0b64d8e04a /tests
parentf64f9d559caa08b5649b9bd356af2812acf103bd (diff)
parent756d8d38502e934ea180c4cfb8dea3efd124a3bf (diff)
downloadcmd2-git-ddd07f9cd6d72baca1232ae98856cf3b3d564706.tar.gz
Merge pull request #696 from python-cmd2/script_refactor
Script refactor
Diffstat (limited to 'tests')
-rw-r--r--tests/conftest.py3
-rw-r--r--tests/pyscript/stop.py9
-rw-r--r--tests/test_acargparse.py3
-rw-r--r--tests/test_autocompletion.py3
-rw-r--r--tests/test_cmd2.py259
-rw-r--r--tests/test_completion.py3
-rw-r--r--tests/test_parsing.py3
-rw-r--r--tests/test_plugin.py47
-rw-r--r--tests/test_pyscript.py14
-rw-r--r--tests/test_transcript.py89
-rw-r--r--tests/test_utils.py3
-rw-r--r--tests/transcripts/from_cmdloop.txt1
12 files changed, 248 insertions, 189 deletions
diff --git a/tests/conftest.py b/tests/conftest.py
index dc5c1ab1..517e2865 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1,9 +1,6 @@
# 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
diff --git a/tests/pyscript/stop.py b/tests/pyscript/stop.py
new file mode 100644
index 00000000..e731218e
--- /dev/null
+++ b/tests/pyscript/stop.py
@@ -0,0 +1,9 @@
+# flake8: noqa F821
+app.cmd_echo = True
+app('help')
+
+# This will set stop to True in the PyscriptBridge
+app('quit')
+
+# Exercise py_quit() in unit test
+quit()
diff --git a/tests/test_acargparse.py b/tests/test_acargparse.py
index 64612737..436158db 100644
--- a/tests/test_acargparse.py
+++ b/tests/test_acargparse.py
@@ -1,9 +1,6 @@
# flake8: noqa E302
"""
Unit/functional testing for argparse customizations in cmd2
-
-Copyright 2018 Eric Lin <anselor@gmail.com>
-Released under MIT license, see LICENSE file
"""
import pytest
from cmd2.argparse_completer import ACArgumentParser, is_potential_flag
diff --git a/tests/test_autocompletion.py b/tests/test_autocompletion.py
index 005eee81..4e1ceff0 100644
--- a/tests/test_autocompletion.py
+++ b/tests/test_autocompletion.py
@@ -2,9 +2,6 @@
# flake8: noqa E302
"""
Unit/functional testing for argparse completer in cmd2
-
-Copyright 2018 Eric Lin <anselor@gmail.com>
-Released under MIT license, see LICENSE file
"""
import pytest
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index 1aafefc2..0dc8c7c2 100644
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -2,9 +2,6 @@
# flake8: noqa E302
"""
Cmd2 unit/functional testing
-
-Copyright 2016 Federico Ceratto <federico.ceratto@gmail.com>
-Released under MIT license, see LICENSE file
"""
import argparse
import builtins
@@ -28,13 +25,15 @@ from cmd2 import clipboard, constants, utils
from .conftest import run_cmd, normalize, BASE_HELP, BASE_HELP_VERBOSE, \
HELP_HISTORY, SHORTCUTS_TXT, SHOW_TXT, SHOW_LONG
-
-@pytest.fixture
-def outsim_app():
+def CreateOutsimApp():
c = cmd2.Cmd()
c.stdout = utils.StdSim(c.stdout)
return c
+@pytest.fixture
+def outsim_app():
+ return CreateOutsimApp()
+
def test_version(base_app):
assert cmd2.__version__
@@ -112,9 +111,8 @@ def test_base_show_readonly(base_app):
out, err = run_cmd(base_app, 'set -a')
expected = normalize(SHOW_TXT + '\nRead only settings:' + """
Commands may be terminated with: {}
- Arguments at invocation allowed: {}
Output redirection and pipes allowed: {}
-""".format(base_app.statement_parser.terminators, base_app.allow_cli_args, base_app.allow_redirection))
+""".format(base_app.statement_parser.terminators, base_app.allow_redirection))
assert out == expected
@@ -297,17 +295,28 @@ def test_base_load(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
filename = os.path.join(test_dir, 'script.txt')
- assert base_app.cmdqueue == []
assert base_app._script_dir == []
assert base_app._current_script_dir is None
- # Run the load command, which populates the command queue and sets the script directory
- run_cmd(base_app, 'load {}'.format(filename))
+ # Get output out the script
+ script_out, script_err = run_cmd(base_app, 'load {}'.format(filename))
+
+ assert base_app._script_dir == []
+ assert base_app._current_script_dir is None
- assert base_app.cmdqueue == ['help history', 'eos']
- sdir = os.path.dirname(filename)
- assert base_app._script_dir == [sdir]
- assert base_app._current_script_dir == sdir
+ # Now run the commands manually and compare their output to script's
+ with open(filename, encoding='utf-8') as file:
+ script_commands = file.read().splitlines()
+
+ manual_out = []
+ manual_err = []
+ for cmdline in script_commands:
+ out, err = run_cmd(base_app, cmdline)
+ manual_out.extend(out)
+ manual_err.extend(err)
+
+ assert script_out == manual_out
+ assert script_err == manual_err
def test_load_with_empty_args(base_app):
# The way the load command works, we can't directly capture its stdout or stderr
@@ -315,7 +324,6 @@ def test_load_with_empty_args(base_app):
# The load command requires a file path argument, so we should get an error message
assert "the following arguments are required" in err[1]
- assert base_app.cmdqueue == []
def test_load_with_nonexistent_file(base_app, capsys):
@@ -324,7 +332,6 @@ def test_load_with_nonexistent_file(base_app, capsys):
# The load command requires a path to an existing file
assert "does not exist" in err[0]
- assert base_app.cmdqueue == []
def test_load_with_directory(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
@@ -333,7 +340,6 @@ def test_load_with_directory(base_app, request):
out, err = run_cmd(base_app, 'load {}'.format(test_dir))
assert "is not a file" in err[0]
- assert base_app.cmdqueue == []
def test_load_with_empty_file(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
@@ -344,7 +350,6 @@ def test_load_with_empty_file(base_app, request):
# The load command requires non-empty script files
assert "is empty" in err[0]
- assert base_app.cmdqueue == []
def test_load_with_binary_file(base_app, request):
@@ -356,42 +361,45 @@ def test_load_with_binary_file(base_app, request):
# The load command requires non-empty scripts files
assert "is not an ASCII or UTF-8 encoded text file" in err[0]
- assert base_app.cmdqueue == []
def test_load_with_utf8_file(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
filename = os.path.join(test_dir, 'scripts', 'utf8.txt')
- assert base_app.cmdqueue == []
assert base_app._script_dir == []
assert base_app._current_script_dir is None
- # Run the load command, which populates the command queue and sets the script directory
- run_cmd(base_app, 'load {}'.format(filename))
+ # Get output out the script
+ script_out, script_err = run_cmd(base_app, 'load {}'.format(filename))
+
+ assert base_app._script_dir == []
+ assert base_app._current_script_dir is None
- assert base_app.cmdqueue == ['!echo γνωρίζω', 'eos']
- sdir = os.path.dirname(filename)
- assert base_app._script_dir == [sdir]
- assert base_app._current_script_dir == sdir
+ # Now run the commands manually and compare their output to script's
+ with open(filename, encoding='utf-8') as file:
+ script_commands = file.read().splitlines()
+
+ manual_out = []
+ manual_err = []
+ for cmdline in script_commands:
+ out, err = run_cmd(base_app, cmdline)
+ manual_out.extend(out)
+ manual_err.extend(err)
+
+ assert script_out == manual_out
+ assert script_err == manual_err
def test_load_nested_loads(base_app, request):
# Verify that loading a script with nested load commands works correctly,
- # and loads the nested script commands in the correct order. The recursive
- # loads don't happen all at once, but as the commands are interpreted. So,
- # we will need to drain the cmdqueue and inspect the stdout to see if all
- # steps were executed in the expected order.
+ # and loads the nested script commands in the correct order.
test_dir = os.path.dirname(request.module.__file__)
filename = os.path.join(test_dir, 'scripts', 'nested.txt')
- assert base_app.cmdqueue == []
- # Load the top level script and then run the command queue until all
- # commands have been exhausted.
+ # Load the top level script
initial_load = 'load ' + filename
run_cmd(base_app, initial_load)
- while base_app.cmdqueue:
- base_app.onecmd_plus_hooks(base_app.cmdqueue.pop(0))
# Check that the right commands were executed.
expected = """
@@ -407,12 +415,9 @@ set colors Never""" % initial_load
def test_base_runcmds_plus_hooks(base_app, request):
- # Make sure that runcmds_plus_hooks works as intended. I.E. to run multiple
- # commands and process any commands added, by them, to the command queue.
test_dir = os.path.dirname(request.module.__file__)
prefilepath = os.path.join(test_dir, 'scripts', 'precmds.txt')
postfilepath = os.path.join(test_dir, 'scripts', 'postcmds.txt')
- assert base_app.cmdqueue == []
base_app.runcmds_plus_hooks(['load ' + prefilepath,
'help',
@@ -429,27 +434,36 @@ set colors Never""" % (prefilepath, postfilepath)
out, err = run_cmd(base_app, 'history -s')
assert out == normalize(expected)
-
def test_base_relative_load(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
filename = os.path.join(test_dir, 'script.txt')
- assert base_app.cmdqueue == []
assert base_app._script_dir == []
assert base_app._current_script_dir is None
- # Run the load command, which populates the command queue and sets the script directory
- run_cmd(base_app, '_relative_load {}'.format(filename))
+ # Get output out the script
+ script_out, script_err = run_cmd(base_app, 'load {}'.format(filename))
+
+ assert base_app._script_dir == []
+ assert base_app._current_script_dir is None
+
+ # Now run the commands manually and compare their output to script's
+ with open(filename, encoding='utf-8') as file:
+ script_commands = file.read().splitlines()
- assert base_app.cmdqueue == ['help history', 'eos']
- sdir = os.path.dirname(filename)
- assert base_app._script_dir == [sdir]
- assert base_app._current_script_dir == sdir
+ manual_out = []
+ manual_err = []
+ for cmdline in script_commands:
+ out, err = run_cmd(base_app, cmdline)
+ manual_out.extend(out)
+ manual_err.extend(err)
+
+ assert script_out == manual_out
+ assert script_err == manual_err
def test_relative_load_requires_an_argument(base_app):
out, err = run_cmd(base_app, '_relative_load')
assert 'Error: the following arguments' in err[1]
- assert base_app.cmdqueue == []
def test_output_redirection(base_app):
@@ -495,7 +509,11 @@ def test_output_redirection_to_nonexistent_directory(base_app):
assert content == expected
def test_output_redirection_to_too_long_filename(base_app):
- filename = '~/sdkfhksdjfhkjdshfkjsdhfkjsdhfkjdshfkjdshfkjshdfkhdsfkjhewfuihewiufhweiufhiweufhiuewhiuewhfiuwehfiuewhfiuewhfiuewhfiuewhiuewhfiuewhfiuewfhiuwehewiufhewiuhfiweuhfiuwehfiuewfhiuwehiuewfhiuewhiewuhfiuewhfiuwefhewiuhewiufhewiufhewiufhewiufhewiufhewiufhewiufhewiuhewiufhewiufhewiuheiufhiuewheiwufhewiufheiufheiufhieuwhfewiuhfeiufhiuewfhiuewheiwuhfiuewhfiuewhfeiuwfhewiufhiuewhiuewhfeiuwhfiuwehfuiwehfiuehiuewhfieuwfhieufhiuewhfeiuwfhiuefhueiwhfw'
+ filename = '~/sdkfhksdjfhkjdshfkjsdhfkjsdhfkjdshfkjdshfkjshdfkhdsfkjhewfuihewiufhweiufhiweufhiuewhiuewhfiuwehfia' \
+ 'ewhfiuewhfiuewhfiuewhiuewhfiuewhfiuewfhiuwehewiufhewiuhfiweuhfiuwehfiuewfhiuwehiuewfhiuewhiewuhfiueh' \
+ 'fiuwefhewiuhewiufhewiufhewiufhewiufhewiufhewiufhewiufhewiuhewiufhewiufhewiuheiufhiuewheiwufhewiufheu' \
+ 'fheiufhieuwhfewiuhfeiufhiuewfhiuewheiwuhfiuewhfiuewhfeiuwfhewiufhiuewhiuewhfeiuwhfiuwehfuiwehfiuehie' \
+ 'whfieuwfhieufhiuewhfeiuwfhiuefhueiwhfw'
# Verify that writing to a file in a non-existent directory doesn't work
run_cmd(base_app, 'help > {}'.format(filename))
@@ -717,60 +735,66 @@ def test_base_py_interactive(base_app):
m.assert_called_once()
-def test_base_cmdloop_with_queue(outsim_app):
- # Create a cmd2.Cmd() instance and make sure basic settings are like we want for test
- outsim_app.use_rawinput = True
+def test_base_cmdloop_with_startup_commands():
intro = 'Hello World, this is an intro ...'
- outsim_app.cmdqueue.append('quit\n')
# Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
- testargs = ["prog"]
+ testargs = ["prog", 'quit']
expected = intro + '\n'
+
with mock.patch.object(sys, 'argv', testargs):
- # Run the command loop with custom intro
- outsim_app.cmdloop(intro=intro)
- out = outsim_app.stdout.getvalue()
+ app = CreateOutsimApp()
+
+ app.use_rawinput = True
+
+ # Run the command loop with custom intro
+ app.cmdloop(intro=intro)
+
+ out = app.stdout.getvalue()
assert out == expected
-def test_base_cmdloop_without_queue(outsim_app):
- # Create a cmd2.Cmd() instance and make sure basic settings are like we want for test
- outsim_app.use_rawinput = True
- outsim_app.intro = 'Hello World, this is an intro ...'
+def test_base_cmdloop_without_startup_commands():
+ # Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
+ testargs = ["prog"]
+ with mock.patch.object(sys, 'argv', testargs):
+ app = CreateOutsimApp()
+
+ app.use_rawinput = True
+ app.intro = 'Hello World, this is an intro ...'
# Mock out the input call so we don't actually wait for a user's response on stdin
m = mock.MagicMock(name='input', return_value='quit')
builtins.input = m
+ expected = app.intro + '\n'
+
+ # Run the command loop
+ app.cmdloop()
+ out = app.stdout.getvalue()
+ assert out == expected
+
+
+def test_cmdloop_without_rawinput():
# Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
testargs = ["prog"]
- expected = outsim_app.intro + '\n'
with mock.patch.object(sys, 'argv', testargs):
- # Run the command loop
- outsim_app.cmdloop()
- out = outsim_app.stdout.getvalue()
- assert out == expected
+ app = CreateOutsimApp()
-
-def test_cmdloop_without_rawinput(outsim_app):
- # Create a cmd2.Cmd() instance and make sure basic settings are like we want for test
- outsim_app.use_rawinput = False
- outsim_app.echo = False
- outsim_app.intro = 'Hello World, this is an intro ...'
+ app.use_rawinput = False
+ app.echo = False
+ app.intro = 'Hello World, this is an intro ...'
# Mock out the input call so we don't actually wait for a user's response on stdin
m = mock.MagicMock(name='input', return_value='quit')
builtins.input = m
- # Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
- testargs = ["prog"]
- expected = outsim_app.intro + '\n'
- with mock.patch.object(sys, 'argv', testargs):
- # Run the command loop
- outsim_app.cmdloop()
- out = outsim_app.stdout.getvalue()
- assert out == expected
+ expected = app.intro + '\n'
+ with pytest.raises(OSError):
+ app.cmdloop()
+ out = app.stdout.getvalue()
+ assert out == expected
class HookFailureApp(cmd2.Cmd):
def __init__(self, *args, **kwargs):
@@ -807,8 +831,7 @@ class SayApp(cmd2.Cmd):
@pytest.fixture
def say_app():
- app = SayApp()
- app.allow_cli_args = False
+ app = SayApp(allow_cli_args=False)
app.stdout = utils.StdSim(app.stdout)
return app
@@ -820,7 +843,10 @@ def test_interrupt_quit(say_app):
m.side_effect = ['say hello', KeyboardInterrupt(), 'say goodbye', 'eof']
builtins.input = m
- say_app.cmdloop()
+ try:
+ say_app.cmdloop()
+ except KeyboardInterrupt:
+ pass
# And verify the expected output to stdout
out = say_app.stdout.getvalue()
@@ -834,7 +860,10 @@ def test_interrupt_noquit(say_app):
m.side_effect = ['say hello', KeyboardInterrupt(), 'say goodbye', 'eof']
builtins.input = m
- say_app.cmdloop()
+ try:
+ say_app.cmdloop()
+ except KeyboardInterrupt:
+ pass
# And verify the expected output to stdout
out = say_app.stdout.getvalue()
@@ -1358,36 +1387,15 @@ def test_eof(base_app):
# Only thing to verify is that it returns True
assert base_app.do_eof('')
-def test_eos(base_app):
- sdir = 'dummy_dir'
- base_app._script_dir.append(sdir)
- assert len(base_app._script_dir) == 1
-
- # Assert that it does NOT return true
- assert not base_app.do_eos('')
-
- # And make sure it reduced the length of the script dir list
- assert len(base_app._script_dir) == 0
-
def test_echo(capsys):
app = cmd2.Cmd()
- # Turn echo on and pre-stage some commands in the queue, simulating like we are in the middle of a script
app.echo = True
- command = 'help history'
- app.cmdqueue = [command, 'quit', 'eos']
- app._script_dir.append('some_dir')
-
- assert app._current_script_dir is not None
+ commands = ['help history']
- # Run the inner _cmdloop
- app._cmdloop()
+ app.runcmds_plus_hooks(commands)
out, err = capsys.readouterr()
-
- # Check the output
- assert app.cmdqueue == []
- assert app._current_script_dir is None
- assert out.startswith('{}{}\n'.format(app.prompt, command) + HELP_HISTORY.split()[0])
+ assert out.startswith('{}{}\n'.format(app.prompt, commands[0]) + HELP_HISTORY.split()[0])
def test_pseudo_raw_input_tty_rawinput_true():
# use context managers so original functions get put back when we are done
@@ -1395,7 +1403,7 @@ def test_pseudo_raw_input_tty_rawinput_true():
with mock.patch('sys.stdin.isatty', mock.MagicMock(name='isatty', return_value=True)):
with mock.patch('builtins.input', mock.MagicMock(name='input', side_effect=['set', EOFError])) as m_input:
# run the cmdloop, which should pull input from our mocks
- app = cmd2.Cmd()
+ app = cmd2.Cmd(allow_cli_args=False)
app.use_rawinput = True
app._cmdloop()
# because we mocked the input() call, we won't get the prompt
@@ -1414,7 +1422,7 @@ def test_pseudo_raw_input_tty_rawinput_false():
fakein.readline = mreadline
# run the cmdloop, telling it where to get input from
- app = cmd2.Cmd(stdin=fakein)
+ app = cmd2.Cmd(stdin=fakein, allow_cli_args=False)
app.use_rawinput = False
app._cmdloop()
@@ -1428,7 +1436,7 @@ def test_pseudo_raw_input_tty_rawinput_false():
# the next helper function and two tests check for piped
# input when use_rawinput is True.
def piped_rawinput_true(capsys, echo, command):
- app = cmd2.Cmd()
+ app = cmd2.Cmd(allow_cli_args=False)
app.use_rawinput = True
app.echo = echo
# run the cmdloop, which should pull input from our mock
@@ -1458,8 +1466,7 @@ def test_pseudo_raw_input_piped_rawinput_true_echo_false(capsys):
# input when use_rawinput=False
def piped_rawinput_false(capsys, echo, command):
fakein = io.StringIO(u'{}'.format(command))
- # run the cmdloop, telling it where to get input from
- app = cmd2.Cmd(stdin=fakein)
+ app = cmd2.Cmd(stdin=fakein, allow_cli_args=False)
app.use_rawinput = False
app.echo = echo
app._cmdloop()
@@ -1913,7 +1920,7 @@ def test_onecmd_raw_str_quit(outsim_app):
def test_get_all_commands(base_app):
# Verify that the base app has the expected commands
commands = base_app.get_all_commands()
- expected_commands = ['_relative_load', 'alias', 'edit', 'eof', 'eos', 'help', 'history', 'load', 'macro',
+ expected_commands = ['_relative_load', 'alias', 'edit', 'eof', 'help', 'history', 'load', 'macro',
'py', 'pyscript', 'quit', 'set', 'shell', 'shortcuts']
assert commands == expected_commands
@@ -1927,7 +1934,7 @@ class ReplWithExitCode(cmd2.Cmd):
""" Example cmd2 application where we can specify an exit code when existing."""
def __init__(self):
- super().__init__()
+ super().__init__(allow_cli_args=False)
@cmd2.with_argument_list
def do_exit(self, arg_list) -> bool:
@@ -1945,8 +1952,8 @@ Usage: exit [exit_code]
self.perror("{} isn't a valid integer exit code".format(arg_list[0]))
self.exit_code = -1
- self._should_quit = True
- return self._STOP_AND_EXIT
+ # Return True to stop the command loop
+ return True
def postloop(self) -> None:
"""Hook method executed once when the cmdloop() method is about to return."""
@@ -1959,7 +1966,6 @@ def exit_code_repl():
return app
def test_exit_code_default(exit_code_repl):
- # Create a cmd2.Cmd() instance and make sure basic settings are like we want for test
app = exit_code_repl
app.use_rawinput = True
@@ -1967,17 +1973,14 @@ def test_exit_code_default(exit_code_repl):
m = mock.MagicMock(name='input', return_value='exit')
builtins.input = m
- # Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
- testargs = ["prog"]
expected = 'exiting with code: 0\n'
- with mock.patch.object(sys, 'argv', testargs):
- # Run the command loop
- app.cmdloop()
+
+ # Run the command loop
+ app.cmdloop()
out = app.stdout.getvalue()
assert out == expected
def test_exit_code_nonzero(exit_code_repl):
- # Create a cmd2.Cmd() instance and make sure basic settings are like we want for test
app = exit_code_repl
app.use_rawinput = True
@@ -1985,12 +1988,10 @@ def test_exit_code_nonzero(exit_code_repl):
m = mock.MagicMock(name='input', return_value='exit 23')
builtins.input = m
- # Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
- testargs = ["prog"]
expected = 'exiting with code: 23\n'
- with mock.patch.object(sys, 'argv', testargs):
- # Run the command loop
- app.cmdloop()
+
+ # Run the command loop
+ app.cmdloop()
out = app.stdout.getvalue()
assert out == expected
diff --git a/tests/test_completion.py b/tests/test_completion.py
index 6fd45ff9..0a16bc28 100644
--- a/tests/test_completion.py
+++ b/tests/test_completion.py
@@ -5,9 +5,6 @@ Unit/functional testing for readline tab-completion functions in the cmd2.py mod
These are primarily tests related to readline completer functions which handle tab-completion of cmd2/cmd commands,
file system paths, and shell commands.
-
-Copyright 2017 Todd Leonhardt <todd.leonhardt@gmail.com>
-Released under MIT license, see LICENSE file
"""
import argparse
import os
diff --git a/tests/test_parsing.py b/tests/test_parsing.py
index de8d67af..5ba02a95 100644
--- a/tests/test_parsing.py
+++ b/tests/test_parsing.py
@@ -2,9 +2,6 @@
# flake8: noqa E302
"""
Test the parsing logic in parsing.py
-
-Copyright 2017 Todd Leonhardt <todd.leonhardt@gmail.com>
-Released under MIT license, see LICENSE file
"""
import attr
import pytest
diff --git a/tests/test_plugin.py b/tests/test_plugin.py
index 242b0d25..f7065db5 100644
--- a/tests/test_plugin.py
+++ b/tests/test_plugin.py
@@ -2,12 +2,17 @@
# flake8: noqa E302
"""
Test plugin infrastructure and hooks.
-
-Copyright 2018 Jared Crapo <jared@kotfu.net>
-Released under MIT license, see LICENSE file
"""
+import sys
+
import pytest
+# Python 3.5 had some regressions in the unitest.mock module, so use 3rd party mock if available
+try:
+ import mock
+except ImportError:
+ from unittest import mock
+
import cmd2
from cmd2 import plugin
@@ -265,21 +270,27 @@ def test_register_preloop_hook_with_return_annotation():
app.register_preloop_hook(app.prepost_hook_with_wrong_return_annotation)
def test_preloop_hook(capsys):
- app = PluggedApp()
+ # Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
+ testargs = ["prog", "say hello", 'quit']
+
+ with mock.patch.object(sys, 'argv', testargs):
+ app = PluggedApp()
+
app.register_preloop_hook(app.prepost_hook_one)
- app.cmdqueue.append('say hello')
- app.cmdqueue.append('quit')
app.cmdloop()
out, err = capsys.readouterr()
assert out == 'one\nhello\n'
assert not err
def test_preloop_hooks(capsys):
- app = PluggedApp()
+ # Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
+ testargs = ["prog", "say hello", 'quit']
+
+ with mock.patch.object(sys, 'argv', testargs):
+ app = PluggedApp()
+
app.register_preloop_hook(app.prepost_hook_one)
app.register_preloop_hook(app.prepost_hook_two)
- app.cmdqueue.append('say hello')
- app.cmdqueue.append('quit')
app.cmdloop()
out, err = capsys.readouterr()
assert out == 'one\ntwo\nhello\n'
@@ -296,21 +307,27 @@ def test_register_postloop_hook_with_wrong_return_annotation():
app.register_postloop_hook(app.prepost_hook_with_wrong_return_annotation)
def test_postloop_hook(capsys):
- app = PluggedApp()
+ # Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
+ testargs = ["prog", "say hello", 'quit']
+
+ with mock.patch.object(sys, 'argv', testargs):
+ app = PluggedApp()
+
app.register_postloop_hook(app.prepost_hook_one)
- app.cmdqueue.append('say hello')
- app.cmdqueue.append('quit')
app.cmdloop()
out, err = capsys.readouterr()
assert out == 'hello\none\n'
assert not err
def test_postloop_hooks(capsys):
- app = PluggedApp()
+ # Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
+ testargs = ["prog", "say hello", 'quit']
+
+ with mock.patch.object(sys, 'argv', testargs):
+ app = PluggedApp()
+
app.register_postloop_hook(app.prepost_hook_one)
app.register_postloop_hook(app.prepost_hook_two)
- app.cmdqueue.append('say hello')
- app.cmdqueue.append('quit')
app.cmdloop()
out, err = capsys.readouterr()
assert out == 'hello\none\ntwo\n'
diff --git a/tests/test_pyscript.py b/tests/test_pyscript.py
index 4866548b..8da4b35a 100644
--- a/tests/test_pyscript.py
+++ b/tests/test_pyscript.py
@@ -40,3 +40,17 @@ def test_pyscript_stdout_capture(base_app, request):
assert out[0] == "PASSED"
assert out[1] == "PASSED"
+
+def test_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 returns True for stop
+ python_script = os.path.join(test_dir, 'pyscript', 'help.py')
+ stop = base_app.onecmd_plus_hooks('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('pyscript {}'.format(python_script))
+ assert stop
diff --git a/tests/test_transcript.py b/tests/test_transcript.py
index 70c9119c..5dd39e1b 100644
--- a/tests/test_transcript.py
+++ b/tests/test_transcript.py
@@ -2,9 +2,6 @@
# flake8: noqa E302
"""
Cmd2 functional testing based on transcript
-
-Copyright 2016 Federico Ceratto <federico.ceratto@gmail.com>
-Released under MIT license, see LICENSE file
"""
import argparse
import os
@@ -90,10 +87,11 @@ def test_commands_at_invocation():
expected = "This is an intro banner ...\nhello\nGracie\n"
with mock.patch.object(sys, 'argv', testargs):
app = CmdLineApp()
- app.stdout = StdSim(app.stdout)
- app.cmdloop()
- out = app.stdout.getvalue()
- assert out == expected
+
+ app.stdout = StdSim(app.stdout)
+ app.cmdloop()
+ out = app.stdout.getvalue()
+ assert out == expected
@pytest.mark.parametrize('filename,feedback_to_output', [
('bol_eol.txt', False),
@@ -113,11 +111,6 @@ def test_commands_at_invocation():
('word_boundaries.txt', False),
])
def test_transcript(request, capsys, filename, feedback_to_output):
- # Create a cmd2.Cmd() instance and make sure basic settings are
- # like we want for test
- app = CmdLineApp()
- app.feedback_to_output = feedback_to_output
-
# Get location of the transcript
test_dir = os.path.dirname(request.module.__file__)
transcript_file = os.path.join(test_dir, 'transcripts', filename)
@@ -126,9 +119,15 @@ def test_transcript(request, capsys, filename, feedback_to_output):
# arguments equal to the py.test args
testargs = ['prog', '-t', transcript_file]
with mock.patch.object(sys, 'argv', testargs):
- # Run the command loop
- sys_exit_code = app.cmdloop()
- assert sys_exit_code == 0
+ # Create a cmd2.Cmd() instance and make sure basic settings are
+ # like we want for test
+ app = CmdLineApp()
+
+ app.feedback_to_output = feedback_to_output
+
+ # Run the command loop
+ sys_exit_code = app.cmdloop()
+ assert sys_exit_code == 0
# Check for the unittest "OK" condition for the 1 test which ran
expected_start = ".\n----------------------------------------------------------------------\nRan 1 test in"
@@ -195,7 +194,6 @@ def test_load_record_transcript(base_app, request):
test_dir = os.path.dirname(request.module.__file__)
filename = os.path.join(test_dir, 'scripts', 'help.txt')
- assert base_app.cmdqueue == []
assert base_app._script_dir == []
assert base_app._current_script_dir is None
@@ -206,7 +204,6 @@ def test_load_record_transcript(base_app, request):
# Run the load command with the -r option to generate a transcript
run_cmd(base_app, 'load {} -t {}'.format(filename, transcript_fname))
- assert base_app.cmdqueue == []
assert base_app._script_dir == []
assert base_app._current_script_dir is None
@@ -219,6 +216,27 @@ def test_load_record_transcript(base_app, request):
assert xscript == expected
+def test_generate_transcript_stop(capsys):
+ # Verify transcript generation stops when a command returns True for stop
+ app = CmdLineApp()
+
+ # Make a tmp file to use as a transcript
+ fd, transcript_fname = tempfile.mkstemp(prefix='', suffix='.trn')
+ os.close(fd)
+
+ # This should run all commands
+ commands = ['help', 'alias']
+ app._generate_transcript(commands, transcript_fname)
+ _, err = capsys.readouterr()
+ assert err.startswith("2 commands")
+
+ # Since quit returns True for stop, only the first 2 commands will run
+ commands = ['help', 'quit', 'alias']
+ app._generate_transcript(commands, transcript_fname)
+ _, err = capsys.readouterr()
+ assert err.startswith("Command 2 triggered a stop")
+
+
@pytest.mark.parametrize('expected, transformed', [
# strings with zero or one slash or with escaped slashes means no regular
# expression present, so the result should just be what re.escape returns.
@@ -251,11 +269,6 @@ def test_parse_transcript_expected(expected, transformed):
def test_transcript_failure(request, capsys):
- # Create a cmd2.Cmd() instance and make sure basic settings are
- # like we want for test
- app = CmdLineApp()
- app.feedback_to_output = False
-
# Get location of the transcript
test_dir = os.path.dirname(request.module.__file__)
transcript_file = os.path.join(test_dir, 'transcripts', 'failure.txt')
@@ -264,13 +277,37 @@ def test_transcript_failure(request, capsys):
# arguments equal to the py.test args
testargs = ['prog', '-t', transcript_file]
with mock.patch.object(sys, 'argv', testargs):
- # Run the command loop
- sys_exit_code = app.cmdloop()
- assert sys_exit_code != 0
+ # Create a cmd2.Cmd() instance and make sure basic settings are
+ # like we want for test
+ app = CmdLineApp()
+
+ app.feedback_to_output = False
+
+ # Run the command loop
+ sys_exit_code = app.cmdloop()
+ assert sys_exit_code != 0
- # Check for the unittest "OK" condition for the 1 test which ran
expected_start = "File "
expected_end = "s\n\nFAILED (failures=1)\n\n"
_, err = capsys.readouterr()
assert err.startswith(expected_start)
assert err.endswith(expected_end)
+
+
+def test_transcript_no_file(request, capsys):
+ # Need to patch sys.argv so cmd2 doesn't think it was called with
+ # arguments equal to the py.test args
+ testargs = ['prog', '-t']
+ with mock.patch.object(sys, 'argv', testargs):
+ app = CmdLineApp()
+
+ app.feedback_to_output = False
+
+ # Run the command loop
+ sys_exit_code = app.cmdloop()
+ assert sys_exit_code != 0
+
+ # Check for the unittest "OK" condition for the 1 test which ran
+ expected = 'No test files found - nothing to test\n'
+ _, err = capsys.readouterr()
+ assert err == expected
diff --git a/tests/test_utils.py b/tests/test_utils.py
index c0b16990..b43eb10c 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -2,9 +2,6 @@
# flake8: noqa E302
"""
Unit testing for cmd2/utils.py module.
-
-Copyright 2018 Todd Leonhardt <todd.leonhardt@gmail.com>
-Released under MIT license, see LICENSE file
"""
import signal
import sys
diff --git a/tests/transcripts/from_cmdloop.txt b/tests/transcripts/from_cmdloop.txt
index 871b71f1..84d7f8fc 100644
--- a/tests/transcripts/from_cmdloop.txt
+++ b/tests/transcripts/from_cmdloop.txt
@@ -42,7 +42,6 @@ OODNIGHT, GRACIEGAY
5 set maxrepeats 5
6 say -ps --repeat=5 goodnight, Gracie
(Cmd) history -r 4
-say -ps --repeat=5 goodnight, Gracie
OODNIGHT, GRACIEGAY
OODNIGHT, GRACIEGAY
OODNIGHT, GRACIEGAY