The Wordish modules declares three central classes:
The wordish() module function, which is the main entry point of the script, requires a file descriptor f argument containing a shell session in a restructured text article. A simplified version of wordish() boils down to:
filter = BlockFilter( directive='sourcecode', arg=['sh'] )
with CommandRunner() as run:
for cmd, expected in ShellSessionParser( filter( f ) ):
if run( cmd ) != expected:
print "Warning: unexpected command %s 's output"
Wordish also declares two additional classes:
The Reporter formats the parsed commands and output, accumulates the success and failures, and formats a report in the end.
The CommandOutput is used to model the ouput of a shell command: the message printed on stdout, the message printed on stderr, and the return code. The CommandRunner.__call__() method returns instances of this class.
A CommandOutput can be compared to a simple string, with the == or != syntax (as in the example above), in which case, only the stdout message is used for the comparison.
The wordish() module function articulates the five classes:
report = TestReporter()
filter = BlockFilter(directive='sourcecode', arg=['sh'])
with CommandRunner() as run:
for cmd, expected in ShellSessionParser( filter(f) ):
print report.before(cmd, expected)
out = run(cmd)
print report.success(out) if out == expected else report.failure(out)
if out.aborted():
print("there was a serious error: bailing out")
break
Wordish makes use of five python modules from the standard library:
Also, the required additional module, docutils offers the tools to filter text in the restructured text format.
Created with an open file f, containing a shell text session, and optionally, prompts, the list of potential prompts in the session.
A session begins with a prompt, then a command follows until a newline, except when the newline is nested in curly brackets or parentheses. Then follows the output which ends with a newline and a prompt.
This object is an iterable, and can be called in a for loop or a generator expression: the next() method yields lists of two strings: a command and an output.
The parsed commands can be sent to a ICommandRunner and the parsed output can be compared to the CommandOutput instance returned by the ICommandRunner
Also, The SessionParser is instantiated twice in the command runner, connected to the stdout and stderr files of the shell subprocess.
The CommandRunner is a context manager which runs a shell created only for the duration of a with python code block. A context manager is an object which can be called from a with statement.
The instance is a callable, which takes, as first argument, a shell command to be executed, the stdin, stdout and returncode of the command is returned as an OutputCommand.
On entering the context, setup the ressource (the shell) executing the commands. On exiting the context, terminate the shell.
Structures the output of a standard shell command with the two strings read on stdout and stderr plus the returncode.
The equality operator can be used with the CommandOutput, The equality operator expects either a string or a CommandOuput as a right hand side. The right hand side can contain the three dots pattern ‘...’ to match anything.
When matching against another CommandOutput, only the non null attributes are matched: output == CommandOutput(out=None, err=None, returncode=None) is always True.
The Reporter methods are introduced between the calls to the SessionParser and the CommandRunner
Given an open file on a restructured text document, returns an open file containing the text blocks marked up by the directive attribute.