xonsh/tests/test_contexts.py

322 lines
8.6 KiB
Python
Raw Normal View History

2016-06-05 16:25:43 -04:00
"""Tests xonsh contexts."""
from textwrap import dedent
from tools import check_exec
from xonsh.contexts import Block, Functor
2016-06-05 16:25:43 -04:00
import pytest
@pytest.fixture(autouse=True)
def xonsh_execer_autouse(xonsh_builtins, xonsh_execer):
return xonsh_execer
2018-08-30 09:18:49 -05:00
2016-06-05 17:02:10 -04:00
#
# helpers
#
2018-08-30 09:18:49 -05:00
X1_WITH = "x = 1\n" "with! Block() as b:\n"
SIMPLE_WITH = "with! Block() as b:\n"
FUNC_WITH = (
"x = 1\n"
"def func():\n"
" y = 1\n"
" with! Block() as b:\n"
"{body}"
" y += 1\n"
" return b\n"
"x += 1\n"
"rtn = func()\n"
"x += 1\n"
)
FUNC_OBSG = {"x": 3}
FUNC_OBSL = {"y": 1}
2016-06-05 18:25:52 -04:00
def norm_body(body):
if not isinstance(body, str):
2018-08-30 09:18:49 -05:00
body = "\n".join(body)
body = dedent(body)
body = body.splitlines()
return body
2016-06-05 17:49:12 -04:00
def block_checks_glb(name, glbs, body, obs=None):
2016-06-05 17:02:10 -04:00
block = glbs[name]
2016-06-05 17:49:12 -04:00
obs = obs or {}
2016-06-05 17:02:10 -04:00
for k, v in obs.items():
2016-06-22 17:12:33 -04:00
assert v == glbs[k]
body = norm_body(body)
2016-06-22 17:12:33 -04:00
assert body == block.lines
assert glbs is block.glbs
assert block.locs is None
2016-06-05 17:02:10 -04:00
2016-06-05 18:25:52 -04:00
def block_checks_func(name, glbs, body, obsg=None, obsl=None):
block = glbs[name]
obsg = obsg or {}
for k, v in obsg.items():
2016-06-22 17:12:33 -04:00
assert v == glbs[k]
body = norm_body(body)
2016-06-22 17:12:33 -04:00
assert body == block.lines
assert glbs is block.glbs
2016-06-05 18:25:52 -04:00
# local context tests
locs = block.locs
2016-06-22 17:12:33 -04:00
assert locs is not None
2016-06-05 18:25:52 -04:00
obsl = obsl or {}
for k, v in obsl.items():
2016-06-22 17:12:33 -04:00
assert v == locs[k]
2016-06-05 17:49:12 -04:00
2016-06-05 17:44:21 -04:00
2016-06-05 17:02:10 -04:00
#
# Block tests
2016-06-05 17:02:10 -04:00
#
2016-06-05 16:25:43 -04:00
2018-08-30 09:18:49 -05:00
2016-06-05 16:25:43 -04:00
def test_block_noexec():
2018-08-30 09:18:49 -05:00
s = "x = 1\n" "with! Block():\n" " x += 42\n"
glbs = {"Block": Block}
2016-06-05 16:25:43 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
assert 1 == glbs["x"]
2016-06-05 16:25:43 -04:00
2016-06-05 17:02:10 -04:00
2016-06-05 16:25:43 -04:00
def test_block_oneline():
2018-08-30 09:18:49 -05:00
body = " x += 42\n"
2016-06-05 17:44:21 -04:00
s = X1_WITH + body
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 16:25:43 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("b", glbs, body, {"x": 1})
2016-06-05 17:02:10 -04:00
def test_block_manylines():
2018-08-30 09:18:49 -05:00
body = " ![echo wow mom]\n" "# bad place for a comment\n" " x += 42"
2016-06-05 17:44:21 -04:00
s = X1_WITH + body
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 17:02:10 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("b", glbs, body, {"x": 1})
2016-06-05 17:02:10 -04:00
def test_block_leading_comment():
# leading comments do not show up in block lines
2018-08-30 09:18:49 -05:00
body = " # I am a leading comment\n" " x += 42\n"
2016-06-05 17:44:21 -04:00
s = X1_WITH + body
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 17:02:10 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("b", glbs, [" x += 42"], {"x": 1})
2016-06-05 17:02:10 -04:00
def test_block_trailing_comment():
# trailing comments show up in block lines
2018-08-30 09:18:49 -05:00
body = " x += 42\n" " # I am a trailing comment\n"
2016-06-05 17:44:21 -04:00
s = X1_WITH + body
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 17:02:10 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("b", glbs, body, {"x": 1})
2016-06-05 17:02:10 -04:00
2016-06-05 17:44:21 -04:00
def test_block_trailing_line_continuation():
2018-08-30 09:18:49 -05:00
body = " x += \\\n" " 42\n"
2016-06-05 17:44:21 -04:00
s = X1_WITH + body
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 17:44:21 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("b", glbs, body, {"x": 1})
2016-06-05 17:44:21 -04:00
def test_block_trailing_close_paren():
2018-08-30 09:18:49 -05:00
body = ' x += int("42"\n' " )\n"
2016-06-05 17:44:21 -04:00
s = X1_WITH + body
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 17:44:21 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("b", glbs, body, {"x": 1})
2016-06-05 17:44:21 -04:00
2016-06-05 17:49:12 -04:00
def test_block_trailing_close_many():
2018-08-30 09:18:49 -05:00
body = (
' x = {None: [int("42"\n'
" )\n"
" ]\n"
" }\n"
)
2016-06-05 17:49:12 -04:00
s = SIMPLE_WITH + body
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 17:49:12 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("b", glbs, body)
2016-06-05 17:49:12 -04:00
2016-06-05 18:25:52 -04:00
def test_block_trailing_triple_string():
2018-08-30 09:18:49 -05:00
body = ' x = """This\n' "is\n" '"probably"\n' "'not' what I meant.\n" '"""\n'
2016-06-05 18:25:52 -04:00
s = SIMPLE_WITH + body
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 18:25:52 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("b", glbs, body)
2016-06-05 18:25:52 -04:00
def test_block_func_oneline():
2018-08-30 09:18:49 -05:00
body = " x += 42\n"
2016-06-05 18:25:52 -04:00
s = FUNC_WITH.format(body=body)
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 18:25:52 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
2016-06-05 18:25:52 -04:00
2016-06-05 18:34:37 -04:00
def test_block_func_manylines():
2018-08-30 09:18:49 -05:00
body = " ![echo wow mom]\n" "# bad place for a comment\n" " x += 42\n"
2016-06-05 18:34:37 -04:00
s = FUNC_WITH.format(body=body)
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 18:34:37 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
2016-06-05 18:34:37 -04:00
def test_block_func_leading_comment():
# leading comments do not show up in block lines
2018-08-30 09:18:49 -05:00
body = " # I am a leading comment\n" " x += 42\n"
2016-06-05 18:34:37 -04:00
s = FUNC_WITH.format(body=body)
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 18:34:37 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_func("rtn", glbs, " x += 42\n", FUNC_OBSG, FUNC_OBSL)
2016-06-05 18:34:37 -04:00
def test_block_func_trailing_comment():
# trailing comments show up in block lines
2018-08-30 09:18:49 -05:00
body = " x += 42\n" " # I am a trailing comment\n"
2016-06-05 18:34:37 -04:00
s = FUNC_WITH.format(body=body)
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 18:34:37 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
2016-06-05 18:34:37 -04:00
def test_blockfunc__trailing_line_continuation():
2018-08-30 09:18:49 -05:00
body = " x += \\\n" " 42\n"
2016-06-05 18:34:37 -04:00
s = FUNC_WITH.format(body=body)
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 18:34:37 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
2016-06-05 18:34:37 -04:00
def test_block_func_trailing_close_paren():
2018-08-30 09:18:49 -05:00
body = ' x += int("42"\n' " )\n"
2016-06-05 18:34:37 -04:00
s = FUNC_WITH.format(body=body)
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 18:34:37 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
2016-06-05 18:34:37 -04:00
def test_block_func_trailing_close_many():
2018-08-30 09:18:49 -05:00
body = (
' x = {None: [int("42"\n'
" )\n"
" ]\n"
" }\n"
)
2016-06-05 18:34:37 -04:00
s = FUNC_WITH.format(body=body)
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 18:34:37 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
2016-06-05 18:34:37 -04:00
def test_block_func_trailing_triple_string():
2018-08-30 09:18:49 -05:00
body = ' x = """This\n' "is\n" '"probably"\n' "'not' what I meant.\n" '"""\n'
2016-06-05 18:34:37 -04:00
s = FUNC_WITH.format(body=body)
2018-08-30 09:18:49 -05:00
glbs = {"Block": Block}
2016-06-05 18:34:37 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
#
# Functor tests
#
2018-08-30 09:18:49 -05:00
X2_WITH = "{var} = 1\n" "with! Functor() as f:\n" "{body}" "{var} += 1\n" "{calls}\n"
def test_functor_oneline_onecall_class():
2018-08-30 09:18:49 -05:00
body = " global y\n" " y += 42\n"
calls = "f()"
s = X2_WITH.format(body=body, calls=calls, var="y")
glbs = {"Functor": Functor}
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("f", glbs, body, {"y": 44})
def test_functor_oneline_onecall_func():
2018-08-30 09:18:49 -05:00
body = " global z\n" " z += 42\n"
calls = "f.func()"
s = X2_WITH.format(body=body, calls=calls, var="z")
glbs = {"Functor": Functor}
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("f", glbs, body, {"z": 44})
def test_functor_oneline_onecall_both():
2018-08-30 09:18:49 -05:00
body = " global x\n" " x += 42\n"
calls = "f()\nf.func()"
s = X2_WITH.format(body=body, calls=calls, var="x")
glbs = {"Functor": Functor}
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("f", glbs, body, {"x": 86})
2018-08-30 09:18:49 -05:00
XA_WITH = "x = [1]\n" "with! Functor() as f:\n" "{body}" "x.append(2)\n" "{calls}\n"
2016-06-05 21:44:03 -04:00
def test_functor_oneline_append():
2018-08-30 09:18:49 -05:00
body = " x.append(3)\n"
calls = "f()\n"
2016-06-05 21:44:03 -04:00
s = XA_WITH.format(body=body, calls=calls)
2018-08-30 09:18:49 -05:00
glbs = {"Functor": Functor}
2016-06-05 21:44:03 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("f", glbs, body, {"x": [1, 2, 3]})
2016-06-05 21:44:03 -04:00
def test_functor_return():
2018-08-30 09:18:49 -05:00
body = " x = 42"
t = "res = 0\n" 'with! Functor(rtn="x") as f:\n' "{body}\n" "res = f()\n"
2016-06-05 21:44:03 -04:00
s = t.format(body=body)
2018-08-30 09:18:49 -05:00
glbs = {"Functor": Functor}
2016-06-05 21:44:03 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("f", glbs, body, {"res": 42})
2016-06-05 21:44:03 -04:00
def test_functor_args():
2018-08-30 09:18:49 -05:00
body = " x = 42 + a"
t = (
"res = 0\n"
'with! Functor(args=("a",), rtn="x") as f:\n'
"{body}\n"
"res = f(2)\n"
)
2016-06-05 21:44:03 -04:00
s = t.format(body=body)
2018-08-30 09:18:49 -05:00
glbs = {"Functor": Functor}
2016-06-05 21:44:03 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("f", glbs, body, {"res": 44})
2016-06-05 21:44:03 -04:00
def test_functor_kwargs():
2018-08-30 09:18:49 -05:00
body = " x = 42 + a + b"
t = (
"res = 0\n"
'with! Functor(kwargs={{"a": 1, "b": 12}}, rtn="x") as f:\n'
"{body}\n"
"res = f(b=6)\n"
)
2016-06-05 21:44:03 -04:00
s = t.format(body=body)
2018-08-30 09:18:49 -05:00
glbs = {"Functor": Functor}
2016-06-05 21:44:03 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("f", glbs, body, {"res": 49})
2016-06-05 21:44:03 -04:00
def test_functor_fullsig():
2018-08-30 09:18:49 -05:00
body = " x = 42 + a + b + c"
t = (
"res = 0\n"
'with! Functor(args=("c",), kwargs={{"a": 1, "b": 12}}, rtn="x") as f:\n'
"{body}\n"
"res = f(55)\n"
)
2016-06-05 21:44:03 -04:00
s = t.format(body=body)
2018-08-30 09:18:49 -05:00
glbs = {"Functor": Functor}
2016-06-05 21:44:03 -04:00
check_exec(s, glbs=glbs, locs=None)
2018-08-30 09:18:49 -05:00
block_checks_glb("f", glbs, body, {"res": 110})