summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorKevin Van Brunt <kmvanbrunt@gmail.com>2018-09-26 14:37:13 -0400
committerKevin Van Brunt <kmvanbrunt@gmail.com>2018-09-26 14:37:13 -0400
commit8aeb29cf1fd027093b87b8f9f9c640cf50595db7 (patch)
tree23cb1ef06b4f9e52fe8b6da0b7e9f51a05e609e1 /tests
parent149f6eba2620b1623f6071227318450c779b2b50 (diff)
parentc8983d9d6df4d057672166a7e8df544199788b9a (diff)
downloadcmd2-git-8aeb29cf1fd027093b87b8f9f9c640cf50595db7.tar.gz
Merge branch 'macro' into argparse_conversion
Diffstat (limited to 'tests')
-rw-r--r--tests/conftest.py18
-rw-r--r--tests/scripts/postcmds.txt2
-rw-r--r--tests/scripts/precmds.txt2
-rw-r--r--tests/test_cmd2.py209
-rw-r--r--tests/transcripts/regex_set.txt4
5 files changed, 191 insertions, 44 deletions
diff --git a/tests/conftest.py b/tests/conftest.py
index 1295a633..da6ffcd6 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -45,7 +45,7 @@ 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 shows current settings of parameters
+set Set a settable parameter or show current settings of parameters
shell Execute a command as if at the OS prompt
shortcuts List shortcuts available
"""
@@ -82,11 +82,8 @@ SHORTCUTS_TXT = """Shortcuts for other commands:
@@: _relative_load
"""
-expect_colors = True
-if sys.platform.startswith('win'):
- expect_colors = False
# Output from the show command with default settings
-SHOW_TXT = """colors: {}
+SHOW_TXT = """colors: Terminal
continuation_prompt: >
debug: False
echo: False
@@ -96,14 +93,10 @@ locals_in_py: False
prompt: (Cmd)
quiet: False
timing: False
-""".format(expect_colors)
+"""
-if expect_colors:
- color_str = 'True '
-else:
- color_str = 'False'
SHOW_LONG = """
-colors: {} # Colorized output (*nix only)
+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
@@ -113,8 +106,7 @@ 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
-""".format(color_str)
-
+"""
def normalize(block):
""" Normalize a block of text to perform comparison.
diff --git a/tests/scripts/postcmds.txt b/tests/scripts/postcmds.txt
index 2b478b57..dea8f265 100644
--- a/tests/scripts/postcmds.txt
+++ b/tests/scripts/postcmds.txt
@@ -1 +1 @@
-set colors off
+set colors Never
diff --git a/tests/scripts/precmds.txt b/tests/scripts/precmds.txt
index d0b27fb6..0ae7eae8 100644
--- a/tests/scripts/precmds.txt
+++ b/tests/scripts/precmds.txt
@@ -1 +1 @@
-set colors on
+set colors Always
diff --git a/tests/test_cmd2.py b/tests/test_cmd2.py
index d250af26..d3d1d585 100644
--- a/tests/test_cmd2.py
+++ b/tests/test_cmd2.py
@@ -13,6 +13,7 @@ import os
import sys
import tempfile
+from colorama import Fore, Back, Style
import pytest
# Python 3.5 had some regressions in the unitest.mock module, so use 3rd party mock if available
@@ -564,11 +565,11 @@ def test_load_nested_loads(base_app, request):
expected = """
%s
_relative_load precmds.txt
-set colors on
+set colors Always
help
shortcuts
_relative_load postcmds.txt
-set colors off""" % initial_load
+set colors Never""" % initial_load
assert run_cmd(base_app, 'history -s') == normalize(expected)
@@ -586,11 +587,11 @@ def test_base_runcmds_plus_hooks(base_app, request):
'load ' + postfilepath])
expected = """
load %s
-set colors on
+set colors Always
help
shortcuts
load %s
-set colors off""" % (prefilepath, postfilepath)
+set colors Never""" % (prefilepath, postfilepath)
assert run_cmd(base_app, 'history -s') == normalize(expected)
@@ -817,12 +818,7 @@ def test_base_colorize(base_app):
# But if we create a fresh Cmd() instance, it will
fresh_app = cmd2.Cmd()
color_test = fresh_app.colorize('Test', 'red')
- # Actually, colorization only ANSI escape codes is only applied on non-Windows systems
- if sys.platform == 'win32':
- assert color_test == 'Test'
- else:
- assert color_test == '\x1b[31mTest\x1b[39m'
-
+ assert color_test == '\x1b[31mTest\x1b[39m'
def _expected_no_editor_error():
expected_exception = 'OSError'
@@ -1111,22 +1107,22 @@ def test_ansi_prompt_not_esacped(base_app):
def test_ansi_prompt_escaped():
from cmd2.rl_utils import rl_make_safe_prompt
app = cmd2.Cmd()
- color = 'cyan'
+ color = Fore.CYAN
prompt = 'InColor'
- color_prompt = app.colorize(prompt, color)
+ color_prompt = color + prompt + Fore.RESET
readline_hack_start = "\x01"
readline_hack_end = "\x02"
readline_safe_prompt = rl_make_safe_prompt(color_prompt)
+ assert prompt != color_prompt
if sys.platform.startswith('win'):
- # colorize() does nothing on Windows due to lack of ANSI color support
- assert prompt == color_prompt
- assert readline_safe_prompt == prompt
+ # PyReadline on Windows doesn't suffer from the GNU readline bug which requires the hack
+ assert readline_safe_prompt.startswith(color)
+ assert readline_safe_prompt.endswith(Fore.RESET)
else:
- assert prompt != color_prompt
- assert readline_safe_prompt.startswith(readline_hack_start + app._colorcodes[color][True] + readline_hack_end)
- assert readline_safe_prompt.endswith(readline_hack_start + app._colorcodes[color][False] + readline_hack_end)
+ assert readline_safe_prompt.startswith(readline_hack_start + color + readline_hack_end)
+ assert readline_safe_prompt.endswith(readline_hack_start + Fore.RESET + readline_hack_end)
class HelpApp(cmd2.Cmd):
@@ -1263,7 +1259,7 @@ 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 shows current settings of parameters
+set Set a settable parameter or show current settings of parameters
shell Execute a command as if at the OS prompt
shortcuts List shortcuts available
@@ -1752,6 +1748,24 @@ def test_poutput_none(base_app):
expected = ''
assert out == expected
+def test_poutput_color_always(base_app):
+ msg = 'Hello World'
+ color = Fore.CYAN
+ base_app.colors = 'Always'
+ base_app.poutput(msg, color=color)
+ out = base_app.stdout.getvalue()
+ expected = color + msg + '\n' + Fore.RESET
+ assert out == expected
+
+def test_poutput_color_never(base_app):
+ msg = 'Hello World'
+ color = Fore.CYAN
+ base_app.colors = 'Never'
+ base_app.poutput(msg, color=color)
+ out = base_app.stdout.getvalue()
+ expected = msg + '\n'
+ assert out == expected
+
def test_alias_create(base_app, capsys):
# Create the alias
@@ -1767,7 +1781,7 @@ def test_alias_create(base_app, capsys):
out = run_cmd(base_app, 'alias list')
assert out == normalize('alias create fake pyscript')
- # Lookup the new alias
+ # Look up the new alias
out = run_cmd(base_app, 'alias list fake')
assert out == normalize('alias create fake pyscript')
@@ -1776,7 +1790,7 @@ def test_alias_create_with_quotes(base_app, capsys):
out = run_cmd(base_app, 'alias create fake help ">" "out file.txt"')
assert out == normalize("Alias 'fake' created")
- # Lookup the new alias (Only the redirector should be unquoted)
+ # Look up the new alias (Only the redirector should be unquoted)
out = run_cmd(base_app, 'alias list fake')
assert out == normalize('alias create fake help > "out file.txt"')
@@ -1793,7 +1807,7 @@ def test_alias_create_with_quotes(base_app, capsys):
def test_alias_create_invalid_name(base_app, alias_name, capsys):
run_cmd(base_app, 'alias create {} help'.format(alias_name))
out, err = capsys.readouterr()
- assert "cannot" in err
+ assert "Invalid alias name" in err
def test_alias_create_with_macro_name(base_app, capsys):
macro = "my_macro"
@@ -1802,13 +1816,22 @@ def test_alias_create_with_macro_name(base_app, capsys):
out, err = capsys.readouterr()
assert "cannot have the same name" in err
-def test_alias_create_with_empty_command(base_app, capsys):
- run_cmd(base_app, 'alias create my_alias ""')
+@pytest.mark.parametrize('alias_target', [
+ '""', # Blank name
+ '">"',
+ '"no>pe"',
+ '"no spaces"',
+ '"nopipe|"',
+ '"noterm;"',
+ 'noembedded"quotes',
+])
+def test_alias_create_with_invalid_command(base_app, alias_target, capsys):
+ run_cmd(base_app, 'alias create my_alias {}'.format(alias_target))
out, err = capsys.readouterr()
- assert "cannot resolve to an empty command" in err
+ assert "Invalid alias target" in err
def test_alias_list_invalid_alias(base_app, capsys):
- # Lookup invalid alias
+ # Look up invalid alias
out = run_cmd(base_app, 'alias list invalid')
out, err = capsys.readouterr()
assert "not found" in err
@@ -1965,7 +1988,6 @@ def test_bad_history_file_path(capsys, request):
assert 'readline cannot read' in err
-
def test_get_all_commands(base_app):
# Verify that the base app has the expected commands
commands = base_app.get_all_commands()
@@ -2052,3 +2074,136 @@ def test_exit_code_nonzero(exit_code_repl):
app.cmdloop()
out = app.stdout.getvalue()
assert out == expected
+
+
+class ColorsApp(cmd2.Cmd):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ def do_echo(self, args):
+ self.poutput(args)
+ self.perror(args, False)
+
+ def do_echo_error(self, args):
+ color_on = Fore.RED + Back.BLACK
+ color_off = Style.RESET_ALL
+ self.poutput(color_on + args + color_off)
+ # perror uses colors by default
+ self.perror(args, False)
+
+def test_colors_default():
+ app = ColorsApp()
+ assert app.colors == cmd2.constants.COLORS_TERMINAL
+
+def test_colors_pouterr_always_tty(mocker, capsys):
+ app = ColorsApp()
+ app.colors = cmd2.constants.COLORS_ALWAYS
+ mocker.patch.object(app.stdout, 'isatty', return_value=True)
+ mocker.patch.object(sys.stderr, 'isatty', return_value=True)
+
+ app.onecmd_plus_hooks('echo_error oopsie')
+ out, err = capsys.readouterr()
+ # if colors are on, the output should have some escape sequences in it
+ assert len(out) > len('oopsie\n')
+ assert 'oopsie' in out
+ assert len(err) > len('Error: oopsie\n')
+ assert 'ERROR: oopsie' in err
+
+ # but this one shouldn't
+ app.onecmd_plus_hooks('echo oopsie')
+ out, err = capsys.readouterr()
+ assert out == 'oopsie\n'
+ # errors always have colors
+ assert len(err) > len('Error: oopsie\n')
+ assert 'ERROR: oopsie' in err
+
+def test_colors_pouterr_always_notty(mocker, capsys):
+ app = ColorsApp()
+ app.colors = cmd2.constants.COLORS_ALWAYS
+ mocker.patch.object(app.stdout, 'isatty', return_value=False)
+ mocker.patch.object(sys.stderr, 'isatty', return_value=False)
+
+ app.onecmd_plus_hooks('echo_error oopsie')
+ out, err = capsys.readouterr()
+ # if colors are on, the output should have some escape sequences in it
+ assert len(out) > len('oopsie\n')
+ assert 'oopsie' in out
+ assert len(err) > len('Error: oopsie\n')
+ assert 'ERROR: oopsie' in err
+
+ # but this one shouldn't
+ app.onecmd_plus_hooks('echo oopsie')
+ out, err = capsys.readouterr()
+ assert out == 'oopsie\n'
+ # errors always have colors
+ assert len(err) > len('Error: oopsie\n')
+ assert 'ERROR: oopsie' in err
+
+def test_colors_terminal_tty(mocker, capsys):
+ app = ColorsApp()
+ app.colors = cmd2.constants.COLORS_TERMINAL
+ mocker.patch.object(app.stdout, 'isatty', return_value=True)
+ mocker.patch.object(sys.stderr, 'isatty', return_value=True)
+
+ app.onecmd_plus_hooks('echo_error oopsie')
+ # if colors are on, the output should have some escape sequences in it
+ out, err = capsys.readouterr()
+ assert len(out) > len('oopsie\n')
+ assert 'oopsie' in out
+ assert len(err) > len('Error: oopsie\n')
+ assert 'ERROR: oopsie' in err
+
+ # but this one shouldn't
+ app.onecmd_plus_hooks('echo oopsie')
+ out, err = capsys.readouterr()
+ assert out == 'oopsie\n'
+ assert len(err) > len('Error: oopsie\n')
+ assert 'ERROR: oopsie' in err
+
+def test_colors_terminal_notty(mocker, capsys):
+ app = ColorsApp()
+ app.colors = cmd2.constants.COLORS_TERMINAL
+ mocker.patch.object(app.stdout, 'isatty', return_value=False)
+ mocker.patch.object(sys.stderr, 'isatty', return_value=False)
+
+ app.onecmd_plus_hooks('echo_error oopsie')
+ out, err = capsys.readouterr()
+ assert out == 'oopsie\n'
+ assert err == 'ERROR: oopsie\n'
+
+ app.onecmd_plus_hooks('echo oopsie')
+ out, err = capsys.readouterr()
+ assert out == 'oopsie\n'
+ assert err == 'ERROR: oopsie\n'
+
+def test_colors_never_tty(mocker, capsys):
+ app = ColorsApp()
+ app.colors = cmd2.constants.COLORS_NEVER
+ mocker.patch.object(app.stdout, 'isatty', return_value=True)
+ mocker.patch.object(sys.stderr, 'isatty', return_value=True)
+
+ app.onecmd_plus_hooks('echo_error oopsie')
+ out, err = capsys.readouterr()
+ assert out == 'oopsie\n'
+ assert err == 'ERROR: oopsie\n'
+
+ app.onecmd_plus_hooks('echo oopsie')
+ out, err = capsys.readouterr()
+ assert out == 'oopsie\n'
+ assert err == 'ERROR: oopsie\n'
+
+def test_colors_never_notty(mocker, capsys):
+ app = ColorsApp()
+ app.colors = cmd2.constants.COLORS_NEVER
+ mocker.patch.object(app.stdout, 'isatty', return_value=False)
+ mocker.patch.object(sys.stderr, 'isatty', return_value=False)
+
+ app.onecmd_plus_hooks('echo_error oopsie')
+ out, err = capsys.readouterr()
+ assert out == 'oopsie\n'
+ assert err == 'ERROR: oopsie\n'
+
+ app.onecmd_plus_hooks('echo oopsie')
+ out, err = capsys.readouterr()
+ assert out == 'oopsie\n'
+ assert err == 'ERROR: oopsie\n'
diff --git a/tests/transcripts/regex_set.txt b/tests/transcripts/regex_set.txt
index b818c464..d45672a7 100644
--- a/tests/transcripts/regex_set.txt
+++ b/tests/transcripts/regex_set.txt
@@ -1,10 +1,10 @@
# Run this transcript with "python example.py -t transcript_regex.txt"
-# The regex for colors is because no color on Windows.
+# The regex for colors shows all possible settings for colors
# The regex for editor will match whatever program you use.
# Regexes on prompts just make the trailing space obvious
(Cmd) set
-colors: /(True|False)/
+colors: /(Terminal|Always|Never)/
continuation_prompt: >/ /
debug: False
echo: False