2016-06-05 14:32:59 -04:00
|
|
|
"""Xonsh AST tests."""
|
2016-08-19 01:45:44 -04:00
|
|
|
import ast as pyast
|
|
|
|
|
2016-06-05 14:32:59 -04:00
|
|
|
from xonsh import ast
|
2020-05-05 06:42:28 -04:00
|
|
|
from xonsh.ast import Tuple, Name, Store, min_line, Call, BinOp, isexpression
|
2016-06-10 02:50:56 -04:00
|
|
|
|
2016-07-01 21:52:37 +03:00
|
|
|
import pytest
|
2016-06-10 02:50:56 -04:00
|
|
|
|
2016-08-19 01:45:44 -04:00
|
|
|
from tools import check_parse, nodes_equal
|
2016-06-10 02:50:56 -04:00
|
|
|
|
2016-06-05 14:32:59 -04:00
|
|
|
|
2016-07-01 21:52:37 +03:00
|
|
|
@pytest.fixture(autouse=True)
|
|
|
|
def xonsh_execer_autouse(xonsh_execer):
|
|
|
|
return xonsh_execer
|
2016-06-05 14:32:59 -04:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
|
2016-06-05 14:32:59 -04:00
|
|
|
def test_gather_names_name():
|
2018-08-30 09:18:49 -05:00
|
|
|
node = Name(id="y", ctx=Store())
|
|
|
|
exp = {"y"}
|
2016-06-05 14:32:59 -04:00
|
|
|
obs = ast.gather_names(node)
|
2016-06-22 17:12:33 -04:00
|
|
|
assert exp == obs
|
2016-06-05 14:32:59 -04:00
|
|
|
|
|
|
|
|
|
|
|
def test_gather_names_tuple():
|
2018-08-30 09:18:49 -05:00
|
|
|
node = Tuple(elts=[Name(id="y", ctx=Store()), Name(id="z", ctx=Store())])
|
|
|
|
exp = {"y", "z"}
|
2016-06-05 14:32:59 -04:00
|
|
|
obs = ast.gather_names(node)
|
2016-06-22 17:12:33 -04:00
|
|
|
assert exp == obs
|
2016-06-10 02:50:56 -04:00
|
|
|
|
2016-08-21 14:58:07 -04:00
|
|
|
|
2016-09-09 19:07:41 -04:00
|
|
|
def test_gather_load_store_names_tuple():
|
2018-08-30 09:18:49 -05:00
|
|
|
node = Tuple(elts=[Name(id="y", ctx=Store()), Name(id="z", ctx=Store())])
|
2016-09-09 19:07:41 -04:00
|
|
|
lexp = set()
|
2018-08-30 09:18:49 -05:00
|
|
|
sexp = {"y", "z"}
|
2016-09-09 19:07:41 -04:00
|
|
|
lobs, sobs = ast.gather_load_store_names(node)
|
|
|
|
assert lexp == lobs
|
|
|
|
assert sexp == sobs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"line1",
|
|
|
|
[
|
2020-04-15 20:14:24 +02:00
|
|
|
"x = 1", # Both, ls and l remain undefined.
|
|
|
|
"ls = 1", # l remains undefined.
|
|
|
|
"l = 1", # ls remains undefined.
|
2018-08-30 09:18:49 -05:00
|
|
|
],
|
|
|
|
)
|
2018-11-19 20:08:44 -05:00
|
|
|
def test_multilline_num(xonsh_execer, line1):
|
2020-04-15 20:14:24 +02:00
|
|
|
# Subprocess transformation happens on the second line,
|
|
|
|
# because not all variables are known.
|
2018-08-30 09:18:49 -05:00
|
|
|
code = line1 + "\nls -l\n"
|
2016-06-10 02:50:56 -04:00
|
|
|
tree = check_parse(code)
|
|
|
|
lsnode = tree.body[1]
|
2016-06-22 17:12:33 -04:00
|
|
|
assert 2 == min_line(lsnode)
|
2016-08-21 14:58:07 -04:00
|
|
|
assert isinstance(lsnode.value, Call)
|
|
|
|
|
|
|
|
|
|
|
|
def test_multilline_no_transform():
|
2020-04-15 20:14:24 +02:00
|
|
|
# No subprocess transformations happen here, since all variables are known.
|
2018-08-30 09:18:49 -05:00
|
|
|
code = "ls = 1\nl = 1\nls -l\n"
|
2016-08-21 14:58:07 -04:00
|
|
|
tree = check_parse(code)
|
|
|
|
lsnode = tree.body[2]
|
|
|
|
assert 3 == min_line(lsnode)
|
|
|
|
assert isinstance(lsnode.value, BinOp)
|
2016-08-19 01:45:44 -04:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp",
|
|
|
|
[
|
|
|
|
"""def f():
|
2016-08-19 01:45:44 -04:00
|
|
|
if True:
|
|
|
|
pass
|
|
|
|
""",
|
2018-08-30 09:18:49 -05:00
|
|
|
"""def f(x):
|
2016-08-19 01:45:44 -04:00
|
|
|
if x:
|
|
|
|
pass
|
|
|
|
""",
|
2018-08-30 09:18:49 -05:00
|
|
|
"""def f(*args):
|
2016-08-19 01:45:44 -04:00
|
|
|
if not args:
|
|
|
|
pass
|
|
|
|
""",
|
2018-08-30 09:18:49 -05:00
|
|
|
"""def f(*, y):
|
2016-08-19 01:45:44 -04:00
|
|
|
if y:
|
|
|
|
pass
|
|
|
|
""",
|
2018-08-30 09:18:49 -05:00
|
|
|
"""def f(**kwargs):
|
2016-08-19 01:45:44 -04:00
|
|
|
if not kwargs:
|
|
|
|
pass
|
|
|
|
""",
|
2018-08-30 09:18:49 -05:00
|
|
|
"""def f(k=42):
|
2016-08-19 01:45:44 -04:00
|
|
|
if not k:
|
|
|
|
pass
|
|
|
|
""",
|
2018-08-30 09:18:49 -05:00
|
|
|
"""def f(k=10, *, a, b=1, **kw):
|
2016-08-19 01:45:44 -04:00
|
|
|
if not kw and b:
|
|
|
|
pass
|
|
|
|
""",
|
2018-08-30 09:18:49 -05:00
|
|
|
"""import os
|
2016-09-09 19:07:41 -04:00
|
|
|
path = '/path/to/wakka'
|
|
|
|
paths = []
|
|
|
|
for root, dirs, files in os.walk(path):
|
|
|
|
paths.extend(os.path.join(root, d) for d in dirs)
|
|
|
|
paths.extend(os.path.join(root, f) for f in files)
|
|
|
|
""",
|
2018-08-30 09:18:49 -05:00
|
|
|
"""lambda x: x + 1
|
2018-04-03 21:57:30 -04:00
|
|
|
""",
|
2018-08-30 09:18:49 -05:00
|
|
|
],
|
|
|
|
)
|
2016-09-09 19:07:41 -04:00
|
|
|
def test_unmodified(inp):
|
2016-08-19 01:45:44 -04:00
|
|
|
# Context sensitive parsing should not modify AST
|
|
|
|
exp = pyast.parse(inp)
|
|
|
|
obs = check_parse(inp)
|
2016-09-09 19:07:41 -04:00
|
|
|
|
2016-08-19 01:45:44 -04:00
|
|
|
assert nodes_equal(exp, obs)
|
2018-09-29 01:55:30 -07:00
|
|
|
|
2018-11-09 13:49:33 -06:00
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"test_input",
|
|
|
|
["echo; echo && echo\n", "echo; echo && echo a\n", "true && false && true\n"],
|
|
|
|
)
|
2018-09-29 01:55:30 -07:00
|
|
|
def test_whitespace_subproc(test_input):
|
|
|
|
assert check_parse(test_input)
|
2018-11-09 13:49:33 -06:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp,exp",
|
|
|
|
[
|
|
|
|
("1+1", True),
|
|
|
|
("1+1;", True),
|
|
|
|
("1+1\n", True),
|
|
|
|
("1+1; 2+2", False),
|
|
|
|
("1+1; 2+2;", False),
|
|
|
|
("1+1; 2+2\n", False),
|
|
|
|
("1+1; 2+2;\n", False),
|
|
|
|
("x = 42", False),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_isexpression(xonsh_execer, inp, exp):
|
|
|
|
obs = isexpression(inp)
|
|
|
|
assert exp is obs
|