How to use command_include method in pytest-play

Best Python code snippet using pytest-play_python

dox_parser.py

Source:dox_parser.py Github

copy

Full Screen

1#!/usr/bin/env python2"""Parser for SeqAn Doxygen dialect.3The Doxygen documentation has a regular grammar and thus can be parsed quite4easily. We do not use a parser generator such as PLY since it is a bit5overkill (it can generate parser for some context-free grammars) and not6as straightforward to use as writing a simple parser by hand.7"""8import itertools9import operator10import os.path11import re12import sys13import termcolor14import raw_doc15import lexer16import dox_tokens17class MessagePrinter(object):18 """Allows to pretty print warning and error messages.19 @ivar ignore_dirs: The directories to ignore warnings for.20 @ivar counts: Dict mapping 'error' and 'warning' to counts.21 """22 def __init__(self, ignore_dirs=[]):23 self.ignore_dirs = [os.path.realpath(x) for x in ignore_dirs]24 self.counts = {'error': 0, 'warning': 0}25 def isIgnored(self, path):26 """Return whether path is below one of the ignored directories."""27 real_path = os.path.realpath(path)28 return any([os.path.commonprefix([real_path, x]) == x for x in self.ignore_dirs])29 def printTokenError(self, token, msg, level='error'):30 """Print user-friendly error at location token."""31 if self.isIgnored(token.file_name):32 return # Is ignored.33 # Print location and error message.34 location = (token.file_name, token.lineno + 1, token.column)35 if sys.stderr.isatty():36 location_str = termcolor.colored('%s:%d:%d:' % location, 'white', attrs=['bold'])37 error_str = termcolor.colored('%s:' % level, 'red', attrs=['bold'])38 msg = termcolor.colored(msg, 'white', attrs=['bold'])39 else:40 location_str = '%s:%d:%d:' % location41 error_str = '%s:' % level42 print >>sys.stderr, '%s %s %s' % (location_str, error_str, msg)43 # Increase error counter.44 self.counts[level] += 145 if token.file_name == '<mem>':46 return # do not attempt to access line below47 # Load line with error and print it with an indicator of the error.48 fcontents = open(token.file_name).read()49 lines = fcontents.splitlines()50 if token.lineno >= len(lines):51 return # Invalid line number.52 print >>sys.stderr, '%s' % lines[token.lineno].rstrip()53 if sys.stderr.isatty():54 print >>sys.stderr, token.column * ' ' + termcolor.colored('^', 'green', attrs=['bold'])55 else:56 print >>sys.stderr, token.column * ' ' + '^'57 def printParserError(self, e):58 """Print user-friendly error message for ParserError e."""59 msg = e.msg60 if not e.msg:61 msg = 'Parse error'62 if e.token:63 self.printTokenError(e.token, e.msg)64 else:65 self.counts['error'] += 166 print >>sys.stderr, 'ERROR: %s' % msg67 def printStats(self):68 print >>sys.stderr, 'Issued %d warnings and %d errors.' % (self.counts['error'], self.counts['warning'])69 def numWarnings(self):70 return self.counts['warning']71 def numErrors(self):72 return self.counts['error']73class ParserError(Exception):74 """Raised when there is a parser error."""75 76 def __init__(self, token=None, msg=''):77 if msg and token:78 args = (token.file_name, token.lineno, token.column, repr(token.val), msg)79 message = ('Parse error at %s:%d (column %d) '80 'at token "%s": %s)' % args)81 elif not msg and token:82 args = (token.lineno, token.column, repr(token.val))83 message = 'Parser error at %d:%d ("%s").' % args84 else:85 message = 'Parse error: %s' % (msg,)86 Exception.__init__(self, message)87 self.msg = msg88 self.token = token89def stripWhitespaceTokens(token_list, strip_lt_breaks=False):90 """Strip leading and trailing whitespace tokens from token_list."""91 types = ['SPACE']92 if strip_lt_breaks:93 types.append('BREAK')94 while token_list and token_list[0].type in types:95 token_list.pop(0)96 while token_list and token_list[-1].type in types:97 token_list.pop()98def normalizeWhitespaceTokens(token_list, strip_lt_breaks=False):99 """Normalize whitespace by replacing multiple consecutive spaces by one.100 """101 positions = [i for i, t in enumerate(token_list) if t.type == 'SPACE']102 for i in reversed(positions):103 token_list[i].val = ' '104 stripWhitespaceTokens(token_list, strip_lt_breaks)105class GenericSimpleClauseState(object):106 """Handler used in *DocState for handling simple text clauses clauses.107 """108 109 def __init__(self, parser, parent):110 self.parser = parser111 self.parent = parent112 self.tokens = []113 # The first token, usually starting the clause at all, set outside.114 self.first_token = None115 self.entry_class = None116 # Whether or not to strip leading and trailing breaks.117 self.strip_lt_breaks = False118 # Whether to normalize whitespace tokens in getEntry().119 self.normalize_tokens = True120 def entered(self, token):121 self.first_token = token122 def left(self):123 pass124 def getEntry(self):125 """Returns the Entry for the brief clause."""126 if self.normalize_tokens:127 normalizeWhitespaceTokens(self.tokens, self.strip_lt_breaks)128 return self.entry_class(self.first_token, raw_doc.RawText(self.tokens))129 def handle(self, token):130 # One or more empty lines end such a clause as well as another131 # clause-starting command.132 if token.type in ['EMPTYLINE', 'EOF']:133 self.parent.endClause()134 elif token.type in dox_tokens.CLAUSE_STARTING or \135 token.type in dox_tokens.ITEM_STARTING:136 self.parent.endClause(token)137 elif token.type == 'SPACE' and (not self.tokens or self.tokens[-1].type == 'BREAK'):138 return # Skip space at beginning or after break139 elif token.type == 'BREAK' and (self.tokens and self.tokens[-1].type == 'SPACE'):140 self.tokens[-1] = token # Replace space before break141 else:142 #print 'APPEND %s' % repr(token.val)143 self.tokens.append(token)144class ParagraphState(GenericSimpleClauseState):145 """Handler used in *DocState for handling tokens of a paragraph."""146 147 def __init__(self, parser, parent):148 GenericSimpleClauseState.__init__(self, parser, parent)149 self.entry_class = raw_doc.RawParagraph150class SignatureState(GenericSimpleClauseState):151 """Handler used in *DocState for handling tokens of a paragraph."""152 153 def __init__(self, parser, parent):154 GenericSimpleClauseState.__init__(self, parser, parent)155 self.entry_class = raw_doc.RawSignature156class CodeState(GenericSimpleClauseState):157 """Handler used in *DocState for handling tokens of a paragraph."""158 159 def __init__(self, parser, parent):160 GenericSimpleClauseState.__init__(self, parser, parent)161 self.entry_class = raw_doc.RawCode162 self.normalize_tokens = False163 def handle(self, token):164 # Code is only ended by @endcode.165 if token.type == 'COMMAND_ENDCODE':166 self.parent.endClause()167 else:168 self.tokens.append(token)169class HtmlOnlyState(GenericSimpleClauseState):170 """Handler used in *DocState for handling tokens of a paragraph."""171 172 def __init__(self, parser, parent):173 GenericSimpleClauseState.__init__(self, parser, parent)174 self.entry_class = raw_doc.RawHtmlOnly175 self.normalize_tokens = False176 def handle(self, token):177 # HTML-only section is only ended by @endhtmlonly.178 if token.type == 'COMMAND_ENDHTMLONLY':179 self.parent.endClause()180 else:181 self.tokens.append(token)182class DeprecatedState(GenericSimpleClauseState):183 """Handler for the @deprecated clause."""184 def __init__(self, parser, parent):185 GenericSimpleClauseState.__init__(self, parser, parent)186 self.entry_class = raw_doc.RawDeprecated187class NoteState(GenericSimpleClauseState):188 """Handler for the @note clause."""189 def __init__(self, parser, parent):190 GenericSimpleClauseState.__init__(self, parser, parent)191 self.entry_class = raw_doc.RawNote192class WarningState(GenericSimpleClauseState):193 """Handler for the @warning clause."""194 def __init__(self, parser, parent):195 GenericSimpleClauseState.__init__(self, parser, parent)196 self.entry_class = raw_doc.RawWarning197class AkaState(GenericSimpleClauseState):198 """Handler for the @aka clause."""199 def __init__(self, parser, parent):200 GenericSimpleClauseState.__init__(self, parser, parent)201 self.entry_class = raw_doc.RawAka202class InternalState(GenericSimpleClauseState):203 """Handler for the @internal clause."""204 def __init__(self, parser, parent):205 GenericSimpleClauseState.__init__(self, parser, parent)206 self.entry_class = raw_doc.RawInternal207class HeaderfileState(GenericSimpleClauseState):208 """Handler for the @headerfile clause."""209 def __init__(self, parser, parent):210 GenericSimpleClauseState.__init__(self, parser, parent)211 self.entry_class = raw_doc.RawHeaderfile212class ImplementsState(GenericSimpleClauseState):213 """Handler for the @implements clause."""214 def __init__(self, parser, parent):215 GenericSimpleClauseState.__init__(self, parser, parent)216 self.entry_class = raw_doc.RawImplements217class ExtendsState(GenericSimpleClauseState):218 """Handler for the @extends clause."""219 def __init__(self, parser, parent):220 GenericSimpleClauseState.__init__(self, parser, parent)221 self.entry_class = raw_doc.RawExtends222 self.strip_lt_breaks = True223class BriefState(GenericSimpleClauseState):224 """Handler for the @brief clause."""225 def __init__(self, parser, parent):226 GenericSimpleClauseState.__init__(self, parser, parent)227 self.entry_class = raw_doc.RawBrief228class SeeState(GenericSimpleClauseState):229 """Handler for the @see clause."""230 def __init__(self, parser, parent):231 GenericSimpleClauseState.__init__(self, parser, parent)232 self.entry_class = raw_doc.RawSee233class ParamState(GenericSimpleClauseState):234 """Handler used in *DocState for handling @param clauses.235 """236 237 def __init__(self, parser, parent):238 GenericSimpleClauseState.__init__(self, parser, parent)239 self.entry_class = raw_doc.RawParam240 # Parameters need more than one token list.241 self.in_out = None242 self.name = []243 def handle(self, token):244 # Special handling of the in/out token and the name, if any.245 #print '.... TOKEN', token, token.type == 'PARAM_IN_OUT'246 if token.type == 'PARAM_IN_OUT':247 self.in_out = token248 elif not self.name:249 if token.type != 'SPACE':250 self.name.append(token)251 # Skipping whitespace.252 else:253 GenericSimpleClauseState.handle(self, token)254 def getEntry(self):255 """Returns the Entry for the parameter."""256 normalizeWhitespaceTokens(self.tokens)257 return self.entry_class(self.first_token, raw_doc.RawText(self.name),258 raw_doc.RawText(self.tokens), self.in_out)259class TParamState(ParamState):260 """Handler used in *DocState for handling @tparam clauses.261 """262 263 def __init__(self, parser, parent):264 ParamState.__init__(self, parser, parent)265 self.entry_class = raw_doc.RawTParam266class ReturnState(ParamState):267 """Handler used in *DocState for handling @return clauses.268 269 Stores return type in self.name (member variable inherited from270 ParamState). Sorry for any confusion. The flag self.type_read271 is used for storing whether the type has been read.272 """273 274 def __init__(self, parser, parent):275 ParamState.__init__(self, parser, parent)276 self.entry_class = raw_doc.RawReturn277 self.type_read = False278 def handle(self, token):279 if self.type_read:280 GenericSimpleClauseState.handle(self, token)281 else:282 if self.name and token.type in dox_tokens.WHITESPACE:283 self.type_read = True284 elif self.name or token.type not in dox_tokens.WHITESPACE:285 self.name.append(token)286class ThrowState(ParamState):287 """Handler used in *DocState for handling @throw clauses.288 289 Stores throw type in self.name (member variable inherited from290 ParamState). Sorry for any confusion. The flag self.type_read291 is used for storing whether the type has been read.292 """293 294 def __init__(self, parser, parent):295 ParamState.__init__(self, parser, parent)296 self.entry_class = raw_doc.RawThrow297 self.type_read = False298 def handle(self, token):299 if self.type_read:300 GenericSimpleClauseState.handle(self, token)301 else:302 if self.name and token.type in dox_tokens.WHITESPACE:303 self.type_read = True304 elif self.name or token.type not in dox_tokens.WHITESPACE:305 self.name.append(token)306class DataRaceState(GenericSimpleClauseState):307 """Handler used in *DocState for handling @datarace clauses.308 309 Inherits from GenericSimpleClauseState.310 """311 def __init__(self, parser, parent):312 GenericSimpleClauseState.__init__(self, parser, parent)313 self.entry_class = raw_doc.RawDataRace314 self.type_read = False315class SectionState(object):316 """Handler used in *DocState for handling @section clauses.317 """318 319 def __init__(self, parser, parent):320 self.first_token = None321 self.parser = parser322 self.parent = parent323 self.tokens = []324 self.level = 0325 def getEntry(self):326 """Returns the Entry for the template parameter."""327 return raw_doc.RawSection(self.first_token, raw_doc.RawText(self.tokens), self.level)328 def entered(self, token):329 self.first_token = token330 def left(self):331 pass332 def handle(self, token):333 # One or more empty lines end a @section raw_doc.Raw334 if token.type in ['EMPTYLINE', 'EOF']:335 self.parent.endClause()336 elif token.type in dox_tokens.CLAUSE_STARTING:337 self.parent.endClause(token)338 else:339 self.tokens.append(token)340class SubsectionState(SectionState):341 """Handler used in *DocState for handling @subsection clauses.342 """343 344 def __init__(self, parser, parent):345 SectionState.__init__(self, parser, parent)346 self.level = 1347class IncludeState(object):348 """Handler used in *DocState for handling @include clauses.349 """350 351 def __init__(self, parser, parent):352 self.first_token = None353 self.parser = parser354 self.parent = parent355 self.tokens = []356 def getEntry(self):357 return raw_doc.RawInclude(self.first_token, self.tokens)358 def entered(self, token):359 self.first_token = token360 def left(self):361 pass362 def handle(self, token):363 if token.type in dox_tokens.LINE_BREAKS or token.type == 'EOF':364 self.parent.endClause()365 elif token.type in dox_tokens.CLAUSE_STARTING:366 self.parent.endClause(token)367 else:368 if token.type != 'SPACE' or self.tokens:369 self.tokens.append(token)370class SnippetState(object):371 """Handler used in *DocState for handling @snippet clauses.372 """373 374 def __init__(self, parser, parent):375 self.first_token = None376 self.parser = parser377 self.parent = parent378 self.path_done = False # True after first space after path379 self.path_tokens = []380 self.name_tokens = []381 def getEntry(self):382 return raw_doc.RawSnippet(self.first_token, self.path_tokens, self.name_tokens)383 def entered(self, token):384 self.first_token = token385 def left(self):386 pass387 def handle(self, token):388 if token.type in dox_tokens.LINE_BREAKS or token.type == 'EOF':389 self.parent.endClause()390 elif token.type in dox_tokens.CLAUSE_STARTING:391 self.parent.endClause(token)392 else:393 if token.type == 'SPACE':394 if not self.path_tokens:395 return # Ignore beginning space.396 elif self.path_tokens and not self.name_tokens:397 self.path_done = True398 else: # append to name399 self.name_tokens.append(token)400 else:401 if self.path_done:402 self.name_tokens.append(token)403 else:404 self.path_tokens.append(token)405class TopLevelState(object):406 """Top level state, expecting a command starting a documentation item.407 408 Whitespace is skipped.409 """410 def __init__(self, parser):411 self.parser = parser412 def handle(self, token):413 # We ignore whitespace.414 if token.type in dox_tokens.WHITESPACE:415 return416 # We expect an item-starting token.417 if token.type in dox_tokens.ITEM_STARTING:418 state_map = {'COMMAND_CLASS' : 'class',419 'COMMAND_CONCEPT' : 'concept',420 'COMMAND_FUNCTION' : 'function',421 'COMMAND_MACRO': 'macro',422 'COMMAND_METAFUNCTION': 'metafunction',423 'COMMAND_PAGE': 'page',424 'COMMAND_MAINPAGE': 'mainpage',425 'COMMAND_DEFGROUP': 'group',426 'COMMAND_VARIABLE': 'var',427 'COMMAND_VALUE': 'val',428 'COMMAND_TAG': 'tag',429 'COMMAND_TYPEDEF': 'typedef',430 'COMMAND_ADAPTION': 'adaption',431 'COMMAND_ENUM': 'enum',}432 self.parser.enterState(state_map[token.type], token)433 return434 msg = 'Expecting one of {%s.} but is %s' % (", ".join(dox_tokens.ITEM_STARTING), token.type)435 raise ParserError(token, msg)436class GenericDocState(object):437 """Generic token handler for top-level entries.438 """439 def __init__(self, parser, entry_class, state_name):440 self.parser = parser441 # Substate is one of "first_line" or "body".442 self.substate = 'first_line'443 self.state_name = state_name444 self.first_line_tokens = None445 self.entry_class = entry_class446 self.clause_state = None447 self.allowed_commands = dox_tokens.CLAUSE_STARTING448 def getEntry(self):449 return self.entry450 def entered(self, first_token):451 """Called when the state is entered successfully with @class etc.452 """453 #print >>sys.stderr, ">>>>ENTERING CLASS STATE"454 self.first_token = first_token455 self.first_line_tokens = []456 self.substate = 'first_line'457 self.entry = self.entry_class(first_token)458 # Variables for name/title separation.459 self.name_read = False460 self.name_tokens = []461 self.title_tokens = []462 def left(self):463 pass464 def handle(self, token):465 #print 'state = class, substate = %s, clause_state %s' % (self.substate, self.clause_state)466 if self.substate == 'first_line':467 # If we have a line break in the first line then we go to the body468 # of the class documentation.469 if token.type in dox_tokens.LINE_BREAKS or token.type == 'EOF':470 #print >>sys.stderr, [v.val for v in self.name_tokens], [v.val for v in self.type_tokens]471 normalizeWhitespaceTokens(self.name_tokens)472 normalizeWhitespaceTokens(self.title_tokens)473 self.entry.name = raw_doc.RawText(self.name_tokens)474 self.entry.title = raw_doc.RawText(self.title_tokens)475 self.substate = 'body'476 return477 # Skip space at the beginning of the type.478 if not self.name_tokens and token.type == 'SPACE':479 return480 # Otherwise, we collect the token's value.481 if self.name_read:482 #print >>sys.stderr, 'NAME', token.type, repr(token.val)483 self.title_tokens.append(token)484 else:485 if token.type == 'SPACE':486 self.name_read = True487 else:488 #print >>sys.stderr, 'TYPE', token.type, repr(token.val)489 self.name_tokens.append(token)490 elif self.substate == 'body':491 # If we are already in a clause then continue to use the state.492 if not self.clause_state is None:493 self.clause_state.handle(token)494 return495 # In the body, we look for a item-generating token and will enter496 # the corresponding state if we hit it.497 if token.type in dox_tokens.ITEM_STARTING:498 # Leave the top-level class state and handle the token with the499 # top-level handler. This will create the appropriate state.500 self.parser.leaveState(self.state_name)501 assert self.parser.states[0] == 'top'502 self.parser.handleToken(token)503 return504 # In a class documentation body, a clause-starting command triggers505 # parsing of that clause.506 if token.type in dox_tokens.CLAUSE_STARTING:507 state_map = {'COMMAND_SIGNATURE' : SignatureState(self.parser, self),508 'COMMAND_CODE' : CodeState(self.parser, self),509 'COMMAND_HTMLONLY' : HtmlOnlyState(self.parser, self),510 'COMMAND_BRIEF' : BriefState(self.parser, self),511 'COMMAND_EXTENDS' : ExtendsState(self.parser, self),512 'COMMAND_HEADERFILE' : HeaderfileState(self.parser, self),513 'COMMAND_DEPRECATED' : DeprecatedState(self.parser, self),514 'COMMAND_NOTE' : NoteState(self.parser, self),515 'COMMAND_WARNING' : WarningState(self.parser, self),516 'COMMAND_AKA' : AkaState(self.parser, self),517 'COMMAND_INTERNAL' : InternalState(self.parser, self),518 'COMMAND_IMPLEMENTS' : ImplementsState(self.parser, self),519 'COMMAND_SEE' : SeeState(self.parser, self),520 'COMMAND_RETURN' : ReturnState(self.parser, self),521 'COMMAND_THROW' : ThrowState(self.parser, self),522 'COMMAND_DATARACE' : DataRaceState(self.parser, self),523 'COMMAND_PARAM' : ParamState(self.parser, self),524 'COMMAND_TPARAM' : TParamState(self.parser, self),525 'COMMAND_SECTION' : SectionState(self.parser, self),526 'COMMAND_SNIPPET' : SnippetState(self.parser, self),527 'COMMAND_SUBSECTION' : SubsectionState(self.parser, self),528 'COMMAND_INCLUDE' : IncludeState(self.parser, self),}529 if not token.type in self.allowed_commands:530 msg = 'Invalid command %s, expecting one of %s.'531 args = (repr(token.val), map(dox_tokens.transToken, self.allowed_commands))532 raise ParserError(token, msg % args)533 if self.clause_state:534 self.clause_state.left()535 self.clause_state = state_map[token.type]536 self.clause_state.entered(token)537 #print '>>> SWITCHING TO CLAUSE STATE %s' % self.clause_state538 return539 # Some commands are explicitely marked as non-paragraph, such as540 # the @endcode and @endhtmlonly token. These are invalid tokens.541 if token.type in dox_tokens.NON_PARAGRAPH:542 raise ParserError(token, 'Invalid command!')543 # Any other token is an inline-token and part of a paragraph that544 # we will start. The same is true for any word.545 self.clause_state = ParagraphState(self.parser, self)546 self.clause_state.handle(token)547 else:548 raise ParserError(msg='Invalid substate in @class!')549 def endClause(self, token=None):550 """Ends the current clause and appends its result to the documentation."""551 #print '>>> END CLAUSE(%s)' % token552 if self.clause_state.getEntry():553 entry = self.clause_state.getEntry()554 if entry.getType() in ['paragraph', 'section', 'include', 'code', 'htmlonly', 'snippet']:555 self.entry.addParagraph(entry)556 elif entry.getType() == 'signature':557 self.entry.addSignature(entry)558 elif entry.getType() == 'tparam':559 self.entry.addTParam(entry)560 elif entry.getType() == 'brief':561 self.entry.addBrief(entry)562 elif entry.getType() == 'param':563 self.entry.addParam(entry)564 elif entry.getType() == 'see':565 self.entry.addSee(entry)566 elif entry.getType() == 'return':567 self.entry.addReturn(entry)568 elif entry.getType() == 'throw':569 self.entry.addThrow(entry)570 elif entry.getType() == 'datarace':571 self.entry.addDataRace(entry)572 elif entry.getType() == 'extends':573 self.entry.addExtends(entry)574 elif entry.getType() == 'implements':575 self.entry.addImplements(entry)576 elif entry.getType() == 'headerfile':577 self.entry.addHeaderfile(entry)578 elif entry.getType() == 'deprecated':579 self.entry.addDeprecationMsg(entry)580 elif entry.getType() == 'note':581 self.entry.addNote(entry)582 elif entry.getType() == 'warning':583 self.entry.addWarning(entry)584 elif entry.getType() == 'aka':585 self.entry.addAka(entry)586 elif entry.getType() == 'internal':587 self.entry.addInternal(entry)588 else:589 assert False, '%s' % entry590 self.clause_state = None591 if token:592 self.handle(token)593class ClassDocState(GenericDocState):594 """State for documentation of a class."""595 596 def __init__(self, parser):597 GenericDocState.__init__(self, parser, raw_doc.RawClass, 'class')598 self.allowed_commands = set(['COMMAND_SIGNATURE', 'COMMAND_CODE', 'COMMAND_HTMLONLY',599 'COMMAND_SEE', 'COMMAND_BRIEF', 'COMMAND_TPARAM',600 'COMMAND_SECTION', 'COMMAND_SUBSECTION',601 'COMMAND_INCLUDE', 'COMMAND_SNIPPET', 'COMMAND_EXTENDS',602 'COMMAND_IMPLEMENTS', 'COMMAND_HEADERFILE',603 'COMMAND_DEPRECATED', 'COMMAND_NOTE', 'COMMAND_WARNING',604 'COMMAND_AKA', 'COMMAND_INTERNAL'])605class FunctionDocState(GenericDocState):606 """State for documentation of a function."""607 608 def __init__(self, parser):609 GenericDocState.__init__(self, parser, raw_doc.RawFunction, 'function')610 self.allowed_commands = set(['COMMAND_SIGNATURE', 'COMMAND_CODE', 'COMMAND_HTMLONLY',611 'COMMAND_SEE', 'COMMAND_BRIEF', 'COMMAND_TPARAM',612 'COMMAND_PARAM',613 'COMMAND_SECTION', 'COMMAND_SUBSECTION',614 'COMMAND_INCLUDE', 'COMMAND_SNIPPET', 'COMMAND_RETURN',615 'COMMAND_THROW', 'COMMAND_HEADERFILE', 'COMMAND_DEPRECATED', 616 'COMMAND_NOTE', 'COMMAND_WARNING', 'COMMAND_AKA', 617 'COMMAND_INTERNAL', 'COMMAND_DATARACE'])618class MacroDocState(GenericDocState):619 """State for documentation of a macro."""620 621 def __init__(self, parser):622 GenericDocState.__init__(self, parser, raw_doc.RawMacro, 'macro')623 self.allowed_commands = set(['COMMAND_SIGNATURE', 'COMMAND_CODE', 'COMMAND_HTMLONLY',624 'COMMAND_SEE', 'COMMAND_BRIEF', 'COMMAND_PARAM',625 'COMMAND_SECTION', 'COMMAND_SUBSECTION',626 'COMMAND_INCLUDE', 'COMMAND_SNIPPET', 'COMMAND_RETURN',627 'COMMAND_THROW', 'COMMAND_HEADERFILE', 'COMMAND_DEPRECATED',628 'COMMAND_NOTE', 'COMMAND_WARNING', 'COMMAND_AKA',629 'COMMAND_INTERNAL', 'COMMAND_DATARACE'])630class MetafunctionDocState(GenericDocState):631 """State for documentation of a metafunction."""632 633 def __init__(self, parser):634 GenericDocState.__init__(self, parser, raw_doc.RawMetafunction, 'metafunction')635 self.allowed_commands = set(['COMMAND_SIGNATURE', 'COMMAND_CODE', 'COMMAND_HTMLONLY',636 'COMMAND_SEE', 'COMMAND_BRIEF', 'COMMAND_TPARAM',637 'COMMAND_SECTION', 'COMMAND_SUBSECTION',638 'COMMAND_INCLUDE', 'COMMAND_SNIPPET', 'COMMAND_RETURN',639 'COMMAND_HEADERFILE', 'COMMAND_DEPRECATED', 'COMMAND_NOTE', 'COMMAND_WARNING',640 'COMMAND_AKA', 'COMMAND_INTERNAL'])641class ConceptDocState(GenericDocState):642 """State for documentation of a concept."""643 644 def __init__(self, parser):645 GenericDocState.__init__(self, parser, raw_doc.RawConcept, 'concept')646 self.allowed_commands = set(['COMMAND_SIGNATURE', 'COMMAND_CODE', 'COMMAND_HTMLONLY',647 'COMMAND_SEE', 'COMMAND_BRIEF',648 'COMMAND_SECTION', 'COMMAND_SUBSECTION',649 'COMMAND_INCLUDE', 'COMMAND_SNIPPET', 'COMMAND_EXTENDS',650 'COMMAND_HEADERFILE', 'COMMAND_DEPRECATED', 'COMMAND_NOTE', 'COMMAND_WARNING',651 'COMMAND_AKA', 'COMMAND_INTERNAL'])652class PageState(GenericDocState):653 """State for a documentation page."""654 655 def __init__(self, parser):656 GenericDocState.__init__(self, parser, raw_doc.RawPage, 'page')657 self.allowed_commands = set(['COMMAND_CODE', 'COMMAND_HTMLONLY',658 'COMMAND_SEE', 'COMMAND_BRIEF',659 'COMMAND_SECTION', 'COMMAND_SUBSECTION',660 'COMMAND_INCLUDE', 'COMMAND_SNIPPET'])661class MainPageState(GenericDocState):662 """State for a documentation main page."""663 664 def __init__(self, parser):665 GenericDocState.__init__(self, parser, raw_doc.RawMainPage, 'mainpage')666 self.allowed_commands = set(['COMMAND_CODE', 'COMMAND_HTMLONLY',667 'COMMAND_SEE', 'COMMAND_BRIEF',668 'COMMAND_SECTION', 'COMMAND_SUBSECTION',669 'COMMAND_INCLUDE', 'COMMAND_SNIPPET'])670 def entered(self, first_token):671 GenericDocState.entered(self, first_token)672 self.name_read = True673 self.name_tokens = [lexer.Token('IDENTIFIER', 'mainpage', 0, 0, 0)]674class GroupState(GenericDocState):675 def __init__(self, parser):676 GenericDocState.__init__(self, parser, raw_doc.RawGroup, 'group')677 self.allowed_commands = set(['COMMAND_CODE', 'COMMAND_HTMLONLY',678 'COMMAND_SEE', 'COMMAND_BRIEF',679 'COMMAND_SECTION', 'COMMAND_SUBSECTION',680 'COMMAND_INCLUDE', 'COMMAND_SNIPPET', 'COMMAND_AKA'])681class VariableState(GenericDocState):682 """State for a variable."""683 684 def __init__(self, parser, entry_class=raw_doc.RawVariable, state_name='var'):685 GenericDocState.__init__(self, parser, entry_class, state_name)686 self.allowed_commands = set(['COMMAND_SIGNATURE', 'COMMAND_CODE', 'COMMAND_HTMLONLY',687 'COMMAND_SEE', 'COMMAND_BRIEF',688 'COMMAND_SECTION', 'COMMAND_SUBSECTION',689 'COMMAND_INCLUDE', 'COMMAND_SNIPPET',690 'COMMAND_HEADERFILE', 'COMMAND_DEPRECATED', 'COMMAND_NOTE', 'COMMAND_WARNING',691 'COMMAND_AKA', 'COMMAND_INTERNAL'])692 def entered(self, first_token):693 GenericDocState.entered(self, first_token)694 self.type_read = False695 self.type_tokens = []696 self.name_tokens = []697 def left(self):698 if not self.type_tokens or not self.name_tokens:699 msg = ('Missing variable type or name! Must be given as "@var '700 '<type> <name>".')701 raise ParserError(self.first_token, msg)702 def handle(self, token):703 # Handle first state here and the remaining in the parent class.704 #print >>sys.stderr, token.type, repr(token.val), self.type_read705 if self.substate == 'first_line':706 # If we have a line break in the first line then we go to the body707 # of the class documentation.708 if token.type in dox_tokens.LINE_BREAKS or token.type == 'EOF':709 #print >>sys.stderr, [v.val for v in self.name_tokens], [v.val for v in self.type_tokens]710 normalizeWhitespaceTokens(self.name_tokens)711 normalizeWhitespaceTokens(self.type_tokens)712 self.entry.name = raw_doc.RawText(self.name_tokens)713 if self.entry.name.tokens[-1].val.endswith(';'): # remove semicolon714 self.entry.name.tokens[-1].val = self.entry.name.tokens[-1].val[:-1]715 self.entry.type = raw_doc.RawText(self.type_tokens)716 self.substate = 'body'717 return718 # Skip space at the beginning of the type.719 if not self.type_tokens and token.type == 'SPACE':720 return721 # Otherwise, we collect the token's value.722 if self.type_read:723 #print >>sys.stderr, 'NAME', token.type, repr(token.val)724 self.name_tokens.append(token)725 else:726 if token.type == 'SPACE':727 self.type_read = True728 else:729 #print >>sys.stderr, 'TYPE', token.type, repr(token.val)730 self.type_tokens.append(token)731 else:732 GenericDocState.handle(self, token)733class EnumValueState(VariableState):734 """State for an enum value."""735 def __init__(self, parser):736 VariableState.__init__(self, parser, raw_doc.RawEnumValue, 'val')737class TagState(GenericDocState):738 def __init__(self, parser):739 GenericDocState.__init__(self, parser, raw_doc.RawTag, 'tag')740 self.allowed_commands = set(['COMMAND_SIGNATURE', 'COMMAND_CODE', 'COMMAND_HTMLONLY',741 'COMMAND_SEE', 'COMMAND_BRIEF', 'COMMAND_TPARAM',742 'COMMAND_SECTION', 'COMMAND_SUBSECTION',743 'COMMAND_INCLUDE', 'COMMAND_SNIPPET',744 'COMMAND_HEADERFILE', 'COMMAND_DEPRECATED', 'COMMAND_NOTE', 'COMMAND_WARNING',745 'COMMAND_AKA', 'COMMAND_INTERNAL'])746class EnumState(GenericDocState):747 """State for an enum."""748 749 def __init__(self, parser):750 GenericDocState.__init__(self, parser, raw_doc.RawEnum, 'enum')751 self.allowed_commands = set(['COMMAND_SIGNATURE', 'COMMAND_CODE', 'COMMAND_HTMLONLY',752 'COMMAND_SEE', 'COMMAND_BRIEF',753 'COMMAND_SECTION', 'COMMAND_SUBSECTION',754 'COMMAND_INCLUDE', 'COMMAND_SNIPPET',755 'COMMAND_HEADERFILE', 'COMMAND_DEPRECATED', 'COMMAND_NOTE', 'COMMAND_WARNING',756 'COMMAND_AKA', 'COMMAND_INTERNAL'])757class AdaptionState(GenericDocState):758 """State for an adaption."""759 760 def __init__(self, parser):761 GenericDocState.__init__(self, parser, raw_doc.RawAdaption, 'adaption')762 self.allowed_commands = set(['COMMAND_SIGNATURE', 'COMMAND_CODE', 'COMMAND_HTMLONLY',763 'COMMAND_SEE', 'COMMAND_BRIEF',764 'COMMAND_SECTION', 'COMMAND_SUBSECTION',765 'COMMAND_INCLUDE', 'COMMAND_SNIPPET',766 'COMMAND_HEADERFILE', 'COMMAND_DEPRECATED', 'COMMAND_NOTE', 'COMMAND_WARNING',767 'COMMAND_AKA', 'COMMAND_INTERNAL'])768class TypedefState(GenericDocState):769 """State for an typedef."""770 771 def __init__(self, parser):772 GenericDocState.__init__(self, parser, raw_doc.RawTypedef, 'typedef')773 self.allowed_commands = set(['COMMAND_SIGNATURE', 'COMMAND_CODE', 'COMMAND_HTMLONLY',774 'COMMAND_SEE', 'COMMAND_BRIEF',775 'COMMAND_SECTION', 'COMMAND_SUBSECTION',776 'COMMAND_INCLUDE', 'COMMAND_SNIPPET',777 'COMMAND_HEADERFILE', 'COMMAND_DEPRECATED', 'COMMAND_NOTE', 'COMMAND_WARNING',778 'COMMAND_AKA', 'COMMAND_INTERNAL'])779class Parser(object):780 """The parser class takes tokens from a lexer.Lexer class.781 782 It generates a raw_doc.RawDoc object from this with783 raw_doc.RawEntry objects.784 """785 def __init__(self):786 self.states = ['top']787 self.handlers = {788 'top': TopLevelState(self),789 'class': ClassDocState(self),790 'function': FunctionDocState(self),791 'macro': MacroDocState(self),792 'metafunction': MetafunctionDocState(self),793 'concept': ConceptDocState(self),794 'page': PageState(self),795 'mainpage': MainPageState(self),796 'group': GroupState(self),797 'var': VariableState(self),798 'val': EnumValueState(self),799 'tag': TagState(self),800 'enum': EnumState(self),801 'adaption': AdaptionState(self),802 'typedef': TypedefState(self),803 }804 self.documentation = raw_doc.RawDoc()805 def parse(self, lexer):806 for token in lexer.tokens():807 self.handleToken(token)808 while len(self.states) > 1:809 self.leaveState(self.states[-1])810 def handleToken(self, token):811 #print 'Handling %s in states %s' % (token, self.states)812 self.handlers[self.states[-1]].handle(token)813 def enterState(self, state, first_token):814 #print 'entering state %s' % state815 self.states.append(state)816 self.handlers[state].entered(first_token)817 def leaveState(self, state):818 #print 'leaving state %s' % state819 if self.states[-1] == state:820 self.handlers[state].left()821 if self.handlers[state].getEntry():822 self.documentation.addEntry(self.handlers[state].getEntry())823 return self.states.pop()...

