def test_type_only(self): parsed, e = expression('~a') self.assertEqual( ast_matchers.UnaryOp().match(matcher.MatchContext(parsed), e), matcher.MatchInfo( matcher.LexicalASTMatch(e, parsed.text, e.first_token, e.last_token)))
def test_fully_specified_matcher(self): parsed, e = expression('~a') self.assertEqual( ast_matchers.UnaryOp( op=ast_matchers.Invert(), operand=ast_matchers.Name(ctx=ast_matchers.Load())).match( matcher.MatchContext(parsed), e), matcher.MatchInfo( matcher.LexicalASTMatch(e, parsed.text, e.first_token, e.last_token)))
def test_explicit_anything(self): parsed, e = expression('~a') self.assertEqual( ast_matchers.UnaryOp( op=base_matchers.Anything(), operand=base_matchers.Anything()).match( matcher.MatchContext(parsed), e), matcher.MatchInfo( matcher.LexicalASTMatch(e, parsed.text, e.first_token, e.last_token)))
def test_lvalue_variable(self): parsed = matcher.parse_ast('a = b', '<string>') stmt = parsed.tree.body[0] self.assertEqual( syntax_matchers.StmtPattern('$x = $y').match( matcher.MatchContext(parsed), stmt), matcher.MatchInfo(matcher.LexicalASTMatch(stmt, parsed.text, stmt.first_token, stmt.last_token), bindings=mock.ANY))
def test_complex_variable(self): parsed = matcher.parse_ast('foo + bar', '<string>') expr = parsed.tree.body[0].value self.assertEqual( syntax_matchers.ExprPattern('foo + $name').match( matcher.MatchContext(parsed), expr), matcher.MatchInfo(matcher.LexicalASTMatch(expr, parsed.text, expr.first_token, expr.last_token), bindings=mock.ANY))
def test_variable_name(self): parsed = matcher.parse_ast('3', '<string>') expr = parsed.tree.body[0].value expr_match = matcher.LexicalASTMatch(expr, parsed.text, expr.first_token, expr.last_token) self.assertEqual( syntax_matchers.ExprPattern('$name').match( matcher.MatchContext(parsed), expr), matcher.MatchInfo(expr_match, {'name': matcher.BoundValue(expr_match)}))
def test_identical_patterns(self): """Tests that patterns match themselves when not parameterized. Many cases (e.g. None) are interesting for 2/3 compatibility, because the AST changes in Python 3. syntax_matchers gives an easy way to get cross-version compatibility. """ for code in ['None', '{}', '[]', '{1:2, 3:4}', 'lambda a: a', '""']: parsed = matcher.parse_ast(code, '<string>') expr = parsed.tree.body[0].value for extra_comment in ['', "# comment doesn't matter"]: with self.subTest(code=code, extra_comment=extra_comment): self.assertEqual( syntax_matchers.ExprPattern( code + extra_comment).match( matcher.MatchContext(parsed), expr), matcher.MatchInfo( matcher.LexicalASTMatch(expr, parsed.text, expr.first_token, expr.last_token)))