summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkotfu <kotfu@kotfu.net>2018-05-04 16:56:53 -0600
committerkotfu <kotfu@kotfu.net>2018-05-04 16:56:53 -0600
commit6c33b5823c14286a3ec2ddac89561a62e164090b (patch)
tree8337558defdc3e4bc732a6039fc60fb4c20cb6a9
parent23824e83fc835291c093738326c4d903dcc9b839 (diff)
downloadcmd2-git-6c33b5823c14286a3ec2ddac89561a62e164090b.tar.gz
Refactor transcript from history implementation and test
-rwxr-xr-xcmd2/cmd2.py122
-rw-r--r--tests/test_transcript.py18
-rw-r--r--tests/transcripts/expected_history.txt20
3 files changed, 71 insertions, 89 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index b463ff48..ad2038d4 100755
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -3002,65 +3002,7 @@ a..b, a:b, a:, ..b items by indices (inclusive)
except Exception as e:
self.perror('Saving {!r} - {}'.format(args.output_file, e), traceback_war=False)
elif args.transcript:
- # Save the current echo state, and turn it off. We inject commands into the
- # output using a different mechanism
- saved_echo = self.echo
- self.echo = False
-
- # Redirect stdout to the transcript file
- saved_self_stdout = self.stdout
-
- # The problem with supporting regular expressions in transcripts
- # is that they shouldn't be processed in the command, just the output.
- # In addition, when we generate a transcript, any slashes in the output
- # are not really intended to indicate regular expressions, so they should
- # be escaped.
- #
- # We have to jump through some hoops here in order to catch the commands
- # separately from the output and escape the slashes in the output.
- transcript = ''
- for history_item in history:
- # build the command, complete with prompts. When we replay
- # the transcript, it looks for the prompts to separate
- # the command from the output
- first = True
- command = ''
- for line in history_item.splitlines():
- if first:
- command += '{}{}\n'.format(self.prompt, line)
- first = False
- else:
- command += '{}{}\n'.format(self.continuation_prompt, line)
- transcript += command
- # create a new string buffer and set it to stdout to catch the output
- # of the command
- membuf = io.StringIO()
- self.stdout = membuf
- # then run the command and let the output go into our buffer
- self.onecmd_plus_hooks(history_item)
- # rewind the buffer to the beginning
- membuf.seek(0)
- # get the output out of the buffer
- output = membuf.read()
- # and add the regex-escaped output to the transcript
- transcript += output.replace('/', '\/')
-
- # Restore stdout to its original state
- self.stdout = saved_self_stdout
- # Set echo back to its original state
- self.echo = saved_echo
-
- # finally, we can write the transcript out to the file
- with open(args.transcript, 'w') as fout:
- fout.write(transcript)
-
- # and let the user know what we did
- if len(history) > 1:
- plural = 'commands and their outputs'
- else:
- plural = 'command and its output'
- msg = '{} {} saved to transcript file {!r}'
- self.pfeedback(msg.format(len(history), plural, args.transcript))
+ self._generate_transcript(history, args.transcript)
else:
# Display the history items retrieved
for hi in history:
@@ -3069,6 +3011,68 @@ a..b, a:b, a:, ..b items by indices (inclusive)
else:
self.poutput(hi.pr())
+ def _generate_transcript(self, history, transcript_file):
+ """Generate a transcript file from a given history of commands."""
+ # Save the current echo state, and turn it off. We inject commands into the
+ # output using a different mechanism
+ saved_echo = self.echo
+ self.echo = False
+
+ # Redirect stdout to the transcript file
+ saved_self_stdout = self.stdout
+
+ # The problem with supporting regular expressions in transcripts
+ # is that they shouldn't be processed in the command, just the output.
+ # In addition, when we generate a transcript, any slashes in the output
+ # are not really intended to indicate regular expressions, so they should
+ # be escaped.
+ #
+ # We have to jump through some hoops here in order to catch the commands
+ # separately from the output and escape the slashes in the output.
+ transcript = ''
+ for history_item in history:
+ # build the command, complete with prompts. When we replay
+ # the transcript, we look for the prompts to separate
+ # the command from the output
+ first = True
+ command = ''
+ for line in history_item.splitlines():
+ if first:
+ command += '{}{}\n'.format(self.prompt, line)
+ first = False
+ else:
+ command += '{}{}\n'.format(self.continuation_prompt, line)
+ transcript += command
+ # create a new string buffer and set it to stdout to catch the output
+ # of the command
+ membuf = io.StringIO()
+ self.stdout = membuf
+ # then run the command and let the output go into our buffer
+ self.onecmd_plus_hooks(history_item)
+ # rewind the buffer to the beginning
+ membuf.seek(0)
+ # get the output out of the buffer
+ output = membuf.read()
+ # and add the regex-escaped output to the transcript
+ transcript += output.replace('/', '\/')
+
+ # Restore stdout to its original state
+ self.stdout = saved_self_stdout
+ # Set echo back to its original state
+ self.echo = saved_echo
+
+ # finally, we can write the transcript out to the file
+ with open(transcript_file, 'w') as fout:
+ fout.write(transcript)
+
+ # and let the user know what we did
+ if len(history) > 1:
+ plural = 'commands and their outputs'
+ else:
+ plural = 'command and its output'
+ msg = '{} {} saved to transcript file {!r}'
+ self.pfeedback(msg.format(len(history), plural, transcript_file))
+
@with_argument_list
def do_edit(self, arglist):
"""Edit a file in a text editor.
diff --git a/tests/test_transcript.py b/tests/test_transcript.py
index 5fee1363..70658161 100644
--- a/tests/test_transcript.py
+++ b/tests/test_transcript.py
@@ -129,18 +129,16 @@ def test_transcript(request, capsys, filename, feedback_to_output):
def test_history_transcript(request, capsys):
app = CmdLineApp()
app.stdout = StdOut()
- run_cmd(app, 'help')
- run_cmd(app, 'orate this is\na multiline\ncommand;\n')
+ run_cmd(app, 'orate this is\na /multiline/\ncommand;\n')
run_cmd(app, 'speak /tmp/file.txt is not a regex')
- # Get location of the expected transcript
- test_dir = os.path.dirname(request.module.__file__)
- expected_fname = os.path.join(test_dir, 'transcripts', 'expected_history.txt')
- with open(expected_fname) as f:
- lines = f.readlines()
- # trim off the first 7 lines so we can have a comment in the
- # expected_history.txt file explaining what it is
- expected = ''.join(lines[7:])
+ expected = r"""(Cmd) orate this is
+> a /multiline/
+> command;
+this is a \/multiline\/ command
+(Cmd) speak /tmp/file.txt is not a regex
+\/tmp\/file.txt is not a regex
+"""
# make a tmp file
fd, history_fname = tempfile.mkstemp(prefix='', suffix='.txt')
diff --git a/tests/transcripts/expected_history.txt b/tests/transcripts/expected_history.txt
deleted file mode 100644
index ba2d94ce..00000000
--- a/tests/transcripts/expected_history.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-# this file contains the expected output of a 'history -t' command.
-# Because the help command outputs trailing spaces, this file
-# contains trailing spaces. Don't mess it up with your editor
-# which may be configured to trim trailing spaces
-# The first 7 lines of this file are stripped out by the
-# test case before comparing the actual output with
-# the contents of this file.
-(Cmd) help
-
-Documented commands (type help <topic>):
-========================================
-alias help load orate pyscript say shell speak
-edit history mumble py quit set shortcuts unalias
-
-(Cmd) orate this is
-> a multiline
-> command;
-this is a multiline command
-(Cmd) speak /tmp/file.txt is not a regex
-\/tmp\/file.txt is not a regex