diff --git a/test/test_parser/test_fast_parser.py b/test/test_parser/test_fast_parser.py index 6857283c..881f0f74 100644 --- a/test/test_parser/test_fast_parser.py +++ b/test/test_parser/test_fast_parser.py @@ -36,32 +36,6 @@ def test_add_to_end(): assert jedi.Script(a + b, path='example.py').completions() -def test_class_in_docstr(): - """ - Regression test for a problem with classes in docstrings. - """ - a = '"\nclasses\n"' - jedi.Script(a, 1, 0)._get_module() - - b = a + '\nimport os' - assert jedi.Script(b, 4, 8).goto_assignments() - - -def test_carriage_return_splitting(): - source = u(dedent(''' - - - - "string" - - class Foo(): - pass - ''')) - source = source.replace('\n', '\r\n') - p = FastParser(load_grammar(), source) - assert [n.value for lst in p.module.names_dict.values() for n in lst] == ['Foo'] - - def test_split_parts(): cache.parser_cache.pop(None, None) @@ -131,23 +105,6 @@ def test_positions(): assert m.end_pos == (1, 1) -def test_if(): - src = dedent('''\ - def func(): - x = 3 - if x: - def y(): - return x - return y() - - func() - ''') - - # Two parsers needed, one for pass and one for the function. - check_fp(src, 2) - assert [d.name for d in jedi.Script(src, 8, 6).goto_definitions()] == ['int'] - - def test_if_simple(): src = dedent('''\ if 1: @@ -157,80 +114,6 @@ def test_if_simple(): check_fp(src + "else:\n a = ''\na", 1) -def test_for(): - src = dedent("""\ - for a in [1,2]: - a - - for a1 in 1,"": - a1 - """) - check_fp(src, 1) - - -def test_class_with_class_var(): - src = dedent("""\ - class SuperClass: - class_super = 3 - def __init__(self): - self.foo = 4 - pass - """) - check_fp(src, 3) - - -def test_func_with_if(): - src = dedent("""\ - def recursion(a): - if foo: - return recursion(a) - else: - if bar: - return inexistent - else: - return a - """) - check_fp(src, 1) - - -def test_decorator(): - src = dedent("""\ - class Decorator(): - @memoize - def dec(self, a): - return a - """) - check_fp(src, 2) - - -def test_nested_funcs(): - src = dedent("""\ - def memoize(func): - def wrapper(*args, **kwargs): - return func(*args, **kwargs) - return wrapper - """) - check_fp(src, 3) - - -def test_class_and_if(): - src = dedent("""\ - class V: - def __init__(self): - pass - - if 1: - c = 3 - - def a_func(): - return 1 - - # COMMENT - a_func()""") - check_fp(src, 5, 5) - assert [d.name for d in jedi.Script(src).goto_definitions()] == ['int'] - - def test_func_with_for_and_comment(): # The first newline is important, leave it. It should not trigger another # parser split. @@ -249,17 +132,6 @@ def test_func_with_for_and_comment(): check_fp('a\n' + src, 2, 3) -def test_multi_line_params(): - src = dedent("""\ - def x(a, - b): - pass - - foo = 1 - """) - check_fp(src, 2) - - def test_one_statement_func(): src = dedent("""\ first @@ -272,20 +144,6 @@ def test_one_statement_func(): check_fp(src + 'def second():\n a', 3) -def test_class_func_if(): - src = dedent("""\ - class Class: - def func(self): - if 1: - a - else: - b - - pass - """) - check_fp(src, 3) - - def test_for_on_one_line(): src = dedent("""\ foo = 1 @@ -315,39 +173,6 @@ def test_for_on_one_line(): check_fp(src, 2) -def test_multi_line_for(): - src = dedent("""\ - for x in [1, - 2]: - pass - - pass - """) - check_fp(src, 1) - - -def test_wrong_indentation(): - src = dedent("""\ - def func(): - a - b - a - """) - #check_fp(src, 1) - - src = dedent("""\ - def complex(): - def nested(): - a - b - a - - def other(): - pass - """) - check_fp(src, 3) - - def test_open_parentheses(): func = 'def func():\n a' code = u('isinstance(\n\n' + func) @@ -364,17 +189,6 @@ def test_open_parentheses(): check_fp('isinstance()\n' + func, 1, 2) -def test_strange_parentheses(): - src = dedent(""" - class X(): - a = (1 - if 1 else 2) - def x(): - pass - """) - check_fp(src, 2) - - def test_backslash(): src = dedent(r""" a = 1\ @@ -405,92 +219,3 @@ def test_backslash(): pass """) check_fp(src, 2) - - - -def test_fake_parentheses(): - """ - The fast parser splitting counts parentheses, but not as correct tokens. - Therefore parentheses in string tokens are included as well. This needs to - be accounted for. - """ - src = dedent(r""" - def x(): - a = (')' - if 1 else 2) - def y(): - pass - def z(): - pass - """) - check_fp(src, 3, 2, 1) - - -def test_additional_indent(): - source = dedent('''\ - int( - def x(): - pass - ''') - - check_fp(source, 2) - - -def test_incomplete_function(): - source = '''return ImportErr''' - - script = jedi.Script(dedent(source), 1, 3) - assert script.completions() - - -def test_string_literals(): - """Simplified case of jedi-vim#377.""" - source = dedent(""" - x = ur''' - - def foo(): - pass - """) - - script = jedi.Script(dedent(source)) - script._get_module().end_pos == (6, 0) - assert script.completions() - - -def test_decorator_string_issue(): - """ - Test case from #589 - """ - source = dedent('''\ - """ - @""" - def bla(): - pass - - bla.''') - - s = jedi.Script(source) - assert s.completions() - assert s._get_module().get_code() == source - - -def test_round_trip(): - source = dedent(''' - def x(): - """hahaha""" - func''') - - f = FastParser(load_grammar(), u(source)) - assert f.get_parsed_node().get_code() == source - - -@pytest.mark.xfail() -def test_parentheses_in_string(): - code = dedent(''' - def x(): - '(' - - import abc - - abc.''') - check_fp(code, 2, 1, 1) diff --git a/test/test_parser/test_old_fast_parser.py b/test/test_parser/test_old_fast_parser.py new file mode 100644 index 00000000..161efe1f --- /dev/null +++ b/test/test_parser/test_old_fast_parser.py @@ -0,0 +1,302 @@ +""" +These tests test the cases that the old fast parser tested with the normal +parser. + +The old fast parser doesn't exist anymore and was replaced with a diff parser. +However the tests might still be relevant for the parser. +""" + +from textwrap import dedent + +import jedi +from jedi._compatibility import u +from jedi.parser import load_grammar +from jedi.parser.fast import FastParser +from jedi.parser.utils import save_parser + + +def test_carriage_return_splitting(): + source = u(dedent(''' + + + + "string" + + class Foo(): + pass + ''')) + source = source.replace('\n', '\r\n') + p = FastParser(load_grammar(), source) + assert [n.value for lst in p.module.names_dict.values() for n in lst] == ['Foo'] + + +def test_class_in_docstr(): + """ + Regression test for a problem with classes in docstrings. + """ + a = '"\nclasses\n"' + jedi.Script(a, 1, 0)._get_module() + + b = a + '\nimport os' + assert jedi.Script(b, 4, 8).goto_assignments() + + +def check_fp(src, number_parsers_used, number_of_splits=None, number_of_misses=0): + if number_of_splits is None: + number_of_splits = number_parsers_used + + p = FastParser(load_grammar(), u(src)) + save_parser(None, p, pickling=False) + + assert src == p.module.get_code() + assert p.number_of_splits == number_of_splits + assert p.number_parsers_used == number_parsers_used + assert p.number_of_misses == number_of_misses + return p.module + + +def test_if(): + src = dedent('''\ + def func(): + x = 3 + if x: + def y(): + return x + return y() + + func() + ''') + + # Two parsers needed, one for pass and one for the function. + check_fp(src, 2) + assert [d.name for d in jedi.Script(src, 8, 6).goto_definitions()] == ['int'] + + +def test_for(): + src = dedent("""\ + for a in [1,2]: + a + + for a1 in 1,"": + a1 + """) + check_fp(src, 1) + + +def test_class_with_class_var(): + src = dedent("""\ + class SuperClass: + class_super = 3 + def __init__(self): + self.foo = 4 + pass + """) + check_fp(src, 3) + + +def test_func_with_if(): + src = dedent("""\ + def recursion(a): + if foo: + return recursion(a) + else: + if bar: + return inexistent + else: + return a + """) + check_fp(src, 1) + + +def test_decorator(): + src = dedent("""\ + class Decorator(): + @memoize + def dec(self, a): + return a + """) + check_fp(src, 2) + + +def test_nested_funcs(): + src = dedent("""\ + def memoize(func): + def wrapper(*args, **kwargs): + return func(*args, **kwargs) + return wrapper + """) + check_fp(src, 3) + + +def test_class_and_if(): + src = dedent("""\ + class V: + def __init__(self): + pass + + if 1: + c = 3 + + def a_func(): + return 1 + + # COMMENT + a_func()""") + check_fp(src, 5, 5) + assert [d.name for d in jedi.Script(src).goto_definitions()] == ['int'] + + +def test_multi_line_params(): + src = dedent("""\ + def x(a, + b): + pass + + foo = 1 + """) + check_fp(src, 2) + + +def test_class_func_if(): + src = dedent("""\ + class Class: + def func(self): + if 1: + a + else: + b + + pass + """) + check_fp(src, 3) + + +def test_multi_line_for(): + src = dedent("""\ + for x in [1, + 2]: + pass + + pass + """) + check_fp(src, 1) + + +def test_wrong_indentation(): + src = dedent("""\ + def func(): + a + b + a + """) + #check_fp(src, 1) + + src = dedent("""\ + def complex(): + def nested(): + a + b + a + + def other(): + pass + """) + check_fp(src, 3) + + +def test_strange_parentheses(): + src = dedent(""" + class X(): + a = (1 + if 1 else 2) + def x(): + pass + """) + check_fp(src, 2) + + +def test_fake_parentheses(): + """ + The fast parser splitting counts parentheses, but not as correct tokens. + Therefore parentheses in string tokens are included as well. This needs to + be accounted for. + """ + src = dedent(r""" + def x(): + a = (')' + if 1 else 2) + def y(): + pass + def z(): + pass + """) + check_fp(src, 3, 2, 1) + + +def test_additional_indent(): + source = dedent('''\ + int( + def x(): + pass + ''') + + check_fp(source, 2) + + +def test_incomplete_function(): + source = '''return ImportErr''' + + script = jedi.Script(dedent(source), 1, 3) + assert script.completions() + + +def test_string_literals(): + """Simplified case of jedi-vim#377.""" + source = dedent(""" + x = ur''' + + def foo(): + pass + """) + + script = jedi.Script(dedent(source)) + script._get_module().end_pos == (6, 0) + assert script.completions() + + +def test_decorator_string_issue(): + """ + Test case from #589 + """ + source = dedent('''\ + """ + @""" + def bla(): + pass + + bla.''') + + s = jedi.Script(source) + assert s.completions() + assert s._get_module().get_code() == source + + +def test_round_trip(): + source = dedent(''' + def x(): + """hahaha""" + func''') + + f = FastParser(load_grammar(), u(source)) + assert f.get_parsed_node().get_code() == source + + +def test_parentheses_in_string(): + code = dedent(''' + def x(): + '(' + + import abc + + abc.''') + check_fp(code, 2, 1, 1)