diff options
Diffstat (limited to 'tests.py')
-rw-r--r-- | tests.py | 115 |
1 files changed, 114 insertions, 1 deletions
@@ -1,3 +1,116 @@ ''' This file should contain all tests for Cmd2. -'''
\ No newline at end of file +''' + + +class Cmd2TestCase(unittest.TestCase): + ''' + Subclass this (setting CmdApp) to make a "unittest.TestCase" class + that executes commands from a transcript file and expects the results shown. + + See example.py. + ''' + CmdApp = None + + def fetchTranscripts(self): + self.transcripts = {} + for fileset in self.CmdApp.testfiles: + for fname in glob.glob(fileset): + tfile = open(fname) + self.transcripts[fname] = iter(tfile.readlines()) + tfile.close() + if not len(self.transcripts): + raise (StandardError,), "No test files found...nothing to test." + + def setUp(self): + if self.CmdApp: + self.outputTrap = OutputTrap() + self.cmdapp = self.CmdApp() + self.fetchTranscripts() + + def runTest(self): # was testall + if self.CmdApp: + its = sorted(self.transcripts.items()) + for (fname, transcript) in its: + self._test_transcript(fname, transcript) + + regexPattern = pyparsing.QuotedString(quoteChar=r'/', escChar='\\', multiline=True, unquoteResults=True) + regexPattern.ignore(pyparsing.cStyleComment) + + notRegexPattern = pyparsing.Word(pyparsing.printables) + notRegexPattern.setParseAction(lambda t: re.escape(t[0])) + + expectationParser = regexPattern | notRegexPattern + anyWhitespace = re.compile(r'\s', re.DOTALL | re.MULTILINE) + + def _test_transcript(self, fname, transcript): + lineNum = 0 + finished = False + line = transcript.next() + lineNum += 1 + tests_run = 0 + + while not finished: + # Scroll forward to where actual commands begin + while not line.startswith(self.cmdapp.prompt): + try: + line = transcript.next() + except StopIteration: + finished = True + break + lineNum += 1 + command = [line[len(self.cmdapp.prompt):]] + line = transcript.next() + + # Read the entirety of a multi-line command + while line.startswith(self.cmdapp.continuation_prompt): + command.append(line[len(self.cmdapp.continuation_prompt):]) + try: + line = transcript.next() + except StopIteration: + raise (StopIteration, + 'Transcript broke off while reading command beginning at line %d with\n%s' + % (command[0])) + lineNum += 1 + + command = ''.join(command) + + # Send the command into the application and capture the resulting output + stop = self.cmdapp.onecmd_plus_hooks(command) + + #TODO: should act on ``stop`` + result = self.outputTrap.read() + + # Read the expected result from transcript + if line.startswith(self.cmdapp.prompt): + message = '\nFile %s, line %d\nCommand was:\n%s\nExpected: (nothing)\nGot:\n%s\n'%\ + (fname, lineNum, command, result) + self.assert_(not(result.strip()), message) + continue + + expected = [] + + while not line.startswith(self.cmdapp.prompt): + expected.append(line) + try: + line = transcript.next() + except StopIteration: + finished = True + break + lineNum += 1 + + expected = ''.join(expected) + + # Compare actual result to expected + message = '\nFile %s, line %d\nCommand was:\n%s\nExpected:\n%s\nGot:\n%s\n'%\ + (fname, lineNum, command, expected, result) + expected = self.expectationParser.transformString(expected) + + # checking whitespace is a pain - let's skip it + expected = self.anyWhitespace.sub('', expected) + result = self.anyWhitespace.sub('', result) + self.assert_(re.match(expected, result, re.MULTILINE | re.DOTALL), message) + + def tearDown(self): + if self.CmdApp: + self.outputTrap.tearDown() |