Mercurial > python-cmd2
comparison cmd2.py @ 173:10a45c030364
simplifying testcase
author | catherine@dellzilla |
---|---|
date | Fri, 12 Dec 2008 11:41:55 -0500 |
parents | c01f8e612a0a |
children | 471318e59e51 |
comparison
equal
deleted
inserted
replaced
172:c01f8e612a0a | 173:10a45c030364 |
---|---|
347 - args: > inside | 347 - args: > inside |
348 - command: has | 348 - command: has |
349 - terminator: ; | 349 - terminator: ; |
350 - terminator: ; | 350 - terminator: ; |
351 >>> print c.parser.parseString('multiline has > inside an unfinished command').dump() | 351 >>> print c.parser.parseString('multiline has > inside an unfinished command').dump() |
352 ['multiline', 'has > inside an unfinished command'] | 352 ['multiline', ' has > inside an unfinished command'] |
353 - multilineCommand: multiline | 353 - multilineCommand: multiline |
354 >>> print c.parser.parseString('multiline has > inside;').dump() | 354 >>> print c.parser.parseString('multiline has > inside;').dump() |
355 ['multiline', 'has > inside', ';', ''] | 355 ['multiline', 'has > inside', ';', ''] |
356 - args: has > inside | 356 - args: has > inside |
357 - multilineCommand: multiline | 357 - multilineCommand: multiline |
359 - args: has > inside | 359 - args: has > inside |
360 - multilineCommand: multiline | 360 - multilineCommand: multiline |
361 - terminator: ; | 361 - terminator: ; |
362 - terminator: ; | 362 - terminator: ; |
363 >>> print c.parser.parseString('multiline command /* with comment in progress;').dump() | 363 >>> print c.parser.parseString('multiline command /* with comment in progress;').dump() |
364 ['multiline', 'command /* with comment in progress;'] | 364 ['multiline', ' command /* with comment in progress;'] |
365 - multilineCommand: multiline | 365 - multilineCommand: multiline |
366 >>> print c.parser.parseString('multiline command /* with comment complete */ is done;').dump() | 366 >>> print c.parser.parseString('multiline command /* with comment complete */ is done;').dump() |
367 ['multiline', 'command /* with comment complete */ is done', ';', ''] | 367 ['multiline', 'command /* with comment complete */ is done', ';', ''] |
368 - args: command /* with comment complete */ is done | 368 - args: command /* with comment complete */ is done |
369 - multilineCommand: multiline | 369 - multilineCommand: multiline |
386 pyparsing.Optional(outputParser + pyparsing.SkipTo(stringEnd).setParseAction(lambda x: x[0].strip())('outputTo')) | 386 pyparsing.Optional(outputParser + pyparsing.SkipTo(stringEnd).setParseAction(lambda x: x[0].strip())('outputTo')) |
387 if self.caseInsensitive: | 387 if self.caseInsensitive: |
388 multilineCommand.setParseAction(lambda x: x[0].lower()) | 388 multilineCommand.setParseAction(lambda x: x[0].lower()) |
389 oneLineCommand.setParseAction(lambda x: x[0].lower()) | 389 oneLineCommand.setParseAction(lambda x: x[0].lower()) |
390 if self.blankLinesAllowed: | 390 if self.blankLinesAllowed: |
391 subparser0 = pyparsing.NoMatch | 391 blankLineTerminationParser = pyparsing.NoMatch |
392 else: | 392 else: |
393 blankLineTerminator = (pyparsing.Literal('\n') + pyparsing.stringEnd)('terminator') | 393 blankLineTerminator = (pyparsing.Literal('\n') + stringEnd)('terminator') |
394 subparser0 = ((multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(blankLineTerminator).setParseAction(lambda x: x[0].strip())('args') + blankLineTerminator)('statement') | 394 blankLineTerminationParser = ((multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(blankLineTerminator).setParseAction(lambda x: x[0].strip())('args') + blankLineTerminator)('statement') |
395 subparser1 = (((multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(terminatorParser).setParseAction(lambda x: x[0].strip())('args') + terminatorParser)('statement') + | 395 multilineParser = (((multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(terminatorParser).setParseAction(lambda x: x[0].strip())('args') + terminatorParser)('statement') + |
396 pyparsing.SkipTo(outputParser ^ pipe ^ stringEnd).setParseAction(lambda x: x[0].strip())('suffix') + afterElements) | 396 pyparsing.SkipTo(outputParser ^ pipe ^ stringEnd).setParseAction(lambda x: x[0].strip())('suffix') + afterElements) |
397 #subparser1 = (((multilineCommand ^ oneLineCommand) + pyparsing.SkipTo(terminatorParser).setParseAction(lambda x: x[0].strip())('args') + terminatorParser)('statement') + | 397 singleLineParser = ((oneLineCommand + pyparsing.SkipTo(terminatorParser ^ stringEnd ^ pipe ^ outputParser).setParseAction(lambda x:x[0].strip())('args'))('statement') + |
398 # pyparsing.Optional(pyparsing.SkipTo(outputParser ^ pipe ^ stringEnd).setParseAction(lambda x: x[0].strip()))('suffix') + afterElements) | |
399 subparser2 = ((oneLineCommand + pyparsing.SkipTo(terminatorParser ^ stringEnd ^ pipe ^ outputParser).setParseAction(lambda x:x[0].strip())('args'))('statement') + | |
400 pyparsing.Optional(terminatorParser) + afterElements) | 398 pyparsing.Optional(terminatorParser) + afterElements) |
401 self.parser = ( | 399 self.parser = ( |
402 pyparsing.stringEnd | 400 stringEnd | |
403 | | 401 blankLineTerminationParser | |
404 subparser0 | 402 multilineParser | |
405 | | 403 multilineCommand + pyparsing.SkipTo(stringEnd) | |
406 subparser1 | 404 singleLineParser |
407 | | |
408 multilineCommand + pyparsing.SkipTo(pyparsing.stringEnd) | |
409 | | |
410 subparser2 | |
411 ) | 405 ) |
412 self.parser.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(self.commentGrammars).ignore(self.commentInProgress) | 406 self.parser.ignore(pyparsing.sglQuotedString).ignore(pyparsing.dblQuotedString).ignore(self.commentGrammars).ignore(self.commentInProgress) |
413 | 407 |
414 inputMark = pyparsing.Literal('<') | 408 inputMark = pyparsing.Literal('<') |
415 inputMark.setParseAction(lambda x: '') | 409 inputMark.setParseAction(lambda x: '') |
875 self.trap.truncate(0) | 869 self.trap.truncate(0) |
876 return result.strip('\x00') | 870 return result.strip('\x00') |
877 def tearDown(self): | 871 def tearDown(self): |
878 sys.stdout = self.old_stdout | 872 sys.stdout = self.old_stdout |
879 | 873 |
880 class TranscriptReader(object): | 874 class Transcript(object): |
881 def __init__(self, cmdapp, filename='test_cmd2.txt'): | 875 def __init__(self, cmdapp, filename='test_cmd2.txt'): |
882 self.cmdapp = cmdapp | 876 self.cmdapp = cmdapp |
883 try: | 877 try: |
884 tfile = open(filename) | 878 tfile = open(filename) |
885 self.transcript = tfile.read() | 879 self.transcript = tfile.readlines() |
886 tfile.close() | 880 tfile.close() |
887 except IOError: | 881 except IOError: |
888 self.transcript = '' | 882 self.transcript = [] |
889 self.bookmark = 0 | |
890 def refreshCommandFinder(self): | |
891 prompt = pyparsing.Suppress(pyparsing.lineStart + self.cmdapp.prompt) | |
892 continuationPrompt = pyparsing.Suppress(pyparsing.lineStart + self.cmdapp.continuationPrompt) | |
893 self.cmdtxtPattern = (prompt + pyparsing.restOfLine + pyparsing.ZeroOrMore( | |
894 pyparsing.lineEnd + continuationPrompt + pyparsing.restOfLine))("command") | |
895 def inputGenerator(self): | |
896 while True: | |
897 self.refreshCommandFinder() | |
898 (thiscmd, startpos, endpos) = self.cmdtxtPattern.scanString(self.transcript[self.bookmark:], maxMatches=1).next() | |
899 lineNum = self.transcript.count('\n', 0, self.bookmark+startpos) + 2 | |
900 self.bookmark += endpos | |
901 yield (''.join(thiscmd.command), lineNum) | |
902 def nextExpected(self): | |
903 self.refreshCommandFinder() | |
904 try: | |
905 (thiscmd, startpos, endpos) = self.cmdtxtPattern.scanString(self.transcript[self.bookmark:], maxMatches=1).next() | |
906 result = self.transcript[self.bookmark:self.bookmark+startpos] | |
907 self.bookmark += startpos | |
908 return result | |
909 except StopIteration: | |
910 return self.transcript[self.bookmark:] | |
911 | 883 |
912 class Cmd2TestCase(unittest.TestCase): | 884 class Cmd2TestCase(unittest.TestCase): |
913 '''Subclass this, setting CmdApp and transcriptFileName, to make a unittest.TestCase class | 885 '''Subclass this, setting CmdApp and transcriptFileName, to make a unittest.TestCase class |
914 that will execute the commands in transcriptFileName and expect the results shown. | 886 that will execute the commands in transcriptFileName and expect the results shown. |
915 See example.py''' | 887 See example.py''' |
916 # problem: this (raw) case gets called by unittest.main - we don't want it to be. hmm | |
917 CmdApp = None | 888 CmdApp = None |
918 transcriptFileName = '' | 889 transcriptFileName = '' |
919 def setUp(self): | 890 def setUp(self): |
920 if self.CmdApp: | 891 if self.CmdApp: |
921 self.outputTrap = OutputTrap() | 892 self.outputTrap = OutputTrap() |
922 self.cmdapp = self.CmdApp() | 893 self.cmdapp = self.CmdApp() |
923 self.transcriptReader = TranscriptReader(self.cmdapp, self.transcriptFileName) | 894 try: |
895 tfile = open(self.transcriptFileName) | |
896 self.transcript = tfile.readlines() | |
897 tfile.close() | |
898 except IOError: | |
899 self.transcript = [] | |
900 def divideTranscript(self): | |
901 self.dialogue = [] | |
902 commandStart = None | |
903 responseStart = None | |
904 prompt = self.cmdapp.prompt.rstrip() | |
905 continuationPrompt = self.cmdapp.continuationPrompt.rstrip() | |
906 for (lineNum, line) in enumerate(self.transcript): | |
907 if line.startswith(prompt): | |
908 if responseStart is not None: | |
909 self.dialogue.append(commandStart, ''.join(command), ''.join(self.transcript[responseStart:lineNum])) | |
910 command = [line[len(prompt):]] | |
911 commandStart = lineNum | |
912 elif line.startswith(continuationPrompt): | |
913 command.append(line[len(continuationPrompt):]) | |
914 else: | |
915 if responseStart < commandStart: | |
916 responseStart = lineNum | |
924 def testall(self): | 917 def testall(self): |
925 if self.CmdApp: | 918 if self.CmdApp: |
926 for (cmdInput, lineNum) in self.transcriptReader.inputGenerator(): | 919 self.divideTranscript() |
927 parsed = self.cmdapp.parsed(cmdInput) | 920 for (lineNum, command, expected) in self.dialogue: |
928 if parsed.parsed.multilineCommand and (parsed.parsed.terminator != ''): | 921 self.cmdapp.onecmd(commandSlice) |
929 cmdInput = cmdInput + self.cmdapp.terminators[0] | |
930 self.cmdapp.onecmd(cmdInput) | |
931 result = self.outputTrap.read() | 922 result = self.outputTrap.read() |
932 expected = self.transcriptReader.nextExpected() | 923 self.assertEqual(result, expected, |
933 self.assertEqual(self.stripByLine(result), self.stripByLine(expected), | |
934 '\nFile %s, line %d\nCommand was:\n%s\nExpected:\n%s\nGot:\n%s\n' % | 924 '\nFile %s, line %d\nCommand was:\n%s\nExpected:\n%s\nGot:\n%s\n' % |
935 (self.transcriptFileName, lineNum, cmdInput, expected, result)) | 925 (self.transcriptFileName, lineNum, command, expected, result)) |
936 #self.assertEqual(self.stripByLine(result), self.stripByLine(expected), | |
937 # '\nFile %s, line %d\nCommand was:\n%s\nExpected:\n%s\nGot:\n%s\n' % | |
938 # (self.transcriptFileName, lineNum, cmdInput, expected, result)) | |
939 def stripByLine(self, s): | |
940 bareprompt = self.cmdapp.continuationPrompt.strip() | |
941 lines = [] | |
942 for line in s.splitlines(): | |
943 line = line.rstrip() | |
944 if line.startswith(bareprompt): | |
945 line = line.replace(bareprompt, '', 1) | |
946 lines.append(line) | |
947 return '\n'.join(lines).strip() | |
948 def tearDown(self): | 926 def tearDown(self): |
949 if self.CmdApp: | 927 if self.CmdApp: |
950 self.outputTrap.tearDown() | 928 self.outputTrap.tearDown() |
951 | 929 |
952 if __name__ == '__main__': | 930 if __name__ == '__main__': |