Full Screen

Full Screen

test_engine.py

Source:test_engine.py Github

copy

Full Screen

1import pytest2import mock3def test_play_engine_constructor(request):4 from pytest_play.engine import PlayEngine5 executor = PlayEngine(request, {'foo': 'bar'})6 assert executor.request is request7 assert executor.variables == {'foo': 'bar'}8def test_get_file_contents(play, data_base_path):9 play.get_file_contents(data_base_path, 'included.yml')10def test_register_teardown(play, data_base_path):11 assert play._teardown == []12 import mock13 callback = mock.MagicMock()14 play.register_teardown_callback(callback)15 play.register_teardown_callback(callback)16 assert callback in play._teardown17 assert len(play._teardown) == 118 assert not callback.called19 play.teardown()20 assert callback.assert_called_once_with() is None21def test_executor_parametrize(dummy_executor):22 assert dummy_executor.parametrize('$foo') == 'bar'23@pytest.mark.parametrize("expr,expected", [24 ('{! variables["foo"].upper() !}', 'BAR')])25def test_executor_parametrize_expression(dummy_executor, expr, expected):26 assert dummy_executor.parametrize(27 expr) == expected28def test_execute(dummy_executor):29 execute_command_mock = mock.MagicMock()30 dummy_executor.execute_command = execute_command_mock31 yml_data = [32 {'provider': 'python', 'type': 'assert', 'expression': '1'},33 {'provider': 'python', 'type': 'assert', 'expression': '2'}34 ]35 dummy_executor.execute(yml_data)36 calls = [37 mock.call(yml_data[0]),38 mock.call(yml_data[1]),39 ]40 assert dummy_executor.execute_command.assert_has_calls(41 calls, any_order=False) is None42def test_execute_extra_vars(dummy_executor):43 execute_command_mock = mock.MagicMock()44 dummy_executor.execute_command = execute_command_mock45 yml_data = [46 {'provider': 'python', 'type': 'assert', 'expression': '1'},47 {'provider': 'python', 'type': 'assert',48 'expression': '2 == $does_not_exist'}49 ]50 assert 'does_not_exist' not in dummy_executor.variables51 dummy_executor.execute(yml_data, extra_variables={'does_not_exist': '2'})52 calls = [53 mock.call(yml_data[0]),54 mock.call(yml_data[1]),55 ]56 assert dummy_executor.execute_command.assert_has_calls(57 calls, any_order=False) is None58def test_execute_bad_type(dummy_executor):59 command = {'provider': 'python', 'typeXX': 'assert', 'expression': '1'}60 with pytest.raises(KeyError):61 dummy_executor.execute_command(command)62def test_execute_bad_command(dummy_executor):63 command = {'provider': 'python', 'type': 'assert', 'expressionXX': '1'}64 with pytest.raises(KeyError):65 dummy_executor.execute_command(command)66def test_execute_not_implemented_command(dummy_executor):67 command = {'provider': 'python', 'type': 'new_command',68 'param': 'http://1'}69 dummy_executor.COMMANDS = ['new_command']70 with pytest.raises(NotImplementedError):71 dummy_executor.execute_command(command)72def test_execute_condition_true(dummy_executor):73 command = {'provider': 'python',74 'type': 'assert',75 'expression': 'False',76 'skip_condition': '1 == 1'}77 dummy_executor.execute_command(command)78def test_execute_condition_false(dummy_executor):79 command = {'provider': 'python',80 'type': 'assert',81 'expression': 'True',82 'skip_condition': '1 == 0'}83 dummy_executor.execute_command(command)84def test_execute_get_basestring(dummy_executor):85 import yaml86 command = yaml.load("""87---88provider: python89type: assert90expression: 1 == 191 """)92 dummy_executor.execute_command(command)93def test_execute_get_basestring_param(dummy_executor):94 import yaml95 command = yaml.load("""96---97provider: python98type: assert99expression: "'$foo' == 'bar'"100""")101 dummy_executor.execute_command(command)102def test_new_provider_custom_command(dummy_executor):103 command = {'type': 'newCommand', 'provider': 'newprovider'}104 dummy_provider = mock.MagicMock()105 with pytest.raises(ValueError):106 dummy_executor.execute_command(command)107 dummy_executor.register_command_provider(108 dummy_provider, 'newprovider')109 # execute new custom command110 dummy_executor.execute_command(command)111 assert dummy_provider.assert_called_once_with(dummy_executor) is None112 assert dummy_provider \113 .return_value \114 .command_newCommand \115 .assert_called_once_with(command) is None116def test_execute_includes(dummy_executor, data_base_path):117 yml_data = [118 {'type': 'include', 'provider': 'include',119 'path': '{0}/{1}'.format(120 data_base_path, 'included.yml')},121 {'type': 'include', 'provider': 'include',122 'path': '{0}/{1}'.format(123 data_base_path, 'assertion.yml')},124 ]125 dummy_executor.execute(yml_data)126 assert dummy_executor.variables['included'] == 1127def test_default_command(play, data_base_path):128 play.variables['include'] = {'comment': 'default comment'}129 play.get_command_provider = mock.MagicMock()130 yml_data = [131 {"provider": "include", "type": "include",132 "path": "{0}/included.yml".format(data_base_path)},133 ]134 from copy import deepcopy135 expected_command = deepcopy(yml_data)[0]136 expected_command['comment'] = 'default comment'137 play.execute(yml_data)138 assert play \139 .get_command_provider \140 .return_value \141 .command_include \142 .assert_called_once_with(143 expected_command) is None144def test_default_command_override(play, data_base_path):145 play.variables['include'] = {'comment': 'default comment'}146 play.get_command_provider = mock.MagicMock()147 yml_data = [148 {"provider": "include", "type": "include",149 "comment": "override",150 "path": "{0}/included.yml".format(data_base_path)},151 ]152 from copy import deepcopy153 expected_command = deepcopy(yml_data)[0]154 expected_command['comment'] = 'override'155 play.execute(yml_data)156 assert play \157 .get_command_provider \158 .return_value \159 .command_include \160 .assert_called_once_with(161 expected_command) is None162def test_default_command_override_dict(play, data_base_path):163 play.variables['include'] = {164 'comment': {'comment': 'default comment'}}165 play.get_command_provider = mock.MagicMock()166 yml_data = [167 {"provider": "include", "type": "include",168 "comment": {"another": "override"},169 "path": "{0}/included.yml".format(data_base_path)},170 ]171 from copy import deepcopy172 expected_command = deepcopy(yml_data)[0]173 expected_command['comment'] = {174 'another': 'override', 'comment': 'default comment'}175 play.execute(yml_data)176 assert play \177 .get_command_provider \178 .return_value \179 .command_include \180 .assert_called_once_with(181 expected_command) is None182def test_default_command_override_dict_2(play, data_base_path):183 play.variables['include'] = {184 'comment': {'comment': 'default comment'}}185 play.get_command_provider = mock.MagicMock()186 yml_data = [187 {"provider": "include", "type": "include",188 "comment": {"another": "override", "comment": "other"},189 "path": "{0}/included.yml".format(data_base_path)},190 ]191 from copy import deepcopy192 expected_command = deepcopy(yml_data)[0]193 expected_command['comment'] = {194 'another': 'override', 'comment': 'other'}195 play.execute(yml_data)196 assert play \197 .get_command_provider \198 .return_value \199 .command_include \200 .assert_called_once_with(201 expected_command) is None202def test_default_command_override_dict_4(203 play, data_base_path):204 play.variables['include'] = {205 'comment': {'comment': 'default comment'}}206 play.get_command_provider = mock.MagicMock()207 yml_data = [208 {"provider": "include", "type": "include",209 "comment": "default comment",210 "path": "{0}/included.yml".format(data_base_path)},211 ]212 from copy import deepcopy213 expected_command = deepcopy(yml_data)[0]214 expected_command['comment'] = 'default comment'215 play.execute(yml_data)216 assert play \217 .get_command_provider \218 .return_value \219 .command_include \220 .assert_called_once_with(221 expected_command) is None222def test_default_command_override_dict_3(223 play, data_base_path):224 play.variables['include'] = {225 'comment': 'default comment'}226 play.get_command_provider = mock.MagicMock()227 yml_data = [228 {"provider": "include", "type": "include",229 "comment": {"another": "override", "comment": "other"},230 "path": "{0}/included.yml".format(data_base_path)},231 ]232 from copy import deepcopy233 expected_command = deepcopy(yml_data)[0]234 expected_command['comment'] = {235 'another': 'override', 'comment': 'other'}236 play.execute(yml_data)237 assert play \238 .get_command_provider \239 .return_value \240 .command_include \241 .assert_called_once_with(242 expected_command) is None243def test_include_string(play, data_base_path):244 play.variables['foo'] = 'bar'245 yml_data = """246---247- provider: include248 type: include249 path: "%s/included.yml"250- provider: python251 type: assert252 expression: "$included == 1"253- provider: python254 type: store_variable255 name: included256 expression: "2"257 comment: update included value from 1 to 2258- provider: python259 type: assert260 expression: "$included == 2"261 """ % data_base_path262 play.execute_raw(yml_data)263 assert play.variables['included'] == 2264def test_teardown(play):265 import mock266 play._teardown = [267 mock.MagicMock(side_effect=AttributeError()),268 mock.MagicMock()]269 play.teardown()270 assert play._teardown[0].assert_called_once_with() is None271 assert play._teardown[1].assert_called_once_with() is None272def test_elapsed_variable(play):273 command = {'provider': 'python',274 'type': 'assert',275 'expression': 'True', }276 assert '_elapsed' not in play.variables277 play.execute_command(command)...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run pytest-play automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful