xonsh/tests/test_contexts.py

339 lines
9 KiB
Python
Raw Normal View History

2016-06-05 16:25:43 -04:00
"""Tests xonsh contexts."""
from tools import (mock_xonsh_env, execer_setup, check_exec, check_eval,
2016-06-22 18:23:36 -04:00
check_parse)
2016-06-05 16:25:43 -04:00
from xonsh.contexts import Block, Functor
2016-06-05 16:25:43 -04:00
2016-06-05 17:02:10 -04:00
#
# helpers
#
2016-06-22 10:06:55 -04:00
def setup_module():
2016-06-05 16:25:43 -04:00
execer_setup()
2016-06-05 18:25:52 -04: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 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]
2016-06-05 17:02:10 -04:00
if isinstance(body, str):
body = body.splitlines()
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]
2016-06-05 18:25:52 -04:00
if isinstance(body, str):
body = body.splitlines()
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
def test_block_noexec():
s = ('x = 1\n'
'with Block():\n'
' x += 42\n')
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04: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():
2016-06-05 17:44:21 -04:00
body = ' x += 42\n'
s = X1_WITH + body
2016-06-05 16:25:43 -04:00
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_glb('b', glbs, body, {'x': 1})
2016-06-05 17:02:10 -04:00
def test_block_manylines():
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
2016-06-05 17:02:10 -04:00
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04: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
2016-06-05 17:44:21 -04:00
body = (' # I am a leading comment\n'
' x += 42\n')
s = X1_WITH + body
2016-06-05 17:02:10 -04:00
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04: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 do not show up in block lines
2016-06-05 17:44:21 -04:00
body = (' x += 42\n'
' # I am a trailing comment\n')
s = X1_WITH + body
2016-06-05 17:02:10 -04:00
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_glb('b', glbs, [' x += 42'], {'x': 1})
2016-06-05 17:02:10 -04:00
2016-06-05 17:44:21 -04:00
def test_block_trailing_line_continuation():
body = (' x += \\\n'
' 42\n')
s = X1_WITH + body
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_glb('b', glbs, body, {'x': 1})
2016-06-05 17:44:21 -04:00
def test_block_trailing_close_paren():
body = (' x += int("42"\n'
' )\n')
s = X1_WITH + body
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04: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():
body = (' x = {None: [int("42"\n'
' )\n'
' ]\n'
' }\n')
s = SIMPLE_WITH + body
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04: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():
body = (' x = """This\n'
'is\n'
'"probably"\n'
'\'not\' what I meant.\n'
'"""\n')
s = SIMPLE_WITH + body
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_glb('b', glbs, body)
2016-06-05 18:25:52 -04:00
def test_block_func_oneline():
body = ' x += 42\n'
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04: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():
body = (' ![echo wow mom]\n'
'# bad place for a comment\n'
' x += 42\n')
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04: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
body = (' # I am a leading comment\n'
' x += 42\n')
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_func('rtn', glbs, ' x += 42\n',
2016-06-05 18:34:37 -04:00
FUNC_OBSG, FUNC_OBSL)
def test_block_func_trailing_comment():
# trailing comments do not show up in block lines
body = (' x += 42\n'
' # I am a trailing comment\n')
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_func('rtn', glbs, ' x += 42\n',
2016-06-05 18:34:37 -04:00
FUNC_OBSG, FUNC_OBSL)
def test_blockfunc__trailing_line_continuation():
body = (' x += \\\n'
' 42\n')
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04: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():
body = (' x += int("42"\n'
' )\n')
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04: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():
body = (' x = {None: [int("42"\n'
' )\n'
' ]\n'
' }\n')
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04: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():
body = (' x = """This\n'
'is\n'
'"probably"\n'
'\'not\' what I meant.\n'
'"""\n')
s = FUNC_WITH.format(body=body)
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL)
#
# Functor tests
#
X2_WITH = ('x = 1\n'
'with Functor() as f:\n'
'{body}'
'x += 1\n'
'{calls}\n'
)
def test_functor_oneline_onecall_class():
body = (' global x\n'
' x += 42\n')
calls = 'f()'
s = X2_WITH.format(body=body, calls=calls)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_glb('f', glbs, body, {'x': 44})
def test_functor_oneline_onecall_func():
body = (' global x\n'
' x += 42\n')
calls = 'f.func()'
s = X2_WITH.format(body=body, calls=calls)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_glb('f', glbs, body, {'x': 44})
def test_functor_oneline_onecall_both():
body = (' global x\n'
' x += 42\n')
calls = 'f()\nf.func()'
s = X2_WITH.format(body=body, calls=calls)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_glb('f', glbs, body, {'x': 86})
2016-06-05 21:44:03 -04:00
XA_WITH = ('x = [1]\n'
'with Functor() as f:\n'
'{body}'
'x.append(2)\n'
'{calls}\n'
)
def test_functor_oneline_append():
body = ' x.append(3)\n'
calls = 'f()\n'
s = XA_WITH.format(body=body, calls=calls)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_glb('f', glbs, body, {'x': [1, 2, 3]})
2016-06-05 21:44:03 -04:00
def test_functor_return():
body = ' x = 42\n'
t = ('res = 0\n'
'with Functor(rtn="x") as f:\n'
'{body}\n'
'res = f()\n')
s = t.format(body=body)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_glb('f', glbs, body, {'res': 42})
2016-06-05 21:44:03 -04:00
def test_functor_args():
body = ' x = 42 + a\n'
t = ('res = 0\n'
'with Functor(args=("a",), rtn="x") as f:\n'
'{body}\n'
'res = f(2)\n')
s = t.format(body=body)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_glb('f', glbs, body, {'res': 44})
2016-06-05 21:44:03 -04:00
def test_functor_kwargs():
body = ' x = 42 + a + b\n'
t = ('res = 0\n'
'with Functor(kwargs={{"a": 1, "b": 12}}, rtn="x") as f:\n'
'{body}\n'
'res = f(b=6)\n')
s = t.format(body=body)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_glb('f', glbs, body, {'res': 49})
2016-06-05 21:44:03 -04:00
def test_functor_fullsig():
body = ' x = 42 + a + b + c\n'
t = ('res = 0\n'
'with Functor(args=("c",), kwargs={{"a": 1, "b": 12}}, rtn="x") as f:\n'
'{body}\n'
'res = f(55)\n')
s = t.format(body=body)
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None)
2016-06-22 17:12:33 -04:00
block_checks_glb('f', glbs, body, {'res': 110})
2016-06-05 21:44:03 -04:00