summaryrefslogtreecommitdiff
path: root/tests/test_transcript.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_transcript.py')
-rw-r--r--tests/test_transcript.py148
1 files changed, 82 insertions, 66 deletions
diff --git a/tests/test_transcript.py b/tests/test_transcript.py
index 2400066e..5092a2cd 100644
--- a/tests/test_transcript.py
+++ b/tests/test_transcript.py
@@ -7,6 +7,7 @@ Released under MIT license, see LICENSE file
"""
import os
import sys
+import random
import mock
import pytest
@@ -15,11 +16,17 @@ import six
# Used for sm.input: raw_input() for Python 2 or input() for Python 3
import six.moves as sm
-from cmd2 import Cmd, make_option, options, Cmd2TestCase, set_use_arg_list, set_posix_shlex, set_strip_quotes
+from cmd2 import (Cmd, make_option, options, Cmd2TestCase, set_use_arg_list,
+ set_posix_shlex, set_strip_quotes)
from conftest import run_cmd, StdOut, normalize
class CmdLineApp(Cmd):
+
+ MUMBLES = ['like', '...', 'um', 'er', 'hmmm', 'ahh']
+ MUMBLE_FIRST = ['so', 'like', 'well']
+ MUMBLE_LAST = ['right?']
+
def __init__(self, *args, **kwargs):
self.abbrev = True
self.multilineCommands = ['orate']
@@ -47,19 +54,36 @@ class CmdLineApp(Cmd):
"""Repeats what you tell me to."""
arg = ''.join(arg)
if opts.piglatin:
- arg = '%s%say' % (arg[1:].rstrip(), arg[0])
+ arg = '%s%say' % (arg[1:], arg[0])
if opts.shout:
arg = arg.upper()
repetitions = opts.repeat or 1
for i in range(min(repetitions, self.maxrepeats)):
- self.stdout.write(arg)
- self.stdout.write('\n')
- # self.stdout.write is better than "print", because Cmd can be
- # initialized with a non-standard output destination
+ self.poutput(arg)
+ # recommend using the poutput function instead of
+ # self.stdout.write or "print", because Cmd allows the user
+ # to redirect output
do_say = do_speak # now "say" is a synonym for "speak"
do_orate = do_speak # another synonym, but this one takes multi-line input
+ @options([ make_option('-r', '--repeat', type="int", help="output [n] times") ])
+ def do_mumble(self, arg, opts=None):
+ """Mumbles what you tell me to."""
+ repetitions = opts.repeat or 1
+ arg = arg.split()
+ for i in range(min(repetitions, self.maxrepeats)):
+ output = []
+ if (random.random() < .33):
+ output.append(random.choice(self.MUMBLE_FIRST))
+ for word in arg:
+ if (random.random() < .40):
+ output.append(random.choice(self.MUMBLES))
+ output.append(word)
+ if (random.random() < .25):
+ output.append(random.choice(self.MUMBLE_LAST))
+ self.poutput(' '.join(output))
+
class DemoApp(Cmd):
@options(make_option('-n', '--name', action="store", help="your name"))
@@ -107,8 +131,9 @@ def test_base_with_transcript(_cmdline_app):
Documented commands (type help <topic>):
========================================
-_relative_load edit history orate pyscript run say shell show
-cmdenvironment help load py quit save set shortcuts speak
+_relative_load help mumble pyscript save shell speak
+cmdenvironment history orate quit say shortcuts
+edit load py run set show
(Cmd) help say
Repeats what you tell me to.
@@ -232,60 +257,6 @@ def test_commands_at_invocation():
out = app.stdout.buffer
assert out == expected
-
-def test_transcript_from_cmdloop(request, capsys):
- # Create a cmd2.Cmd() instance and make sure basic settings are like we want for test
- app = CmdLineApp()
- app.feedback_to_output = True
-
- # Get location of the transcript
- test_dir = os.path.dirname(request.module.__file__)
- transcript_file = os.path.join(test_dir, 'transcript.txt')
-
- # Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
- testargs = ['prog', '-t', transcript_file]
- with mock.patch.object(sys, 'argv', testargs):
- # Run the command loop
- app.cmdloop()
-
- # Check for the unittest "OK" condition for the 1 test which ran
- expected_start = ".\n----------------------------------------------------------------------\nRan 1 test in"
- expected_end = "s\n\nOK\n"
- out, err = capsys.readouterr()
- if six.PY3:
- assert err.startswith(expected_start)
- assert err.endswith(expected_end)
- else:
- assert err == ''
- assert out == ''
-
-
-def test_multiline_command_transcript_with_comments_at_beginning(request, capsys):
- # Create a cmd2.Cmd() instance and make sure basic settings are like we want for test
- app = CmdLineApp()
-
- # Get location of the transcript
- test_dir = os.path.dirname(request.module.__file__)
- transcript_file = os.path.join(test_dir, 'multiline_transcript.txt')
-
- # Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
- testargs = ['prog', '-t', transcript_file]
- with mock.patch.object(sys, 'argv', testargs):
- # Run the command loop
- app.cmdloop()
-
- # Check for the unittest "OK" condition for the 1 test which ran
- expected_start = ".\n----------------------------------------------------------------------\nRan 1 test in"
- expected_end = "s\n\nOK\n"
- out, err = capsys.readouterr()
- if six.PY3:
- assert err.startswith(expected_start)
- assert err.endswith(expected_end)
- else:
- assert err == ''
- assert out == ''
-
-
def test_invalid_syntax(_cmdline_app, capsys):
run_cmd(_cmdline_app, 'speak "')
out, err = capsys.readouterr()
@@ -293,15 +264,33 @@ def test_invalid_syntax(_cmdline_app, capsys):
assert normalize(str(err)) == expected
-def test_regex_transcript(request, capsys):
- # Create a cmd2.Cmd() instance and make sure basic settings are like we want for test
+@pytest.mark.parametrize('filename, feedback_to_output', [
+ ('bol_eol.txt', False),
+ ('characterclass.txt', False),
+ ('dotstar.txt', False),
+ ('extension_notation.txt', False),
+ ('from_cmdloop.txt', True),
+ ('multiline_no_regex.txt', False),
+ ('multiline_regex.txt', False),
+ ('regex_set.txt', False),
+ ('singleslash.txt', False),
+ ('slashes_escaped.txt', False),
+ ('slashslash.txt', False),
+ ('spaces.txt', False),
+ ('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, 'transcript_regex.txt')
+ transcript_file = os.path.join(test_dir, 'transcripts', filename)
- # Need to patch sys.argv so cmd2 doesn't think it was called with arguments equal to the py.test args
+ # Need to patch sys.argv so cmd2 doesn't think it was called with
+ # arguments equal to the py.test args
testargs = ['prog', '-t', transcript_file]
with mock.patch.object(sys, 'argv', testargs):
# Run the command loop
@@ -317,3 +306,30 @@ def test_regex_transcript(request, capsys):
else:
assert err == ''
assert out == ''
+
+
+@pytest.mark.parametrize('expected, transformed', [
+ ( 'text with no slashes', 'text\ with\ no\ slashes' ),
+ # stuff with just one slash
+ ( 'use 2/3 cup', 'use\ 2\/3\ cup' ),
+ ( '/tmp is nice', '\/tmp\ is\ nice'),
+ ( 'slash at end/', 'slash\ at\ end\/'),
+ # regexes
+ ( 'specials .*', 'specials\ \.\*' ),
+ ( '/.*/', '.*' ),
+ ( 'specials ^ and + /[0-9]+/', 'specials\ \^\ and\ \+\ [0-9]+' ),
+ ( '/a{6}/ but not \/a{6} with /.*?/ more', 'a{6}\ but\ not\ \/a\{6\}\ with\ .*?\ more' ),
+ ( 'not this slash\/ or this one\/', 'not\ this\ slash\\/\ or\ this\ one\\/' ),
+ ( 'not \/, use /\|?/, not \/', 'not\ \\/\,\ use\ \|?\,\ not\ \\/' ),
+ # inception: slashes in our regex. backslashed on input, bare on output
+ ( 'not \/, use /\/?/, not \/', 'not\ \\/\,\ use\ /?\,\ not\ \\/' ),
+ ( 'the /\/?/ more /.*/ stuff', 'the\ /?\ more\ .*\ stuff' ),
+ ])
+def test_parse_transcript_expected(expected, transformed):
+ app = CmdLineApp()
+
+ class TestMyAppCase(Cmd2TestCase):
+ cmdapp = app
+
+ testcase = TestMyAppCase()
+ assert testcase._transform_transcript_expected(expected) == transformed