How to use AlternatesWith method in autotest

Best Python code snippet using autotest_python Github


Full Screen

...255 pred = self._GetPredicate(pred_str)256 else:257 pred = None258 self.current_block.NewOrClause(pred)259 def AlternatesWith(self):260 self.current_block.AlternatesWith()261 def NewPredicateSection(self, pred_str):262 """For chains of predicate clauses."""263 pred = self._GetPredicate(pred_str)264 block = _PredicateSection()265 block.NewOrClause(pred)266 self._NewSection(_DoPredicates, block)267 def EndSection(self):268 self.stack.pop()269 self.current_block = self.stack[-1]270 def Root(self):271 # It's assumed that we call this at the end of the program272 return self.current_block273class _AbstractSection(object):274 def __init__(self):275 # Pairs of func, args, or a literal string276 self.current_clause = []277 def Append(self, statement):278 """Append a statement to this block."""279 self.current_clause.append(statement)280 def AlternatesWith(self):281 raise TemplateSyntaxError(282 '{.alternates with} can only appear with in {.repeated section ...}')283 def NewOrClause(self):284 raise NotImplementedError285class _Section(_AbstractSection):286 """Represents a (repeated) section."""287 def __init__(self, section_name=None):288 """289 Args:290 section_name: name given as an argument to the section291 token_type: The token type that created this section (e.g.292 PREDICATE_TOKEN)293 """294 _AbstractSection.__init__(self)295 self.section_name = section_name296 # Clauses is just a string and a list of statements.297 self.statements = {'default': self.current_clause}298 def __repr__(self):299 return '<Section %s>' % self.section_name300 def Statements(self, clause='default'):301 return self.statements.get(clause, [])302 def NewOrClause(self, pred):303 if pred:304 raise TemplateSyntaxError(305 '{.or} clause only takes a predicate inside predicate blocks')306 self.current_clause = []307 self.statements['or'] = self.current_clause308class _RepeatedSection(_Section):309 """Repeated section is like section, but it supports {.alternates with}"""310 def AlternatesWith(self):311 self.current_clause = []312 self.statements['alternates with'] = self.current_clause313class _PredicateSection(_AbstractSection):314 """Represents a sequence of predicate clauses."""315 def __init__(self):316 _AbstractSection.__init__(self)317 # List of func, statements318 self.clauses = []319 def NewOrClause(self, pred):320 # {.or} always executes if reached321 pred = pred or (lambda x: True, None, SIMPLE_FUNC) # 3-tuple322 self.current_clause = []323 self.clauses.append((pred, self.current_clause))324class _Frame(object):325 """A stack frame."""326 def __init__(self, context, index=-1):327 # Public attributes328 self.context = context329 self.index = index # An iteration index. -1 means we're NOT iterating.330 def __str__(self):331 return 'Frame %s (%s)' % (self.context, self.index)332class _ScopedContext(object):333 """Allows scoped lookup of variables.334 If the variable isn't in the current context, then we search up the stack.335 """336 def __init__(self, context, undefined_str):337 """338 Args:339 context: The root context340 undefined_str: See Template() constructor.341 """342 self.stack = [_Frame(context)]343 self.undefined_str = undefined_str344 def PushSection(self, name):345 """Given a section name, push it on the top of the stack.346 Returns:347 The new section, or None if there is no such section.348 """349 if name == '@':350 new_context = self.stack[-1].context351 else:352 new_context = self.stack[-1].context.get(name)353 self.stack.append(_Frame(new_context))354 return new_context355 def Pop(self):356 self.stack.pop()357 def Next(self):358 """Advance to the next item in a repeated section.359 Raises:360 StopIteration if there are no more elements361 """362 stacktop = self.stack[-1]363 # Now we're iterating -- push a new mutable object onto the stack364 if stacktop.index == -1:365 stacktop = _Frame(None, index=0)366 self.stack.append(stacktop)367 context_array = self.stack[-2].context368 if stacktop.index == len(context_array):369 self.stack.pop()370 raise StopIteration371 stacktop.context = context_array[stacktop.index]372 stacktop.index += 1373 return True # OK, we mutated the stack374 def _Undefined(self, name):375 if self.undefined_str is None:376 raise UndefinedVariable('%r is not defined' % name)377 else:378 return self.undefined_str379 def _LookUpStack(self, name):380 """Look up the stack for the given name."""381 i = len(self.stack) - 1382 while 1:383 frame = self.stack[i]384 if name == '@index':385 if frame.index != -1: # -1 is undefined386 return frame.index # @index is 1-based387 else:388 context = frame.context389 if hasattr(context, 'get'): # Can't look up names in a list or atom390 try:391 return context[name]392 except KeyError:393 pass394 i -= 1 # Next frame395 if i <= -1: # Couldn't find it anywhere396 return self._Undefined(name)397 def Lookup(self, name):398 """Get the value associated with a name in the current context.399 The current context could be an dictionary in a list, or a dictionary400 outside a list.401 Args:402 name: name to lookup, e.g. 'foo' or ''403 Returns:404 The value, or self.undefined_str405 Raises:406 UndefinedVariable if self.undefined_str is not set407 """408 if name == '@':409 return self.stack[-1].context410 parts = name.split('.')411 value = self._LookUpStack(parts[0])412 # Now do simple lookups of the rest of the parts413 for part in parts[1:]:414 try:415 value = value[part]416 except (KeyError, TypeError): # TypeError for non-dictionaries417 return self._Undefined(part)418 return value419def _ToString(x):420 # Some cross-language values for primitives421 if x is None:422 return 'null'423 if isinstance(x, basestring):424 return x425 return pprint.pformat(x)426def _HtmlAttrValue(x):427 return cgi.escape(x, quote=True)428def _AbsUrl(relative_url, context, unused_args):429 """Returns an absolute URL, given the current node as a relative URL.430 Assumes that the context has a value named 'base-url'. This is a little like431 the HTML <base> tag, but implemented with HTML generation.432 Raises:433 UndefinedVariable if 'base-url' doesn't exist434 """435 # urljoin is flexible about trailing/leading slashes -- it will add or de-dupe436 # them437 return urlparse.urljoin(context.Lookup('base-url'), relative_url)438# See for more439# escape types.440#441# Also, we might want to take a look at Django filters.442#443# This is a *public* constant, so that callers can use it construct their own444# formatter lookup dictionaries, and pass them in to Template.445_DEFAULT_FORMATTERS = {446 'html': cgi.escape,447 # The 'htmltag' name is deprecated. The html-attr-value name is preferred448 # because it can be read with "as":449 # {url|html-attr-value} means:450 # "substitute 'url' as an HTML attribute value"451 'html-attr-value': _HtmlAttrValue,452 'htmltag': _HtmlAttrValue,453 'raw': lambda x: x,454 # Used for the length of a list. Can be used for the size of a dictionary455 # too, though I haven't run into that use case.456 'size': lambda value: str(len(value)),457 # The argument is a dictionary, and we get a a=1&b=2 string back.458 'url-params': urlencode,459 # The argument is an atom, and it takes 'Search query?' -> 'Search+query%3F'460 'url-param-value': quote_plus, # param is an atom461 # The default formatter, when no other default is specifier. For debugging,462 # this could be lambda x: json.dumps(x, indent=2), but here we want to be463 # compatible to Python 2.4.464 'str': _ToString,465 # Just show a plain URL on an HTML page (without anchor text).466 'plain-url': lambda x: '<a href="%s">%s</a>' % (467 cgi.escape(x, quote=True), cgi.escape(x)),468 # A context formatter469 'AbsUrl': _AbsUrl,470 # Placeholders for "standard names". We're not including them by default471 # since they require additional dependencies. We can provide a part of the472 # "lookup chain" in for people people want the dependency.473 # 'json' formats arbitrary data dictionary nodes as JSON strings. 'json'474 # and 'js-string' are identical (since a JavaScript string *is* JSON). The475 # latter is meant to be serve as extra documentation when you want a string476 # argument only, which is a common case.477 'json': None,478 'js-string': None,479 }480def _Pluralize(value, unused_context, args):481 """Formatter to pluralize words."""482 if len(args) == 0:483 s, p = '', 's'484 elif len(args) == 1:485 s, p = '', args[0]486 elif len(args) == 2:487 s, p = args488 else:489 # Should have been checked at compile time490 raise AssertionError491 if value > 1:492 return p493 else:494 return s495def _Cycle(value, unused_context, args):496 """Cycle between various values on consecutive integers."""497 # @index starts from 1, so used 1-based indexing498 return args[(value - 1) % len(args)]499def _IsDebugMode(unused_value, context, unused_args):500 try:501 return bool(context.Lookup('debug'))502 except UndefinedVariable:503 return False504_DEFAULT_PREDICATES = {505 'singular?': lambda x: x == 1,506 'plural?': lambda x: x > 1,507 'Debug?': _IsDebugMode,508 }509def SplitMeta(meta):510 """Split and validate metacharacters.511 Example: '{}' -> ('{', '}')512 This is public so the syntax highlighter and other tools can use it.513 """514 n = len(meta)515 if n % 2 == 1:516 raise ConfigurationError(517 '%r has an odd number of metacharacters' % meta)518 return meta[:n//2], meta[n//2:]519_token_re_cache = {}520def MakeTokenRegex(meta_left, meta_right):521 """Return a (compiled) regular expression for tokenization.522 Args:523 meta_left, meta_right: e.g. '{' and '}'524 - The regular expressions are memoized.525 - This function is public so the syntax highlighter can use it.526 """527 key = meta_left, meta_right528 if key not in _token_re_cache:529 # - Need () grouping for re.split530 # - For simplicity, we allow all characters except newlines inside531 # metacharacters ({} / [])532 _token_re_cache[key] = re.compile(533 r'(' +534 re.escape(meta_left) +535 r'.+?' +536 re.escape(meta_right) +537 r')')538 return _token_re_cache[key]539# Examples:540( LITERAL_TOKEN, # "Hi"541 SUBSTITUTION_TOKEN, # {var|html}542 SECTION_TOKEN, # {.section name}543 REPEATED_SECTION_TOKEN, # {.repeated section name}544 PREDICATE_TOKEN, # {.predicate?}545 ALTERNATES_TOKEN, # {.or}546 OR_TOKEN, # {.or}547 END_TOKEN, # {.end}548 ) = list(range(8))549def _MatchDirective(token):550 """Helper function for matching certain directives."""551 if token.startswith('.'):552 token = token[1:]553 else:554 return None, None # Must start with .555 if token == 'alternates with':556 return ALTERNATES_TOKEN, token557 if token.startswith('or'):558 if token.strip() == 'or':559 return OR_TOKEN, None560 else:561 pred_str = token[2:].strip()562 return OR_TOKEN, pred_str563 if token == 'end':564 return END_TOKEN, None565 match = _SECTION_RE.match(token)566 if match:567 repeated, section_name = match.groups()568 if repeated:569 return REPEATED_SECTION_TOKEN, section_name570 else:571 return SECTION_TOKEN, section_name572 # {.if plural?} and {.plural?} are synonyms. The ".if" will read better for573 # expressions, for people who like that kind of dirty thing...574 if token.startswith('if '):575 return PREDICATE_TOKEN, token[3:].strip()576 if token.endswith('?'):577 return PREDICATE_TOKEN, token578 return None, None # no match579def _Tokenize(template_str, meta_left, meta_right):580 """Yields tokens, which are 2-tuples (TOKEN_TYPE, token_string)."""581 trimlen = len(meta_left)582 token_re = MakeTokenRegex(meta_left, meta_right)583 for line in template_str.splitlines(True): # retain newlines584 tokens = token_re.split(line)585 # Check for a special case first. If a comment or "block" directive is on a586 # line by itself (with only space surrounding it), then the space is587 # omitted. For simplicity, we don't handle the case where we have 2588 # directives, say '{.end} # {#comment}' on a line.589 if len(tokens) == 3:590 # ''.isspace() == False, so work around that591 if (tokens[0].isspace() or not tokens[0]) and \592 (tokens[2].isspace() or not tokens[2]):593 token = tokens[1][trimlen : -trimlen]594 if token.startswith('#'):595 continue # The whole line is omitted596 token_type, token = _MatchDirective(token)597 if token_type is not None:598 yield token_type, token # Only yield the token, not space599 continue600 # The line isn't special; process it normally.601 for i, token in enumerate(tokens):602 if i % 2 == 0:603 yield LITERAL_TOKEN, token604 else: # It's a "directive" in metachracters605 assert token.startswith(meta_left), repr(token)606 assert token.endswith(meta_right), repr(token)607 token = token[trimlen : -trimlen]608 # It's a comment609 if token.startswith('#'):610 continue611 if token.startswith('.'):612 literal = {613 '.meta-left': meta_left,614 '.meta-right': meta_right,615 '.space': ' ',616 '.tab': '\t',617 '.newline': '\n',618 }.get(token)619 if literal is not None:620 yield LITERAL_TOKEN, literal621 continue622 token_type, token = _MatchDirective(token)623 if token_type is not None:624 yield token_type, token625 else: # Now we know the directive is a substitution.626 yield SUBSTITUTION_TOKEN, token627def CompileTemplate(628 template_str, builder=None, meta='{}', format_char='|',629 more_formatters=lambda x: None, more_predicates=lambda x: None,630 default_formatter='str'):631 """Compile the template string, calling methods on the 'program builder'.632 Args:633 template_str: The template string. It should not have any compilation634 options in the header -- those are parsed by FromString/FromFile635 builder: The interface of _ProgramBuilder isn't fixed. Use at your own636 risk.637 meta: The metacharacters to use, e.g. '{}', '[]'.638 more_formatters:639 Something that can map format strings to formatter functions. One of:640 - A plain dictionary of names -> functions e.g. {'html': cgi.escape}641 - A higher-order function which takes format strings and returns642 formatter functions. Useful for when formatters have parsed643 arguments.644 - A FunctionRegistry instance for the most control. This allows645 formatters which takes contexts as well.646 more_predicates:647 Like more_formatters, but for predicates.648 default_formatter: The formatter to use for substitutions that are missing a649 formatter. The 'str' formatter the "default default" -- it just tries650 to convert the context value to a string in some unspecified manner.651 Returns:652 The compiled program (obtained from the builder)653 Raises:654 The various subclasses of CompilationError. For example, if655 default_formatter=None, and a variable is missing a formatter, then656 MissingFormatter is raised.657 This function is public so it can be used by other tools, e.g. a syntax658 checking tool run before submitting a template to source control.659 """660 builder = builder or _ProgramBuilder(more_formatters, more_predicates)661 meta_left, meta_right = SplitMeta(meta)662 # : is meant to look like Python 3000 formatting {foo:.3f}. According to663 # PEP 3101, that's also what .NET uses.664 # | is more readable, but, more importantly, reminiscent of pipes, which is665 # useful for multiple formatters, e.g. {name|js-string|html}666 if format_char not in (':', '|'):667 raise ConfigurationError(668 'Only format characters : and | are accepted (got %r)' % format_char)669 # If we go to -1, then we got too many {end}. If end at 1, then we're missing670 # an {end}.671 balance_counter = 0672 for token_type, token in _Tokenize(template_str, meta_left, meta_right):673 if token_type == LITERAL_TOKEN:674 if token:675 builder.Append(token)676 continue677 if token_type in (SECTION_TOKEN, REPEATED_SECTION_TOKEN):678 builder.NewSection(token_type, token)679 balance_counter += 1680 continue681 if token_type == PREDICATE_TOKEN:682 # Everything of the form {.predicate?} starts a new predicate section683 block_made = builder.NewPredicateSection(token)684 balance_counter += 1685 continue686 if token_type == OR_TOKEN:687 builder.NewOrClause(token)688 continue689 if token_type == ALTERNATES_TOKEN:690 builder.AlternatesWith()691 continue692 if token_type == END_TOKEN:693 balance_counter -= 1694 if balance_counter < 0:695 # TODO: Show some context for errors696 raise TemplateSyntaxError(697 'Got too many %send%s statements. You may have mistyped an '698 "earlier 'section' or 'repeated section' directive."699 % (meta_left, meta_right))700 builder.EndSection()701 continue702 if token_type == SUBSTITUTION_TOKEN:703 parts = token.split(format_char)704 if len(parts) == 1:...

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:


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

Run autotest 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?