From b1dabc8596b7f986eabc7eb5e2415799391d2265 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Wed, 12 Jul 2017 23:09:21 +0200 Subject: [PATCH] Add the each_version fixture to a lot more parser tests. --- test/test_parser.py | 73 ++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/test/test_parser.py b/test/test_parser.py index 31a876d..33892f3 100644 --- a/test/test_parser.py +++ b/test/test_parser.py @@ -1,20 +1,18 @@ # -*- coding: utf-8 -*- -import sys from textwrap import dedent import pytest -from parso._compatibility import u, py_version +from parso._compatibility import u from parso import parse -from parso import load_grammar from parso.python import tree from parso.utils import splitlines -def test_basic_parsing(): +def test_basic_parsing(each_version): def compare(string): """Generates the AST object and then regenerates the code.""" - assert parse(string).get_code() == string + assert parse(string, version=each_version).get_code() == string compare('\na #pass\n') compare('wblabla* 1\t\n') @@ -22,9 +20,9 @@ def test_basic_parsing(): compare('assert foo\n') -def test_subscope_names(): +def test_subscope_names(each_version): def get_sub(source): - return parse(source).children[0] + return parse(source, version=each_version).children[0] name = get_sub('class Foo: pass').name assert name.start_pos == (1, len('class ')) @@ -37,9 +35,9 @@ def test_subscope_names(): assert name.value == 'foo' -def test_import_names(): +def test_import_names(each_version): def get_import(source): - return next(parse(source).iter_imports()) + return next(parse(source, version=each_version).iter_imports()) imp = get_import('import math\n') names = imp.get_defined_names() @@ -52,77 +50,76 @@ def test_import_names(): assert imp.end_pos == (1, len('import math')) -def test_end_pos(): +def test_end_pos(each_version): s = dedent(''' x = ['a', 'b', 'c'] def func(): y = None ''') - parser = parse(s) + parser = parse(s, version=each_version) scope = next(parser.iter_funcdefs()) assert scope.start_pos == (3, 0) assert scope.end_pos == (5, 0) -def test_carriage_return_statements(): +def test_carriage_return_statements(each_version): source = dedent(''' foo = 'ns1!' # this is a namespace package ''') source = source.replace('\n', '\r\n') - stmt = parse(source).children[0] + stmt = parse(source, version=each_version).children[0] assert '#' not in stmt.get_code() -def test_incomplete_list_comprehension(): +def test_incomplete_list_comprehension(each_version): """ Shouldn't raise an error, same bug as #418. """ # With the old parser this actually returned a statement. With the new # parser only valid statements generate one. - children = parse('(1 for def').children + children = parse('(1 for def', version=each_version).children assert [c.type for c in children] == \ ['error_node', 'error_node', 'endmarker'] -def test_newline_positions(): - endmarker = parse('a\n').children[-1] +def test_newline_positions(each_version): + endmarker = parse('a\n', version=each_version).children[-1] assert endmarker.end_pos == (2, 0) new_line = endmarker.get_previous_leaf() assert new_line.start_pos == (1, 1) assert new_line.end_pos == (2, 0) -def test_end_pos_error_correction(): +def test_end_pos_error_correction(each_version): """ Source code without ending newline are given one, because the Python grammar needs it. However, they are removed again. We still want the right end_pos, even if something breaks in the parser (error correction). """ s = 'def x():\n .' - m = parse(s) + m = parse(s, version=each_version) func = m.children[0] assert func.type == 'funcdef' assert func.end_pos == (2, 2) assert m.end_pos == (2, 2) -def test_param_splitting(): +def test_param_splitting(each_version): """ Jedi splits parameters into params, this is not what the grammar does, but Jedi does this to simplify argument parsing. """ def check(src, result): # Python 2 tuple params should be ignored for now. - grammar = load_grammar('%s.%s' % sys.version_info[:2]) - m = grammar.parse(src) - if py_version >= 30: - assert not list(m.iter_funcdefs()) - else: + m = parse(src, version=each_version) + if each_version.startswith('2'): # We don't want b and c to be a part of the param enumeration. Just # ignore them, because it's not what we want to support in the # future. func = next(m.iter_funcdefs()) assert [param.name.value for param in func.params] == result + else: + assert not list(m.iter_funcdefs()) check('def x(a, (b, c)):\n pass', ['a']) check('def x((b, c)):\n pass', []) @@ -133,32 +130,32 @@ def test_unicode_string(): assert repr(s) # Should not raise an Error! -def test_backslash_dos_style(): - assert parse('\\\r\n') +def test_backslash_dos_style(each_version): + assert parse('\\\r\n', version=each_version) -def test_started_lambda_stmt(): - m = parse(u'lambda a, b: a i') +def test_started_lambda_stmt(each_version): + m = parse(u'lambda a, b: a i', version=each_version) assert m.children[0].type == 'error_node' def test_python2_octal(each_version): module = parse('0660', version=each_version) first = module.children[0] - if each_version.startswith('3'): - assert first.type == 'error_node' - else: + if each_version.startswith('2'): assert first.type == 'number' + else: + assert first.type == 'error_node' @pytest.mark.parametrize('code', ['foo "', 'foo """\n', 'foo """\nbar']) -def test_open_string_literal(code): +def test_open_string_literal(each_version, code): """ Testing mostly if removing the last newline works. """ lines = splitlines(code, keepends=True) end_pos = (len(lines), len(lines[-1])) - module = parse(code) + module = parse(code, version=each_version) assert module.get_code() == code assert module.end_pos == end_pos == module.children[1].end_pos @@ -168,18 +165,18 @@ def test_too_many_params(): parse('asdf', hello=3) -def test_dedent_at_end(): +def test_dedent_at_end(each_version): code = dedent(''' for foobar in [1]: foobar''') - module = parse(code) + module = parse(code, version=each_version) assert module.get_code() == code suite = module.children[0].children[-1] foobar = suite.children[-1] assert foobar.type == 'name' -def test_no_error_nodes(): +def test_no_error_nodes(each_version): def check(node): assert node.type not in ('error_leaf', 'error_node') @@ -191,4 +188,4 @@ def test_no_error_nodes(): for child in children: check(child) - check(parse("if foo:\n bar")) + check(parse("if foo:\n bar", version=each_version))