diff options
Diffstat (limited to 'contrib/python/parso/py2/tests/test_get_code.py')
-rw-r--r-- | contrib/python/parso/py2/tests/test_get_code.py | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/contrib/python/parso/py2/tests/test_get_code.py b/contrib/python/parso/py2/tests/test_get_code.py new file mode 100644 index 0000000000..d99d792b93 --- /dev/null +++ b/contrib/python/parso/py2/tests/test_get_code.py @@ -0,0 +1,133 @@ +import difflib + +import pytest + +from parso import parse + +code_basic_features = ''' +"""A mod docstring""" + +def a_function(a_argument, a_default = "default"): + """A func docstring""" + + a_result = 3 * a_argument + print(a_result) # a comment + b = """ +from +to""" + "huhu" + + + if a_default == "default": + return str(a_result) + else + return None +''' + + +def diff_code_assert(a, b, n=4): + if a != b: + diff = "\n".join(difflib.unified_diff( + a.splitlines(), + b.splitlines(), + n=n, + lineterm="" + )) + assert False, "Code does not match:\n%s\n\ncreated code:\n%s" % ( + diff, + b + ) + pass + + +def test_basic_parsing(): + """Validate the parsing features""" + + m = parse(code_basic_features) + diff_code_assert( + code_basic_features, + m.get_code() + ) + + +def test_operators(): + src = '5 * 3' + module = parse(src) + diff_code_assert(src, module.get_code()) + + +def test_get_code(): + """Use the same code that the parser also generates, to compare""" + s = '''"""a docstring""" +class SomeClass(object, mixin): + def __init__(self): + self.xy = 3.0 + """statement docstr""" + def some_method(self): + return 1 + def yield_method(self): + while hasattr(self, 'xy'): + yield True + for x in [1, 2]: + yield x + def empty(self): + pass +class Empty: + pass +class WithDocstring: + """class docstr""" + pass +def method_with_docstring(): + """class docstr""" + pass +''' + assert parse(s).get_code() == s + + +def test_end_newlines(): + """ + The Python grammar explicitly needs a newline at the end. Jedi though still + wants to be able, to return the exact same code without the additional new + line the parser needs. + """ + def test(source, end_pos): + module = parse(source) + assert module.get_code() == source + assert module.end_pos == end_pos + + test('a', (1, 1)) + test('a\n', (2, 0)) + test('a\nb', (2, 1)) + test('a\n#comment\n', (3, 0)) + test('a\n#comment', (2, 8)) + test('a#comment', (1, 9)) + test('def a():\n pass', (2, 5)) + + test('def a(', (1, 6)) + + +@pytest.mark.parametrize(('code', 'types'), [ + ('\r', ['endmarker']), + ('\n\r', ['endmarker']) +]) +def test_carriage_return_at_end(code, types): + """ + By adding an artificial newline this created weird side effects for + \r at the end of files. + """ + tree = parse(code) + assert tree.get_code() == code + assert [c.type for c in tree.children] == types + assert tree.end_pos == (len(code) + 1, 0) + + +@pytest.mark.parametrize('code', [ + ' ', + ' F"""', + ' F"""\n', + ' F""" \n', + ' F""" \n3', + ' f"""\n"""', + ' f"""\n"""\n', +]) +def test_full_code_round_trip(code): + assert parse(code).get_code() == code |