diff --git a/cmd2/transcript.py b/cmd2/transcript.py index 83ede932..4101fafe 100644 --- a/cmd2/transcript.py +++ b/cmd2/transcript.py @@ -23,6 +23,7 @@ class is used in cmd2.py::run_transcript_tests() from . import ( ansi, + py_bridge, utils, ) @@ -75,6 +76,7 @@ def _test_transcript(self, fname: str, transcript: Iterator[str]) -> None: if self.cmdapp is None: return + pybridge = py_bridge.PyBridge(self.cmdapp) line_num = 0 finished = False line = ansi.strip_style(next(transcript)) @@ -105,8 +107,9 @@ def _test_transcript(self, fname: str, transcript: Iterator[str]) -> None: line_num += 1 command = ''.join(command_parts) # Send the command into the application and capture the resulting output - stop = self.cmdapp.onecmd_plus_hooks(command) - result = self.cmdapp.stdout.read() + cmd_result = pybridge(command) + stop = cmd_result.stop + result = cmd_result.stderr + cmd_result.stdout stop_msg = 'Command indicated application should quit, but more commands in transcript' # Read the expected result from transcript if ansi.strip_style(line).startswith(self.cmdapp.visible_prompt): diff --git a/tests/test_transcript.py b/tests/test_transcript.py index f5ca653e..f27dbbf0 100644 --- a/tests/test_transcript.py +++ b/tests/test_transcript.py @@ -92,6 +92,14 @@ def do_nothing(self, statement): """Do nothing and output nothing""" pass + def do_say_warn(self, statement): + """Do pwarn message""" + self.pwarning("speak a warning: " + statement) + + def do_say_error(self, statement): + """Do perror message""" + self.perror("speak an error: " + statement) + def do_keyboard_interrupt(self, _): raise KeyboardInterrupt('Interrupting this command') @@ -120,6 +128,7 @@ def test_commands_at_invocation(): ('multiline_regex.txt', False), ('no_output.txt', False), ('no_output_last.txt', False), + ('pwarn_perror.txt', False), ('regex_set.txt', False), ('singleslash.txt', False), ('slashes_escaped.txt', False), @@ -332,3 +341,30 @@ def test_transcript_no_file(request, capsys): expected = 'No test files found - nothing to test\n' _, err = capsys.readouterr() assert err == expected + + +def test_transcript_bad_cmd(request, capsys): + # Get location of the transcript + test_dir = os.path.dirname(request.module.__file__) + transcript_file = os.path.join(test_dir, 'transcripts', 'fail_no_command.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): + # 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 + expected_start = "File " + expected_middle = "youdontsay is not a recognized command, alias, or macro" + expected_end = "s\n\nFAILED (failures=1)\n\n" + _, err = capsys.readouterr() + assert err.startswith(expected_start) + assert expected_middle in err + assert err.endswith(expected_end) diff --git a/tests/transcripts/fail_no_command.txt b/tests/transcripts/fail_no_command.txt new file mode 100644 index 00000000..ad259aa6 --- /dev/null +++ b/tests/transcripts/fail_no_command.txt @@ -0,0 +1,4 @@ +# This is an example of a transcript test which will fail due to nonexistant command + +(Cmd) youdontsay -r 3 -s yabba dabba do +foo bar baz diff --git a/tests/transcripts/pwarn_perror.txt b/tests/transcripts/pwarn_perror.txt new file mode 100644 index 00000000..bdd2812a --- /dev/null +++ b/tests/transcripts/pwarn_perror.txt @@ -0,0 +1,8 @@ +# ensure the transcript catches output to perror and pwarn from a command + +(Cmd) say_warn something +speak a warning: something +(Cmd) say_error something +speak an error: something +(Cmd) say something else +something else