black tests

This commit is contained in:
Anthony Scopatz 2018-08-30 09:18:49 -05:00
parent 0557eecee0
commit 634a8ec9f2
41 changed files with 4320 additions and 3029 deletions

View file

@ -11,7 +11,8 @@ def mockopen(xonsh_builtins, monkeypatch):
@contextmanager @contextmanager
def mocked_open(fpath, *args, **kwargs): def mocked_open(fpath, *args, **kwargs):
yield MagicMock(read=lambda: fpath) yield MagicMock(read=lambda: fpath)
monkeypatch.setattr(builtins, 'open', mocked_open)
monkeypatch.setattr(builtins, "open", mocked_open)
def test_source_current_dir(mockopen, monkeypatch): def test_source_current_dir(mockopen, monkeypatch):
@ -19,10 +20,11 @@ def test_source_current_dir(mockopen, monkeypatch):
def mocked_execx(src, *args, **kwargs): def mocked_execx(src, *args, **kwargs):
checker.append(src.strip()) checker.append(src.strip())
monkeypatch.setattr(builtins, 'execx', mocked_execx)
monkeypatch.setattr(os.path, 'isfile', lambda x: True) monkeypatch.setattr(builtins, "execx", mocked_execx)
source_alias(['foo', 'bar']) monkeypatch.setattr(os.path, "isfile", lambda x: True)
assert checker == ['foo', 'bar'] source_alias(["foo", "bar"])
assert checker == ["foo", "bar"]
def test_source_path(mockopen, monkeypatch): def test_source_path(mockopen, monkeypatch):
@ -30,9 +32,10 @@ def test_source_path(mockopen, monkeypatch):
def mocked_execx(src, *args, **kwargs): def mocked_execx(src, *args, **kwargs):
checker.append(src.strip()) checker.append(src.strip())
monkeypatch.setattr(builtins, 'execx', mocked_execx)
source_alias(['foo', 'bar']) monkeypatch.setattr(builtins, "execx", mocked_execx)
path_foo = os.path.join('tests', 'bin', 'foo') source_alias(["foo", "bar"])
path_bar = os.path.join('tests', 'bin', 'bar') path_foo = os.path.join("tests", "bin", "foo")
path_bar = os.path.join("tests", "bin", "bar")
assert checker[0].endswith(path_foo) assert checker[0].endswith(path_foo)
assert checker[1].endswith(path_bar) assert checker[1].endswith(path_bar)

View file

@ -23,8 +23,10 @@ def source_path():
@pytest.fixture @pytest.fixture
def xonsh_execer(monkeypatch): def xonsh_execer(monkeypatch):
"""Initiate the Execer with a mocked nop `load_builtins`""" """Initiate the Execer with a mocked nop `load_builtins`"""
monkeypatch.setattr('xonsh.built_ins.load_builtins.__code__', monkeypatch.setattr(
(lambda *args, **kwargs: None).__code__) "xonsh.built_ins.load_builtins.__code__",
(lambda *args, **kwargs: None).__code__,
)
execer = Execer(unload=False) execer = Execer(unload=False)
builtins.__xonsh_execer__ = execer builtins.__xonsh_execer__ = execer
return execer return execer
@ -46,7 +48,7 @@ def xonsh_builtins(xonsh_events):
old_builtins = set(dir(builtins)) old_builtins = set(dir(builtins))
builtins.__xonsh_env__ = DummyEnv() builtins.__xonsh_env__ = DummyEnv()
if ON_WINDOWS: if ON_WINDOWS:
builtins.__xonsh_env__['PATHEXT'] = ['.EXE', '.BAT', '.CMD'] builtins.__xonsh_env__["PATHEXT"] = [".EXE", ".BAT", ".CMD"]
builtins.__xonsh_ctx__ = {} builtins.__xonsh_ctx__ = {}
builtins.__xonsh_shell__ = DummyShell() builtins.__xonsh_shell__ = DummyShell()
builtins.__xonsh_help__ = lambda x: x builtins.__xonsh_help__ = lambda x: x
@ -84,8 +86,9 @@ if ON_WINDOWS:
except ImportError: except ImportError:
pass pass
else: else:
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def disable_win_unicode_console(monkeypatch): def disable_win_unicode_console(monkeypatch):
""" Disable win_unicode_console if it is present since it collides with """ Disable win_unicode_console if it is present since it collides with
pytests ouptput capture""" pytests ouptput capture"""
monkeypatch.setattr(win_unicode_console, 'enable', lambda: None) monkeypatch.setattr(win_unicode_console, "enable", lambda: None)

View file

@ -16,38 +16,41 @@ from tools import skip_if_on_windows
def cd(args, stdin=None): def cd(args, stdin=None):
return args return args
ALIASES = Aliases({'o': ['omg', 'lala']},
color_ls=['ls', '--color=true'], ALIASES = Aliases(
ls="ls '- -'", {"o": ["omg", "lala"]},
cd=cd, color_ls=["ls", "--color=true"],
indirect_cd='cd ..') ls="ls '- -'",
cd=cd,
indirect_cd="cd ..",
)
RAW = ALIASES._raw RAW = ALIASES._raw
def test_imports(): def test_imports():
expected = { expected = {
'o': ['omg', 'lala'], "o": ["omg", "lala"],
'ls': ['ls', '- -'], "ls": ["ls", "- -"],
'color_ls': ['ls', '--color=true'], "color_ls": ["ls", "--color=true"],
'cd': cd, "cd": cd,
'indirect_cd': ['cd', '..'] "indirect_cd": ["cd", ".."],
} }
assert RAW == expected assert RAW == expected
def test_eval_normal(xonsh_builtins): def test_eval_normal(xonsh_builtins):
assert ALIASES.get('o') == ['omg', 'lala'] assert ALIASES.get("o") == ["omg", "lala"]
def test_eval_self_reference(xonsh_builtins): def test_eval_self_reference(xonsh_builtins):
assert ALIASES.get('ls') == ['ls', '- -'] assert ALIASES.get("ls") == ["ls", "- -"]
def test_eval_recursive(xonsh_builtins): def test_eval_recursive(xonsh_builtins):
assert ALIASES.get('color_ls') == ['ls', '- -', '--color=true'] assert ALIASES.get("color_ls") == ["ls", "- -", "--color=true"]
@skip_if_on_windows @skip_if_on_windows
def test_eval_recursive_callable_partial(xonsh_builtins): def test_eval_recursive_callable_partial(xonsh_builtins):
xonsh_builtins.__xonsh_env__ = Env(HOME=os.path.expanduser('~')) xonsh_builtins.__xonsh_env__ = Env(HOME=os.path.expanduser("~"))
assert ALIASES.get('indirect_cd')(['arg2', 'arg3']) == ['..', 'arg2', 'arg3'] assert ALIASES.get("indirect_cd")(["arg2", "arg3"]) == ["..", "arg2", "arg3"]

View file

@ -13,42 +13,44 @@ from tools import check_parse, nodes_equal
def xonsh_execer_autouse(xonsh_execer): def xonsh_execer_autouse(xonsh_execer):
return xonsh_execer return xonsh_execer
def test_gather_names_name(): def test_gather_names_name():
node = Name(id='y', ctx=Store()) node = Name(id="y", ctx=Store())
exp = {'y'} exp = {"y"}
obs = ast.gather_names(node) obs = ast.gather_names(node)
assert exp == obs assert exp == obs
def test_gather_names_tuple(): def test_gather_names_tuple():
node = Tuple(elts=[Name(id='y', ctx=Store()), node = Tuple(elts=[Name(id="y", ctx=Store()), Name(id="z", ctx=Store())])
Name(id='z', ctx=Store())]) exp = {"y", "z"}
exp = {'y', 'z'}
obs = ast.gather_names(node) obs = ast.gather_names(node)
assert exp == obs assert exp == obs
def test_gather_load_store_names_tuple(): def test_gather_load_store_names_tuple():
node = Tuple(elts=[Name(id='y', ctx=Store()), node = Tuple(elts=[Name(id="y", ctx=Store()), Name(id="z", ctx=Store())])
Name(id='z', ctx=Store())])
lexp = set() lexp = set()
sexp = {'y', 'z'} sexp = {"y", "z"}
lobs, sobs = ast.gather_load_store_names(node) lobs, sobs = ast.gather_load_store_names(node)
assert lexp == lobs assert lexp == lobs
assert sexp == sobs assert sexp == sobs
@pytest.mark.parametrize('line1', [ @pytest.mark.parametrize(
# this second line wil be transformed into a subprocess call "line1",
'x = 1', [
# this second line wil be transformed into a subprocess call even though # this second line wil be transformed into a subprocess call
# ls is defined. "x = 1",
'ls = 1', # this second line wil be transformed into a subprocess call even though
# the second line wil be transformed still even though l exists. # ls is defined.
'l = 1', "ls = 1",
]) # the second line wil be transformed still even though l exists.
"l = 1",
],
)
def test_multilline_num(xonsh_builtins, line1): def test_multilline_num(xonsh_builtins, line1):
code = line1 + '\nls -l\n' code = line1 + "\nls -l\n"
tree = check_parse(code) tree = check_parse(code)
lsnode = tree.body[1] lsnode = tree.body[1]
assert 2 == min_line(lsnode) assert 2 == min_line(lsnode)
@ -57,52 +59,55 @@ def test_multilline_num(xonsh_builtins, line1):
def test_multilline_no_transform(): def test_multilline_no_transform():
# no subprocess transformations happen here since all variables are known # no subprocess transformations happen here since all variables are known
code = 'ls = 1\nl = 1\nls -l\n' code = "ls = 1\nl = 1\nls -l\n"
tree = check_parse(code) tree = check_parse(code)
lsnode = tree.body[2] lsnode = tree.body[2]
assert 3 == min_line(lsnode) assert 3 == min_line(lsnode)
assert isinstance(lsnode.value, BinOp) assert isinstance(lsnode.value, BinOp)
@pytest.mark.parametrize('inp', [ @pytest.mark.parametrize(
"""def f(): "inp",
[
"""def f():
if True: if True:
pass pass
""", """,
"""def f(x): """def f(x):
if x: if x:
pass pass
""", """,
"""def f(*args): """def f(*args):
if not args: if not args:
pass pass
""", """,
"""def f(*, y): """def f(*, y):
if y: if y:
pass pass
""", """,
"""def f(**kwargs): """def f(**kwargs):
if not kwargs: if not kwargs:
pass pass
""", """,
"""def f(k=42): """def f(k=42):
if not k: if not k:
pass pass
""", """,
"""def f(k=10, *, a, b=1, **kw): """def f(k=10, *, a, b=1, **kw):
if not kw and b: if not kw and b:
pass pass
""", """,
"""import os """import os
path = '/path/to/wakka' path = '/path/to/wakka'
paths = [] paths = []
for root, dirs, files in os.walk(path): 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, d) for d in dirs)
paths.extend(os.path.join(root, f) for f in files) paths.extend(os.path.join(root, f) for f in files)
""", """,
"""lambda x: x + 1 """lambda x: x + 1
""", """,
]) ],
)
def test_unmodified(inp): def test_unmodified(inp):
# Context sensitive parsing should not modify AST # Context sensitive parsing should not modify AST
exp = pyast.parse(inp) exp = pyast.parse(inp)

View file

@ -7,10 +7,12 @@ from xonsh.base_shell import BaseShell
from xonsh.shell import transform_command from xonsh.shell import transform_command
def test_pwd_tracks_cwd(xonsh_builtins, xonsh_execer, tmpdir_factory, monkeypatch ): def test_pwd_tracks_cwd(xonsh_builtins, xonsh_execer, tmpdir_factory, monkeypatch):
asubdir = str(tmpdir_factory.mktemp("asubdir")) asubdir = str(tmpdir_factory.mktemp("asubdir"))
cur_wd = os.getcwd() cur_wd = os.getcwd()
xonsh_builtins.__xonsh_env__ = Env(PWD=cur_wd, XONSH_CACHE_SCRIPTS=False, XONSH_CACHE_EVERYTHING=False) xonsh_builtins.__xonsh_env__ = Env(
PWD=cur_wd, XONSH_CACHE_SCRIPTS=False, XONSH_CACHE_EVERYTHING=False
)
monkeypatch.setattr(xonsh_execer, "cacheall", False, raising=False) monkeypatch.setattr(xonsh_execer, "cacheall", False, raising=False)
bc = BaseShell(xonsh_execer, None) bc = BaseShell(xonsh_execer, None)
@ -20,19 +22,23 @@ def test_pwd_tracks_cwd(xonsh_builtins, xonsh_execer, tmpdir_factory, monkeypatc
bc.default('os.chdir(r"' + asubdir + '")') bc.default('os.chdir(r"' + asubdir + '")')
assert os.path.abspath(os.getcwd()) == os.path.abspath(asubdir) assert os.path.abspath(os.getcwd()) == os.path.abspath(asubdir)
assert os.path.abspath(os.getcwd()) == os.path.abspath(xonsh_builtins.__xonsh_env__['PWD']) assert os.path.abspath(os.getcwd()) == os.path.abspath(
assert 'OLDPWD' in xonsh_builtins.__xonsh_env__ xonsh_builtins.__xonsh_env__["PWD"]
assert os.path.abspath(cur_wd) == os.path.abspath(xonsh_builtins.__xonsh_env__['OLDPWD']) )
assert "OLDPWD" in xonsh_builtins.__xonsh_env__
assert os.path.abspath(cur_wd) == os.path.abspath(
xonsh_builtins.__xonsh_env__["OLDPWD"]
)
def test_transform(xonsh_builtins): def test_transform(xonsh_builtins):
@xonsh_builtins.events.on_transform_command @xonsh_builtins.events.on_transform_command
def spam2egg(cmd, **_): def spam2egg(cmd, **_):
if cmd == 'spam': if cmd == "spam":
return 'egg' return "egg"
else: else:
return cmd return cmd
assert transform_command('spam') == 'egg' assert transform_command("spam") == "egg"
assert transform_command('egg') == 'egg' assert transform_command("egg") == "egg"
assert transform_command('foo') == 'foo' assert transform_command("foo") == "foo"

View file

@ -1,13 +1,12 @@
"""Tests bashisms xontrib.""" """Tests bashisms xontrib."""
import pytest import pytest
@pytest.mark.parametrize('inp, exp', [
('x = 42', 'x = 42'), @pytest.mark.parametrize("inp, exp", [("x = 42", "x = 42"), ("!!", "ls")])
('!!', 'ls'),
])
def test_preproc(inp, exp, xonsh_builtins): def test_preproc(inp, exp, xonsh_builtins):
"""Test the bash preprocessor.""" """Test the bash preprocessor."""
from xontrib.bashisms import bash_preproc from xontrib.bashisms import bash_preproc
xonsh_builtins.__xonsh_history__.inps = ['ls\n']
xonsh_builtins.__xonsh_history__.inps = ["ls\n"]
obs = bash_preproc(inp) obs = bash_preproc(inp)
assert exp == obs assert exp == obs

View file

@ -10,25 +10,37 @@ from ast import AST
import pytest import pytest
from xonsh import built_ins from xonsh import built_ins
from xonsh.built_ins import reglob, pathsearch, helper, superhelper, \ from xonsh.built_ins import (
ensure_list_of_strs, list_of_strs_or_callables, regexsearch, \ reglob,
globsearch, expand_path, convert_macro_arg, in_macro_call, call_macro, \ pathsearch,
enter_macro helper,
superhelper,
ensure_list_of_strs,
list_of_strs_or_callables,
regexsearch,
globsearch,
expand_path,
convert_macro_arg,
in_macro_call,
call_macro,
enter_macro,
)
from xonsh.environ import Env from xonsh.environ import Env
from tools import skip_if_on_windows from tools import skip_if_on_windows
HOME_PATH = os.path.expanduser('~') HOME_PATH = os.path.expanduser("~")
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def xonsh_execer_autouse(xonsh_execer): def xonsh_execer_autouse(xonsh_execer):
return xonsh_execer return xonsh_execer
@pytest.mark.parametrize('testfile', reglob('test_.*'))
@pytest.mark.parametrize("testfile", reglob("test_.*"))
def test_reglob_tests(testfile): def test_reglob_tests(testfile):
assert (testfile.startswith('test_')) assert testfile.startswith("test_")
@pytest.fixture @pytest.fixture
@ -41,252 +53,269 @@ def home_env(xonsh_builtins):
@skip_if_on_windows @skip_if_on_windows
def test_repath_backslash(home_env): def test_repath_backslash(home_env):
exp = os.listdir(HOME_PATH) exp = os.listdir(HOME_PATH)
exp = {p for p in exp if re.match(r'\w\w.*', p)} exp = {p for p in exp if re.match(r"\w\w.*", p)}
exp = {os.path.join(HOME_PATH, p) for p in exp} exp = {os.path.join(HOME_PATH, p) for p in exp}
obs = set(pathsearch(regexsearch, r'~/\w\w.*')) obs = set(pathsearch(regexsearch, r"~/\w\w.*"))
assert exp == obs assert exp == obs
@skip_if_on_windows @skip_if_on_windows
def test_repath_HOME_PATH_itself(home_env): def test_repath_HOME_PATH_itself(home_env):
exp = HOME_PATH exp = HOME_PATH
obs = pathsearch(regexsearch, '~') obs = pathsearch(regexsearch, "~")
assert 1 == len(obs) assert 1 == len(obs)
assert exp == obs[0] assert exp == obs[0]
@skip_if_on_windows @skip_if_on_windows
def test_repath_HOME_PATH_contents(home_env): def test_repath_HOME_PATH_contents(home_env):
exp = os.listdir(HOME_PATH) exp = os.listdir(HOME_PATH)
exp = {os.path.join(HOME_PATH, p) for p in exp} exp = {os.path.join(HOME_PATH, p) for p in exp}
obs = set(pathsearch(regexsearch, '~/.*')) obs = set(pathsearch(regexsearch, "~/.*"))
assert exp == obs assert exp == obs
@skip_if_on_windows @skip_if_on_windows
def test_repath_HOME_PATH_var(home_env): def test_repath_HOME_PATH_var(home_env):
exp = HOME_PATH exp = HOME_PATH
obs = pathsearch(regexsearch, '$HOME') obs = pathsearch(regexsearch, "$HOME")
assert 1 == len(obs) assert 1 == len(obs)
assert exp == obs[0] assert exp == obs[0]
@skip_if_on_windows @skip_if_on_windows
def test_repath_HOME_PATH_var_brace(home_env): def test_repath_HOME_PATH_var_brace(home_env):
exp = HOME_PATH exp = HOME_PATH
obs = pathsearch(regexsearch, '${"HOME"}') obs = pathsearch(regexsearch, '${"HOME"}')
assert 1 == len(obs) assert 1 == len(obs)
assert exp == obs[0] assert exp == obs[0]
def test_helper_int(home_env): def test_helper_int(home_env):
helper(int, 'int') helper(int, "int")
def test_helper_helper(home_env): def test_helper_helper(home_env):
helper(helper, 'helper') helper(helper, "helper")
def test_helper_env(home_env): def test_helper_env(home_env):
helper(Env, 'Env') helper(Env, "Env")
def test_superhelper_int(home_env): def test_superhelper_int(home_env):
superhelper(int, 'int') superhelper(int, "int")
def test_superhelper_helper(home_env): def test_superhelper_helper(home_env):
superhelper(helper, 'helper') superhelper(helper, "helper")
def test_superhelper_env(home_env): def test_superhelper_env(home_env):
superhelper(Env, 'Env') superhelper(Env, "Env")
@pytest.mark.parametrize('exp, inp', [ @pytest.mark.parametrize(
(['yo'], 'yo'), "exp, inp", [(["yo"], "yo"), (["yo"], ["yo"]), (["42"], 42), (["42"], [42])]
(['yo'], ['yo']), )
(['42'], 42),
(['42'], [42])
])
def test_ensure_list_of_strs(exp, inp): def test_ensure_list_of_strs(exp, inp):
obs = ensure_list_of_strs(inp) obs = ensure_list_of_strs(inp)
assert exp == obs assert exp == obs
f = lambda x: 20 f = lambda x: 20
@pytest.mark.parametrize('exp, inp', [
(['yo'], 'yo'),
(['yo'], ['yo']), @pytest.mark.parametrize(
(['42'], 42), "exp, inp",
(['42'], [42]), [
([f], f), (["yo"], "yo"),
([f], [f]) (["yo"], ["yo"]),
]) (["42"], 42),
(["42"], [42]),
([f], f),
([f], [f]),
],
)
def test_list_of_strs_or_callables(exp, inp): def test_list_of_strs_or_callables(exp, inp):
obs = list_of_strs_or_callables(inp) obs = list_of_strs_or_callables(inp)
assert exp == obs assert exp == obs
@pytest.mark.parametrize('s', [ @pytest.mark.parametrize(
'~', "s",
'~/', [
'x=~/place', "~",
'x=one:~/place', "~/",
'x=one:~/place:~/yo', "x=~/place",
'x=~/one:~/place:~/yo', "x=one:~/place",
]) "x=one:~/place:~/yo",
"x=~/one:~/place:~/yo",
],
)
def test_expand_path(s, home_env): def test_expand_path(s, home_env):
if os.sep != '/': if os.sep != "/":
s = s.replace('/', os.sep) s = s.replace("/", os.sep)
if os.pathsep != ':': if os.pathsep != ":":
s = s.replace(':', os.pathsep) s = s.replace(":", os.pathsep)
assert expand_path(s) == s.replace('~', HOME_PATH) assert expand_path(s) == s.replace("~", HOME_PATH)
@pytest.mark.parametrize('kind', [str, 's', 'S', 'str', 'string']) @pytest.mark.parametrize("kind", [str, "s", "S", "str", "string"])
def test_convert_macro_arg_str(kind): def test_convert_macro_arg_str(kind):
raw_arg = 'value' raw_arg = "value"
arg = convert_macro_arg(raw_arg, kind, None, None) arg = convert_macro_arg(raw_arg, kind, None, None)
assert arg is raw_arg assert arg is raw_arg
@pytest.mark.parametrize('kind', [AST, 'a', 'Ast']) @pytest.mark.parametrize("kind", [AST, "a", "Ast"])
def test_convert_macro_arg_ast(kind): def test_convert_macro_arg_ast(kind):
raw_arg = '42' raw_arg = "42"
arg = convert_macro_arg(raw_arg, kind, {}, None) arg = convert_macro_arg(raw_arg, kind, {}, None)
assert isinstance(arg, AST) assert isinstance(arg, AST)
@pytest.mark.parametrize('kind', [types.CodeType, compile, 'c', 'code', @pytest.mark.parametrize("kind", [types.CodeType, compile, "c", "code", "compile"])
'compile'])
def test_convert_macro_arg_code(kind): def test_convert_macro_arg_code(kind):
raw_arg = '42' raw_arg = "42"
arg = convert_macro_arg(raw_arg, kind, {}, None) arg = convert_macro_arg(raw_arg, kind, {}, None)
assert isinstance(arg, types.CodeType) assert isinstance(arg, types.CodeType)
@pytest.mark.parametrize('kind', [eval, None, 'v', 'eval']) @pytest.mark.parametrize("kind", [eval, None, "v", "eval"])
def test_convert_macro_arg_eval(kind): def test_convert_macro_arg_eval(kind):
# literals # literals
raw_arg = '42' raw_arg = "42"
arg = convert_macro_arg(raw_arg, kind, {}, None) arg = convert_macro_arg(raw_arg, kind, {}, None)
assert arg == 42 assert arg == 42
# exprs # exprs
raw_arg = 'x + 41' raw_arg = "x + 41"
arg = convert_macro_arg(raw_arg, kind, {}, {'x': 1}) arg = convert_macro_arg(raw_arg, kind, {}, {"x": 1})
assert arg == 42 assert arg == 42
@pytest.mark.parametrize('kind', [exec, 'x', 'exec']) @pytest.mark.parametrize("kind", [exec, "x", "exec"])
def test_convert_macro_arg_exec(kind): def test_convert_macro_arg_exec(kind):
# at global scope # at global scope
raw_arg = 'def f(x, y):\n return x + y' raw_arg = "def f(x, y):\n return x + y"
glbs = {} glbs = {}
arg = convert_macro_arg(raw_arg, kind, glbs, None) arg = convert_macro_arg(raw_arg, kind, glbs, None)
assert arg is None assert arg is None
assert 'f' in glbs assert "f" in glbs
assert glbs['f'](1, 41) == 42 assert glbs["f"](1, 41) == 42
# at local scope # at local scope
raw_arg = 'def g(z):\n return x + z\ny += 42' raw_arg = "def g(z):\n return x + z\ny += 42"
glbs = {'x': 40} glbs = {"x": 40}
locs = {'y': 1} locs = {"y": 1}
arg = convert_macro_arg(raw_arg, kind, glbs, locs) arg = convert_macro_arg(raw_arg, kind, glbs, locs)
assert arg is None assert arg is None
assert 'g' in locs assert "g" in locs
assert locs['g'](1) == 41 assert locs["g"](1) == 41
assert 'y' in locs assert "y" in locs
assert locs['y'] == 43 assert locs["y"] == 43
@pytest.mark.parametrize('kind', [type, 't', 'type']) @pytest.mark.parametrize("kind", [type, "t", "type"])
def test_convert_macro_arg_eval(kind): def test_convert_macro_arg_eval(kind):
# literals # literals
raw_arg = '42' raw_arg = "42"
arg = convert_macro_arg(raw_arg, kind, {}, None) arg = convert_macro_arg(raw_arg, kind, {}, None)
assert arg is int assert arg is int
# exprs # exprs
raw_arg = 'x + 41' raw_arg = "x + 41"
arg = convert_macro_arg(raw_arg, kind, {}, {'x': 1}) arg = convert_macro_arg(raw_arg, kind, {}, {"x": 1})
assert arg is int assert arg is int
def test_in_macro_call(): def test_in_macro_call():
def f(): def f():
pass pass
with in_macro_call(f, True, True): with in_macro_call(f, True, True):
assert f.macro_globals assert f.macro_globals
assert f.macro_locals assert f.macro_locals
assert not hasattr(f, 'macro_globals') assert not hasattr(f, "macro_globals")
assert not hasattr(f, 'macro_locals') assert not hasattr(f, "macro_locals")
@pytest.mark.parametrize('arg', ['x', '42', 'x + y']) @pytest.mark.parametrize("arg", ["x", "42", "x + y"])
def test_call_macro_str(arg): def test_call_macro_str(arg):
def f(x : str): def f(x: str):
return x return x
rtn = call_macro(f, [arg], None, None) rtn = call_macro(f, [arg], None, None)
assert rtn is arg assert rtn is arg
@pytest.mark.parametrize('arg', ['x', '42', 'x + y']) @pytest.mark.parametrize("arg", ["x", "42", "x + y"])
def test_call_macro_ast(arg): def test_call_macro_ast(arg):
def f(x : AST): def f(x: AST):
return x return x
rtn = call_macro(f, [arg], {}, None) rtn = call_macro(f, [arg], {}, None)
assert isinstance(rtn, AST) assert isinstance(rtn, AST)
@pytest.mark.parametrize('arg', ['x', '42', 'x + y']) @pytest.mark.parametrize("arg", ["x", "42", "x + y"])
def test_call_macro_code(arg): def test_call_macro_code(arg):
def f(x : compile): def f(x: compile):
return x return x
rtn = call_macro(f, [arg], {}, None) rtn = call_macro(f, [arg], {}, None)
assert isinstance(rtn, types.CodeType) assert isinstance(rtn, types.CodeType)
@pytest.mark.parametrize('arg', ['x', '42', 'x + y']) @pytest.mark.parametrize("arg", ["x", "42", "x + y"])
def test_call_macro_eval(arg): def test_call_macro_eval(arg):
def f(x : eval): def f(x: eval):
return x return x
rtn = call_macro(f, [arg], {'x': 42, 'y': 0}, None)
rtn = call_macro(f, [arg], {"x": 42, "y": 0}, None)
assert rtn == 42 assert rtn == 42
@pytest.mark.parametrize('arg', ['if y:\n pass', @pytest.mark.parametrize(
'if 42:\n pass', "arg", ["if y:\n pass", "if 42:\n pass", "if x + y:\n pass"]
'if x + y:\n pass']) )
def test_call_macro_exec(arg): def test_call_macro_exec(arg):
def f(x : exec): def f(x: exec):
return x return x
rtn = call_macro(f, [arg], {'x': 42, 'y': 0}, None)
rtn = call_macro(f, [arg], {"x": 42, "y": 0}, None)
assert rtn is None assert rtn is None
@pytest.mark.parametrize('arg', ['x', '42', 'x + y']) @pytest.mark.parametrize("arg", ["x", "42", "x + y"])
def test_call_macro_raw_arg(arg): def test_call_macro_raw_arg(arg):
def f(x : str): def f(x: str):
return x return x
rtn = call_macro(f, ['*', arg], {'x': 42, 'y': 0}, None)
rtn = call_macro(f, ["*", arg], {"x": 42, "y": 0}, None)
assert rtn == 42 assert rtn == 42
@pytest.mark.parametrize('arg', ['x', '42', 'x + y']) @pytest.mark.parametrize("arg", ["x", "42", "x + y"])
def test_call_macro_raw_kwarg(arg): def test_call_macro_raw_kwarg(arg):
def f(x : str): def f(x: str):
return x return x
rtn = call_macro(f, ['*', 'x=' + arg], {'x': 42, 'y': 0}, None)
rtn = call_macro(f, ["*", "x=" + arg], {"x": 42, "y": 0}, None)
assert rtn == 42 assert rtn == 42
@pytest.mark.parametrize('arg', ['x', '42', 'x + y']) @pytest.mark.parametrize("arg", ["x", "42", "x + y"])
def test_call_macro_raw_kwargs(arg): def test_call_macro_raw_kwargs(arg):
def f(x : str): def f(x: str):
return x return x
rtn = call_macro(f, ['*', '**{"x" :' + arg + '}'], {'x': 42, 'y': 0}, None)
rtn = call_macro(f, ["*", '**{"x" :' + arg + "}"], {"x": 42, "y": 0}, None)
assert rtn == 42 assert rtn == 42
def test_enter_macro(): def test_enter_macro():
obj = lambda: None obj = lambda: None
rtn = enter_macro(obj, 'wakka', True, True) rtn = enter_macro(obj, "wakka", True, True)
assert obj is rtn assert obj is rtn
assert obj.macro_block == 'wakka' assert obj.macro_block == "wakka"
assert obj.macro_globals assert obj.macro_globals
assert obj.macro_locals assert obj.macro_locals

View file

@ -3,85 +3,91 @@ import builtins
import pytest import pytest
from xonsh.commands_cache import (CommandsCache, predict_shell, from xonsh.commands_cache import (
SHELL_PREDICTOR_PARSER, predict_true, predict_false) CommandsCache,
predict_shell,
SHELL_PREDICTOR_PARSER,
predict_true,
predict_false,
)
from tools import skip_if_on_windows from tools import skip_if_on_windows
def test_commands_cache_lazy(xonsh_builtins): def test_commands_cache_lazy(xonsh_builtins):
cc = CommandsCache() cc = CommandsCache()
assert not cc.lazyin('xonsh') assert not cc.lazyin("xonsh")
assert 0 == len(list(cc.lazyiter())) assert 0 == len(list(cc.lazyiter()))
assert 0 == cc.lazylen() assert 0 == cc.lazylen()
TRUE_SHELL_ARGS = [ TRUE_SHELL_ARGS = [
['-c', 'yo'], ["-c", "yo"],
['-c=yo'], ["-c=yo"],
['file'], ["file"],
['-i', '-l', 'file'], ["-i", "-l", "file"],
['-i', '-c', 'yo'], ["-i", "-c", "yo"],
['-i', 'file'], ["-i", "file"],
['-i', '-c', 'yo', 'file'], ["-i", "-c", "yo", "file"],
] ]
@pytest.mark.parametrize('args', TRUE_SHELL_ARGS)
@pytest.mark.parametrize("args", TRUE_SHELL_ARGS)
def test_predict_shell_parser(args): def test_predict_shell_parser(args):
ns, unknown = SHELL_PREDICTOR_PARSER.parse_known_args(args) ns, unknown = SHELL_PREDICTOR_PARSER.parse_known_args(args)
if ns.filename is not None: if ns.filename is not None:
assert not ns.filename.startswith('-') assert not ns.filename.startswith("-")
@pytest.mark.parametrize('args', TRUE_SHELL_ARGS) @pytest.mark.parametrize("args", TRUE_SHELL_ARGS)
def test_predict_shell_true(args): def test_predict_shell_true(args):
assert predict_shell(args) assert predict_shell(args)
FALSE_SHELL_ARGS = [ FALSE_SHELL_ARGS = [[], ["-c"], ["-i"], ["-i", "-l"]]
[],
['-c'],
['-i'],
['-i', '-l'],
]
@pytest.mark.parametrize('args', FALSE_SHELL_ARGS)
@pytest.mark.parametrize("args", FALSE_SHELL_ARGS)
def test_predict_shell_false(args): def test_predict_shell_false(args):
assert not predict_shell(args) assert not predict_shell(args)
PATTERN_BIN_USING_TTY_OR_NOT = [ PATTERN_BIN_USING_TTY_OR_NOT = [
(False, {10: b'isnotatty'}), (False, {10: b"isnotatty"}),
(False, {12: b'isatty'}), (False, {12: b"isatty"}),
(False, {151: b'gpm'}), (False, {151: b"gpm"}),
(False, {10: b'isatty', 100: b'tcgetattr', }), (False, {10: b"isatty", 100: b"tcgetattr"}),
(False, {10: b'isatty', 100: b'tcsetattr'}), (False, {10: b"isatty", 100: b"tcsetattr"}),
(True, {10: b'isatty', 100: b'tcsetattr', 1000: b'tcgetattr'}), (True, {10: b"isatty", 100: b"tcsetattr", 1000: b"tcgetattr"}),
(True, {1000: b'libncurses'}), (True, {1000: b"libncurses"}),
(True, {4094: b'libgpm'}), (True, {4094: b"libgpm"}),
(True, {2045: b'tcgetattr', 4095: b'tcgetattr', 6140: b'tcsetattr', (
8190: b'isatty'}), True,
{2045: b"tcgetattr", 4095: b"tcgetattr", 6140: b"tcsetattr", 8190: b"isatty"},
),
] ]
@pytest.mark.parametrize('args', PATTERN_BIN_USING_TTY_OR_NOT) @pytest.mark.parametrize("args", PATTERN_BIN_USING_TTY_OR_NOT)
@skip_if_on_windows @skip_if_on_windows
def test_commands_cache_predictor_default(args): def test_commands_cache_predictor_default(args):
cc = CommandsCache() cc = CommandsCache()
use_tty, patterns = args use_tty, patterns = args
f = open('testfile', 'wb') f = open("testfile", "wb")
where = list(patterns.keys()) where = list(patterns.keys())
where.sort() where.sort()
pos = 0 pos = 0
for w in where: for w in where:
f.write(b'\x20' * (w - pos)) f.write(b"\x20" * (w - pos))
f.write(patterns[w]) f.write(patterns[w])
pos = w + len(patterns[w]) pos = w + len(patterns[w])
f.write(b'\x20' * (pos // 2)) f.write(b"\x20" * (pos // 2))
f.close() f.close()
result = cc.default_predictor_readbin('', os.getcwd() + os.sep + 'testfile', result = cc.default_predictor_readbin(
timeout=1, failure=None) "", os.getcwd() + os.sep + "testfile", timeout=1, failure=None
)
expected = predict_false if use_tty else predict_true expected = predict_false if use_tty else predict_true
assert result == expected assert result == expected
@ -89,25 +95,25 @@ def test_commands_cache_predictor_default(args):
@skip_if_on_windows @skip_if_on_windows
def test_cd_is_only_functional_alias(xonsh_builtins): def test_cd_is_only_functional_alias(xonsh_builtins):
cc = CommandsCache() cc = CommandsCache()
builtins.aliases['cd'] = lambda args: os.chdir(args[0]) builtins.aliases["cd"] = lambda args: os.chdir(args[0])
assert cc.is_only_functional_alias('cd') assert cc.is_only_functional_alias("cd")
def test_non_exist_is_only_functional_alias(xonsh_builtins): def test_non_exist_is_only_functional_alias(xonsh_builtins):
cc = CommandsCache() cc = CommandsCache()
assert not cc.is_only_functional_alias('<not really a command name>') assert not cc.is_only_functional_alias("<not really a command name>")
@skip_if_on_windows @skip_if_on_windows
def test_bash_is_only_functional_alias(xonsh_builtins): def test_bash_is_only_functional_alias(xonsh_builtins):
builtins.__xonsh_env__['PATH'] = os.environ['PATH'].split(os.pathsep) builtins.__xonsh_env__["PATH"] = os.environ["PATH"].split(os.pathsep)
cc = CommandsCache() cc = CommandsCache()
assert not cc.is_only_functional_alias('bash') assert not cc.is_only_functional_alias("bash")
@skip_if_on_windows @skip_if_on_windows
def test_bash_and_is_alias_is_only_functional_alias(xonsh_builtins): def test_bash_and_is_alias_is_only_functional_alias(xonsh_builtins):
builtins.__xonsh_env__['PATH'] = os.environ['PATH'].split(os.pathsep) builtins.__xonsh_env__["PATH"] = os.environ["PATH"].split(os.pathsep)
cc = CommandsCache() cc = CommandsCache()
builtins.aliases['bash'] = lambda args: os.chdir(args[0]) builtins.aliases["bash"] = lambda args: os.chdir(args[0])
assert not cc.is_only_functional_alias('bash') assert not cc.is_only_functional_alias("bash")

View file

@ -11,31 +11,33 @@ import pytest
def xonsh_execer_autouse(xonsh_builtins, xonsh_execer): def xonsh_execer_autouse(xonsh_builtins, xonsh_execer):
return xonsh_execer return xonsh_execer
# #
# helpers # helpers
# #
X1_WITH = ('x = 1\n' X1_WITH = "x = 1\n" "with! Block() as b:\n"
'with! Block() as b:\n') SIMPLE_WITH = "with! Block() as b:\n"
SIMPLE_WITH = 'with! Block() as b:\n' FUNC_WITH = (
FUNC_WITH = ('x = 1\n' "x = 1\n"
'def func():\n' "def func():\n"
' y = 1\n' " y = 1\n"
' with! Block() as b:\n' " with! Block() as b:\n"
'{body}' "{body}"
' y += 1\n' " y += 1\n"
' return b\n' " return b\n"
'x += 1\n' "x += 1\n"
'rtn = func()\n' "rtn = func()\n"
'x += 1\n') "x += 1\n"
)
FUNC_OBSG = {'x': 3} FUNC_OBSG = {"x": 3}
FUNC_OBSL = {'y': 1} FUNC_OBSL = {"y": 1}
def norm_body(body): def norm_body(body):
if not isinstance(body, str): if not isinstance(body, str):
body = '\n'.join(body) body = "\n".join(body)
body = dedent(body) body = dedent(body)
body = body.splitlines() body = body.splitlines()
return body return body
@ -72,276 +74,248 @@ def block_checks_func(name, glbs, body, obsg=None, obsl=None):
# Block tests # Block tests
# #
def test_block_noexec(): def test_block_noexec():
s = ('x = 1\n' s = "x = 1\n" "with! Block():\n" " x += 42\n"
'with! Block():\n' glbs = {"Block": Block}
' x += 42\n')
glbs = {'Block': Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
assert 1 == glbs['x'] assert 1 == glbs["x"]
def test_block_oneline(): def test_block_oneline():
body = ' x += 42\n' body = " x += 42\n"
s = X1_WITH + body s = X1_WITH + body
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('b', glbs, body, {'x': 1}) block_checks_glb("b", glbs, body, {"x": 1})
def test_block_manylines(): def test_block_manylines():
body = (' ![echo wow mom]\n' body = " ![echo wow mom]\n" "# bad place for a comment\n" " x += 42"
'# bad place for a comment\n'
' x += 42')
s = X1_WITH + body s = X1_WITH + body
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('b', glbs, body, {'x': 1}) block_checks_glb("b", glbs, body, {"x": 1})
def test_block_leading_comment(): def test_block_leading_comment():
# leading comments do not show up in block lines # leading comments do not show up in block lines
body = (' # I am a leading comment\n' body = " # I am a leading comment\n" " x += 42\n"
' x += 42\n')
s = X1_WITH + body s = X1_WITH + body
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('b', glbs, [' x += 42'], {'x': 1}) block_checks_glb("b", glbs, [" x += 42"], {"x": 1})
def test_block_trailing_comment(): def test_block_trailing_comment():
# trailing comments show up in block lines # trailing comments show up in block lines
body = (' x += 42\n' body = " x += 42\n" " # I am a trailing comment\n"
' # I am a trailing comment\n')
s = X1_WITH + body s = X1_WITH + body
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('b', glbs, body, {'x': 1}) block_checks_glb("b", glbs, body, {"x": 1})
def test_block_trailing_line_continuation(): def test_block_trailing_line_continuation():
body = (' x += \\\n' body = " x += \\\n" " 42\n"
' 42\n')
s = X1_WITH + body s = X1_WITH + body
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('b', glbs, body, {'x': 1}) block_checks_glb("b", glbs, body, {"x": 1})
def test_block_trailing_close_paren(): def test_block_trailing_close_paren():
body = (' x += int("42"\n' body = ' x += int("42"\n' " )\n"
' )\n')
s = X1_WITH + body s = X1_WITH + body
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('b', glbs, body, {'x': 1}) block_checks_glb("b", glbs, body, {"x": 1})
def test_block_trailing_close_many(): def test_block_trailing_close_many():
body = (' x = {None: [int("42"\n' body = (
' )\n' ' x = {None: [int("42"\n'
' ]\n' " )\n"
' }\n') " ]\n"
" }\n"
)
s = SIMPLE_WITH + body s = SIMPLE_WITH + body
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('b', glbs, body) block_checks_glb("b", glbs, body)
def test_block_trailing_triple_string(): def test_block_trailing_triple_string():
body = (' x = """This\n' body = ' x = """This\n' "is\n" '"probably"\n' "'not' what I meant.\n" '"""\n'
'is\n'
'"probably"\n'
'\'not\' what I meant.\n'
'"""\n')
s = SIMPLE_WITH + body s = SIMPLE_WITH + body
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('b', glbs, body) block_checks_glb("b", glbs, body)
def test_block_func_oneline(): def test_block_func_oneline():
body = ' x += 42\n' body = " x += 42\n"
s = FUNC_WITH.format(body=body) s = FUNC_WITH.format(body=body)
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL) block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
def test_block_func_manylines(): def test_block_func_manylines():
body = (' ![echo wow mom]\n' body = " ![echo wow mom]\n" "# bad place for a comment\n" " x += 42\n"
'# bad place for a comment\n'
' x += 42\n')
s = FUNC_WITH.format(body=body) s = FUNC_WITH.format(body=body)
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL) block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
def test_block_func_leading_comment(): def test_block_func_leading_comment():
# leading comments do not show up in block lines # leading comments do not show up in block lines
body = (' # I am a leading comment\n' body = " # I am a leading comment\n" " x += 42\n"
' x += 42\n')
s = FUNC_WITH.format(body=body) s = FUNC_WITH.format(body=body)
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_func('rtn', glbs, ' x += 42\n', block_checks_func("rtn", glbs, " x += 42\n", FUNC_OBSG, FUNC_OBSL)
FUNC_OBSG, FUNC_OBSL)
def test_block_func_trailing_comment(): def test_block_func_trailing_comment():
# trailing comments show up in block lines # trailing comments show up in block lines
body = (' x += 42\n' body = " x += 42\n" " # I am a trailing comment\n"
' # I am a trailing comment\n')
s = FUNC_WITH.format(body=body) s = FUNC_WITH.format(body=body)
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL) block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
def test_blockfunc__trailing_line_continuation(): def test_blockfunc__trailing_line_continuation():
body = (' x += \\\n' body = " x += \\\n" " 42\n"
' 42\n')
s = FUNC_WITH.format(body=body) s = FUNC_WITH.format(body=body)
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL) block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
def test_block_func_trailing_close_paren(): def test_block_func_trailing_close_paren():
body = (' x += int("42"\n' body = ' x += int("42"\n' " )\n"
' )\n')
s = FUNC_WITH.format(body=body) s = FUNC_WITH.format(body=body)
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL) block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
def test_block_func_trailing_close_many(): def test_block_func_trailing_close_many():
body = (' x = {None: [int("42"\n' body = (
' )\n' ' x = {None: [int("42"\n'
' ]\n' " )\n"
' }\n') " ]\n"
" }\n"
)
s = FUNC_WITH.format(body=body) s = FUNC_WITH.format(body=body)
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL) block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
def test_block_func_trailing_triple_string(): def test_block_func_trailing_triple_string():
body = (' x = """This\n' body = ' x = """This\n' "is\n" '"probably"\n' "'not' what I meant.\n" '"""\n'
'is\n'
'"probably"\n'
'\'not\' what I meant.\n'
'"""\n')
s = FUNC_WITH.format(body=body) s = FUNC_WITH.format(body=body)
glbs = {'Block': Block} glbs = {"Block": Block}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_func('rtn', glbs, body, FUNC_OBSG, FUNC_OBSL) block_checks_func("rtn", glbs, body, FUNC_OBSG, FUNC_OBSL)
# #
# Functor tests # Functor tests
# #
X2_WITH = ('{var} = 1\n' X2_WITH = "{var} = 1\n" "with! Functor() as f:\n" "{body}" "{var} += 1\n" "{calls}\n"
'with! Functor() as f:\n'
'{body}'
'{var} += 1\n'
'{calls}\n'
)
def test_functor_oneline_onecall_class(): def test_functor_oneline_onecall_class():
body = (' global y\n' body = " global y\n" " y += 42\n"
' y += 42\n') calls = "f()"
calls = 'f()' s = X2_WITH.format(body=body, calls=calls, var="y")
s = X2_WITH.format(body=body, calls=calls, var='y') glbs = {"Functor": Functor}
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('f', glbs, body, {'y': 44}) block_checks_glb("f", glbs, body, {"y": 44})
def test_functor_oneline_onecall_func(): def test_functor_oneline_onecall_func():
body = (' global z\n' body = " global z\n" " z += 42\n"
' z += 42\n') calls = "f.func()"
calls = 'f.func()' s = X2_WITH.format(body=body, calls=calls, var="z")
s = X2_WITH.format(body=body, calls=calls, var='z') glbs = {"Functor": Functor}
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('f', glbs, body, {'z': 44}) block_checks_glb("f", glbs, body, {"z": 44})
def test_functor_oneline_onecall_both(): def test_functor_oneline_onecall_both():
body = (' global x\n' body = " global x\n" " x += 42\n"
' x += 42\n') calls = "f()\nf.func()"
calls = 'f()\nf.func()' s = X2_WITH.format(body=body, calls=calls, var="x")
s = X2_WITH.format(body=body, calls=calls, var='x') glbs = {"Functor": Functor}
glbs = {'Functor': Functor}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('f', glbs, body, {'x': 86}) block_checks_glb("f", glbs, body, {"x": 86})
XA_WITH = ('x = [1]\n' XA_WITH = "x = [1]\n" "with! Functor() as f:\n" "{body}" "x.append(2)\n" "{calls}\n"
'with! Functor() as f:\n'
'{body}'
'x.append(2)\n'
'{calls}\n'
)
def test_functor_oneline_append(): def test_functor_oneline_append():
body = ' x.append(3)\n' body = " x.append(3)\n"
calls = 'f()\n' calls = "f()\n"
s = XA_WITH.format(body=body, calls=calls) s = XA_WITH.format(body=body, calls=calls)
glbs = {'Functor': Functor} glbs = {"Functor": Functor}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('f', glbs, body, {'x': [1, 2, 3]}) block_checks_glb("f", glbs, body, {"x": [1, 2, 3]})
def test_functor_return(): def test_functor_return():
body = ' x = 42' body = " x = 42"
t = ('res = 0\n' t = "res = 0\n" 'with! Functor(rtn="x") as f:\n' "{body}\n" "res = f()\n"
'with! Functor(rtn="x") as f:\n'
'{body}\n'
'res = f()\n')
s = t.format(body=body) s = t.format(body=body)
glbs = {'Functor': Functor} glbs = {"Functor": Functor}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('f', glbs, body, {'res': 42}) block_checks_glb("f", glbs, body, {"res": 42})
def test_functor_args(): def test_functor_args():
body = ' x = 42 + a' body = " x = 42 + a"
t = ('res = 0\n' t = (
'with! Functor(args=("a",), rtn="x") as f:\n' "res = 0\n"
'{body}\n' 'with! Functor(args=("a",), rtn="x") as f:\n'
'res = f(2)\n') "{body}\n"
"res = f(2)\n"
)
s = t.format(body=body) s = t.format(body=body)
glbs = {'Functor': Functor} glbs = {"Functor": Functor}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('f', glbs, body, {'res': 44}) block_checks_glb("f", glbs, body, {"res": 44})
def test_functor_kwargs(): def test_functor_kwargs():
body = ' x = 42 + a + b' body = " x = 42 + a + b"
t = ('res = 0\n' t = (
'with! Functor(kwargs={{"a": 1, "b": 12}}, rtn="x") as f:\n' "res = 0\n"
'{body}\n' 'with! Functor(kwargs={{"a": 1, "b": 12}}, rtn="x") as f:\n'
'res = f(b=6)\n') "{body}\n"
"res = f(b=6)\n"
)
s = t.format(body=body) s = t.format(body=body)
glbs = {'Functor': Functor} glbs = {"Functor": Functor}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('f', glbs, body, {'res': 49}) block_checks_glb("f", glbs, body, {"res": 49})
def test_functor_fullsig(): def test_functor_fullsig():
body = ' x = 42 + a + b + c' body = " x = 42 + a + b + c"
t = ('res = 0\n' t = (
'with! Functor(args=("c",), kwargs={{"a": 1, "b": 12}}, rtn="x") as f:\n' "res = 0\n"
'{body}\n' 'with! Functor(args=("c",), kwargs={{"a": 1, "b": 12}}, rtn="x") as f:\n'
'res = f(55)\n') "{body}\n"
"res = f(55)\n"
)
s = t.format(body=body) s = t.format(body=body)
glbs = {'Functor': Functor} glbs = {"Functor": Functor}
check_exec(s, glbs=glbs, locs=None) check_exec(s, glbs=glbs, locs=None)
block_checks_glb('f', glbs, body, {'res': 110}) block_checks_glb("f", glbs, body, {"res": 110})

View file

@ -17,6 +17,7 @@ from xonsh.built_ins import load_builtins
HERE = os.path.abspath(os.path.dirname(__file__)) HERE = os.path.abspath(os.path.dirname(__file__))
PARENT = os.path.dirname(HERE) PARENT = os.path.dirname(HERE)
@contextmanager @contextmanager
def chdir(adir): def chdir(adir):
old_dir = os.getcwd() old_dir = os.getcwd()
@ -28,17 +29,17 @@ def chdir(adir):
def test_simple(xonsh_builtins): def test_simple(xonsh_builtins):
xonsh_builtins.__xonsh_env__ = Env(CDPATH=PARENT, PWD=PARENT) xonsh_builtins.__xonsh_env__ = Env(CDPATH=PARENT, PWD=PARENT)
with chdir(PARENT): with chdir(PARENT):
assert os.getcwd() != HERE assert os.getcwd() != HERE
dirstack.cd(["tests"]) dirstack.cd(["tests"])
assert os.getcwd() == HERE assert os.getcwd() == HERE
def test_cdpath_simple(xonsh_builtins): def test_cdpath_simple(xonsh_builtins):
xonsh_builtins.__xonsh_env__ = Env(CDPATH=PARENT, PWD=HERE) xonsh_builtins.__xonsh_env__ = Env(CDPATH=PARENT, PWD=HERE)
with chdir(os.path.normpath("/")): with chdir(os.path.normpath("/")):
assert os.getcwd() != HERE assert os.getcwd() != HERE
dirstack.cd(["tests"]) dirstack.cd(["tests"])
assert os.getcwd() == HERE assert os.getcwd() == HERE
def test_cdpath_collision(xonsh_builtins): def test_cdpath_collision(xonsh_builtins):
@ -49,20 +50,22 @@ def test_cdpath_collision(xonsh_builtins):
with chdir(HERE): with chdir(HERE):
assert os.getcwd() == HERE assert os.getcwd() == HERE
dirstack.cd(["tests"]) dirstack.cd(["tests"])
assert os.getcwd() == os.path.join(HERE, "tests") assert os.getcwd() == os.path.join(HERE, "tests")
def test_cdpath_expansion(xonsh_builtins): def test_cdpath_expansion(xonsh_builtins):
xonsh_builtins.__xonsh_env__ = Env(HERE=HERE, CDPATH=("~", "$HERE")) xonsh_builtins.__xonsh_env__ = Env(HERE=HERE, CDPATH=("~", "$HERE"))
test_dirs = ( test_dirs = (
os.path.join(HERE, "xonsh-test-cdpath-here"), os.path.join(HERE, "xonsh-test-cdpath-here"),
os.path.expanduser("~/xonsh-test-cdpath-home") os.path.expanduser("~/xonsh-test-cdpath-home"),
) )
try: try:
for d in test_dirs: for d in test_dirs:
if not os.path.exists(d): if not os.path.exists(d):
os.mkdir(d) os.mkdir(d)
assert os.path.exists(dirstack._try_cdpath(d)), "dirstack._try_cdpath: could not resolve {0}".format(d) assert os.path.exists(
dirstack._try_cdpath(d)
), "dirstack._try_cdpath: could not resolve {0}".format(d)
finally: finally:
for d in test_dirs: for d in test_dirs:
if os.path.exists(d): if os.path.exists(d):
@ -74,6 +77,7 @@ def test_cdpath_events(xonsh_builtins, tmpdir):
target = str(tmpdir) target = str(tmpdir)
ev = None ev = None
@xonsh_builtins.events.on_chdir @xonsh_builtins.events.on_chdir
def handler(olddir, newdir, **kw): def handler(olddir, newdir, **kw):
nonlocal ev nonlocal ev

View file

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Testing dirstack""" """Testing dirstack"""
#from __future__ import unicode_literals, print_function # from __future__ import unicode_literals, print_function
from contextlib import contextmanager from contextlib import contextmanager
from functools import wraps from functools import wraps
@ -22,16 +22,19 @@ PARENT = os.path.dirname(HERE)
def drive_in_use(letter): def drive_in_use(letter):
return ON_WINDOWS and os.system('vol {}: 2>nul>nul'.format(letter)) == 0 return ON_WINDOWS and os.system("vol {}: 2>nul>nul".format(letter)) == 0
MAX_TEMP_DRIVES = 4 MAX_TEMP_DRIVES = 4
TEMP_DRIVE = [] TEMP_DRIVE = []
for d in 'zyxwvuts': for d in "zyxwvuts":
if not drive_in_use(d): if not drive_in_use(d):
TEMP_DRIVE.append(d + ':') TEMP_DRIVE.append(d + ":")
pytestmark = pytest.mark.skipif(len(TEMP_DRIVE) < MAX_TEMP_DRIVES, pytestmark = pytest.mark.skipif(
reason='Too many drive letters are already used by Windows to run the tests.') len(TEMP_DRIVE) < MAX_TEMP_DRIVES,
reason="Too many drive letters are already used by Windows to run the tests.",
)
@pytest.yield_fixture(scope="module") @pytest.yield_fixture(scope="module")
@ -46,32 +49,44 @@ def shares_setup(tmpdir_factory):
if not ON_WINDOWS: if not ON_WINDOWS:
return [] return []
shares = [[r'uncpushd_test_HERE', TEMP_DRIVE[1], HERE] shares = [
, [r'uncpushd_test_PARENT', TEMP_DRIVE[3], PARENT]] [r"uncpushd_test_HERE", TEMP_DRIVE[1], HERE],
[r"uncpushd_test_PARENT", TEMP_DRIVE[3], PARENT],
]
for s, d, l in shares: # set up some shares on local machine. dirs already exist test case must invoke wd_setup. for (
rtn = subprocess.call(['NET', 'SHARE', s, '/delete'], universal_newlines=True) # clean up from previous run after good, long wait. s,
d,
l,
) in (
shares
): # set up some shares on local machine. dirs already exist test case must invoke wd_setup.
rtn = subprocess.call(
["NET", "SHARE", s, "/delete"], universal_newlines=True
) # clean up from previous run after good, long wait.
if rtn != 0: if rtn != 0:
yield None yield None
return return
rtn = subprocess.call(['NET', 'SHARE', s + '=' + l], universal_newlines=True) rtn = subprocess.call(["NET", "SHARE", s + "=" + l], universal_newlines=True)
if rtn != 0: if rtn != 0:
yield None yield None
return return
rtn = subprocess.call(['NET', 'USE', d, r"\\localhost" + '\\' + s], universal_newlines=True) rtn = subprocess.call(
["NET", "USE", d, r"\\localhost" + "\\" + s], universal_newlines=True
)
if rtn != 0: if rtn != 0:
yield None yield None
return return
yield [[r"\\localhost" + '\\' + s[0], s[1], s[2]] for s in shares] yield [[r"\\localhost" + "\\" + s[0], s[1], s[2]] for s in shares]
# we want to delete the test shares we've created, but can't do that if unc shares in DIRSTACK # we want to delete the test shares we've created, but can't do that if unc shares in DIRSTACK
# (left over from assert fail aborted test) # (left over from assert fail aborted test)
os.chdir(HERE) os.chdir(HERE)
for dl in _unc_tempDrives: for dl in _unc_tempDrives:
rtn = subprocess.call(['net', 'use', dl, '/delete'], universal_newlines=True) rtn = subprocess.call(["net", "use", dl, "/delete"], universal_newlines=True)
for s, d, l in shares: for s, d, l in shares:
rtn = subprocess.call(['net', 'use', d, '/delete'], universal_newlines=True) rtn = subprocess.call(["net", "use", d, "/delete"], universal_newlines=True)
# subprocess.call(['net', 'share', s, '/delete'], universal_newlines=True) # fails with access denied, # subprocess.call(['net', 'share', s, '/delete'], universal_newlines=True) # fails with access denied,
# unless I wait > 10 sec. see http://stackoverflow.com/questions/38448413/access-denied-in-net-share-delete # unless I wait > 10 sec. see http://stackoverflow.com/questions/38448413/access-denied-in-net-share-delete
@ -83,7 +98,7 @@ def test_pushdpopd(xonsh_builtins):
dirstack.cd([PARENT]) dirstack.cd([PARENT])
owd = os.getcwd() owd = os.getcwd()
assert owd.casefold() == xonsh_builtins.__xonsh_env__['PWD'].casefold() assert owd.casefold() == xonsh_builtins.__xonsh_env__["PWD"].casefold()
dirstack.pushd([HERE]) dirstack.pushd([HERE])
wd = os.getcwd() wd = os.getcwd()
assert wd.casefold() == HERE.casefold() assert wd.casefold() == HERE.casefold()
@ -95,22 +110,22 @@ def test_cd_dot(xonsh_builtins):
xonsh_builtins.__xonsh_env__ = Env(PWD=os.getcwd()) xonsh_builtins.__xonsh_env__ = Env(PWD=os.getcwd())
owd = os.getcwd().casefold() owd = os.getcwd().casefold()
dirstack.cd(['.']) dirstack.cd(["."])
assert owd == os.getcwd().casefold() assert owd == os.getcwd().casefold()
@pytest.mark.skipif( not ON_WINDOWS, reason="Windows-only UNC functionality") @pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality")
def test_uncpushd_simple_push_pop(xonsh_builtins, shares_setup): def test_uncpushd_simple_push_pop(xonsh_builtins, shares_setup):
if shares_setup is None: if shares_setup is None:
return return
xonsh_builtins.__xonsh_env__ = Env(CDPATH=PARENT, PWD=HERE) xonsh_builtins.__xonsh_env__ = Env(CDPATH=PARENT, PWD=HERE)
dirstack.cd([PARENT]) dirstack.cd([PARENT])
owd = os.getcwd() owd = os.getcwd()
assert owd.casefold() == xonsh_builtins.__xonsh_env__['PWD'].casefold() assert owd.casefold() == xonsh_builtins.__xonsh_env__["PWD"].casefold()
dirstack.pushd([r'\\localhost\uncpushd_test_HERE']) dirstack.pushd([r"\\localhost\uncpushd_test_HERE"])
wd = os.getcwd() wd = os.getcwd()
assert os.path.splitdrive(wd)[0].casefold() == TEMP_DRIVE[0] assert os.path.splitdrive(wd)[0].casefold() == TEMP_DRIVE[0]
assert os.path.splitdrive(wd)[1].casefold() == '\\' assert os.path.splitdrive(wd)[1].casefold() == "\\"
dirstack.popd([]) dirstack.popd([])
assert owd.casefold() == os.getcwd().casefold(), "popd returned cwd to expected dir" assert owd.casefold() == os.getcwd().casefold(), "popd returned cwd to expected dir"
assert len(_unc_tempDrives) == 0 assert len(_unc_tempDrives) == 0
@ -124,29 +139,31 @@ def test_uncpushd_push_to_same_share(xonsh_builtins, shares_setup):
dirstack.cd([PARENT]) dirstack.cd([PARENT])
owd = os.getcwd() owd = os.getcwd()
assert owd.casefold() == xonsh_builtins.__xonsh_env__['PWD'].casefold() assert owd.casefold() == xonsh_builtins.__xonsh_env__["PWD"].casefold()
dirstack.pushd([r'\\localhost\uncpushd_test_HERE']) dirstack.pushd([r"\\localhost\uncpushd_test_HERE"])
wd = os.getcwd() wd = os.getcwd()
assert os.path.splitdrive(wd)[0].casefold() == TEMP_DRIVE[0] assert os.path.splitdrive(wd)[0].casefold() == TEMP_DRIVE[0]
assert os.path.splitdrive(wd)[1].casefold() == '\\' assert os.path.splitdrive(wd)[1].casefold() == "\\"
assert len(_unc_tempDrives) == 1 assert len(_unc_tempDrives) == 1
assert len(DIRSTACK) == 1 assert len(DIRSTACK) == 1
dirstack.pushd([r'\\localhost\uncpushd_test_HERE']) dirstack.pushd([r"\\localhost\uncpushd_test_HERE"])
wd = os.getcwd() wd = os.getcwd()
assert os.path.splitdrive(wd)[0].casefold() == TEMP_DRIVE[0] assert os.path.splitdrive(wd)[0].casefold() == TEMP_DRIVE[0]
assert os.path.splitdrive(wd)[1].casefold() == '\\' assert os.path.splitdrive(wd)[1].casefold() == "\\"
assert len(_unc_tempDrives) == 1 assert len(_unc_tempDrives) == 1
assert len(DIRSTACK) == 2 assert len(DIRSTACK) == 2
dirstack.popd([]) dirstack.popd([])
assert os.path.isdir(TEMP_DRIVE[0] + '\\'), "Temp drive not unmapped till last reference removed" assert os.path.isdir(
TEMP_DRIVE[0] + "\\"
), "Temp drive not unmapped till last reference removed"
dirstack.popd([]) dirstack.popd([])
assert owd.casefold() == os.getcwd().casefold(), "popd returned cwd to expected dir" assert owd.casefold() == os.getcwd().casefold(), "popd returned cwd to expected dir"
assert len(_unc_tempDrives) == 0 assert len(_unc_tempDrives) == 0
@pytest.mark.skipif( not ON_WINDOWS, reason="Windows-only UNC functionality") @pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality")
def test_uncpushd_push_other_push_same(xonsh_builtins, shares_setup): def test_uncpushd_push_other_push_same(xonsh_builtins, shares_setup):
"""push to a, then to b. verify drive letter is TEMP_DRIVE[2], skipping already used TEMP_DRIVE[1] """push to a, then to b. verify drive letter is TEMP_DRIVE[2], skipping already used TEMP_DRIVE[1]
Then push to a again. Pop (check b unmapped and a still mapped), pop, pop (check a is unmapped)""" Then push to a again. Pop (check b unmapped and a still mapped), pop, pop (check a is unmapped)"""
@ -156,43 +173,43 @@ def test_uncpushd_push_other_push_same(xonsh_builtins, shares_setup):
dirstack.cd([PARENT]) dirstack.cd([PARENT])
owd = os.getcwd() owd = os.getcwd()
assert owd.casefold() == xonsh_builtins.__xonsh_env__['PWD'].casefold() assert owd.casefold() == xonsh_builtins.__xonsh_env__["PWD"].casefold()
dirstack.pushd([r'\\localhost\uncpushd_test_HERE']) dirstack.pushd([r"\\localhost\uncpushd_test_HERE"])
assert os.getcwd().casefold() == TEMP_DRIVE[0] + '\\' assert os.getcwd().casefold() == TEMP_DRIVE[0] + "\\"
assert len(_unc_tempDrives) == 1 assert len(_unc_tempDrives) == 1
assert len(DIRSTACK) == 1 assert len(DIRSTACK) == 1
dirstack.pushd([r'\\localhost\uncpushd_test_PARENT']) dirstack.pushd([r"\\localhost\uncpushd_test_PARENT"])
wd = os.getcwd() wd = os.getcwd()
assert os.getcwd().casefold() == TEMP_DRIVE[2] + '\\' assert os.getcwd().casefold() == TEMP_DRIVE[2] + "\\"
assert len(_unc_tempDrives) == 2 assert len(_unc_tempDrives) == 2
assert len(DIRSTACK) == 2 assert len(DIRSTACK) == 2
dirstack.pushd([r'\\localhost\uncpushd_test_HERE']) dirstack.pushd([r"\\localhost\uncpushd_test_HERE"])
assert os.getcwd().casefold() == TEMP_DRIVE[0] + '\\' assert os.getcwd().casefold() == TEMP_DRIVE[0] + "\\"
assert len(_unc_tempDrives) == 2 assert len(_unc_tempDrives) == 2
assert len(DIRSTACK) == 3 assert len(DIRSTACK) == 3
dirstack.popd([]) dirstack.popd([])
assert os.getcwd().casefold() == TEMP_DRIVE[2] + '\\' assert os.getcwd().casefold() == TEMP_DRIVE[2] + "\\"
assert len(_unc_tempDrives) == 2 assert len(_unc_tempDrives) == 2
assert len(DIRSTACK) == 2 assert len(DIRSTACK) == 2
assert os.path.isdir(TEMP_DRIVE[2] + '\\') assert os.path.isdir(TEMP_DRIVE[2] + "\\")
assert os.path.isdir(TEMP_DRIVE[0] + '\\') assert os.path.isdir(TEMP_DRIVE[0] + "\\")
dirstack.popd([]) dirstack.popd([])
assert os.getcwd().casefold() == TEMP_DRIVE[0] + '\\' assert os.getcwd().casefold() == TEMP_DRIVE[0] + "\\"
assert len(_unc_tempDrives) == 1 assert len(_unc_tempDrives) == 1
assert len(DIRSTACK) == 1 assert len(DIRSTACK) == 1
assert not os.path.isdir(TEMP_DRIVE[2] + '\\') assert not os.path.isdir(TEMP_DRIVE[2] + "\\")
assert os.path.isdir(TEMP_DRIVE[0] + '\\') assert os.path.isdir(TEMP_DRIVE[0] + "\\")
dirstack.popd([]) dirstack.popd([])
assert os.getcwd().casefold() == owd.casefold() assert os.getcwd().casefold() == owd.casefold()
assert len(_unc_tempDrives) == 0 assert len(_unc_tempDrives) == 0
assert len(DIRSTACK) == 0 assert len(DIRSTACK) == 0
assert not os.path.isdir(TEMP_DRIVE[2] + '\\') assert not os.path.isdir(TEMP_DRIVE[2] + "\\")
assert not os.path.isdir(TEMP_DRIVE[0] + '\\') assert not os.path.isdir(TEMP_DRIVE[0] + "\\")
@pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality") @pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality")
@ -201,7 +218,7 @@ def test_uncpushd_push_base_push_rempath(xonsh_builtins):
pass pass
#really? Need to cut-and-paste 2 flavors of this? yield_fixture requires yield in defined function body, not callee # really? Need to cut-and-paste 2 flavors of this? yield_fixture requires yield in defined function body, not callee
@pytest.yield_fixture() @pytest.yield_fixture()
def with_unc_check_enabled(): def with_unc_check_enabled():
if not ON_WINDOWS: if not ON_WINDOWS:
@ -210,19 +227,27 @@ def with_unc_check_enabled():
import winreg import winreg
old_wval = 0 old_wval = 0
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'software\microsoft\command processor', access=winreg.KEY_WRITE) key = winreg.OpenKey(
winreg.HKEY_CURRENT_USER,
r"software\microsoft\command processor",
access=winreg.KEY_WRITE,
)
try: try:
wval, wtype = winreg.QueryValueEx(key, 'DisableUNCCheck') wval, wtype = winreg.QueryValueEx(key, "DisableUNCCheck")
old_wval = wval # if values was defined at all old_wval = wval # if values was defined at all
except OSError as e: except OSError as e:
pass pass
winreg.SetValueEx(key, 'DisableUNCCheck', None, winreg.REG_DWORD, 0) winreg.SetValueEx(key, "DisableUNCCheck", None, winreg.REG_DWORD, 0)
winreg.CloseKey(key) winreg.CloseKey(key)
yield old_wval yield old_wval
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'software\microsoft\command processor', access=winreg.KEY_WRITE) key = winreg.OpenKey(
winreg.SetValueEx(key, 'DisableUNCCheck', None, winreg.REG_DWORD, old_wval) winreg.HKEY_CURRENT_USER,
r"software\microsoft\command processor",
access=winreg.KEY_WRITE,
)
winreg.SetValueEx(key, "DisableUNCCheck", None, winreg.REG_DWORD, old_wval)
winreg.CloseKey(key) winreg.CloseKey(key)
@ -234,57 +259,65 @@ def with_unc_check_disabled(): # just like the above, but value is 1 to *disabl
import winreg import winreg
old_wval = 0 old_wval = 0
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'software\microsoft\command processor', access=winreg.KEY_WRITE) key = winreg.OpenKey(
winreg.HKEY_CURRENT_USER,
r"software\microsoft\command processor",
access=winreg.KEY_WRITE,
)
try: try:
wval, wtype = winreg.QueryValueEx(key, 'DisableUNCCheck') wval, wtype = winreg.QueryValueEx(key, "DisableUNCCheck")
old_wval = wval # if values was defined at all old_wval = wval # if values was defined at all
except OSError as e: except OSError as e:
pass pass
winreg.SetValueEx(key, 'DisableUNCCheck', None, winreg.REG_DWORD, 1) winreg.SetValueEx(key, "DisableUNCCheck", None, winreg.REG_DWORD, 1)
winreg.CloseKey(key) winreg.CloseKey(key)
yield old_wval yield old_wval
key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r'software\microsoft\command processor', access=winreg.KEY_WRITE) key = winreg.OpenKey(
winreg.SetValueEx(key, 'DisableUNCCheck', None, winreg.REG_DWORD, old_wval) winreg.HKEY_CURRENT_USER,
r"software\microsoft\command processor",
access=winreg.KEY_WRITE,
)
winreg.SetValueEx(key, "DisableUNCCheck", None, winreg.REG_DWORD, old_wval)
winreg.CloseKey(key) winreg.CloseKey(key)
@pytest.fixture() @pytest.fixture()
def xonsh_builtins_cd(xonsh_builtins): def xonsh_builtins_cd(xonsh_builtins):
xonsh_builtins.__xonsh_env__['CDPATH'] = PARENT xonsh_builtins.__xonsh_env__["CDPATH"] = PARENT
xonsh_builtins.__xonsh_env__['PWD'] = os.getcwd() xonsh_builtins.__xonsh_env__["PWD"] = os.getcwd()
xonsh_builtins.__xonsh_env__['DIRSTACK_SIZE'] = 20 xonsh_builtins.__xonsh_env__["DIRSTACK_SIZE"] = 20
return xonsh_builtins return xonsh_builtins
@pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality") @pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality")
def test_uncpushd_cd_unc_auto_pushd(xonsh_builtins_cd, with_unc_check_enabled): def test_uncpushd_cd_unc_auto_pushd(xonsh_builtins_cd, with_unc_check_enabled):
xonsh_builtins_cd.__xonsh_env__['AUTO_PUSHD'] = True xonsh_builtins_cd.__xonsh_env__["AUTO_PUSHD"] = True
so, se, rc = dirstack.cd([r'\\localhost\uncpushd_test_PARENT']) so, se, rc = dirstack.cd([r"\\localhost\uncpushd_test_PARENT"])
if rc != 0: if rc != 0:
return return
assert os.getcwd().casefold() == TEMP_DRIVE[0] + '\\' assert os.getcwd().casefold() == TEMP_DRIVE[0] + "\\"
assert len(DIRSTACK) == 1 assert len(DIRSTACK) == 1
assert os.path.isdir(TEMP_DRIVE[0] + '\\') assert os.path.isdir(TEMP_DRIVE[0] + "\\")
@pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality") @pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality")
def test_uncpushd_cd_unc_nocheck(xonsh_builtins_cd, with_unc_check_disabled): def test_uncpushd_cd_unc_nocheck(xonsh_builtins_cd, with_unc_check_disabled):
if with_unc_check_disabled == 0: if with_unc_check_disabled == 0:
return return
dirstack.cd([r'\\localhost\uncpushd_test_HERE']) dirstack.cd([r"\\localhost\uncpushd_test_HERE"])
assert os.getcwd().casefold() == r'\\localhost\uncpushd_test_here' assert os.getcwd().casefold() == r"\\localhost\uncpushd_test_here"
@pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality") @pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality")
def test_uncpushd_cd_unc_no_auto_pushd(xonsh_builtins_cd, with_unc_check_enabled): def test_uncpushd_cd_unc_no_auto_pushd(xonsh_builtins_cd, with_unc_check_enabled):
if with_unc_check_enabled == 0: if with_unc_check_enabled == 0:
return return
so, se, rc = dirstack.cd([r'\\localhost\uncpushd_test_PARENT']) so, se, rc = dirstack.cd([r"\\localhost\uncpushd_test_PARENT"])
assert rc != 0 assert rc != 0
assert so is None or len(so) == 0 assert so is None or len(so) == 0
assert 'disableunccheck' in se.casefold() and 'auto_pushd' in se.casefold() assert "disableunccheck" in se.casefold() and "auto_pushd" in se.casefold()
@pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality") @pytest.mark.skipif(not ON_WINDOWS, reason="Windows-only UNC functionality")

View file

@ -11,133 +11,150 @@ from xonsh.tools import ON_WINDOWS
import pytest import pytest
from xonsh.commands_cache import CommandsCache from xonsh.commands_cache import CommandsCache
from xonsh.environ import (Env, locate_binary, DEFAULT_ENSURERS, DEFAULT_VALUES, from xonsh.environ import (
default_env, make_args_env) Env,
locate_binary,
DEFAULT_ENSURERS,
DEFAULT_VALUES,
default_env,
make_args_env,
)
from tools import skip_if_on_unix from tools import skip_if_on_unix
def test_env_normal(): def test_env_normal():
env = Env(VAR='wakka') env = Env(VAR="wakka")
assert 'wakka' == env['VAR'] assert "wakka" == env["VAR"]
def test_env_contains(): def test_env_contains():
env = Env(VAR='wakka') env = Env(VAR="wakka")
assert 'VAR' in env assert "VAR" in env
@pytest.mark.parametrize('path', [['/home/wakka'], ['wakka']])
@pytest.mark.parametrize("path", [["/home/wakka"], ["wakka"]])
def test_env_path_list(path): def test_env_path_list(path):
env = Env(MYPATH=path) env = Env(MYPATH=path)
assert path == env['MYPATH'].paths assert path == env["MYPATH"].paths
@pytest.mark.parametrize('path', [
['/home/wakka' + os.pathsep + '/home/jawaka'], @pytest.mark.parametrize(
['wakka' + os.pathsep + 'jawaka'] "path",
]) [["/home/wakka" + os.pathsep + "/home/jawaka"], ["wakka" + os.pathsep + "jawaka"]],
)
def test_env_path_str(path): def test_env_path_str(path):
env = Env(MYPATH=path) env = Env(MYPATH=path)
assert path == env['MYPATH'].paths assert path == env["MYPATH"].paths
def test_env_detype(): def test_env_detype():
env = Env(MYPATH=['wakka', 'jawaka']) env = Env(MYPATH=["wakka", "jawaka"])
assert 'wakka' + os.pathsep + 'jawaka' == env.detype()['MYPATH'] assert "wakka" + os.pathsep + "jawaka" == env.detype()["MYPATH"]
@pytest.mark.parametrize('path1, path2',[
(['/home/wakka', '/home/jawaka'], '/home/woah'), @pytest.mark.parametrize(
(['wakka', 'jawaka'], 'woah') "path1, path2",
]) [(["/home/wakka", "/home/jawaka"], "/home/woah"), (["wakka", "jawaka"], "woah")],
)
def test_env_detype_mutable_access_clear(path1, path2): def test_env_detype_mutable_access_clear(path1, path2):
env = Env(MYPATH=path1) env = Env(MYPATH=path1)
assert path1[0] + os.pathsep + path1[1] == env.detype()['MYPATH'] assert path1[0] + os.pathsep + path1[1] == env.detype()["MYPATH"]
env['MYPATH'][0] = path2 env["MYPATH"][0] = path2
assert env._detyped is None assert env._detyped is None
assert path2 + os.pathsep + path1[1] == env.detype()['MYPATH'] assert path2 + os.pathsep + path1[1] == env.detype()["MYPATH"]
def test_env_detype_no_dict(): def test_env_detype_no_dict():
env = Env(YO={'hey': 42}) env = Env(YO={"hey": 42})
det = env.detype() det = env.detype()
assert 'YO' not in det assert "YO" not in det
def test_histcontrol_none(): def test_histcontrol_none():
env = Env(HISTCONTROL=None) env = Env(HISTCONTROL=None)
assert isinstance(env['HISTCONTROL'], set) assert isinstance(env["HISTCONTROL"], set)
assert len(env['HISTCONTROL']) == 0 assert len(env["HISTCONTROL"]) == 0
def test_HISTCONTROL_empty(): def test_HISTCONTROL_empty():
env = Env(HISTCONTROL='') env = Env(HISTCONTROL="")
assert isinstance(env['HISTCONTROL'], set) assert isinstance(env["HISTCONTROL"], set)
assert len(env['HISTCONTROL']) == 0 assert len(env["HISTCONTROL"]) == 0
def test_histcontrol_ignoredups(): def test_histcontrol_ignoredups():
env = Env(HISTCONTROL='ignoredups') env = Env(HISTCONTROL="ignoredups")
assert isinstance(env['HISTCONTROL'], set) assert isinstance(env["HISTCONTROL"], set)
assert len(env['HISTCONTROL']) == 1 assert len(env["HISTCONTROL"]) == 1
assert ('ignoredups' in env['HISTCONTROL']) assert "ignoredups" in env["HISTCONTROL"]
assert ('ignoreerr' not in env['HISTCONTROL']) assert "ignoreerr" not in env["HISTCONTROL"]
def test_histcontrol_ignoreerr_ignoredups(): def test_histcontrol_ignoreerr_ignoredups():
env = Env(HISTCONTROL='ignoreerr,ignoredups,ignoreerr') env = Env(HISTCONTROL="ignoreerr,ignoredups,ignoreerr")
assert len(env['HISTCONTROL']) == 2 assert len(env["HISTCONTROL"]) == 2
assert ('ignoreerr' in env['HISTCONTROL']) assert "ignoreerr" in env["HISTCONTROL"]
assert ('ignoredups' in env['HISTCONTROL']) assert "ignoredups" in env["HISTCONTROL"]
def test_swap(): def test_swap():
env = Env(VAR='wakka') env = Env(VAR="wakka")
assert env['VAR'] == 'wakka' assert env["VAR"] == "wakka"
# positional arg # positional arg
with env.swap({'VAR': 'foo'}): with env.swap({"VAR": "foo"}):
assert env['VAR'] == 'foo' assert env["VAR"] == "foo"
# make sure the environment goes back outside the context manager # make sure the environment goes back outside the context manager
assert env['VAR'] == 'wakka' assert env["VAR"] == "wakka"
# kwargs only # kwargs only
with env.swap(VAR1='foo', VAR2='bar'): with env.swap(VAR1="foo", VAR2="bar"):
assert env['VAR1'] == 'foo' assert env["VAR1"] == "foo"
assert env['VAR2'] == 'bar' assert env["VAR2"] == "bar"
# positional and kwargs # positional and kwargs
with env.swap({'VAR3': 'baz'}, VAR1='foo', VAR2='bar'): with env.swap({"VAR3": "baz"}, VAR1="foo", VAR2="bar"):
assert env['VAR1'] == 'foo' assert env["VAR1"] == "foo"
assert env['VAR2'] == 'bar' assert env["VAR2"] == "bar"
assert env['VAR3'] == 'baz' assert env["VAR3"] == "baz"
# make sure the environment goes back outside the context manager # make sure the environment goes back outside the context manager
assert env['VAR'] == 'wakka' assert env["VAR"] == "wakka"
assert 'VAR1' not in env assert "VAR1" not in env
assert 'VAR2' not in env assert "VAR2" not in env
assert 'VAR3' not in env assert "VAR3" not in env
def test_swap_exception_replacement(): def test_swap_exception_replacement():
env = Env(VAR='original value') env = Env(VAR="original value")
try: try:
with env.swap(VAR='inner value'): with env.swap(VAR="inner value"):
assert env['VAR'] == 'inner value' assert env["VAR"] == "inner value"
raise Exception() raise Exception()
except Exception: except Exception:
assert env['VAR'] == 'original value' assert env["VAR"] == "original value"
assert env['VAR'] == 'original value' assert env["VAR"] == "original value"
@skip_if_on_unix @skip_if_on_unix
def test_locate_binary_on_windows(xonsh_builtins): def test_locate_binary_on_windows(xonsh_builtins):
files = ('file1.exe', 'FILE2.BAT', 'file3.txt') files = ("file1.exe", "FILE2.BAT", "file3.txt")
with TemporaryDirectory() as tmpdir: with TemporaryDirectory() as tmpdir:
for fname in files: for fname in files:
fpath = os.path.join(tmpdir, fname) fpath = os.path.join(tmpdir, fname)
with open(fpath, 'w') as f: with open(fpath, "w") as f:
f.write(fpath) f.write(fpath)
xonsh_builtins.__xonsh_env__.update({ xonsh_builtins.__xonsh_env__.update(
'PATH': [tmpdir], {"PATH": [tmpdir], "PATHEXT": [".COM", ".EXE", ".BAT"]}
'PATHEXT': ['.COM', '.EXE', '.BAT'], )
})
xonsh_builtins.__xonsh_commands_cache__ = CommandsCache() xonsh_builtins.__xonsh_commands_cache__ = CommandsCache()
assert locate_binary('file1') == os.path.join(tmpdir, 'file1.exe') assert locate_binary("file1") == os.path.join(tmpdir, "file1.exe")
assert locate_binary('file1.exe') == os.path.join(tmpdir, 'file1.exe') assert locate_binary("file1.exe") == os.path.join(tmpdir, "file1.exe")
assert locate_binary('file2') == os.path.join(tmpdir, 'FILE2.BAT') assert locate_binary("file2") == os.path.join(tmpdir, "FILE2.BAT")
assert locate_binary('file2.bat') == os.path.join(tmpdir, 'FILE2.BAT') assert locate_binary("file2.bat") == os.path.join(tmpdir, "FILE2.BAT")
assert locate_binary('file3') is None assert locate_binary("file3") is None
def test_event_on_envvar_change(xonsh_builtins): def test_event_on_envvar_change(xonsh_builtins):
@ -150,9 +167,9 @@ def test_event_on_envvar_change(xonsh_builtins):
share.extend((name, oldvalue, newvalue)) share.extend((name, oldvalue, newvalue))
# trigger # trigger
env['TEST'] = 1 env["TEST"] = 1
assert share == ['TEST', 0, 1] assert share == ["TEST", 0, 1]
def test_event_on_envvar_new(xonsh_builtins): def test_event_on_envvar_new(xonsh_builtins):
@ -165,9 +182,10 @@ def test_event_on_envvar_new(xonsh_builtins):
share.extend((name, value)) share.extend((name, value))
# trigger # trigger
env['TEST'] = 1 env["TEST"] = 1
assert share == ["TEST", 1]
assert share == ['TEST', 1]
def test_event_on_envvar_change_from_none_value(xonsh_builtins): def test_event_on_envvar_change_from_none_value(xonsh_builtins):
env = Env(TEST=None) env = Env(TEST=None)
@ -179,12 +197,12 @@ def test_event_on_envvar_change_from_none_value(xonsh_builtins):
share.extend((name, oldvalue, newvalue)) share.extend((name, oldvalue, newvalue))
# trigger # trigger
env['TEST'] = 1 env["TEST"] = 1
assert share == ['TEST', None, 1] assert share == ["TEST", None, 1]
@pytest.mark.parametrize('val', [1, None, True, 'ok']) @pytest.mark.parametrize("val", [1, None, True, "ok"])
def test_event_on_envvar_change_no_fire_when_value_is_same(val, xonsh_builtins): def test_event_on_envvar_change_no_fire_when_value_is_same(val, xonsh_builtins):
env = Env(TEST=val) env = Env(TEST=val)
xonsh_builtins.__xonsh_env__ = env xonsh_builtins.__xonsh_env__ = env
@ -194,9 +212,8 @@ def test_event_on_envvar_change_no_fire_when_value_is_same(val, xonsh_builtins):
def handler(name, oldvalue, newvalue, **kwargs): def handler(name, oldvalue, newvalue, **kwargs):
share.extend((name, oldvalue, newvalue)) share.extend((name, oldvalue, newvalue))
# trigger # trigger
env['TEST'] = val env["TEST"] = val
assert share == [] assert share == []
@ -208,21 +225,21 @@ def test_events_on_envvar_called_in_right_order(xonsh_builtins):
# register # register
@xonsh_builtins.events.on_envvar_new @xonsh_builtins.events.on_envvar_new
def handler(name, value, **kwargs): def handler(name, value, **kwargs):
share[:] = ['new'] share[:] = ["new"]
@xonsh_builtins.events.on_envvar_change @xonsh_builtins.events.on_envvar_change
def handler(name, oldvalue, newvalue, **kwargs): def handler(name, oldvalue, newvalue, **kwargs):
share[:] = ['change'] share[:] = ["change"]
# trigger new # trigger new
env['TEST'] = 1 env["TEST"] = 1
assert share == ['new'] assert share == ["new"]
# trigger change # trigger change
env['TEST'] = 2 env["TEST"] = 2
assert share == ['change'] assert share == ["change"]
def test_int_bool_envvars_have_ensurers(): def test_int_bool_envvars_have_ensurers():
@ -233,24 +250,24 @@ def test_int_bool_envvars_have_ensurers():
def test_no_lines_columns(): def test_no_lines_columns():
os.environ['LINES'] = 'spam' os.environ["LINES"] = "spam"
os.environ['COLUMNS'] = 'eggs' os.environ["COLUMNS"] = "eggs"
try: try:
env = default_env() env = default_env()
assert 'LINES' not in env assert "LINES" not in env
assert 'COLUMNS' not in env assert "COLUMNS" not in env
finally: finally:
del os.environ['LINES'] del os.environ["LINES"]
del os.environ['COLUMNS'] del os.environ["COLUMNS"]
def test_make_args_env(): def test_make_args_env():
obs = make_args_env(['script', '1', '2', '3']) obs = make_args_env(["script", "1", "2", "3"])
exp = { exp = {
'ARGS': ['script', '1', '2', '3'], "ARGS": ["script", "1", "2", "3"],
'ARG0': 'script', "ARG0": "script",
'ARG1': '1', "ARG1": "1",
'ARG2': '2', "ARG2": "2",
'ARG3': '3', "ARG3": "3",
} }
assert exp == obs assert exp == obs

View file

@ -54,7 +54,7 @@ def test_validator(events):
@first.validator @first.validator
def v(n): def v(n):
return n == 'spam' return n == "spam"
@events.on_test @events.on_test
def second(n, **_): def second(n, **_):
@ -63,24 +63,24 @@ def test_validator(events):
return False return False
called = 0 called = 0
events.on_test.fire(n='egg') events.on_test.fire(n="egg")
assert called == 1 assert called == 1
called = 0 called = 0
events.on_test.fire(n='spam') events.on_test.fire(n="spam")
assert called == 2 assert called == 2
def test_eventdoc(events): def test_eventdoc(events):
docstring = "Test event" docstring = "Test event"
events.doc('on_test', docstring) events.doc("on_test", docstring)
assert inspect.getdoc(events.on_test) == docstring assert inspect.getdoc(events.on_test) == docstring
def test_transmogrify(events): def test_transmogrify(events):
docstring = "Test event" docstring = "Test event"
events.doc('on_test', docstring) events.doc("on_test", docstring)
@events.on_test @events.on_test
def func(**_): def func(**_):
@ -90,7 +90,7 @@ def test_transmogrify(events):
assert len(events.on_test) == 1 assert len(events.on_test) == 1
assert inspect.getdoc(events.on_test) == docstring assert inspect.getdoc(events.on_test) == docstring
events.transmogrify('on_test', LoadEvent) events.transmogrify("on_test", LoadEvent)
assert isinstance(events.on_test, LoadEvent) assert isinstance(events.on_test, LoadEvent)
assert len(events.on_test) == 1 assert len(events.on_test) == 1
@ -99,7 +99,7 @@ def test_transmogrify(events):
def test_transmogrify_by_string(events): def test_transmogrify_by_string(events):
docstring = "Test event" docstring = "Test event"
events.doc('on_test', docstring) events.doc("on_test", docstring)
@events.on_test @events.on_test
def func(**_): def func(**_):
@ -109,7 +109,7 @@ def test_transmogrify_by_string(events):
assert len(events.on_test) == 1 assert len(events.on_test) == 1
assert inspect.getdoc(events.on_test) == docstring assert inspect.getdoc(events.on_test) == docstring
events.transmogrify('on_test', 'LoadEvent') events.transmogrify("on_test", "LoadEvent")
assert isinstance(events.on_test, LoadEvent) assert isinstance(events.on_test, LoadEvent)
assert len(events.on_test) == 1 assert len(events.on_test) == 1
@ -117,7 +117,7 @@ def test_transmogrify_by_string(events):
def test_load(events): def test_load(events):
events.transmogrify('on_test', 'LoadEvent') events.transmogrify("on_test", "LoadEvent")
called = 0 called = 0
@events.on_test @events.on_test
@ -137,8 +137,9 @@ def test_load(events):
assert called == 2 assert called == 2
def test_load_2nd_call(events): def test_load_2nd_call(events):
events.transmogrify('on_test', 'LoadEvent') events.transmogrify("on_test", "LoadEvent")
called = 0 called = 0
@events.on_test @events.on_test
@ -157,6 +158,6 @@ def test_load_2nd_call(events):
def test_typos(xonsh_builtins): def test_typos(xonsh_builtins):
for name, ev in vars(xonsh_builtins.events).items(): for name, ev in vars(xonsh_builtins.events).items():
if 'pytest' in name: if "pytest" in name:
continue continue
assert inspect.getdoc(ev) assert inspect.getdoc(ev)

View file

@ -2,8 +2,7 @@
"""Tests the xonsh lexer.""" """Tests the xonsh lexer."""
import os import os
from tools import (check_eval, check_parse, from tools import check_eval, check_parse, skip_if_on_unix, skip_if_on_windows
skip_if_on_unix, skip_if_on_windows)
import pytest import pytest
@ -15,85 +14,89 @@ def xonsh_execer_autouse(xonsh_builtins, xonsh_execer):
@skip_if_on_unix @skip_if_on_unix
def test_win_ipconfig(): def test_win_ipconfig():
assert check_eval(os.environ['SYSTEMROOT'] + '\\System32\\ipconfig.exe /all') assert check_eval(os.environ["SYSTEMROOT"] + "\\System32\\ipconfig.exe /all")
@skip_if_on_unix @skip_if_on_unix
def test_ipconfig(): def test_ipconfig():
assert check_eval('ipconfig /all') assert check_eval("ipconfig /all")
@skip_if_on_windows @skip_if_on_windows
def test_bin_ls(): def test_bin_ls():
assert check_eval('/bin/ls -l') assert check_eval("/bin/ls -l")
def test_ls_dashl(): def test_ls_dashl():
assert check_parse('ls -l') assert check_parse("ls -l")
def test_which_ls(): def test_which_ls():
assert check_parse('which ls') assert check_parse("which ls")
def test_echo_hello(): def test_echo_hello():
assert check_parse('echo hello') assert check_parse("echo hello")
def test_echo_star_with_semi(): def test_echo_star_with_semi():
assert check_parse('echo * spam ; ![echo eggs]\n') assert check_parse("echo * spam ; ![echo eggs]\n")
def test_simple_func(): def test_simple_func():
code = ('def prompt():\n' code = "def prompt():\n" " return '{user}'.format(user='me')\n"
" return '{user}'.format(user='me')\n")
assert check_parse(code) assert check_parse(code)
def test_lookup_alias(): def test_lookup_alias():
code = ( code = "def foo(a, s=None):\n" ' return "bar"\n' "@(foo)\n"
'def foo(a, s=None):\n'
' return "bar"\n'
'@(foo)\n')
assert check_parse(code) assert check_parse(code)
def test_lookup_anon_alias(): def test_lookup_anon_alias():
code = ('echo "hi" | @(lambda a, s=None: a[0]) foo bar baz\n') code = 'echo "hi" | @(lambda a, s=None: a[0]) foo bar baz\n'
assert check_parse(code) assert check_parse(code)
def test_simple_func_broken(): def test_simple_func_broken():
code = ('def prompt():\n' code = "def prompt():\n" " return '{user}'.format(\n" " user='me')\n"
" return '{user}'.format(\n"
" user='me')\n")
assert check_parse(code) assert check_parse(code)
def test_bad_indent(): def test_bad_indent():
code = ('if True:\n' code = "if True:\n" "x = 1\n"
'x = 1\n')
with pytest.raises(SyntaxError): with pytest.raises(SyntaxError):
check_parse(code) check_parse(code)
def test_good_rhs_subproc(): def test_good_rhs_subproc():
# nonsense but parsable # nonsense but parsable
code = 'str().split() | ![grep exit]\n' code = "str().split() | ![grep exit]\n"
assert(code) assert code
def test_bad_rhs_subproc(): def test_bad_rhs_subproc():
# nonsense but unparsable # nonsense but unparsable
code = 'str().split() | grep exit\n' code = "str().split() | grep exit\n"
with pytest.raises(SyntaxError): with pytest.raises(SyntaxError):
check_parse(code) check_parse(code)
def test_indent_with_empty_line(): def test_indent_with_empty_line():
code = ('if True:\n' code = "if True:\n" "\n" " some_command for_sub_process_mode\n"
'\n'
' some_command for_sub_process_mode\n')
assert check_parse(code) assert check_parse(code)
def test_command_in_func(): def test_command_in_func():
code = ('def f():\n' code = "def f():\n" " echo hello\n"
' echo hello\n')
assert check_parse(code) assert check_parse(code)
def test_command_in_func_with_comment(): def test_command_in_func_with_comment():
code = ('def f():\n' code = "def f():\n" " echo hello # comment\n"
' echo hello # comment\n')
assert check_parse(code) assert check_parse(code)
def test_pyeval_redirect(): def test_pyeval_redirect():
code = 'echo @("foo") > bar\n' code = 'echo @("foo") > bar\n'
assert check_parse(code) assert check_parse(code)
@ -105,15 +108,17 @@ def test_pyeval_multiline_str():
def test_echo_comma(): def test_echo_comma():
code = 'echo ,\n' code = "echo ,\n"
assert check_parse(code) assert check_parse(code)
def test_echo_comma_val(): def test_echo_comma_val():
code = 'echo ,1\n' code = "echo ,1\n"
assert check_parse(code) assert check_parse(code)
def test_echo_comma_2val(): def test_echo_comma_2val():
code = 'echo 1,2\n' code = "echo 1,2\n"
assert check_parse(code) assert check_parse(code)
@ -121,10 +126,14 @@ def test_echo_line_cont():
code = 'echo "1 \\\n2"\n' code = 'echo "1 \\\n2"\n'
assert check_parse(code) assert check_parse(code)
@pytest.mark.parametrize('code', [
"echo a and \\\necho b\n", @pytest.mark.parametrize(
"echo a \\\n or echo b\n", "code",
"echo a \\\n or echo b and \\\n echo c\n", [
]) "echo a and \\\necho b\n",
"echo a \\\n or echo b\n",
"echo a \\\n or echo b and \\\n echo c\n",
],
)
def test_two_echo_line_cont(code): def test_two_echo_line_cont(code):
assert check_parse(code) assert check_parse(code)

View file

@ -11,68 +11,72 @@ from xonsh.foreign_shells import foreign_shell_data, parse_env, parse_aliases
def test_parse_env(): def test_parse_env():
exp = {'X': 'YES', 'Y': 'NO'} exp = {"X": "YES", "Y": "NO"}
s = ('some garbage\n' s = (
'__XONSH_ENV_BEG__\n' "some garbage\n"
'Y=NO\n' "__XONSH_ENV_BEG__\n"
'X=YES\n' "Y=NO\n"
'__XONSH_ENV_END__\n' "X=YES\n"
'more filth') "__XONSH_ENV_END__\n"
"more filth"
)
obs = parse_env(s) obs = parse_env(s)
assert exp == obs assert exp == obs
def test_parse_env_newline(): def test_parse_env_newline():
exp = {'X': 'YES', 'Y': 'NO', 'PROMPT': 'why\nme '} exp = {"X": "YES", "Y": "NO", "PROMPT": "why\nme "}
s = ('some garbage\n' s = (
'__XONSH_ENV_BEG__\n' "some garbage\n"
'Y=NO\n' "__XONSH_ENV_BEG__\n"
'PROMPT=why\nme \n' "Y=NO\n"
'X=YES\n' "PROMPT=why\nme \n"
'__XONSH_ENV_END__\n' "X=YES\n"
'more filth') "__XONSH_ENV_END__\n"
"more filth"
)
obs = parse_env(s) obs = parse_env(s)
assert exp == obs assert exp == obs
def test_parse_env_equals(): def test_parse_env_equals():
exp = {'X': 'YES', 'Y': 'NO', 'LS_COLORS': '*.tar=5'} exp = {"X": "YES", "Y": "NO", "LS_COLORS": "*.tar=5"}
s = ('some garbage\n' s = (
'__XONSH_ENV_BEG__\n' "some garbage\n"
'Y=NO\n' "__XONSH_ENV_BEG__\n"
'LS_COLORS=*.tar=5\n' "Y=NO\n"
'X=YES\n' "LS_COLORS=*.tar=5\n"
'__XONSH_ENV_END__\n' "X=YES\n"
'more filth') "__XONSH_ENV_END__\n"
"more filth"
)
obs = parse_env(s) obs = parse_env(s)
assert exp == obs assert exp == obs
def test_parse_aliases(): def test_parse_aliases():
exp = {'x': ['yes', '-1'], 'y': ['echo', 'no']} exp = {"x": ["yes", "-1"], "y": ["echo", "no"]}
s = ('some garbage\n' s = (
'__XONSH_ALIAS_BEG__\n' "some garbage\n"
"alias x='yes -1'\n" "__XONSH_ALIAS_BEG__\n"
"alias y='echo no'\n" "alias x='yes -1'\n"
'__XONSH_ALIAS_END__\n' "alias y='echo no'\n"
'more filth') "__XONSH_ALIAS_END__\n"
"more filth"
)
obs = parse_aliases(s) obs = parse_aliases(s)
assert exp == obs assert exp == obs
@skip_if_on_windows @skip_if_on_windows
def test_foreign_bash_data(): def test_foreign_bash_data():
expenv = {"EMERALD": "SWORD", 'MIGHTY': 'WARRIOR'} expenv = {"EMERALD": "SWORD", "MIGHTY": "WARRIOR"}
expaliases = { expaliases = {"l": ["ls", "-CF"], "la": ["ls", "-A"], "ll": ["ls", "-a", "-lF"]}
'l': ['ls', '-CF'], rcfile = os.path.join(os.path.dirname(__file__), "bashrc.sh")
'la': ['ls', '-A'],
'll': ['ls', '-a', '-lF'],
}
rcfile = os.path.join(os.path.dirname(__file__), 'bashrc.sh')
try: try:
obsenv, obsaliases = foreign_shell_data('bash', currenv=(), obsenv, obsaliases = foreign_shell_data(
extra_args=('--rcfile', rcfile), "bash", currenv=(), extra_args=("--rcfile", rcfile), safe=False
safe=False) )
except (subprocess.CalledProcessError, FileNotFoundError): except (subprocess.CalledProcessError, FileNotFoundError):
return return
for key, expval in expenv.items(): for key, expval in expenv.items():
@ -83,18 +87,22 @@ def test_foreign_bash_data():
@skip_if_on_unix @skip_if_on_unix
def test_foreign_cmd_data(): def test_foreign_cmd_data():
env = (('ENV_TO_BE_REMOVED','test'),) env = (("ENV_TO_BE_REMOVED", "test"),)
batchfile = os.path.join(os.path.dirname(__file__), 'batch.bat') batchfile = os.path.join(os.path.dirname(__file__), "batch.bat")
source_cmd ='call "{}"\necho off'.format(batchfile) source_cmd = 'call "{}"\necho off'.format(batchfile)
try: try:
obsenv, _ = foreign_shell_data('cmd',prevcmd=source_cmd, obsenv, _ = foreign_shell_data(
currenv=env, "cmd",
interactive =False, prevcmd=source_cmd,
sourcer='call',envcmd='set', currenv=env,
use_tmpfile=True, interactive=False,
safe=False) sourcer="call",
envcmd="set",
use_tmpfile=True,
safe=False,
)
except (subprocess.CalledProcessError, FileNotFoundError): except (subprocess.CalledProcessError, FileNotFoundError):
return return
assert 'ENV_TO_BE_ADDED' in obsenv assert "ENV_TO_BE_ADDED" in obsenv
assert obsenv['ENV_TO_BE_ADDED']=='Hallo world' assert obsenv["ENV_TO_BE_ADDED"] == "Hallo world"
assert 'ENV_TO_BE_REMOVED' not in obsenv assert "ENV_TO_BE_REMOVED" not in obsenv

View file

@ -12,12 +12,14 @@ from xonsh.history.json import JsonHistory
from xonsh.history.main import history_main, _xh_parse_args, construct_history from xonsh.history.main import history_main, _xh_parse_args, construct_history
CMDS = ['ls', 'cat hello kitty', 'abc', 'def', 'touch me', 'grep from me'] CMDS = ["ls", "cat hello kitty", "abc", "def", "touch me", "grep from me"]
@pytest.yield_fixture @pytest.yield_fixture
def hist(): def hist():
h = JsonHistory(filename='xonsh-HISTORY-TEST.json', here='yup', h = JsonHistory(
sessionid='SESSIONID', gc=False) filename="xonsh-HISTORY-TEST.json", here="yup", sessionid="SESSIONID", gc=False
)
yield h yield h
os.remove(h.filename) os.remove(h.filename)
@ -25,25 +27,25 @@ def hist():
def test_hist_init(hist): def test_hist_init(hist):
"""Test initialization of the shell history.""" """Test initialization of the shell history."""
with LazyJSON(hist.filename) as lj: with LazyJSON(hist.filename) as lj:
obs = lj['here'] obs = lj["here"]
assert 'yup' == obs assert "yup" == obs
def test_hist_append(hist, xonsh_builtins): def test_hist_append(hist, xonsh_builtins):
"""Verify appending to the history works.""" """Verify appending to the history works."""
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = set() xonsh_builtins.__xonsh_env__["HISTCONTROL"] = set()
hf = hist.append({'inp': 'still alive', 'rtn': 0}) hf = hist.append({"inp": "still alive", "rtn": 0})
assert hf is None assert hf is None
assert 'still alive' == hist.buffer[0]['inp'] assert "still alive" == hist.buffer[0]["inp"]
assert 0 == hist.buffer[0]['rtn'] assert 0 == hist.buffer[0]["rtn"]
assert 0 == hist.rtns[-1] assert 0 == hist.rtns[-1]
hf = hist.append({'inp': 'dead now', 'rtn': 1}) hf = hist.append({"inp": "dead now", "rtn": 1})
assert 'dead now' == hist.buffer[1]['inp'] assert "dead now" == hist.buffer[1]["inp"]
assert 1 == hist.buffer[1]['rtn'] assert 1 == hist.buffer[1]["rtn"]
assert 1 == hist.rtns[-1] assert 1 == hist.rtns[-1]
hf = hist.append({'inp': 'reborn', 'rtn': 0}) hf = hist.append({"inp": "reborn", "rtn": 0})
assert 'reborn' == hist.buffer[2]['inp'] assert "reborn" == hist.buffer[2]["inp"]
assert 0 == hist.buffer[2]['rtn'] assert 0 == hist.buffer[2]["rtn"]
assert 0 == hist.rtns[-1] assert 0 == hist.rtns[-1]
@ -51,62 +53,62 @@ def test_hist_flush(hist, xonsh_builtins):
"""Verify explicit flushing of the history works.""" """Verify explicit flushing of the history works."""
hf = hist.flush() hf = hist.flush()
assert hf is None assert hf is None
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = set() xonsh_builtins.__xonsh_env__["HISTCONTROL"] = set()
hist.append({'inp': 'still alive?', 'rtn': 0, 'out': 'yes'}) hist.append({"inp": "still alive?", "rtn": 0, "out": "yes"})
hf = hist.flush() hf = hist.flush()
assert hf is not None assert hf is not None
while hf.is_alive(): while hf.is_alive():
pass pass
with LazyJSON(hist.filename) as lj: with LazyJSON(hist.filename) as lj:
assert len(lj['cmds']) == 1 assert len(lj["cmds"]) == 1
cmd = lj['cmds'][0] cmd = lj["cmds"][0]
assert cmd['inp'] == 'still alive?' assert cmd["inp"] == "still alive?"
assert not cmd.get('out', None) assert not cmd.get("out", None)
def test_hist_flush_with_store_stdout(hist, xonsh_builtins): def test_hist_flush_with_store_stdout(hist, xonsh_builtins):
"""Verify explicit flushing of the history works.""" """Verify explicit flushing of the history works."""
hf = hist.flush() hf = hist.flush()
assert hf is None assert hf is None
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = set() xonsh_builtins.__xonsh_env__["HISTCONTROL"] = set()
xonsh_builtins.__xonsh_env__['XONSH_STORE_STDOUT'] = True xonsh_builtins.__xonsh_env__["XONSH_STORE_STDOUT"] = True
hist.append({'inp': 'still alive?', 'rtn': 0, 'out': 'yes'}) hist.append({"inp": "still alive?", "rtn": 0, "out": "yes"})
hf = hist.flush() hf = hist.flush()
assert hf is not None assert hf is not None
while hf.is_alive(): while hf.is_alive():
pass pass
with LazyJSON(hist.filename) as lj: with LazyJSON(hist.filename) as lj:
assert len(lj['cmds']) == 1 assert len(lj["cmds"]) == 1
assert lj['cmds'][0]['inp'] == 'still alive?' assert lj["cmds"][0]["inp"] == "still alive?"
assert lj['cmds'][0]['out'].strip() == 'yes' assert lj["cmds"][0]["out"].strip() == "yes"
def test_hist_flush_with_hist_control(hist, xonsh_builtins): def test_hist_flush_with_hist_control(hist, xonsh_builtins):
"""Verify explicit flushing of the history works.""" """Verify explicit flushing of the history works."""
hf = hist.flush() hf = hist.flush()
assert hf is None assert hf is None
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = 'ignoredups,ignoreerr' xonsh_builtins.__xonsh_env__["HISTCONTROL"] = "ignoredups,ignoreerr"
hist.append({'inp': 'ls foo1', 'rtn': 0}) hist.append({"inp": "ls foo1", "rtn": 0})
hist.append({'inp': 'ls foo1', 'rtn': 1}) hist.append({"inp": "ls foo1", "rtn": 1})
hist.append({'inp': 'ls foo1', 'rtn': 0}) hist.append({"inp": "ls foo1", "rtn": 0})
hist.append({'inp': 'ls foo2', 'rtn': 2}) hist.append({"inp": "ls foo2", "rtn": 2})
hist.append({'inp': 'ls foo3', 'rtn': 0}) hist.append({"inp": "ls foo3", "rtn": 0})
hf = hist.flush() hf = hist.flush()
assert hf is not None assert hf is not None
while hf.is_alive(): while hf.is_alive():
pass pass
assert len(hist.buffer) == 0 assert len(hist.buffer) == 0
with LazyJSON(hist.filename) as lj: with LazyJSON(hist.filename) as lj:
cmds = list(lj['cmds']) cmds = list(lj["cmds"])
assert len(cmds) == 2 assert len(cmds) == 2
assert [x['inp'] for x in cmds] == ['ls foo1', 'ls foo3'] assert [x["inp"] for x in cmds] == ["ls foo1", "ls foo3"]
assert [x['rtn'] for x in cmds] == [0, 0] assert [x["rtn"] for x in cmds] == [0, 0]
def test_cmd_field(hist, xonsh_builtins): def test_cmd_field(hist, xonsh_builtins):
# in-memory # in-memory
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = set() xonsh_builtins.__xonsh_env__["HISTCONTROL"] = set()
hf = hist.append({'inp': 'ls foo', 'rtn': 1}) hf = hist.append({"inp": "ls foo", "rtn": 1})
assert hf is None assert hf is None
assert 1 == hist.rtns[0] assert 1 == hist.rtns[0]
assert 1 == hist.rtns[-1] assert 1 == hist.rtns[-1]
@ -121,29 +123,34 @@ def test_cmd_field(hist, xonsh_builtins):
assert None == hist.outs[-1] assert None == hist.outs[-1]
@pytest.mark.parametrize('inp, commands, offset', [ @pytest.mark.parametrize(
('', CMDS, (0, 1)), "inp, commands, offset",
('-r', list(reversed(CMDS)), (len(CMDS)- 1, -1)), [
('0', CMDS[0:1], (0, 1)), ("", CMDS, (0, 1)),
('1', CMDS[1:2], (1, 1)), ("-r", list(reversed(CMDS)), (len(CMDS) - 1, -1)),
('-2', CMDS[-2:-1], (len(CMDS) -2 , 1)), ("0", CMDS[0:1], (0, 1)),
('1:3', CMDS[1:3], (1, 1)), ("1", CMDS[1:2], (1, 1)),
('1::2', CMDS[1::2], (1, 2)), ("-2", CMDS[-2:-1], (len(CMDS) - 2, 1)),
('-4:-2', CMDS[-4:-2], (len(CMDS) - 4, 1)) ("1:3", CMDS[1:3], (1, 1)),
]) ("1::2", CMDS[1::2], (1, 2)),
("-4:-2", CMDS[-4:-2], (len(CMDS) - 4, 1)),
],
)
def test_show_cmd_numerate(inp, commands, offset, hist, xonsh_builtins, capsys): def test_show_cmd_numerate(inp, commands, offset, hist, xonsh_builtins, capsys):
"""Verify that CLI history commands work.""" """Verify that CLI history commands work."""
base_idx, step = offset base_idx, step = offset
xonsh_builtins.__xonsh_history__ = hist xonsh_builtins.__xonsh_history__ = hist
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = set() xonsh_builtins.__xonsh_env__["HISTCONTROL"] = set()
for ts, cmd in enumerate(CMDS): # populate the shell history for ts, cmd in enumerate(CMDS): # populate the shell history
hist.append({'inp': cmd, 'rtn': 0, 'ts':(ts + 1, ts + 1.5)}) hist.append({"inp": cmd, "rtn": 0, "ts": (ts + 1, ts + 1.5)})
exp = ('{}: {}'.format(base_idx + idx * step, cmd) exp = (
for idx, cmd in enumerate(list(commands))) "{}: {}".format(base_idx + idx * step, cmd)
exp = '\n'.join(exp) for idx, cmd in enumerate(list(commands))
)
exp = "\n".join(exp)
history_main(['show', '-n'] + shlex.split(inp)) history_main(["show", "-n"] + shlex.split(inp))
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert out.rstrip() == exp assert out.rstrip() == exp
@ -151,124 +158,134 @@ def test_show_cmd_numerate(inp, commands, offset, hist, xonsh_builtins, capsys):
def test_histcontrol(hist, xonsh_builtins): def test_histcontrol(hist, xonsh_builtins):
"""Test HISTCONTROL=ignoredups,ignoreerr""" """Test HISTCONTROL=ignoredups,ignoreerr"""
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = 'ignoredups,ignoreerr' xonsh_builtins.__xonsh_env__["HISTCONTROL"] = "ignoredups,ignoreerr"
assert len(hist.buffer) == 0 assert len(hist.buffer) == 0
# An error, buffer remains empty # An error, buffer remains empty
hist.append({'inp': 'ls foo', 'rtn': 2}) hist.append({"inp": "ls foo", "rtn": 2})
assert len(hist.buffer) == 1 assert len(hist.buffer) == 1
assert hist.rtns[-1] == 2 assert hist.rtns[-1] == 2
assert hist.inps[-1] == 'ls foo' assert hist.inps[-1] == "ls foo"
# Success # Success
hist.append({'inp': 'ls foobazz', 'rtn': 0}) hist.append({"inp": "ls foobazz", "rtn": 0})
assert len(hist.buffer) == 2 assert len(hist.buffer) == 2
assert 'ls foobazz' == hist.buffer[-1]['inp'] assert "ls foobazz" == hist.buffer[-1]["inp"]
assert 0 == hist.buffer[-1]['rtn'] assert 0 == hist.buffer[-1]["rtn"]
assert hist.rtns[-1] == 0 assert hist.rtns[-1] == 0
assert hist.inps[-1] == 'ls foobazz' assert hist.inps[-1] == "ls foobazz"
# Error # Error
hist.append({'inp': 'ls foo', 'rtn': 2}) hist.append({"inp": "ls foo", "rtn": 2})
assert len(hist.buffer) == 3 assert len(hist.buffer) == 3
assert 'ls foo' == hist.buffer[-1]['inp'] assert "ls foo" == hist.buffer[-1]["inp"]
assert 2 == hist.buffer[-1]['rtn'] assert 2 == hist.buffer[-1]["rtn"]
assert hist.rtns[-1] == 2 assert hist.rtns[-1] == 2
assert hist.inps[-1] == 'ls foo' assert hist.inps[-1] == "ls foo"
# File now exists, success # File now exists, success
hist.append({'inp': 'ls foo', 'rtn': 0}) hist.append({"inp": "ls foo", "rtn": 0})
assert len(hist.buffer) == 4 assert len(hist.buffer) == 4
assert 'ls foo' == hist.buffer[-1]['inp'] assert "ls foo" == hist.buffer[-1]["inp"]
assert 0 == hist.buffer[-1]['rtn'] assert 0 == hist.buffer[-1]["rtn"]
assert hist.rtns[-1] == 0 assert hist.rtns[-1] == 0
assert hist.inps[-1] == 'ls foo' assert hist.inps[-1] == "ls foo"
# Success # Success
hist.append({'inp': 'ls', 'rtn': 0}) hist.append({"inp": "ls", "rtn": 0})
assert len(hist.buffer) == 5 assert len(hist.buffer) == 5
assert 'ls' == hist.buffer[-1]['inp'] assert "ls" == hist.buffer[-1]["inp"]
assert 0 == hist.buffer[-1]['rtn'] assert 0 == hist.buffer[-1]["rtn"]
assert hist.rtns[-1] == 0 assert hist.rtns[-1] == 0
assert hist.inps[-1] == 'ls' assert hist.inps[-1] == "ls"
# Dup # Dup
hist.append({'inp': 'ls', 'rtn': 0}) hist.append({"inp": "ls", "rtn": 0})
assert len(hist.buffer) == 6 assert len(hist.buffer) == 6
assert hist.rtns[-1] == 0 assert hist.rtns[-1] == 0
assert hist.inps[-1] == 'ls' assert hist.inps[-1] == "ls"
# Success # Success
hist.append({'inp': '/bin/ls', 'rtn': 0}) hist.append({"inp": "/bin/ls", "rtn": 0})
assert len(hist.buffer) == 7 assert len(hist.buffer) == 7
assert '/bin/ls' == hist.buffer[-1]['inp'] assert "/bin/ls" == hist.buffer[-1]["inp"]
assert 0 == hist.buffer[-1]['rtn'] assert 0 == hist.buffer[-1]["rtn"]
assert hist.rtns[-1] == 0 assert hist.rtns[-1] == 0
assert hist.inps[-1] == '/bin/ls' assert hist.inps[-1] == "/bin/ls"
# Error # Error
hist.append({'inp': 'ls bazz', 'rtn': 1}) hist.append({"inp": "ls bazz", "rtn": 1})
assert len(hist.buffer) == 8 assert len(hist.buffer) == 8
assert 'ls bazz' == hist.buffer[-1]['inp'] assert "ls bazz" == hist.buffer[-1]["inp"]
assert 1 == hist.buffer[-1]['rtn'] assert 1 == hist.buffer[-1]["rtn"]
assert hist.rtns[-1] == 1 assert hist.rtns[-1] == 1
assert hist.inps[-1] == 'ls bazz' assert hist.inps[-1] == "ls bazz"
# Error # Error
hist.append({'inp': 'ls bazz', 'rtn': -1}) hist.append({"inp": "ls bazz", "rtn": -1})
assert len(hist.buffer) == 9 assert len(hist.buffer) == 9
assert 'ls bazz' == hist.buffer[-1]['inp'] assert "ls bazz" == hist.buffer[-1]["inp"]
assert -1 == hist.buffer[-1]['rtn'] assert -1 == hist.buffer[-1]["rtn"]
assert hist.rtns[-1] == -1 assert hist.rtns[-1] == -1
assert hist.inps[-1] == 'ls bazz' assert hist.inps[-1] == "ls bazz"
@pytest.mark.parametrize('args', [ '-h', '--help', 'show -h', 'show --help']) @pytest.mark.parametrize("args", ["-h", "--help", "show -h", "show --help"])
def test_parse_args_help(args, capsys): def test_parse_args_help(args, capsys):
with pytest.raises(SystemExit): with pytest.raises(SystemExit):
args = _xh_parse_args(shlex.split(args)) args = _xh_parse_args(shlex.split(args))
assert 'show this help message and exit' in capsys.readouterr()[0] assert "show this help message and exit" in capsys.readouterr()[0]
@pytest.mark.parametrize('args, exp', [ @pytest.mark.parametrize(
('', ('show', 'session', [], False, False)), "args, exp",
('1:5', ('show', 'session', ['1:5'], False, False)), [
('show', ('show', 'session', [], False, False)), ("", ("show", "session", [], False, False)),
('show 15', ('show', 'session', ['15'], False, False)), ("1:5", ("show", "session", ["1:5"], False, False)),
('show bash 3:5 15:66', ('show', 'bash', ['3:5', '15:66'], False, False)), ("show", ("show", "session", [], False, False)),
('show -r', ('show', 'session', [], False, True)), ("show 15", ("show", "session", ["15"], False, False)),
('show -rn bash', ('show', 'bash', [], True, True)), ("show bash 3:5 15:66", ("show", "bash", ["3:5", "15:66"], False, False)),
('show -n -r -30:20', ('show', 'session', ['-30:20'], True, True)), ("show -r", ("show", "session", [], False, True)),
('show -n zsh 1:2:3', ('show', 'zsh', ['1:2:3'], True, False)) ("show -rn bash", ("show", "bash", [], True, True)),
]) ("show -n -r -30:20", ("show", "session", ["-30:20"], True, True)),
("show -n zsh 1:2:3", ("show", "zsh", ["1:2:3"], True, False)),
],
)
def test_parser_show(args, exp): def test_parser_show(args, exp):
# use dict instead of argparse.Namespace for pretty pytest diff # use dict instead of argparse.Namespace for pretty pytest diff
exp_ns = {'action': exp[0], exp_ns = {
'session': exp[1], "action": exp[0],
'slices': exp[2], "session": exp[1],
'numerate': exp[3], "slices": exp[2],
'reverse': exp[4], "numerate": exp[3],
'start_time': None, "reverse": exp[4],
'end_time': None, "start_time": None,
'datetime_format': None, "end_time": None,
'timestamp': False, "datetime_format": None,
'null_byte': False} "timestamp": False,
"null_byte": False,
}
ns = _xh_parse_args(shlex.split(args)) ns = _xh_parse_args(shlex.split(args))
assert ns.__dict__ == exp_ns assert ns.__dict__ == exp_ns
@pytest.mark.parametrize('index, exp', [ @pytest.mark.parametrize(
(-1, ('grep from me', 'out', 0, (5, 6))), "index, exp",
(1, ('cat hello kitty', 'out', 0, (1, 2))), [
(slice(1, 3), [('cat hello kitty', 'out', 0, (1, 2)), (-1, ("grep from me", "out", 0, (5, 6))),
('abc', 'out', 0, (2, 3))]), (1, ("cat hello kitty", "out", 0, (1, 2))),
]) (
slice(1, 3),
[("cat hello kitty", "out", 0, (1, 2)), ("abc", "out", 0, (2, 3))],
),
],
)
def test_history_getitem(index, exp, hist, xonsh_builtins): def test_history_getitem(index, exp, hist, xonsh_builtins):
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = set() xonsh_builtins.__xonsh_env__["HISTCONTROL"] = set()
attrs = ('inp', 'out', 'rtn', 'ts') attrs = ("inp", "out", "rtn", "ts")
for ts,cmd in enumerate(CMDS): # populate the shell history for ts, cmd in enumerate(CMDS): # populate the shell history
entry = {k: v for k, v in zip(attrs, [cmd, 'out', 0, (ts, ts+1)])} entry = {k: v for k, v in zip(attrs, [cmd, "out", 0, (ts, ts + 1)])}
hist.append(entry) hist.append(entry)
entry = hist[index] entry = hist[index]
@ -279,15 +296,15 @@ def test_history_getitem(index, exp, hist, xonsh_builtins):
def test_construct_history_str(xonsh_builtins): def test_construct_history_str(xonsh_builtins):
xonsh_builtins.__xonsh_env__['XONSH_HISTORY_BACKEND'] = 'dummy' xonsh_builtins.__xonsh_env__["XONSH_HISTORY_BACKEND"] = "dummy"
assert isinstance(construct_history(), DummyHistory) assert isinstance(construct_history(), DummyHistory)
def test_construct_history_class(xonsh_builtins): def test_construct_history_class(xonsh_builtins):
xonsh_builtins.__xonsh_env__['XONSH_HISTORY_BACKEND'] = DummyHistory xonsh_builtins.__xonsh_env__["XONSH_HISTORY_BACKEND"] = DummyHistory
assert isinstance(construct_history(), DummyHistory) assert isinstance(construct_history(), DummyHistory)
def test_construct_history_instance(xonsh_builtins): def test_construct_history_instance(xonsh_builtins):
xonsh_builtins.__xonsh_env__['XONSH_HISTORY_BACKEND'] = DummyHistory() xonsh_builtins.__xonsh_env__["XONSH_HISTORY_BACKEND"] = DummyHistory()
assert isinstance(construct_history(), DummyHistory) assert isinstance(construct_history(), DummyHistory)

View file

@ -12,42 +12,43 @@ import pytest
@pytest.yield_fixture @pytest.yield_fixture
def hist(): def hist():
h = SqliteHistory(filename='xonsh-HISTORY-TEST.sqlite', h = SqliteHistory(
sessionid='SESSIONID', gc=False) filename="xonsh-HISTORY-TEST.sqlite", sessionid="SESSIONID", gc=False
)
yield h yield h
os.remove(h.filename) os.remove(h.filename)
def test_hist_append(hist, xonsh_builtins): def test_hist_append(hist, xonsh_builtins):
"""Verify appending to the history works.""" """Verify appending to the history works."""
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = set() xonsh_builtins.__xonsh_env__["HISTCONTROL"] = set()
hf = hist.append({'inp': 'still alive', 'rtn': 1}) hf = hist.append({"inp": "still alive", "rtn": 1})
assert hf is None assert hf is None
items = list(hist.items()) items = list(hist.items())
assert len(items) == 1 assert len(items) == 1
assert 'still alive' == items[0]['inp'] assert "still alive" == items[0]["inp"]
assert 1 == items[0]['rtn'] assert 1 == items[0]["rtn"]
hist.append({'inp': 'still alive', 'rtn': 0}) hist.append({"inp": "still alive", "rtn": 0})
items = list(hist.items()) items = list(hist.items())
assert len(items) == 2 assert len(items) == 2
assert 'still alive' == items[1]['inp'] assert "still alive" == items[1]["inp"]
assert 0 == items[1]['rtn'] assert 0 == items[1]["rtn"]
assert list(hist.all_items()) == items assert list(hist.all_items()) == items
def test_hist_attrs(hist, xonsh_builtins): def test_hist_attrs(hist, xonsh_builtins):
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = set() xonsh_builtins.__xonsh_env__["HISTCONTROL"] = set()
hf = hist.append({'inp': 'ls foo', 'rtn': 1}) hf = hist.append({"inp": "ls foo", "rtn": 1})
assert hf is None assert hf is None
assert 'ls foo' == hist.inps[0] assert "ls foo" == hist.inps[0]
assert 'ls foo' == hist.inps[-1] assert "ls foo" == hist.inps[-1]
assert 1 == hist.rtns[0] assert 1 == hist.rtns[0]
assert 1 == hist.rtns[-1] assert 1 == hist.rtns[-1]
assert None is hist.outs[-1] assert None is hist.outs[-1]
assert [1] == hist.rtns[:] assert [1] == hist.rtns[:]
hist.append({'inp': 'ls bar', 'rtn': 0}) hist.append({"inp": "ls bar", "rtn": 0})
assert 'ls bar' == hist.inps[1] assert "ls bar" == hist.inps[1]
assert 'ls bar' == hist.inps[-1] assert "ls bar" == hist.inps[-1]
assert 0 == hist.rtns[1] assert 0 == hist.rtns[1]
assert 0 == hist.rtns[-1] assert 0 == hist.rtns[-1]
assert None is hist.outs[-1] assert None is hist.outs[-1]
@ -56,32 +57,37 @@ def test_hist_attrs(hist, xonsh_builtins):
assert len(hist.tss[0]) == 2 assert len(hist.tss[0]) == 2
CMDS = ['ls', 'cat hello kitty', 'abc', 'def', 'touch me', 'grep from me'] CMDS = ["ls", "cat hello kitty", "abc", "def", "touch me", "grep from me"]
@pytest.mark.parametrize('inp, commands, offset', [ @pytest.mark.parametrize(
('', CMDS, (0, 1)), "inp, commands, offset",
('-r', list(reversed(CMDS)), (len(CMDS) - 1, -1)), [
('0', CMDS[0:1], (0, 1)), ("", CMDS, (0, 1)),
('1', CMDS[1:2], (1, 1)), ("-r", list(reversed(CMDS)), (len(CMDS) - 1, -1)),
('-2', CMDS[-2:-1], (len(CMDS) - 2, 1)), ("0", CMDS[0:1], (0, 1)),
('1:3', CMDS[1:3], (1, 1)), ("1", CMDS[1:2], (1, 1)),
('1::2', CMDS[1::2], (1, 2)), ("-2", CMDS[-2:-1], (len(CMDS) - 2, 1)),
('-4:-2', CMDS[-4:-2], (len(CMDS) - 4, 1)) ("1:3", CMDS[1:3], (1, 1)),
]) ("1::2", CMDS[1::2], (1, 2)),
("-4:-2", CMDS[-4:-2], (len(CMDS) - 4, 1)),
],
)
def test_show_cmd_numerate(inp, commands, offset, hist, xonsh_builtins, capsys): def test_show_cmd_numerate(inp, commands, offset, hist, xonsh_builtins, capsys):
"""Verify that CLI history commands work.""" """Verify that CLI history commands work."""
base_idx, step = offset base_idx, step = offset
xonsh_builtins.__xonsh_history__ = hist xonsh_builtins.__xonsh_history__ = hist
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = set() xonsh_builtins.__xonsh_env__["HISTCONTROL"] = set()
for ts, cmd in enumerate(CMDS): # populate the shell history for ts, cmd in enumerate(CMDS): # populate the shell history
hist.append({'inp': cmd, 'rtn': 0, 'ts': (ts + 1, ts + 1.5)}) hist.append({"inp": cmd, "rtn": 0, "ts": (ts + 1, ts + 1.5)})
exp = ('{}: {}'.format(base_idx + idx * step, cmd) exp = (
for idx, cmd in enumerate(list(commands))) "{}: {}".format(base_idx + idx * step, cmd)
exp = '\n'.join(exp) for idx, cmd in enumerate(list(commands))
)
exp = "\n".join(exp)
history_main(['show', '-n'] + shlex.split(inp)) history_main(["show", "-n"] + shlex.split(inp))
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert out.rstrip() == exp assert out.rstrip() == exp
@ -89,93 +95,98 @@ def test_show_cmd_numerate(inp, commands, offset, hist, xonsh_builtins, capsys):
def test_histcontrol(hist, xonsh_builtins): def test_histcontrol(hist, xonsh_builtins):
"""Test HISTCONTROL=ignoredups,ignoreerr""" """Test HISTCONTROL=ignoredups,ignoreerr"""
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = 'ignoredups,ignoreerr' xonsh_builtins.__xonsh_env__["HISTCONTROL"] = "ignoredups,ignoreerr"
assert len(hist) == 0 assert len(hist) == 0
# An error, items() remains empty # An error, items() remains empty
hist.append({'inp': 'ls foo', 'rtn': 2}) hist.append({"inp": "ls foo", "rtn": 2})
assert len(hist) == 0 assert len(hist) == 0
assert len(hist.inps) == 1 assert len(hist.inps) == 1
assert len(hist.rtns) == 1 assert len(hist.rtns) == 1
assert 2 == hist.rtns[-1] assert 2 == hist.rtns[-1]
# Success # Success
hist.append({'inp': 'ls foobazz', 'rtn': 0}) hist.append({"inp": "ls foobazz", "rtn": 0})
assert len(hist) == 1 assert len(hist) == 1
assert len(hist.inps) == 2 assert len(hist.inps) == 2
assert len(hist.rtns) == 2 assert len(hist.rtns) == 2
items = list(hist.items()) items = list(hist.items())
assert 'ls foobazz' == items[-1]['inp'] assert "ls foobazz" == items[-1]["inp"]
assert 0 == items[-1]['rtn'] assert 0 == items[-1]["rtn"]
assert 0 == hist.rtns[-1] assert 0 == hist.rtns[-1]
# Error # Error
hist.append({'inp': 'ls foo', 'rtn': 2}) hist.append({"inp": "ls foo", "rtn": 2})
assert len(hist) == 1 assert len(hist) == 1
items = list(hist.items()) items = list(hist.items())
assert 'ls foobazz' == items[-1]['inp'] assert "ls foobazz" == items[-1]["inp"]
assert 0 == items[-1]['rtn'] assert 0 == items[-1]["rtn"]
assert 2 == hist.rtns[-1] assert 2 == hist.rtns[-1]
# File now exists, success # File now exists, success
hist.append({'inp': 'ls foo', 'rtn': 0}) hist.append({"inp": "ls foo", "rtn": 0})
assert len(hist) == 2 assert len(hist) == 2
items = list(hist.items()) items = list(hist.items())
assert 'ls foo' == items[-1]['inp'] assert "ls foo" == items[-1]["inp"]
assert 0 == items[-1]['rtn'] assert 0 == items[-1]["rtn"]
assert 0 == hist.rtns[-1] assert 0 == hist.rtns[-1]
# Success # Success
hist.append({'inp': 'ls', 'rtn': 0}) hist.append({"inp": "ls", "rtn": 0})
assert len(hist) == 3 assert len(hist) == 3
items = list(hist.items()) items = list(hist.items())
assert 'ls' == items[-1]['inp'] assert "ls" == items[-1]["inp"]
assert 0 == items[-1]['rtn'] assert 0 == items[-1]["rtn"]
assert 0 == hist.rtns[-1] assert 0 == hist.rtns[-1]
# Dup # Dup
hist.append({'inp': 'ls', 'rtn': 0}) hist.append({"inp": "ls", "rtn": 0})
assert len(hist) == 3 assert len(hist) == 3
# Success # Success
hist.append({'inp': '/bin/ls', 'rtn': 0}) hist.append({"inp": "/bin/ls", "rtn": 0})
assert len(hist) == 4 assert len(hist) == 4
items = list(hist.items()) items = list(hist.items())
assert '/bin/ls' == items[-1]['inp'] assert "/bin/ls" == items[-1]["inp"]
assert 0 == items[-1]['rtn'] assert 0 == items[-1]["rtn"]
assert 0 == hist.rtns[-1] assert 0 == hist.rtns[-1]
# Error # Error
hist.append({'inp': 'ls bazz', 'rtn': 1}) hist.append({"inp": "ls bazz", "rtn": 1})
assert len(hist) == 4 assert len(hist) == 4
items = list(hist.items()) items = list(hist.items())
assert '/bin/ls' == items[-1]['inp'] assert "/bin/ls" == items[-1]["inp"]
assert 0 == items[-1]['rtn'] assert 0 == items[-1]["rtn"]
assert 'ls bazz' == hist.inps[-1] assert "ls bazz" == hist.inps[-1]
assert 1 == hist.rtns[-1] assert 1 == hist.rtns[-1]
# Error # Error
hist.append({'inp': 'ls bazz', 'rtn': -1}) hist.append({"inp": "ls bazz", "rtn": -1})
assert len(hist) == 4 assert len(hist) == 4
items = list(hist.items()) items = list(hist.items())
assert '/bin/ls' == items[-1]['inp'] assert "/bin/ls" == items[-1]["inp"]
assert 0 == items[-1]['rtn'] assert 0 == items[-1]["rtn"]
assert -1 == hist.rtns[-1] assert -1 == hist.rtns[-1]
@pytest.mark.parametrize('index, exp', [ @pytest.mark.parametrize(
(-1, ('grep from me', 'out', 0, (5, 6))), "index, exp",
(1, ('cat hello kitty', 'out', 0, (1, 2))), [
(slice(1, 3), [('cat hello kitty', 'out', 0, (1, 2)), (-1, ("grep from me", "out", 0, (5, 6))),
('abc', 'out', 0, (2, 3))]), (1, ("cat hello kitty", "out", 0, (1, 2))),
]) (
slice(1, 3),
[("cat hello kitty", "out", 0, (1, 2)), ("abc", "out", 0, (2, 3))],
),
],
)
def test_history_getitem(index, exp, hist, xonsh_builtins): def test_history_getitem(index, exp, hist, xonsh_builtins):
xonsh_builtins.__xonsh_env__['HISTCONTROL'] = set() xonsh_builtins.__xonsh_env__["HISTCONTROL"] = set()
xonsh_builtins.__xonsh_env__['XONSH_STORE_STDOUT'] = True xonsh_builtins.__xonsh_env__["XONSH_STORE_STDOUT"] = True
attrs = ('inp', 'out', 'rtn', 'ts') attrs = ("inp", "out", "rtn", "ts")
for ts, cmd in enumerate(CMDS): # populate the shell history for ts, cmd in enumerate(CMDS): # populate the shell history
entry = {k: v for k, v in zip(attrs, [cmd, 'out', 0, (ts, ts + 1)])} entry = {k: v for k, v in zip(attrs, [cmd, "out", 0, (ts, ts + 1)])}
hist.append(entry) hist.append(entry)
entry = hist[index] entry = hist[index]

View file

@ -16,30 +16,34 @@ imphooks.install_import_hooks()
@pytest.yield_fixture(autouse=True) @pytest.yield_fixture(autouse=True)
def imp_env(): def imp_env():
execer = Execer(unload=False) execer = Execer(unload=False)
builtins.__xonsh_env__ = Env({'PATH': [], 'PATHEXT': []}) builtins.__xonsh_env__ = Env({"PATH": [], "PATHEXT": []})
yield yield
unload_builtins() unload_builtins()
def test_import(): def test_import():
import sample import sample
assert ('hello mom jawaka\n' == sample.x)
assert "hello mom jawaka\n" == sample.x
def test_absolute_import(): def test_absolute_import():
from xpack import sample from xpack import sample
assert ('hello mom jawaka\n' == sample.x)
assert "hello mom jawaka\n" == sample.x
def test_relative_import(): def test_relative_import():
from xpack import relimp from xpack import relimp
assert ('hello mom jawaka\n' == relimp.sample.x)
assert ('hello mom jawaka\ndark chest of wonders' == relimp.y) assert "hello mom jawaka\n" == relimp.sample.x
assert "hello mom jawaka\ndark chest of wonders" == relimp.y
def test_sub_import(): def test_sub_import():
from xpack.sub import sample from xpack.sub import sample
assert ('hello mom jawaka\n' == sample.x)
assert "hello mom jawaka\n" == sample.x
TEST_DIR = os.path.dirname(__file__) TEST_DIR = os.path.dirname(__file__)
@ -47,11 +51,13 @@ TEST_DIR = os.path.dirname(__file__)
def test_module_dunder_file_attribute(): def test_module_dunder_file_attribute():
import sample import sample
exp = os.path.join(TEST_DIR, 'sample.xsh')
exp = os.path.join(TEST_DIR, "sample.xsh")
assert os.path.abspath(sample.__file__) == exp assert os.path.abspath(sample.__file__) == exp
def test_module_dunder_file_attribute_sub(): def test_module_dunder_file_attribute_sub():
from xpack.sub import sample from xpack.sub import sample
exp = os.path.join(TEST_DIR, 'xpack', 'sub', 'sample.xsh')
exp = os.path.join(TEST_DIR, "xpack", "sub", "sample.xsh")
assert os.path.abspath(sample.__file__) == exp assert os.path.abspath(sample.__file__) == exp

View file

@ -8,12 +8,18 @@ import pytest
import xonsh import xonsh
from xonsh.platform import ON_WINDOWS from xonsh.platform import ON_WINDOWS
from tools import (skip_if_on_windows, skip_if_on_darwin, skip_if_on_travis, from tools import (
ON_WINDOWS, ON_DARWIN, ON_TRAVIS) skip_if_on_windows,
skip_if_on_darwin,
skip_if_on_travis,
ON_WINDOWS,
ON_DARWIN,
ON_TRAVIS,
)
XONSH_PREFIX = xonsh.__file__ XONSH_PREFIX = xonsh.__file__
if 'site-packages' in XONSH_PREFIX: if "site-packages" in XONSH_PREFIX:
# must be installed version of xonsh # must be installed version of xonsh
num_up = 5 num_up = 5
else: else:
@ -21,34 +27,43 @@ else:
num_up = 2 num_up = 2
for i in range(num_up): for i in range(num_up):
XONSH_PREFIX = os.path.dirname(XONSH_PREFIX) XONSH_PREFIX = os.path.dirname(XONSH_PREFIX)
PATH = os.path.join(os.path.dirname(__file__), 'bin') + os.pathsep + \ PATH = (
os.path.join(XONSH_PREFIX, 'bin') + os.pathsep + \ os.path.join(os.path.dirname(__file__), "bin")
os.path.join(XONSH_PREFIX, 'Scripts') + os.pathsep + \ + os.pathsep
os.path.join(XONSH_PREFIX, 'scripts') + os.pathsep + \ + os.path.join(XONSH_PREFIX, "bin")
os.path.dirname(sys.executable) + os.pathsep + \ + os.pathsep
os.environ['PATH'] + os.path.join(XONSH_PREFIX, "Scripts")
+ os.pathsep
+ os.path.join(XONSH_PREFIX, "scripts")
+ os.pathsep
+ os.path.dirname(sys.executable)
+ os.pathsep
+ os.environ["PATH"]
)
skip_if_no_xonsh = pytest.mark.skipif(shutil.which('xonsh', path=PATH) is None, skip_if_no_xonsh = pytest.mark.skipif(
reason='xonsh not on path') shutil.which("xonsh", path=PATH) is None, reason="xonsh not on path"
)
def run_xonsh(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.STDOUT): def run_xonsh(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.STDOUT):
env = dict(os.environ) env = dict(os.environ)
env['PATH'] = PATH env["PATH"] = PATH
env['XONSH_DEBUG'] = '1' env["XONSH_DEBUG"] = "1"
env['XONSH_SHOW_TRACEBACK'] = '1' env["XONSH_SHOW_TRACEBACK"] = "1"
env['RAISE_SUBPROC_ERROR'] = '1' env["RAISE_SUBPROC_ERROR"] = "1"
env['PROMPT'] = '' env["PROMPT"] = ""
xonsh = 'xonsh.bat' if ON_WINDOWS else 'xon.sh' xonsh = "xonsh.bat" if ON_WINDOWS else "xon.sh"
xonsh = shutil.which(xonsh, path=PATH) xonsh = shutil.which(xonsh, path=PATH)
proc = sp.Popen([xonsh, '--no-rc'], proc = sp.Popen(
env=env, [xonsh, "--no-rc"],
stdin=stdin, env=env,
stdout=stdout, stdin=stdin,
stderr=stderr, stdout=stdout,
universal_newlines=True, stderr=stderr,
) universal_newlines=True,
)
try: try:
out, err = proc.communicate(input=cmd, timeout=10) out, err = proc.communicate(input=cmd, timeout=10)
except sp.TimeoutExpired: except sp.TimeoutExpired:
@ -75,16 +90,21 @@ def check_run_xonsh(cmd, fmt, exp):
# #
ALL_PLATFORMS = [ ALL_PLATFORMS = [
# test calling a function alias # test calling a function alias
(""" (
"""
def _f(): def _f():
print('hello') print('hello')
aliases['f'] = _f aliases['f'] = _f
f f
""", "hello\n", 0), """,
# test redirecting a function alias to a file "hello\n",
(""" 0,
),
# test redirecting a function alias to a file
(
"""
def _f(): def _f():
print('Wow Mom!') print('Wow Mom!')
@ -94,27 +114,39 @@ f > tttt
with open('tttt') as tttt: with open('tttt') as tttt:
s = tttt.read().strip() s = tttt.read().strip()
print('REDIRECTED OUTPUT: ' + s) print('REDIRECTED OUTPUT: ' + s)
""", "REDIRECTED OUTPUT: Wow Mom!\n", 0), """,
# test redirecting a function alias from stderr -> stdout "REDIRECTED OUTPUT: Wow Mom!\n",
(""" 0,
),
# test redirecting a function alias from stderr -> stdout
(
"""
def _f(args, stdin, stdout, stderr): def _f(args, stdin, stdout, stderr):
print('The Truth is Out There', file=stderr) print('The Truth is Out There', file=stderr)
aliases['f'] = _f aliases['f'] = _f
f e>o f e>o
""", "The Truth is Out There\n", 0), """,
# test system exit in function alias "The Truth is Out There\n",
(""" 0,
),
# test system exit in function alias
(
"""
import sys import sys
def _f(): def _f():
sys.exit(42) sys.exit(42)
aliases['f'] = _f aliases['f'] = _f
print(![f].returncode) print(![f].returncode)
""", "42\n", 0), """,
# test uncaptured streaming alias, "42\n",
# order actually printed in is non-deterministic 0,
(""" ),
# test uncaptured streaming alias,
# order actually printed in is non-deterministic
(
"""
def _test_stream(args, stdin, stdout, stderr): def _test_stream(args, stdin, stdout, stderr):
print('hallo on stream', file=stderr) print('hallo on stream', file=stderr)
print('hallo on stream', file=stdout) print('hallo on stream', file=stdout)
@ -123,9 +155,13 @@ def _test_stream(args, stdin, stdout, stderr):
aliases['test-stream'] = _test_stream aliases['test-stream'] = _test_stream
x = ![test-stream] x = ![test-stream]
print(x.returncode) print(x.returncode)
""", "hallo on stream\nhallo on stream\n1\n", 0), """,
# test captured streaming alias "hallo on stream\nhallo on stream\n1\n",
(""" 0,
),
# test captured streaming alias
(
"""
def _test_stream(args, stdin, stdout, stderr): def _test_stream(args, stdin, stdout, stderr):
print('hallo on err', file=stderr) print('hallo on err', file=stderr)
print('hallo on out', file=stdout) print('hallo on out', file=stdout)
@ -134,9 +170,13 @@ def _test_stream(args, stdin, stdout, stderr):
aliases['test-stream'] = _test_stream aliases['test-stream'] = _test_stream
x = !(test-stream) x = !(test-stream)
print(x.returncode) print(x.returncode)
""", "hallo on err\n1\n", 0), """,
# test piping aliases "hallo on err\n1\n",
(""" 0,
),
# test piping aliases
(
"""
def dummy(args, inn, out, err): def dummy(args, inn, out, err):
out.write('hey!') out.write('hey!')
return 0 return 0
@ -149,32 +189,48 @@ def dummy2(args, inn, out, err):
aliases['d'] = dummy aliases['d'] = dummy
aliases['d2'] = dummy2 aliases['d2'] = dummy2
d | d2 d | d2
""", "HEY!", 0), """,
# test output larger than most pipe buffers "HEY!",
(""" 0,
),
# test output larger than most pipe buffers
(
"""
def _g(args, stdin=None): def _g(args, stdin=None):
for i in range(1000): for i in range(1000):
print('x' * 100) print('x' * 100)
aliases['g'] = _g aliases['g'] = _g
g g
""", (("x"*100) + '\n') * 1000, 0), """,
# test piping 'real' command (("x" * 100) + "\n") * 1000,
(""" 0,
),
# test piping 'real' command
(
"""
with open('tttt', 'w') as fp: with open('tttt', 'w') as fp:
fp.write("Wow mom!\\n") fp.write("Wow mom!\\n")
![cat tttt | wc] ![cat tttt | wc]
""", ' 1 2 10\n' if ON_WINDOWS else " 1 2 9 <stdin>\n", 0), """,
# test double piping 'real' command " 1 2 10\n" if ON_WINDOWS else " 1 2 9 <stdin>\n",
(""" 0,
),
# test double piping 'real' command
(
"""
with open('tttt', 'w') as fp: with open('tttt', 'w') as fp:
fp.write("Wow mom!\\n") fp.write("Wow mom!\\n")
![cat tttt | wc | wc] ![cat tttt | wc | wc]
""", ' 1 3 24\n' if ON_WINDOWS else " 1 4 16 <stdin>\n", 0), """,
# test unthreadable alias (which should trigger a ProcPoxy call) " 1 3 24\n" if ON_WINDOWS else " 1 4 16 <stdin>\n",
(""" 0,
),
# test unthreadable alias (which should trigger a ProcPoxy call)
(
"""
from xonsh.tools import unthreadable from xonsh.tools import unthreadable
@unthreadable @unthreadable
@ -183,9 +239,13 @@ def _f():
aliases['f'] = _f aliases['f'] = _f
f f
""", "hello\n", 0), """,
# test ambiguous globs "hello\n",
(""" 0,
),
# test ambiguous globs
(
"""
import os import os
def _echo(args): def _echo(args):
@ -208,42 +268,56 @@ echo *_test.tst and echo *.tst
for f in files: for f in files:
os.remove(f) os.remove(f)
""", """,
'Actually.tst Actually_test.tst Complete.tst Complete_test.tst\n' "Actually.tst Actually_test.tst Complete.tst Complete_test.tst\n"
'Actually_test.tst Complete_test.tst\n' "Actually_test.tst Complete_test.tst\n"
'Actually_test.tst Complete_test.tst\n' "Actually_test.tst Complete_test.tst\n"
'Actually_test.tst Complete_test.tst\n' "Actually_test.tst Complete_test.tst\n"
'Actually.tst Actually_test.tst Complete.tst Complete_test.tst\n', "Actually.tst Actually_test.tst Complete.tst Complete_test.tst\n",
0), 0,
# ),
# test ambiguous line continuations #
# # test ambiguous line continuations
(""" #
(
"""
def _echo(args): def _echo(args):
print(' '.join(args)) print(' '.join(args))
aliases['echo'] = _echo aliases['echo'] = _echo
echo --option1 \ echo --option1 \
--option2 --option2
""", '--option1 --option2\n', 0), """,
# "--option1 --option2\n",
# test @$() with aliases 0,
# ),
(""" #
# test @$() with aliases
#
(
"""
aliases['ls'] = 'spam spam sausage spam' aliases['ls'] = 'spam spam sausage spam'
echo @$(which ls) echo @$(which ls)
""", 'spam spam sausage spam\n', 0), """,
# "spam spam sausage spam\n",
# test redirection 0,
# ),
(""" #
# test redirection
#
(
"""
echo Just the place for a snark. >tttt echo Just the place for a snark. >tttt
cat tttt cat tttt
""", 'Just the place for a snark.\n', 0), """,
# "Just the place for a snark.\n",
# Test completion registration and subproc stack 0,
# ),
(""" #
# Test completion registration and subproc stack
#
(
"""
def _f(): def _f():
def j(): def j():
pass pass
@ -260,12 +334,14 @@ def _f():
_f() _f()
del _f del _f
""" """,
, '', 0), "",
0,
),
] ]
@pytest.mark.parametrize('case', ALL_PLATFORMS) @pytest.mark.parametrize("case", ALL_PLATFORMS)
def test_script(case): def test_script(case):
script, exp_out, exp_rtn = case script, exp_out, exp_rtn = case
out, err, rtn = run_xonsh(script) out, err, rtn = run_xonsh(script)
@ -274,99 +350,121 @@ def test_script(case):
ALL_PLATFORMS_STDERR = [ ALL_PLATFORMS_STDERR = [
# test redirecting a function alias # test redirecting a function alias
(""" (
"""
def _f(args, stdin, stdout): def _f(args, stdin, stdout):
print('Wow Mom!', file=stdout) print('Wow Mom!', file=stdout)
aliases['f'] = _f aliases['f'] = _f
f o>e f o>e
""", "Wow Mom!\n", 0), """,
"Wow Mom!\n",
0,
)
] ]
@pytest.mark.parametrize('case', ALL_PLATFORMS_STDERR)
@pytest.mark.parametrize("case", ALL_PLATFORMS_STDERR)
def test_script_stderr(case): def test_script_stderr(case):
script, exp_err, exp_rtn = case script, exp_err, exp_rtn = case
out, err, rtn = run_xonsh(script, stderr=sp.PIPE) out, err, rtn = run_xonsh(script, stderr=sp.PIPE)
assert exp_err == err assert exp_err == err
assert exp_rtn == rtn assert exp_rtn == rtn
@skip_if_on_windows @skip_if_on_windows
@pytest.mark.parametrize('cmd, fmt, exp', [ @pytest.mark.parametrize(
('pwd', None, lambda: os.getcwd() + '\n'), "cmd, fmt, exp",
('echo WORKING', None, 'WORKING\n'), [
('ls -f', lambda out: out.splitlines().sort(), os.listdir().sort()), ("pwd", None, lambda: os.getcwd() + "\n"),
]) ("echo WORKING", None, "WORKING\n"),
("ls -f", lambda out: out.splitlines().sort(), os.listdir().sort()),
],
)
def test_single_command_no_windows(cmd, fmt, exp): def test_single_command_no_windows(cmd, fmt, exp):
check_run_xonsh(cmd, fmt, exp) check_run_xonsh(cmd, fmt, exp)
def test_eof_syntax_error(): def test_eof_syntax_error():
"""Ensures syntax errors for EOF appear on last line.""" """Ensures syntax errors for EOF appear on last line."""
script = 'x = 1\na = (1, 0\n' script = "x = 1\na = (1, 0\n"
out, err, rtn = run_xonsh(script, stderr=sp.PIPE) out, err, rtn = run_xonsh(script, stderr=sp.PIPE)
assert ':0:0: EOF in multi-line statement' not in err assert ":0:0: EOF in multi-line statement" not in err
assert ':2:0: EOF in multi-line statement' in err assert ":2:0: EOF in multi-line statement" in err
def test_open_quote_syntax_error(): def test_open_quote_syntax_error():
script = ('#!/usr/bin/env xonsh\n\n' script = (
'echo "This is line 3"\n' "#!/usr/bin/env xonsh\n\n"
'print ("This is line 4")\n' 'echo "This is line 3"\n'
'x = "This is a string where I forget the closing quote on line 5\n' 'print ("This is line 4")\n'
'echo "This is line 6"\n') 'x = "This is a string where I forget the closing quote on line 5\n'
'echo "This is line 6"\n'
)
out, err, rtn = run_xonsh(script, stderr=sp.PIPE) out, err, rtn = run_xonsh(script, stderr=sp.PIPE)
assert """:3:5: ('code: "This is line 3"',)""" not in err assert """:3:5: ('code: "This is line 3"',)""" not in err
assert ':5:4: "' in err assert ':5:4: "' in err
assert 'SyntaxError:' in err assert "SyntaxError:" in err
_bad_case = pytest.mark.skipif(ON_DARWIN or ON_WINDOWS or ON_TRAVIS, _bad_case = pytest.mark.skipif(
reason="bad platforms") ON_DARWIN or ON_WINDOWS or ON_TRAVIS, reason="bad platforms"
)
@_bad_case @_bad_case
def test_printfile(): def test_printfile():
check_run_xonsh('printfile.xsh', None, 'printfile.xsh\n') check_run_xonsh("printfile.xsh", None, "printfile.xsh\n")
@_bad_case @_bad_case
def test_printname(): def test_printname():
check_run_xonsh('printfile.xsh', None, 'printfile.xsh\n') check_run_xonsh("printfile.xsh", None, "printfile.xsh\n")
@_bad_case @_bad_case
def test_sourcefile(): def test_sourcefile():
check_run_xonsh('printfile.xsh', None, 'printfile.xsh\n') check_run_xonsh("printfile.xsh", None, "printfile.xsh\n")
@_bad_case @_bad_case
@pytest.mark.parametrize('cmd, fmt, exp', [ @pytest.mark.parametrize(
# test subshell wrapping "cmd, fmt, exp",
(""" [
# test subshell wrapping
(
"""
with open('tttt', 'w') as fp: with open('tttt', 'w') as fp:
fp.write("Wow mom!\\n") fp.write("Wow mom!\\n")
(wc) < tttt (wc) < tttt
""", None, " 1 2 9 <stdin>\n"), """,
# test subshell statement wrapping None,
(""" " 1 2 9 <stdin>\n",
),
# test subshell statement wrapping
(
"""
with open('tttt', 'w') as fp: with open('tttt', 'w') as fp:
fp.write("Wow mom!\\n") fp.write("Wow mom!\\n")
(wc;) < tttt (wc;) < tttt
""", None, " 1 2 9 <stdin>\n"), """,
]) None,
" 1 2 9 <stdin>\n",
),
],
)
def test_subshells(cmd, fmt, exp): def test_subshells(cmd, fmt, exp):
check_run_xonsh(cmd, fmt, exp) check_run_xonsh(cmd, fmt, exp)
@skip_if_on_windows @skip_if_on_windows
@pytest.mark.parametrize('cmd, exp', [ @pytest.mark.parametrize("cmd, exp", [("pwd", lambda: os.getcwd() + "\n")])
('pwd', lambda: os.getcwd() + '\n'),
])
def test_redirect_out_to_file(cmd, exp, tmpdir): def test_redirect_out_to_file(cmd, exp, tmpdir):
outfile = tmpdir.mkdir('xonsh_test_dir').join('xonsh_test_file') outfile = tmpdir.mkdir("xonsh_test_dir").join("xonsh_test_file")
command = '{} > {}\n'.format(cmd, outfile) command = "{} > {}\n".format(cmd, outfile)
out, _, _ = run_xonsh(command) out, _, _ = run_xonsh(command)
content = outfile.read() content = outfile.read()
if callable(exp): if callable(exp):

View file

@ -8,13 +8,18 @@ from xonsh.tools import EnvPath
from xonsh.jsonutils import serialize_xonsh_json from xonsh.jsonutils import serialize_xonsh_json
@pytest.mark.parametrize(
@pytest.mark.parametrize('inp', [ "inp",
42, "yo", ["hello"], {"x": 65}, [
EnvPath(["wakka", "jawaka"]), 42,
["y", EnvPath(["wakka", "jawaka"])], "yo",
{"z": EnvPath(["wakka", "jawaka"])}, ["hello"],
]) {"x": 65},
EnvPath(["wakka", "jawaka"]),
["y", EnvPath(["wakka", "jawaka"])],
{"z": EnvPath(["wakka", "jawaka"])},
],
)
def test_serialize_xonsh_json_roundtrip(inp): def test_serialize_xonsh_json_roundtrip(inp):
s = json.dumps(inp, default=serialize_xonsh_json) s = json.dumps(inp, default=serialize_xonsh_json)
obs = json.loads(s) obs = json.loads(s)

View file

@ -5,7 +5,7 @@ from xonsh.lazyasd import LazyObject
# LazyObject Tests # LazyObject Tests
# #
def test_lazyobject_getitem():
lo = LazyObject(lambda: {'x': 1}, {}, 'lo')
assert 1 == lo['x']
def test_lazyobject_getitem():
lo = LazyObject(lambda: {"x": 1}, {}, "lo")
assert 1 == lo["x"]

View file

@ -5,65 +5,78 @@ from io import StringIO
from xonsh.lazyjson import index, ljdump, LazyJSON, LJNode from xonsh.lazyjson import index, ljdump, LazyJSON, LJNode
def test_index_int(): def test_index_int():
exp = {'offsets': 0, 'sizes': 2} exp = {"offsets": 0, "sizes": 2}
s, obs = index(42) s, obs = index(42)
assert exp == obs assert exp == obs
def test_index_str(): def test_index_str():
exp = {'offsets': 0, 'sizes': 7} exp = {"offsets": 0, "sizes": 7}
s, obs = index('wakka') s, obs = index("wakka")
assert exp == obs assert exp == obs
def test_index_list_ints(): def test_index_list_ints():
exp = {'offsets': [1, 4, 0], 'sizes': [1, 2, 8]} exp = {"offsets": [1, 4, 0], "sizes": [1, 2, 8]}
s, obs = index([1, 42]) s, obs = index([1, 42])
assert exp == obs assert exp == obs
def test_index_list_str(): def test_index_list_str():
exp = {'offsets': [1, 10, 0], 'sizes': [7, 8, 20]} exp = {"offsets": [1, 10, 0], "sizes": [7, 8, 20]}
s, obs = index(['wakka', 'jawaka']) s, obs = index(["wakka", "jawaka"])
assert exp == obs assert exp == obs
def test_index_list_str_int(): def test_index_list_str_int():
exp = {'offsets': [1, 10, 0], 'sizes': [7, 2, 14]} exp = {"offsets": [1, 10, 0], "sizes": [7, 2, 14]}
s, obs = index(['wakka', 42]) s, obs = index(["wakka", 42])
assert exp == obs assert exp == obs
def test_index_list_int_str(): def test_index_list_int_str():
exp = {'offsets': [1, 5, 14, 0], 'sizes': [2, 7, 8, 24]} exp = {"offsets": [1, 5, 14, 0], "sizes": [2, 7, 8, 24]}
s, obs = index([42, 'wakka', 'jawaka']) s, obs = index([42, "wakka", "jawaka"])
assert exp == obs assert exp == obs
def test_index_dict_int(): def test_index_dict_int():
exp = {'offsets': {'wakka': 10, '__total__': 0}, exp = {
'sizes': {'wakka': 2, '__total__': 14}} "offsets": {"wakka": 10, "__total__": 0},
s, obs = index({'wakka': 42}) "sizes": {"wakka": 2, "__total__": 14},
}
s, obs = index({"wakka": 42})
assert exp == obs assert exp == obs
def test_index_dict_str(): def test_index_dict_str():
exp = {'offsets': {'wakka': 10, '__total__': 0}, exp = {
'sizes': {'wakka': 8, '__total__': 20}} "offsets": {"wakka": 10, "__total__": 0},
s, obs = index({'wakka': 'jawaka'}) "sizes": {"wakka": 8, "__total__": 20},
}
s, obs = index({"wakka": "jawaka"})
assert exp == obs assert exp == obs
def test_index_dict_dict_int(): def test_index_dict_dict_int():
exp = {'offsets': {'wakka': {'jawaka': 21, '__total__': 10}, exp = {
'__total__': 0, "offsets": {"wakka": {"jawaka": 21, "__total__": 10}, "__total__": 0},
}, "sizes": {"wakka": {"jawaka": 2, "__total__": 15}, "__total__": 27},
'sizes': {'wakka': {'jawaka': 2, '__total__': 15}, }
'__total__': 27} s, obs = index({"wakka": {"jawaka": 42}})
}
s, obs = index({'wakka': {'jawaka': 42}})
assert exp == obs assert exp == obs
def test_lazy_load_index(): def test_lazy_load_index():
f = StringIO() f = StringIO()
ljdump({'wakka': 42}, f) ljdump({"wakka": 42}, f)
f.seek(0) f.seek(0)
lj = LazyJSON(f) lj = LazyJSON(f)
assert {'wakka': 10, '__total__': 0} == lj.offsets assert {"wakka": 10, "__total__": 0} == lj.offsets
assert {'wakka': 2, '__total__': 14} == lj.sizes assert {"wakka": 2, "__total__": 14} == lj.sizes
def test_lazy_int(): def test_lazy_int():
f = StringIO() f = StringIO()
@ -72,12 +85,14 @@ def test_lazy_int():
lj = LazyJSON(f) lj = LazyJSON(f)
assert 42 == lj.load() assert 42 == lj.load()
def test_lazy_str(): def test_lazy_str():
f = StringIO() f = StringIO()
ljdump('wakka', f) ljdump("wakka", f)
f.seek(0) f.seek(0)
lj = LazyJSON(f) lj = LazyJSON(f)
assert 'wakka' == lj.load() assert "wakka" == lj.load()
def test_lazy_list_empty(): def test_lazy_list_empty():
x = [] x = []
@ -88,6 +103,7 @@ def test_lazy_list_empty():
assert 0 == len(lj) assert 0 == len(lj)
assert x == lj.load() assert x == lj.load()
def test_lazy_list_ints(): def test_lazy_list_ints():
x = [0, 1, 6, 28, 496, 8128] x = [0, 1, 6, 28, 496, 8128]
f = StringIO() f = StringIO()
@ -99,17 +115,19 @@ def test_lazy_list_ints():
assert x == [_ for _ in lj] assert x == [_ for _ in lj]
assert x == lj.load() assert x == lj.load()
def test_lazy_list_str(): def test_lazy_list_str():
x = ['I', 'have', 'seen', 'the', 'wind', 'blow'] x = ["I", "have", "seen", "the", "wind", "blow"]
f = StringIO() f = StringIO()
ljdump(x, f) ljdump(x, f)
f.seek(0) f.seek(0)
lj = LazyJSON(f) lj = LazyJSON(f)
assert 'the' == lj[3] assert "the" == lj[3]
assert x[:2:-2] == lj[:2:-2] assert x[:2:-2] == lj[:2:-2]
assert x == [_ for _ in lj] assert x == [_ for _ in lj]
assert x == lj.load() assert x == lj.load()
def test_lazy_list_list_ints(): def test_lazy_list_list_ints():
x = [[0, 1], [6, 28], [496, 8128]] x = [[0, 1], [6, 28], [496, 8128]]
f = StringIO() f = StringIO()
@ -121,6 +139,7 @@ def test_lazy_list_list_ints():
assert [6 == 28], lj[1].load() assert [6 == 28], lj[1].load()
assert x == lj.load() assert x == lj.load()
def test_lazy_dict_empty(): def test_lazy_dict_empty():
x = {} x = {}
f = StringIO() f = StringIO()
@ -130,24 +149,26 @@ def test_lazy_dict_empty():
assert 0 == len(lj) assert 0 == len(lj)
assert x == lj.load() assert x == lj.load()
def test_lazy_dict(): def test_lazy_dict():
f = StringIO() f = StringIO()
ljdump({'wakka': 42}, f) ljdump({"wakka": 42}, f)
f.seek(0) f.seek(0)
lj = LazyJSON(f) lj = LazyJSON(f)
assert ['wakka'] == list(lj.keys()) assert ["wakka"] == list(lj.keys())
assert 42 == lj['wakka'] assert 42 == lj["wakka"]
assert 1 == len(lj) assert 1 == len(lj)
assert {'wakka': 42} == lj.load() assert {"wakka": 42} == lj.load()
def test_lazy_dict_dict_int(): def test_lazy_dict_dict_int():
x = {'wakka': {'jawaka': 42}} x = {"wakka": {"jawaka": 42}}
f = StringIO() f = StringIO()
ljdump(x, f) ljdump(x, f)
f.seek(0) f.seek(0)
lj = LazyJSON(f) lj = LazyJSON(f)
assert ['wakka'] == list(lj.keys()) assert ["wakka"] == list(lj.keys())
assert isinstance(lj['wakka'], LJNode) assert isinstance(lj["wakka"], LJNode)
assert 42 == lj['wakka']['jawaka'] assert 42 == lj["wakka"]["jawaka"]
assert 1 == len(lj) assert 1 == len(lj)
assert x == lj.load() assert x == lj.load()

View file

@ -4,7 +4,8 @@ from __future__ import unicode_literals, print_function
import os import os
import sys import sys
from collections import Sequence from collections import Sequence
sys.path.insert(0, os.path.abspath('..')) # FIXME
sys.path.insert(0, os.path.abspath("..")) # FIXME
from pprint import pformat from pprint import pformat
import pytest import pytest
@ -17,19 +18,20 @@ except ImportError:
from xonsh.lexer import Lexer from xonsh.lexer import Lexer
LEXER_ARGS = {'lextab': 'lexer_test_table', 'debug': 0} LEXER_ARGS = {"lextab": "lexer_test_table", "debug": 0}
def ensure_tuple(x): def ensure_tuple(x):
if isinstance(x, LexToken): if isinstance(x, LexToken):
# line numbers can no longer be solely determined from the lexer # line numbers can no longer be solely determined from the lexer
#x = (x.type, x.value, x.lineno, x.lexpos) # x = (x.type, x.value, x.lineno, x.lexpos)
x = (x.type, x.value, x.lexpos) x = (x.type, x.value, x.lexpos)
elif isinstance(x, tuple): elif isinstance(x, tuple):
pass pass
elif isinstance(x, Sequence): elif isinstance(x, Sequence):
x = tuple(x) x = tuple(x)
else: else:
raise TypeError('{0} is not a sequence'.format(x)) raise TypeError("{0} is not a sequence".format(x))
return x return x
@ -43,7 +45,7 @@ def tokens_equal(x, y):
def assert_token_equal(x, y): def assert_token_equal(x, y):
"""Asserts that two tokens are equal.""" """Asserts that two tokens are equal."""
if not tokens_equal(x, y): if not tokens_equal(x, y):
msg = 'The tokens differ: {0!r} != {1!r}'.format(x, y) msg = "The tokens differ: {0!r} != {1!r}".format(x, y)
pytest.fail(msg) pytest.fail(msg)
return True return True
@ -51,15 +53,15 @@ def assert_token_equal(x, y):
def assert_tokens_equal(x, y): def assert_tokens_equal(x, y):
"""Asserts that two token sequences are equal.""" """Asserts that two token sequences are equal."""
if len(x) != len(y): if len(x) != len(y):
msg = 'The tokens sequences have different lengths: {0!r} != {1!r}\n' msg = "The tokens sequences have different lengths: {0!r} != {1!r}\n"
msg += '# x\n{2}\n\n# y\n{3}' msg += "# x\n{2}\n\n# y\n{3}"
pytest.fail(msg.format(len(x), len(y), pformat(x), pformat(y))) pytest.fail(msg.format(len(x), len(y), pformat(x), pformat(y)))
diffs = [(a, b) for a, b in zip(x, y) if not tokens_equal(a, b)] diffs = [(a, b) for a, b in zip(x, y) if not tokens_equal(a, b)]
if len(diffs) > 0: if len(diffs) > 0:
msg = ['The token sequences differ: '] msg = ["The token sequences differ: "]
for a, b in diffs: for a, b in diffs:
msg += ['', '- ' + repr(a), '+ ' + repr(b)] msg += ["", "- " + repr(a), "+ " + repr(b)]
msg = '\n'.join(msg) msg = "\n".join(msg)
pytest.fail(msg) pytest.fail(msg)
return True return True
@ -69,8 +71,8 @@ def check_token(inp, exp):
l.input(inp) l.input(inp)
obs = list(l) obs = list(l)
if len(obs) != 1: if len(obs) != 1:
msg = 'The observed sequence does not have length-1: {0!r} != 1\n' msg = "The observed sequence does not have length-1: {0!r} != 1\n"
msg += '# obs\n{1}' msg += "# obs\n{1}"
pytest.fail(msg.format(len(obs), pformat(obs))) pytest.fail(msg.format(len(obs), pformat(obs)))
return assert_token_equal(exp, obs[0]) return assert_token_equal(exp, obs[0])
@ -84,347 +86,365 @@ def check_tokens(inp, exp):
def check_tokens_subproc(inp, exp, stop=-1): def check_tokens_subproc(inp, exp, stop=-1):
l = Lexer() l = Lexer()
l.input('$[{}]'.format(inp)) l.input("$[{}]".format(inp))
obs = list(l)[1:stop] obs = list(l)[1:stop]
return assert_tokens_equal(exp, obs) return assert_tokens_equal(exp, obs)
def test_int_literal(): def test_int_literal():
assert check_token('42', ['NUMBER', '42', 0]) assert check_token("42", ["NUMBER", "42", 0])
assert check_token('4_2', ['NUMBER', '4_2', 0]) assert check_token("4_2", ["NUMBER", "4_2", 0])
def test_hex_literal(): def test_hex_literal():
assert check_token('0x42', ['NUMBER', '0x42', 0]) assert check_token("0x42", ["NUMBER", "0x42", 0])
assert check_token('0x4_2', ['NUMBER', '0x4_2', 0]) assert check_token("0x4_2", ["NUMBER", "0x4_2", 0])
def test_oct_o_literal(): def test_oct_o_literal():
assert check_token('0o42', ['NUMBER', '0o42', 0]) assert check_token("0o42", ["NUMBER", "0o42", 0])
assert check_token('0o4_2', ['NUMBER', '0o4_2', 0]) assert check_token("0o4_2", ["NUMBER", "0o4_2", 0])
def test_bin_literal(): def test_bin_literal():
assert check_token('0b101010', ['NUMBER', '0b101010', 0]) assert check_token("0b101010", ["NUMBER", "0b101010", 0])
assert check_token('0b10_10_10', ['NUMBER', '0b10_10_10', 0]) assert check_token("0b10_10_10", ["NUMBER", "0b10_10_10", 0])
def test_indent(): def test_indent():
exp = [('INDENT', ' \t ', 0), exp = [("INDENT", " \t ", 0), ("NUMBER", "42", 5), ("DEDENT", "", 0)]
('NUMBER', '42', 5), assert check_tokens(" \t 42", exp)
('DEDENT', '', 0)]
assert check_tokens(' \t 42', exp)
def test_post_whitespace(): def test_post_whitespace():
inp = '42 \t ' inp = "42 \t "
exp = [('NUMBER', '42', 0)] exp = [("NUMBER", "42", 0)]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_internal_whitespace(): def test_internal_whitespace():
inp = '42 +\t65' inp = "42 +\t65"
exp = [('NUMBER', '42', 0), exp = [("NUMBER", "42", 0), ("PLUS", "+", 4), ("NUMBER", "65", 6)]
('PLUS', '+', 4),
('NUMBER', '65', 6),]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_indent_internal_whitespace(): def test_indent_internal_whitespace():
inp = ' 42 +\t65' inp = " 42 +\t65"
exp = [('INDENT', ' ', 0), exp = [
('NUMBER', '42', 1), ("INDENT", " ", 0),
('PLUS', '+', 5), ("NUMBER", "42", 1),
('NUMBER', '65', 7), ("PLUS", "+", 5),
('DEDENT', '', 0)] ("NUMBER", "65", 7),
("DEDENT", "", 0),
]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_assignment(): def test_assignment():
inp = 'x = 42' inp = "x = 42"
exp = [('NAME', 'x', 0), exp = [("NAME", "x", 0), ("EQUALS", "=", 2), ("NUMBER", "42", 4)]
('EQUALS', '=', 2),
('NUMBER', '42', 4),]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_multiline(): def test_multiline():
inp = 'x\ny' inp = "x\ny"
exp = [('NAME', 'x', 0), exp = [("NAME", "x", 0), ("NEWLINE", "\n", 1), ("NAME", "y", 0)]
('NEWLINE', '\n', 1),
('NAME', 'y', 0),]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_atdollar_expression(): def test_atdollar_expression():
inp = '@$(which python)' inp = "@$(which python)"
exp = [('ATDOLLAR_LPAREN', '@$(', 0), exp = [
('NAME', 'which', 3), ("ATDOLLAR_LPAREN", "@$(", 0),
('WS', ' ', 8), ("NAME", "which", 3),
('NAME', 'python', 9), ("WS", " ", 8),
('RPAREN', ')', 15)] ("NAME", "python", 9),
("RPAREN", ")", 15),
]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_and(): def test_and():
assert check_token('and', ['AND', 'and', 0]) assert check_token("and", ["AND", "and", 0])
def test_ampersand(): def test_ampersand():
assert check_token('&', ['AMPERSAND', '&', 0]) assert check_token("&", ["AMPERSAND", "&", 0])
def test_not_really_and_pre(): def test_not_really_and_pre():
inp = "![foo-and]" inp = "![foo-and]"
exp = [ exp = [
('BANG_LBRACKET', '![', 0), ("BANG_LBRACKET", "![", 0),
('NAME', 'foo', 2), ("NAME", "foo", 2),
('MINUS', '-', 5), ("MINUS", "-", 5),
('NAME', 'and', 6), ("NAME", "and", 6),
('RBRACKET', ']', 9), ("RBRACKET", "]", 9),
] ]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_not_really_and_post(): def test_not_really_and_post():
inp = "![and-bar]" inp = "![and-bar]"
exp = [ exp = [
('BANG_LBRACKET', '![', 0), ("BANG_LBRACKET", "![", 0),
('NAME', 'and', 2), ("NAME", "and", 2),
('MINUS', '-', 5), ("MINUS", "-", 5),
('NAME', 'bar', 6), ("NAME", "bar", 6),
('RBRACKET', ']', 9), ("RBRACKET", "]", 9),
] ]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_not_really_and_pre_post(): def test_not_really_and_pre_post():
inp = "![foo-and-bar]" inp = "![foo-and-bar]"
exp = [ exp = [
('BANG_LBRACKET', '![', 0), ("BANG_LBRACKET", "![", 0),
('NAME', 'foo', 2), ("NAME", "foo", 2),
('MINUS', '-', 5), ("MINUS", "-", 5),
('NAME', 'and', 6), ("NAME", "and", 6),
('MINUS', '-', 9), ("MINUS", "-", 9),
('NAME', 'bar', 10), ("NAME", "bar", 10),
('RBRACKET', ']', 13), ("RBRACKET", "]", 13),
] ]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_not_really_or_pre(): def test_not_really_or_pre():
inp = "![foo-or]" inp = "![foo-or]"
exp = [ exp = [
('BANG_LBRACKET', '![', 0), ("BANG_LBRACKET", "![", 0),
('NAME', 'foo', 2), ("NAME", "foo", 2),
('MINUS', '-', 5), ("MINUS", "-", 5),
('NAME', 'or', 6), ("NAME", "or", 6),
('RBRACKET', ']', 8), ("RBRACKET", "]", 8),
] ]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_not_really_or_post(): def test_not_really_or_post():
inp = "![or-bar]" inp = "![or-bar]"
exp = [ exp = [
('BANG_LBRACKET', '![', 0), ("BANG_LBRACKET", "![", 0),
('NAME', 'or', 2), ("NAME", "or", 2),
('MINUS', '-', 4), ("MINUS", "-", 4),
('NAME', 'bar', 5), ("NAME", "bar", 5),
('RBRACKET', ']', 8), ("RBRACKET", "]", 8),
] ]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_not_really_or_pre_post(): def test_not_really_or_pre_post():
inp = "![foo-or-bar]" inp = "![foo-or-bar]"
exp = [ exp = [
('BANG_LBRACKET', '![', 0), ("BANG_LBRACKET", "![", 0),
('NAME', 'foo', 2), ("NAME", "foo", 2),
('MINUS', '-', 5), ("MINUS", "-", 5),
('NAME', 'or', 6), ("NAME", "or", 6),
('MINUS', '-', 8), ("MINUS", "-", 8),
('NAME', 'bar', 9), ("NAME", "bar", 9),
('RBRACKET', ']', 12), ("RBRACKET", "]", 12),
] ]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_subproc_line_cont_space(): def test_subproc_line_cont_space():
inp = ("![echo --option1 value1 \\\n" inp = (
" --option2 value2 \\\n" "![echo --option1 value1 \\\n"
" --optionZ valueZ]") " --option2 value2 \\\n"
" --optionZ valueZ]"
)
exp = [ exp = [
('BANG_LBRACKET', '![', 0), ("BANG_LBRACKET", "![", 0),
('NAME', 'echo', 2), ("NAME", "echo", 2),
('WS', ' ', 6), ("WS", " ", 6),
('MINUS', '-', 7), ("MINUS", "-", 7),
('MINUS', '-', 8), ("MINUS", "-", 8),
('NAME', 'option1', 9), ("NAME", "option1", 9),
('WS', ' ', 16), ("WS", " ", 16),
('NAME', 'value1', 17), ("NAME", "value1", 17),
('WS', ' ', 23), ("WS", " ", 23),
('MINUS', '-', 5), ("MINUS", "-", 5),
('MINUS', '-', 6), ("MINUS", "-", 6),
('NAME', 'option2', 7), ("NAME", "option2", 7),
('WS', ' ', 14), ("WS", " ", 14),
('NAME', 'value2', 15), ("NAME", "value2", 15),
('WS', ' ', 21), ("WS", " ", 21),
('MINUS', '-', 5), ("MINUS", "-", 5),
('MINUS', '-', 6), ("MINUS", "-", 6),
('NAME', 'optionZ', 7), ("NAME", "optionZ", 7),
('WS', ' ', 14), ("WS", " ", 14),
('NAME', 'valueZ', 15), ("NAME", "valueZ", 15),
('RBRACKET',']', 21), ("RBRACKET", "]", 21),
] ]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_subproc_line_cont_nospace(): def test_subproc_line_cont_nospace():
inp = ("![echo --option1 value1\\\n" inp = (
" --option2 value2\\\n" "![echo --option1 value1\\\n"
" --optionZ valueZ]") " --option2 value2\\\n"
" --optionZ valueZ]"
)
exp = [ exp = [
('BANG_LBRACKET', '![', 0), ("BANG_LBRACKET", "![", 0),
('NAME', 'echo', 2), ("NAME", "echo", 2),
('WS', ' ', 6), ("WS", " ", 6),
('MINUS', '-', 7), ("MINUS", "-", 7),
('MINUS', '-', 8), ("MINUS", "-", 8),
('NAME', 'option1', 9), ("NAME", "option1", 9),
('WS', ' ', 16), ("WS", " ", 16),
('NAME', 'value1', 17), ("NAME", "value1", 17),
('WS', '\\', 23), ("WS", "\\", 23),
('MINUS', '-', 5), ("MINUS", "-", 5),
('MINUS', '-', 6), ("MINUS", "-", 6),
('NAME', 'option2', 7), ("NAME", "option2", 7),
('WS', ' ', 14), ("WS", " ", 14),
('NAME', 'value2', 15), ("NAME", "value2", 15),
('WS', '\\', 21), ("WS", "\\", 21),
('MINUS', '-', 5), ("MINUS", "-", 5),
('MINUS', '-', 6), ("MINUS", "-", 6),
('NAME', 'optionZ', 7), ("NAME", "optionZ", 7),
('WS', ' ', 14), ("WS", " ", 14),
('NAME', 'valueZ', 15), ("NAME", "valueZ", 15),
('RBRACKET',']', 21), ("RBRACKET", "]", 21),
] ]
assert check_tokens(inp, exp) assert check_tokens(inp, exp)
def test_atdollar(): def test_atdollar():
assert check_token('@$', ['ATDOLLAR', '@$', 0]) assert check_token("@$", ["ATDOLLAR", "@$", 0])
def test_doubleamp(): def test_doubleamp():
assert check_token('&&', ['AND', 'and', 0]) assert check_token("&&", ["AND", "and", 0])
def test_pipe(): def test_pipe():
assert check_token('|', ['PIPE', '|', 0]) assert check_token("|", ["PIPE", "|", 0])
def test_doublepipe(): def test_doublepipe():
assert check_token('||', ['OR', 'or', 0]) assert check_token("||", ["OR", "or", 0])
def test_single_quote_literal(): def test_single_quote_literal():
assert check_token("'yo'", ['STRING', "'yo'", 0]) assert check_token("'yo'", ["STRING", "'yo'", 0])
def test_double_quote_literal(): def test_double_quote_literal():
assert check_token('"yo"', ['STRING', '"yo"', 0]) assert check_token('"yo"', ["STRING", '"yo"', 0])
def test_triple_single_quote_literal(): def test_triple_single_quote_literal():
assert check_token("'''yo'''", ['STRING', "'''yo'''", 0]) assert check_token("'''yo'''", ["STRING", "'''yo'''", 0])
def test_triple_double_quote_literal(): def test_triple_double_quote_literal():
assert check_token('"""yo"""', ['STRING', '"""yo"""', 0]) assert check_token('"""yo"""', ["STRING", '"""yo"""', 0])
def test_single_raw_string_literal(): def test_single_raw_string_literal():
assert check_token("r'yo'", ['STRING', "r'yo'", 0]) assert check_token("r'yo'", ["STRING", "r'yo'", 0])
def test_double_raw_string_literal(): def test_double_raw_string_literal():
assert check_token('r"yo"', ['STRING', 'r"yo"', 0]) assert check_token('r"yo"', ["STRING", 'r"yo"', 0])
def test_single_f_string_literal(): def test_single_f_string_literal():
assert check_token("f'{yo}'", ['STRING', "f'{yo}'", 0]) assert check_token("f'{yo}'", ["STRING", "f'{yo}'", 0])
def test_double_f_string_literal(): def test_double_f_string_literal():
assert check_token('f"{yo}"', ['STRING', 'f"{yo}"', 0]) assert check_token('f"{yo}"', ["STRING", 'f"{yo}"', 0])
def test_single_unicode_literal(): def test_single_unicode_literal():
assert check_token("u'yo'", ['STRING', "u'yo'", 0]) assert check_token("u'yo'", ["STRING", "u'yo'", 0])
def test_double_unicode_literal(): def test_double_unicode_literal():
assert check_token('u"yo"', ['STRING', 'u"yo"', 0]) assert check_token('u"yo"', ["STRING", 'u"yo"', 0])
def test_single_bytes_literal(): def test_single_bytes_literal():
assert check_token("b'yo'", ['STRING', "b'yo'", 0]) assert check_token("b'yo'", ["STRING", "b'yo'", 0])
def test_path_string_literal(): def test_path_string_literal():
assert check_token("p'/foo'", ['STRING', "p'/foo'", 0]) assert check_token("p'/foo'", ["STRING", "p'/foo'", 0])
assert check_token('p"/foo"', ['STRING', 'p"/foo"', 0]) assert check_token('p"/foo"', ["STRING", 'p"/foo"', 0])
assert check_token("pr'/foo'", ['STRING', "pr'/foo'", 0]) assert check_token("pr'/foo'", ["STRING", "pr'/foo'", 0])
assert check_token('pr"/foo"', ['STRING', 'pr"/foo"', 0]) assert check_token('pr"/foo"', ["STRING", 'pr"/foo"', 0])
assert check_token("rp'/foo'", ['STRING', "rp'/foo'", 0]) assert check_token("rp'/foo'", ["STRING", "rp'/foo'", 0])
assert check_token('rp"/foo"', ['STRING', 'rp"/foo"', 0]) assert check_token('rp"/foo"', ["STRING", 'rp"/foo"', 0])
def test_regex_globs(): def test_regex_globs():
for i in ('.*', r'\d*', '.*#{1,2}'): for i in (".*", r"\d*", ".*#{1,2}"):
for p in ('', 'r', 'g', '@somethingelse', 'p', 'pg'): for p in ("", "r", "g", "@somethingelse", "p", "pg"):
c = '{}`{}`'.format(p,i) c = "{}`{}`".format(p, i)
assert check_token(c, ['SEARCHPATH', c, 0]) assert check_token(c, ["SEARCHPATH", c, 0])
@pytest.mark.parametrize('case', [ @pytest.mark.parametrize(
'0.0', '.0', '0.', '1e10', '1.e42', '0.1e42', '0.5e-42', '5E10', '5e+42', '1_0e1_0']) "case",
[
"0.0",
".0",
"0.",
"1e10",
"1.e42",
"0.1e42",
"0.5e-42",
"5E10",
"5e+42",
"1_0e1_0",
],
)
def test_float_literals(case): def test_float_literals(case):
assert check_token(case, ['NUMBER', case, 0]) assert check_token(case, ["NUMBER", case, 0])
@pytest.mark.parametrize('case', [
'2>1', 'err>out', 'o>', 'all>', 'e>o', 'e>', 'out>', '2>&1' @pytest.mark.parametrize(
]) "case", ["2>1", "err>out", "o>", "all>", "e>o", "e>", "out>", "2>&1"]
)
def test_ioredir(case): def test_ioredir(case):
assert check_tokens_subproc(case, [('IOREDIRECT', case, 2)], stop=-2) assert check_tokens_subproc(case, [("IOREDIRECT", case, 2)], stop=-2)
@pytest.mark.parametrize('case', [ @pytest.mark.parametrize("case", [">", ">>", "<", "e>", "> ", ">> ", "< ", "e> "])
'>', '>>', '<', 'e>',
'> ', '>> ', '< ', 'e> ',
])
def test_redir_whitespace(case): def test_redir_whitespace(case):
inp = '![{}/path/to/file]'.format(case) inp = "![{}/path/to/file]".format(case)
l = Lexer() l = Lexer()
l.input(inp) l.input(inp)
obs = list(l) obs = list(l)
assert obs[2].type == 'WS' assert obs[2].type == "WS"
@pytest.mark.parametrize('s, exp', [ @pytest.mark.parametrize(
('', []), "s, exp",
(' \t \n \t ', []), [
('echo hello', ['echo', 'hello']), ("", []),
('echo "hello"', ['echo', '"hello"']), (" \t \n \t ", []),
('![echo "hello"]', ['![echo', '"hello"]']), ("echo hello", ["echo", "hello"]),
('/usr/bin/echo hello', ['/usr/bin/echo', 'hello']), ('echo "hello"', ["echo", '"hello"']),
('$(/usr/bin/echo hello)', ['$(/usr/bin/echo', 'hello)']), ('![echo "hello"]', ["![echo", '"hello"]']),
('C:\\Python\\python.exe -m xonsh', ['C:\\Python\\python.exe', '-m', 'xonsh']), ("/usr/bin/echo hello", ["/usr/bin/echo", "hello"]),
('print("""I am a triple string""")', ['print("""I am a triple string""")']), ("$(/usr/bin/echo hello)", ["$(/usr/bin/echo", "hello)"]),
('print("""I am a \ntriple string""")', ['print("""I am a \ntriple string""")']), ("C:\\Python\\python.exe -m xonsh", ["C:\\Python\\python.exe", "-m", "xonsh"]),
('echo $HOME', ['echo', '$HOME']), ('print("""I am a triple string""")', ['print("""I am a triple string""")']),
('echo -n $HOME', ['echo', '-n', '$HOME']), (
('echo --go=away', ['echo', '--go=away']), 'print("""I am a \ntriple string""")',
('echo --go=$HOME', ['echo', '--go=$HOME']), ['print("""I am a \ntriple string""")'],
]) ),
("echo $HOME", ["echo", "$HOME"]),
("echo -n $HOME", ["echo", "-n", "$HOME"]),
("echo --go=away", ["echo", "--go=away"]),
("echo --go=$HOME", ["echo", "--go=$HOME"]),
],
)
def test_lexer_split(s, exp): def test_lexer_split(s, exp):
lexer = Lexer() lexer = Lexer()
obs = lexer.split(s) obs = lexer.split(s)

View file

@ -21,55 +21,55 @@ def Shell(*args, **kwargs):
@pytest.fixture @pytest.fixture
def shell(xonsh_builtins, xonsh_execer, monkeypatch): def shell(xonsh_builtins, xonsh_execer, monkeypatch):
"""Xonsh Shell Mock""" """Xonsh Shell Mock"""
Shell.shell_type_aliases = {'rl': 'readline'} Shell.shell_type_aliases = {"rl": "readline"}
monkeypatch.setattr(xonsh.main, 'Shell', Shell) monkeypatch.setattr(xonsh.main, "Shell", Shell)
def test_premain_no_arg(shell, monkeypatch): def test_premain_no_arg(shell, monkeypatch):
monkeypatch.setattr(sys.stdin, 'isatty', lambda: True) monkeypatch.setattr(sys.stdin, "isatty", lambda: True)
xonsh.main.premain([]) xonsh.main.premain([])
assert builtins.__xonsh_env__.get('XONSH_LOGIN') assert builtins.__xonsh_env__.get("XONSH_LOGIN")
def test_premain_interactive(shell): def test_premain_interactive(shell):
xonsh.main.premain(['-i']) xonsh.main.premain(["-i"])
assert (builtins.__xonsh_env__.get('XONSH_INTERACTIVE')) assert builtins.__xonsh_env__.get("XONSH_INTERACTIVE")
def test_premain_login_command(shell): def test_premain_login_command(shell):
xonsh.main.premain(['-l', '-c', 'echo "hi"']) xonsh.main.premain(["-l", "-c", 'echo "hi"'])
assert (builtins.__xonsh_env__.get('XONSH_LOGIN')) assert builtins.__xonsh_env__.get("XONSH_LOGIN")
def test_premain_login(shell): def test_premain_login(shell):
xonsh.main.premain(['-l']) xonsh.main.premain(["-l"])
assert (builtins.__xonsh_env__.get('XONSH_LOGIN')) assert builtins.__xonsh_env__.get("XONSH_LOGIN")
def test_premain_D(shell): def test_premain_D(shell):
xonsh.main.premain(['-DTEST1=1616', '-DTEST2=LOL']) xonsh.main.premain(["-DTEST1=1616", "-DTEST2=LOL"])
assert (builtins.__xonsh_env__.get('TEST1') == '1616') assert builtins.__xonsh_env__.get("TEST1") == "1616"
assert (builtins.__xonsh_env__.get('TEST2') == 'LOL') assert builtins.__xonsh_env__.get("TEST2") == "LOL"
def test_premain_custom_rc(shell, tmpdir, monkeypatch): def test_premain_custom_rc(shell, tmpdir, monkeypatch):
monkeypatch.setattr(sys.stdin, 'isatty', lambda: True) monkeypatch.setattr(sys.stdin, "isatty", lambda: True)
builtins.__xonsh_env__ = Env(XONSH_CACHE_SCRIPTS=False) builtins.__xonsh_env__ = Env(XONSH_CACHE_SCRIPTS=False)
f = tmpdir.join('wakkawakka') f = tmpdir.join("wakkawakka")
f.write("print('hi')") f.write("print('hi')")
args = xonsh.main.premain(['--rc', f.strpath]) args = xonsh.main.premain(["--rc", f.strpath])
assert args.mode == XonshMode.interactive assert args.mode == XonshMode.interactive
assert f.strpath in builtins.__xonsh_env__.get('XONSHRC') assert f.strpath in builtins.__xonsh_env__.get("XONSHRC")
def test_no_rc_with_script(shell, tmpdir): def test_no_rc_with_script(shell, tmpdir):
args = xonsh.main.premain(['tests/sample.xsh']) args = xonsh.main.premain(["tests/sample.xsh"])
assert not (args.mode == XonshMode.interactive) assert not (args.mode == XonshMode.interactive)
def test_force_interactive_rc_with_script(shell, tmpdir): def test_force_interactive_rc_with_script(shell, tmpdir):
args = xonsh.main.premain(['-i', 'tests/sample.xsh']) args = xonsh.main.premain(["-i", "tests/sample.xsh"])
assert builtins.__xonsh_env__.get('XONSH_INTERACTIVE') assert builtins.__xonsh_env__.get("XONSH_INTERACTIVE")
def test_force_interactive_custom_rc_with_script(shell, tmpdir): def test_force_interactive_custom_rc_with_script(shell, tmpdir):
@ -77,69 +77,73 @@ def test_force_interactive_custom_rc_with_script(shell, tmpdir):
should run interactively should run interactively
""" """
builtins.__xonsh_env__ = Env(XONSH_CACHE_SCRIPTS=False) builtins.__xonsh_env__ = Env(XONSH_CACHE_SCRIPTS=False)
f = tmpdir.join('wakkawakka') f = tmpdir.join("wakkawakka")
f.write("print('hi')") f.write("print('hi')")
args = xonsh.main.premain(['-i', '--rc', f.strpath, 'tests/sample.xsh']) args = xonsh.main.premain(["-i", "--rc", f.strpath, "tests/sample.xsh"])
assert args.mode == XonshMode.interactive assert args.mode == XonshMode.interactive
assert f.strpath in builtins.__xonsh_env__.get('XONSHRC') assert f.strpath in builtins.__xonsh_env__.get("XONSHRC")
def test_custom_rc_with_script(shell, tmpdir): def test_custom_rc_with_script(shell, tmpdir):
"""Calling a custom RC file on a script-call without the interactive flag """Calling a custom RC file on a script-call without the interactive flag
should not run interactively should not run interactively
""" """
f = tmpdir.join('wakkawakka') f = tmpdir.join("wakkawakka")
f.write("print('hi')") f.write("print('hi')")
args = xonsh.main.premain(['--rc', f.strpath, 'tests/sample.xsh']) args = xonsh.main.premain(["--rc", f.strpath, "tests/sample.xsh"])
assert not (args.mode == XonshMode.interactive) assert not (args.mode == XonshMode.interactive)
def test_premain_no_rc(shell, tmpdir): def test_premain_no_rc(shell, tmpdir):
xonsh.main.premain(['--no-rc']) xonsh.main.premain(["--no-rc"])
assert not builtins.__xonsh_env__.get('XONSHRC') assert not builtins.__xonsh_env__.get("XONSHRC")
@pytest.mark.parametrize( @pytest.mark.parametrize(
'arg', ['', '-i', '-vERSION', '-hAALP', 'TTTT', '-TT', '--TTT']) "arg", ["", "-i", "-vERSION", "-hAALP", "TTTT", "-TT", "--TTT"]
)
def test_premain_with_file_argument(arg, shell): def test_premain_with_file_argument(arg, shell):
xonsh.main.premain(['tests/sample.xsh', arg]) xonsh.main.premain(["tests/sample.xsh", arg])
assert not (builtins.__xonsh_env__.get('XONSH_INTERACTIVE')) assert not (builtins.__xonsh_env__.get("XONSH_INTERACTIVE"))
def test_premain_interactive__with_file_argument(shell): def test_premain_interactive__with_file_argument(shell):
xonsh.main.premain(['-i', 'tests/sample.xsh']) xonsh.main.premain(["-i", "tests/sample.xsh"])
assert (builtins.__xonsh_env__.get('XONSH_INTERACTIVE')) assert builtins.__xonsh_env__.get("XONSH_INTERACTIVE")
@pytest.mark.parametrize('case', ['----', '--hep', '-TT', '--TTTT']) @pytest.mark.parametrize("case", ["----", "--hep", "-TT", "--TTTT"])
def test_premain_invalid_arguments(shell, case, capsys): def test_premain_invalid_arguments(shell, case, capsys):
with pytest.raises(SystemExit): with pytest.raises(SystemExit):
xonsh.main.premain([case]) xonsh.main.premain([case])
assert 'unrecognized argument' in capsys.readouterr()[1] assert "unrecognized argument" in capsys.readouterr()[1]
def test_xonsh_failback(shell, monkeypatch): def test_xonsh_failback(shell, monkeypatch):
failback_checker = [] failback_checker = []
monkeypatch.setattr(sys, 'stderr', open(os.devnull, 'w')) monkeypatch.setattr(sys, "stderr", open(os.devnull, "w"))
def mocked_main(*args): def mocked_main(*args):
raise Exception('A fake failure') raise Exception("A fake failure")
monkeypatch.setattr(xonsh.main, 'main_xonsh', mocked_main)
monkeypatch.setattr(xonsh.main, "main_xonsh", mocked_main)
def mocked_execlp(f, *args): def mocked_execlp(f, *args):
failback_checker.append(f) failback_checker.append(f)
failback_checker.append(args[0]) failback_checker.append(args[0])
monkeypatch.setattr(os, 'execlp', mocked_execlp)
monkeypatch.setattr(os.path, 'exists', lambda x: True) monkeypatch.setattr(os, "execlp", mocked_execlp)
monkeypatch.setattr(sys, 'argv', ['xonsh', '-i']) monkeypatch.setattr(os.path, "exists", lambda x: True)
monkeypatch.setattr(sys, "argv", ["xonsh", "-i"])
@contextmanager @contextmanager
def mocked_open(*args): def mocked_open(*args):
yield ['/usr/bin/xonsh', '/usr/bin/screen', 'bash', '/bin/xshell'] yield ["/usr/bin/xonsh", "/usr/bin/screen", "bash", "/bin/xshell"]
monkeypatch.setattr(builtins, 'open', mocked_open)
monkeypatch.setattr(builtins, "open", mocked_open)
xonsh.main.main() xonsh.main.main()
assert failback_checker == ['/bin/xshell', '/bin/xshell'] assert failback_checker == ["/bin/xshell", "/bin/xshell"]
def test_xonsh_failback_single(shell, monkeypatch): def test_xonsh_failback_single(shell, monkeypatch):
@ -148,9 +152,10 @@ def test_xonsh_failback_single(shell, monkeypatch):
def mocked_main(*args): def mocked_main(*args):
raise FakeFailureError() raise FakeFailureError()
monkeypatch.setattr(xonsh.main, 'main_xonsh', mocked_main)
monkeypatch.setattr(sys, 'argv', ['xonsh', '-c', 'echo', 'foo']) monkeypatch.setattr(xonsh.main, "main_xonsh", mocked_main)
monkeypatch.setattr(sys, 'stderr', open(os.devnull, 'w')) monkeypatch.setattr(sys, "argv", ["xonsh", "-c", "echo", "foo"])
monkeypatch.setattr(sys, "stderr", open(os.devnull, "w"))
with pytest.raises(FakeFailureError): with pytest.raises(FakeFailureError):
xonsh.main.main() xonsh.main.main()
@ -158,13 +163,15 @@ def test_xonsh_failback_single(shell, monkeypatch):
def test_xonsh_failback_script_from_file(shell, monkeypatch): def test_xonsh_failback_script_from_file(shell, monkeypatch):
checker = [] checker = []
def mocked_execlp(f, *args): def mocked_execlp(f, *args):
checker.append(f) checker.append(f)
monkeypatch.setattr(os, 'execlp', mocked_execlp)
script = os.path.join(TEST_DIR, 'scripts', 'raise.xsh') monkeypatch.setattr(os, "execlp", mocked_execlp)
monkeypatch.setattr(sys, 'argv', ['xonsh', script])
monkeypatch.setattr(sys, 'stderr', open(os.devnull, 'w')) script = os.path.join(TEST_DIR, "scripts", "raise.xsh")
monkeypatch.setattr(sys, "argv", ["xonsh", script])
monkeypatch.setattr(sys, "stderr", open(os.devnull, "w"))
with pytest.raises(Exception): with pytest.raises(Exception):
xonsh.main.main() xonsh.main.main()
assert len(checker) == 0 assert len(checker) == 0

View file

@ -8,10 +8,11 @@ from tools import skip_if_on_windows
@skip_if_on_windows @skip_if_on_windows
def test_man_completion(monkeypatch, tmpdir, xonsh_builtins): def test_man_completion(monkeypatch, tmpdir, xonsh_builtins):
tempdir = tmpdir.mkdir('test_man') tempdir = tmpdir.mkdir("test_man")
monkeypatch.setitem(os.environ, 'MANPATH', os.path.dirname(os.path.abspath(__file__))) monkeypatch.setitem(
xonsh_builtins.__xonsh_env__.update({'XONSH_DATA_DIR': str(tempdir)}) os.environ, "MANPATH", os.path.dirname(os.path.abspath(__file__))
completions = complete_from_man('--', 'yes --', 4, 6, )
xonsh_builtins.__xonsh_env__) xonsh_builtins.__xonsh_env__.update({"XONSH_DATA_DIR": str(tempdir)})
assert '--version' in completions completions = complete_from_man("--", "yes --", 4, 6, xonsh_builtins.__xonsh_env__)
assert '--help' in completions assert "--version" in completions
assert "--help" in completions

View file

@ -7,13 +7,14 @@ plt = pytest.importorskip("matplotlib.pyplot")
from xontrib import mplhooks from xontrib import mplhooks
skip_if_mpl2 = pytest.mark.skipif(matplotlib.__version__.startswith('2'), skip_if_mpl2 = pytest.mark.skipif(
reason='Bug in matplotlib v2') matplotlib.__version__.startswith("2"), reason="Bug in matplotlib v2"
)
# some default settings that are temporarily changed by mpl # some default settings that are temporarily changed by mpl
FONT_SIZE = 22 FONT_SIZE = 22
FACE_COLOR = (0.0, 1.0, 0.0, 1.0) FACE_COLOR = (0.0, 1.0, 0.0, 1.0)
DPI = 80 DPI = 80
def create_figure(): def create_figure():
@ -23,7 +24,7 @@ def create_figure():
# set the figure parameters such that mpl will require changes # set the figure parameters such that mpl will require changes
f.set_facecolor(FACE_COLOR) f.set_facecolor(FACE_COLOR)
f.dpi = DPI f.dpi = DPI
matplotlib.rcParams.update({'font.size': FONT_SIZE}) matplotlib.rcParams.update({"font.size": FONT_SIZE})
return f return f
@ -33,9 +34,9 @@ def test_mpl_preserve_font_size():
f = create_figure() f = create_figure()
width, height = f.canvas.get_width_height() width, height = f.canvas.get_width_height()
print(width, height) print(width, height)
s = mplhooks.figure_to_tight_array(f, 0.5*width, 0.5*height, True) s = mplhooks.figure_to_tight_array(f, 0.5 * width, 0.5 * height, True)
exp = FONT_SIZE exp = FONT_SIZE
obs = matplotlib.rcParams['font.size'] obs = matplotlib.rcParams["font.size"]
plt.close(f) plt.close(f)
assert exp == obs assert exp == obs
@ -45,7 +46,7 @@ def test_mpl_preserve_face_color():
"""Make sure that the figure preserves face color settings""" """Make sure that the figure preserves face color settings"""
f = create_figure() f = create_figure()
width, height = f.canvas.get_width_height() width, height = f.canvas.get_width_height()
s = mplhooks.figure_to_tight_array(f, 0.5*width, 0.5*height, True) s = mplhooks.figure_to_tight_array(f, 0.5 * width, 0.5 * height, True)
exp = FACE_COLOR exp = FACE_COLOR
obs = f.get_facecolor() obs = f.get_facecolor()
plt.close(f) plt.close(f)
@ -57,7 +58,7 @@ def test_mpl_preserve_width():
"""Make sure that the figure preserves width settings""" """Make sure that the figure preserves width settings"""
f = create_figure() f = create_figure()
width, height = f.canvas.get_width_height() width, height = f.canvas.get_width_height()
s = mplhooks.figure_to_tight_array(f, 0.5*width, 0.5*height, True) s = mplhooks.figure_to_tight_array(f, 0.5 * width, 0.5 * height, True)
exp = width exp = width
newwidth, newheight = f.canvas.get_width_height() newwidth, newheight = f.canvas.get_width_height()
obs = newwidth obs = newwidth
@ -70,7 +71,7 @@ def test_mpl_preserve_height():
"""Make sure that the figure preserves height settings""" """Make sure that the figure preserves height settings"""
f = create_figure() f = create_figure()
width, height = f.canvas.get_width_height() width, height = f.canvas.get_width_height()
s = mplhooks.figure_to_tight_array(f, 0.5*width, 0.5*height, True) s = mplhooks.figure_to_tight_array(f, 0.5 * width, 0.5 * height, True)
exp = height exp = height
newwidth, newheight = f.canvas.get_width_height() newwidth, newheight = f.canvas.get_width_height()
obs = newheight obs = newheight
@ -82,7 +83,7 @@ def test_mpl_preserve_dpi():
"""Make sure that the figure preserves height settings""" """Make sure that the figure preserves height settings"""
f = create_figure() f = create_figure()
width, height = f.canvas.get_width_height() width, height = f.canvas.get_width_height()
s = mplhooks.figure_to_tight_array(f, 0.5*width, 0.5*height, False) s = mplhooks.figure_to_tight_array(f, 0.5 * width, 0.5 * height, False)
exp = DPI exp = DPI
obs = f.dpi obs = f.dpi
plt.close(f) plt.close(f)
@ -95,7 +96,7 @@ def test_mpl_preserve_image_tight():
f = create_figure() f = create_figure()
exp = mplhooks.figure_to_rgb_array(f) exp = mplhooks.figure_to_rgb_array(f)
width, height = f.canvas.get_width_height() width, height = f.canvas.get_width_height()
s = mplhooks.figure_to_tight_array(f, 0.5*width, 0.5*height, True) s = mplhooks.figure_to_tight_array(f, 0.5 * width, 0.5 * height, True)
obs = mplhooks.figure_to_rgb_array(f) obs = mplhooks.figure_to_rgb_array(f)
plt.close(f) plt.close(f)
assert np.all(exp == obs) assert np.all(exp == obs)
@ -106,7 +107,7 @@ def test_mpl_preserve_standard():
f = create_figure() f = create_figure()
exp = mplhooks.figure_to_rgb_array(f) exp = mplhooks.figure_to_rgb_array(f)
width, height = f.canvas.get_width_height() width, height = f.canvas.get_width_height()
s = mplhooks.figure_to_tight_array(f, 0.5*width, 0.5*height, False) s = mplhooks.figure_to_tight_array(f, 0.5 * width, 0.5 * height, False)
obs = mplhooks.figure_to_rgb_array(f) obs = mplhooks.figure_to_rgb_array(f)
plt.close(f) plt.close(f)
assert np.all(exp == obs) assert np.all(exp == obs)

View file

@ -8,12 +8,14 @@ import pytest
from xonsh.platform import scandir from xonsh.platform import scandir
NEWSDIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'news') NEWSDIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "news")
CATEGORIES = frozenset(['Added', 'Changed', 'Deprecated', 'Removed', CATEGORIES = frozenset(
'Fixed', 'Security']) ["Added", "Changed", "Deprecated", "Removed", "Fixed", "Security"]
)
single_grave_reg = re.compile(r"[^`]`[^`]+`[^`_]")
single_grave_reg = re.compile(r'[^`]`[^`]+`[^`_]')
def check_news_file(fname): def check_news_file(fname):
name = fname.name name = fname.name
@ -22,42 +24,44 @@ def check_news_file(fname):
form = "" form = ""
for i, l in enumerate(lines): for i, l in enumerate(lines):
# search the graves # search the graves
if '`' in l: if "`" in l:
if single_grave_reg.search(l): if single_grave_reg.search(l):
pytest.fail("{}:{}: single grave accents" pytest.fail(
" are not valid rst".format(name, i+1), "{}:{}: single grave accents"
pytrace=False) " are not valid rst".format(name, i + 1),
pytrace=False,
)
# determine the form of line # determine the form of line
if l.startswith('**'): if l.startswith("**"):
cat = l[2:].rsplit(':')[0] cat = l[2:].rsplit(":")[0]
if cat not in CATEGORIES: if cat not in CATEGORIES:
pytest.fail('{}:{}: {!r} not a proper category ' pytest.fail(
'must be one of {}' "{}:{}: {!r} not a proper category "
''.format(name, i+1, cat, list(CATEGORIES)), "must be one of {}"
pytrace=False) "".format(name, i + 1, cat, list(CATEGORIES)),
if l.endswith('None'): pytrace=False,
form += '3' )
if l.endswith("None"):
form += "3"
else: else:
form += '2' form += "2"
elif l.startswith('* ') or l.startswith('- ') or l.startswith(' '): elif l.startswith("* ") or l.startswith("- ") or l.startswith(" "):
form += '1' form += "1"
elif l.strip() == '': elif l.strip() == "":
form += '0' form += "0"
else: else:
pytest.fail('{}:{}: invalid rst'.format(name, i+1), pytest.fail("{}:{}: invalid rst".format(name, i + 1), pytrace=False)
pytrace=False)
# The file should have: # The file should have:
# empty lines around categories # empty lines around categories
# at least one content line in a non null category # at least one content line in a non null category
reg = re.compile(r'^(3(0|$)|201(1|0)*0)+$') reg = re.compile(r"^(3(0|$)|201(1|0)*0)+$")
if not reg.match(form): if not reg.match(form):
pytest.fail('{}: invalid rst'.format(name), pytest.fail("{}: invalid rst".format(name), pytrace=False)
pytrace=False)
@pytest.mark.parametrize('fname', list(scandir(NEWSDIR))) @pytest.mark.parametrize("fname", list(scandir(NEWSDIR)))
def test_news(fname): def test_news(fname):
base, ext = os.path.splitext(fname.path) base, ext = os.path.splitext(fname.path)
assert 'rst' in ext assert "rst" in ext
check_news_file(fname) check_news_file(fname)

File diff suppressed because it is too large Load diff

View file

@ -14,28 +14,30 @@ def xonsh_execer_autouse(xonsh_builtins, xonsh_execer):
def test_pattern_need_quotes(): def test_pattern_need_quotes():
# just make sure the regex compiles # just make sure the regex compiles
xcp.PATTERN_NEED_QUOTES.match('') xcp.PATTERN_NEED_QUOTES.match("")
def test_complete_path(xonsh_builtins): def test_complete_path(xonsh_builtins):
xonsh_builtins.__xonsh_env__ = {'CASE_SENSITIVE_COMPLETIONS': False, xonsh_builtins.__xonsh_env__ = {
'GLOB_SORTED': True, "CASE_SENSITIVE_COMPLETIONS": False,
'SUBSEQUENCE_PATH_COMPLETION': False, "GLOB_SORTED": True,
'FUZZY_PATH_COMPLETION': False, "SUBSEQUENCE_PATH_COMPLETION": False,
'SUGGEST_THRESHOLD': 3, "FUZZY_PATH_COMPLETION": False,
'CDPATH': set(), "SUGGEST_THRESHOLD": 3,
"CDPATH": set(),
} }
xcp.complete_path('[1-0.1]', '[1-0.1]', 0, 7, dict()) xcp.complete_path("[1-0.1]", "[1-0.1]", 0, 7, dict())
@patch('xonsh.completers.path._add_cdpaths') @patch("xonsh.completers.path._add_cdpaths")
def test_cd_path_no_cd(mock_add_cdpaths, xonsh_builtins): def test_cd_path_no_cd(mock_add_cdpaths, xonsh_builtins):
xonsh_builtins.__xonsh_env__ = {'CASE_SENSITIVE_COMPLETIONS': False, xonsh_builtins.__xonsh_env__ = {
'GLOB_SORTED': True, "CASE_SENSITIVE_COMPLETIONS": False,
'SUBSEQUENCE_PATH_COMPLETION': False, "GLOB_SORTED": True,
'FUZZY_PATH_COMPLETION': False, "SUBSEQUENCE_PATH_COMPLETION": False,
'SUGGEST_THRESHOLD': 3, "FUZZY_PATH_COMPLETION": False,
'CDPATH': ['/'], "SUGGEST_THRESHOLD": 3,
"CDPATH": ["/"],
} }
xcp.complete_path('a', 'cat a', 4, 5, dict()) xcp.complete_path("a", "cat a", 4, 5, dict())
mock_add_cdpaths.assert_not_called() mock_add_cdpaths.assert_not_called()

View file

@ -8,8 +8,9 @@ import xonsh.platform as xp
def test_githash_value_error(monkeypatch): def test_githash_value_error(monkeypatch):
@contextmanager @contextmanager
def mocked_open(*args): def mocked_open(*args):
yield MagicMock(read=lambda: 'abc123') yield MagicMock(read=lambda: "abc123")
monkeypatch.setattr(builtins, 'open', mocked_open)
monkeypatch.setattr(builtins, "open", mocked_open)
sha, date_ = xp.githash() sha, date_ = xp.githash()
assert date_ is None assert date_ is None
assert sha is None assert sha is None

View file

@ -17,59 +17,63 @@ def formatter(xonsh_builtins):
return PromptFormatter() return PromptFormatter()
@pytest.mark.parametrize('fields', [{ @pytest.mark.parametrize(
'a_string': 'cat', "fields", [{"a_string": "cat", "none": (lambda: None), "f": (lambda: "wakka")}]
'none': (lambda: None), )
'f': (lambda: 'wakka'), @pytest.mark.parametrize(
}]) "inp, exp",
@pytest.mark.parametrize('inp, exp', [ [
('my {a_string}', 'my cat'), ("my {a_string}", "my cat"),
('my {none}{a_string}', 'my cat'), ("my {none}{a_string}", "my cat"),
('{f} jawaka', 'wakka jawaka'), ("{f} jawaka", "wakka jawaka"),
]) ],
)
def test_format_prompt(inp, exp, fields, formatter): def test_format_prompt(inp, exp, fields, formatter):
obs = formatter(template=inp, fields=fields) obs = formatter(template=inp, fields=fields)
assert exp == obs assert exp == obs
@pytest.mark.parametrize('fields', [{ @pytest.mark.parametrize(
'a_string': 'cats', "fields",
'a_number': 7, [
'empty': '', {
'current_job': (lambda: 'sleep'), "a_string": "cats",
'none': (lambda: None), "a_number": 7,
}]) "empty": "",
@pytest.mark.parametrize('inp, exp', [ "current_job": (lambda: "sleep"),
('{a_number:{0:^3}}cats', ' 7 cats'), "none": (lambda: None),
('{current_job:{} | }xonsh', 'sleep | xonsh'), }
('{none:{} | }{a_string}{empty:!}', 'cats!'), ],
('{none:{}}', ''), )
('{{{a_string:{{{}}}}}}', '{{cats}}'), @pytest.mark.parametrize(
('{{{none:{{{}}}}}}', '{}'), "inp, exp",
]) [
("{a_number:{0:^3}}cats", " 7 cats"),
("{current_job:{} | }xonsh", "sleep | xonsh"),
("{none:{} | }{a_string}{empty:!}", "cats!"),
("{none:{}}", ""),
("{{{a_string:{{{}}}}}}", "{{cats}}"),
("{{{none:{{{}}}}}}", "{}"),
],
)
def test_format_prompt_with_format_spec(inp, exp, fields, formatter): def test_format_prompt_with_format_spec(inp, exp, fields, formatter):
obs = formatter(template=inp, fields=fields) obs = formatter(template=inp, fields=fields)
assert exp == obs assert exp == obs
def test_format_prompt_with_broken_template(formatter): def test_format_prompt_with_broken_template(formatter):
for p in ('{user', '{user}{hostname'): for p in ("{user", "{user}{hostname"):
assert formatter(p) == p assert formatter(p) == p
# '{{user' will be parsed to '{user' # '{{user' will be parsed to '{user'
for p in ('{{user}', '{{user'): for p in ("{{user}", "{{user"):
assert 'user' in formatter(p) assert "user" in formatter(p)
@pytest.mark.parametrize('inp', [ @pytest.mark.parametrize("inp", ["{user", "{{user", "{{user}", "{user}{hostname"])
'{user',
'{{user',
'{{user}',
'{user}{hostname',
])
def test_format_prompt_with_broken_template_in_func(inp, formatter): def test_format_prompt_with_broken_template_in_func(inp, formatter):
# '{{user' will be parsed to '{user' # '{{user' will be parsed to '{user'
assert '{user' in formatter(lambda: inp) assert "{user" in formatter(lambda: inp)
def test_format_prompt_with_invalid_func(formatter, xonsh_builtins): def test_format_prompt_with_invalid_func(formatter, xonsh_builtins):
@ -77,28 +81,26 @@ def test_format_prompt_with_invalid_func(formatter, xonsh_builtins):
def p(): def p():
foo = bar # raises exception # noqa foo = bar # raises exception # noqa
return '{user}' return "{user}"
assert isinstance(formatter(p), str) assert isinstance(formatter(p), str)
def test_format_prompt_with_func_that_raises(formatter, def test_format_prompt_with_func_that_raises(formatter, capsys, xonsh_builtins):
capsys,
xonsh_builtins):
xonsh_builtins.__xonsh_env__ = Env() xonsh_builtins.__xonsh_env__ = Env()
template = 'tt {zerodiv} tt' template = "tt {zerodiv} tt"
exp = 'tt (ERROR:zerodiv) tt' exp = "tt (ERROR:zerodiv) tt"
fields = {'zerodiv': lambda: 1/0} fields = {"zerodiv": lambda: 1 / 0}
obs = formatter(template, fields) obs = formatter(template, fields)
assert exp == obs assert exp == obs
out, err = capsys.readouterr() out, err = capsys.readouterr()
assert 'prompt: error' in err assert "prompt: error" in err
def test_promptformatter_cache(formatter): def test_promptformatter_cache(formatter):
spam = Mock() spam = Mock()
template = '{spam} and {spam}' template = "{spam} and {spam}"
fields = {'spam': spam} fields = {"spam": spam}
formatter(template, fields) formatter(template, fields)
@ -107,8 +109,8 @@ def test_promptformatter_cache(formatter):
def test_promptformatter_clears_cache(formatter): def test_promptformatter_clears_cache(formatter):
spam = Mock() spam = Mock()
template = '{spam} and {spam}' template = "{spam} and {spam}"
fields = {'spam': spam} fields = {"spam": spam}
formatter(template, fields) formatter(template, fields)
formatter(template, fields) formatter(template, fields)
@ -117,11 +119,10 @@ def test_promptformatter_clears_cache(formatter):
# Xonsh interaction with version control systems. # Xonsh interaction with version control systems.
VC_BRANCH = {'git': 'master', VC_BRANCH = {"git": "master", "hg": "default"}
'hg': 'default'}
@pytest.fixture(scope='module', params=VC_BRANCH.keys()) @pytest.fixture(scope="module", params=VC_BRANCH.keys())
def test_repo(request): def test_repo(request):
"""Return a dict with vc and a temporary dir """Return a dict with vc and a temporary dir
that is a repository for testing. that is a repository for testing.
@ -130,28 +131,30 @@ def test_repo(request):
temp_dir = tempfile.mkdtemp() temp_dir = tempfile.mkdtemp()
os.chdir(temp_dir) os.chdir(temp_dir)
try: try:
sp.call([vc, 'init']) sp.call([vc, "init"])
except FileNotFoundError: except FileNotFoundError:
pytest.skip('cannot find {} executable'.format(vc)) pytest.skip("cannot find {} executable".format(vc))
# git needs at least one commit # git needs at least one commit
if vc == 'git': if vc == "git":
with open('test-file', 'w'): with open("test-file", "w"):
pass pass
sp.call(['git', 'add', 'test-file']) sp.call(["git", "add", "test-file"])
sp.call(['git', 'commit', '-m', 'test commit']) sp.call(["git", "commit", "-m", "test commit"])
return {'name': vc, 'dir': temp_dir} return {"name": vc, "dir": temp_dir}
def test_test_repo(test_repo): def test_test_repo(test_repo):
dotdir = os.path.isdir(os.path.join(test_repo['dir'], dotdir = os.path.isdir(
'.{}'.format(test_repo['name']))) os.path.join(test_repo["dir"], ".{}".format(test_repo["name"]))
)
assert dotdir assert dotdir
if test_repo['name'] == 'git': if test_repo["name"] == "git":
assert os.path.isfile(os.path.join(test_repo['dir'], 'test-file')) assert os.path.isfile(os.path.join(test_repo["dir"], "test-file"))
def test_no_repo(xonsh_builtins): def test_no_repo(xonsh_builtins):
import queue import queue
temp_dir = tempfile.mkdtemp() temp_dir = tempfile.mkdtemp()
xonsh_builtins.__xonsh_env__ = Env(VC_BRANCH_TIMEOUT=2, PWD=temp_dir) xonsh_builtins.__xonsh_env__ = Env(VC_BRANCH_TIMEOUT=2, PWD=temp_dir)
q = queue.Queue() q = queue.Queue()
@ -164,27 +167,29 @@ def test_no_repo(xonsh_builtins):
def test_vc_get_branch(test_repo, xonsh_builtins): def test_vc_get_branch(test_repo, xonsh_builtins):
xonsh_builtins.__xonsh_env__ = Env(VC_BRANCH_TIMEOUT=2) xonsh_builtins.__xonsh_env__ = Env(VC_BRANCH_TIMEOUT=2)
# get corresponding function from vc module # get corresponding function from vc module
fun = 'get_{}_branch'.format(test_repo['name']) fun = "get_{}_branch".format(test_repo["name"])
obs = getattr(vc, fun)() obs = getattr(vc, fun)()
if obs is not None: if obs is not None:
assert obs == VC_BRANCH[test_repo['name']] assert obs == VC_BRANCH[test_repo["name"]]
def test_current_branch_calls_locate_binary_for_empty_cmds_cache(xonsh_builtins): def test_current_branch_calls_locate_binary_for_empty_cmds_cache(xonsh_builtins):
cache = xonsh_builtins.__xonsh_commands_cache__ cache = xonsh_builtins.__xonsh_commands_cache__
xonsh_builtins.__xonsh_env__ = DummyEnv(VC_BRANCH_TIMEOUT=1) xonsh_builtins.__xonsh_env__ = DummyEnv(VC_BRANCH_TIMEOUT=1)
cache.is_empty = Mock(return_value=True) cache.is_empty = Mock(return_value=True)
cache.locate_binary = Mock(return_value='') cache.locate_binary = Mock(return_value="")
vc.current_branch() vc.current_branch()
assert cache.locate_binary.called assert cache.locate_binary.called
def test_current_branch_does_not_call_locate_binary_for_non_empty_cmds_cache(xonsh_builtins): def test_current_branch_does_not_call_locate_binary_for_non_empty_cmds_cache(
xonsh_builtins
):
cache = xonsh_builtins.__xonsh_commands_cache__ cache = xonsh_builtins.__xonsh_commands_cache__
xonsh_builtins.__xonsh_env__ = DummyEnv(VC_BRANCH_TIMEOUT=1) xonsh_builtins.__xonsh_env__ = DummyEnv(VC_BRANCH_TIMEOUT=1)
cache.is_empty = Mock(return_value=False) cache.is_empty = Mock(return_value=False)
cache.locate_binary = Mock(return_value='') cache.locate_binary = Mock(return_value="")
# make lazy locate return nothing to avoid running vc binaries # make lazy locate return nothing to avoid running vc binaries
cache.lazy_locate_binary = Mock(return_value='') cache.lazy_locate_binary = Mock(return_value="")
vc.current_branch() vc.current_branch()
assert not cache.locate_binary.called assert not cache.locate_binary.called

View file

@ -5,8 +5,16 @@ import os
import builtins import builtins
import pytest import pytest
from pygments.token import (Keyword, Name, String, Error, Number, from pygments.token import (
Operator, Punctuation, Text) Keyword,
Name,
String,
Error,
Number,
Operator,
Punctuation,
Text,
)
from tools import skip_if_on_windows from tools import skip_if_on_windows
from xonsh.platform import ON_WINDOWS from xonsh.platform import ON_WINDOWS
@ -18,7 +26,7 @@ from xonsh.pyghooks import XonshLexer
def load_command_cache(): def load_command_cache():
load_builtins() load_builtins()
if ON_WINDOWS: if ON_WINDOWS:
for key in ('cd', 'bash'): for key in ("cd", "bash"):
builtins.aliases[key] = lambda *args, **kwargs: None builtins.aliases[key] = lambda *args, **kwargs: None
yield yield
unload_builtins() unload_builtins()
@ -35,105 +43,127 @@ def check_token(code, tokens):
break break
tks = tks[1:] tks = tks[1:]
else: else:
msg = "Token {!r} missing: {!r}".format(tk, msg = "Token {!r} missing: {!r}".format(tk, list(lx.get_tokens(code)))
list(lx.get_tokens(code)))
pytest.fail(msg) pytest.fail(msg)
break break
@skip_if_on_windows @skip_if_on_windows
def test_ls(): def test_ls():
check_token('ls -al', [(Name.Builtin, 'ls')]) check_token("ls -al", [(Name.Builtin, "ls")])
@skip_if_on_windows @skip_if_on_windows
def test_bin_ls(): def test_bin_ls():
check_token('/bin/ls -al', [(Name.Builtin, '/bin/ls')]) check_token("/bin/ls -al", [(Name.Builtin, "/bin/ls")])
def test_py_print(): def test_py_print():
check_token('print("hello")', [(Keyword, 'print'), check_token('print("hello")', [(Keyword, "print"), (String.Double, "hello")])
(String.Double, 'hello')])
def test_invalid_cmd(): def test_invalid_cmd():
check_token('non-existance-cmd -al', [(Name, 'non')]) # parse as python check_token("non-existance-cmd -al", [(Name, "non")]) # parse as python
check_token('![non-existance-cmd -al]', check_token(
[(Error, 'non-existance-cmd')]) # parse as error "![non-existance-cmd -al]", [(Error, "non-existance-cmd")]
check_token('for i in range(10):', [(Keyword, 'for')]) # as py keyword ) # parse as error
check_token('(1, )', [(Punctuation, '('), check_token("for i in range(10):", [(Keyword, "for")]) # as py keyword
(Number.Integer, '1')]) check_token("(1, )", [(Punctuation, "("), (Number.Integer, "1")])
def test_multi_cmd(): def test_multi_cmd():
check_token('cd && cd', [(Name.Builtin, 'cd'), check_token(
(Operator, '&&'), "cd && cd", [(Name.Builtin, "cd"), (Operator, "&&"), (Name.Builtin, "cd")]
(Name.Builtin, 'cd')]) )
check_token('cd || non-existance-cmd', [(Name.Builtin, 'cd'), check_token(
(Operator, '||'), "cd || non-existance-cmd",
(Error, 'non-existance-cmd') [(Name.Builtin, "cd"), (Operator, "||"), (Error, "non-existance-cmd")],
]) )
def test_nested(): def test_nested():
check_token('echo @("hello")', [(Name.Builtin, 'echo'), check_token(
(Keyword, '@'), 'echo @("hello")',
(Punctuation, '('), [
(String.Double, 'hello'), (Name.Builtin, "echo"),
(Punctuation, ')')]) (Keyword, "@"),
check_token('print($(cd))', [(Keyword, 'print'), (Punctuation, "("),
(Punctuation, '('), (String.Double, "hello"),
(Keyword, '$'), (Punctuation, ")"),
(Punctuation, '('), ],
(Name.Builtin, 'cd'), )
(Punctuation, ')'), check_token(
(Punctuation, ')')]) "print($(cd))",
check_token(r'print(![echo "])\""])', [(Keyword, 'print'), [
(Keyword, '!'), (Keyword, "print"),
(Punctuation, '['), (Punctuation, "("),
(Name.Builtin, 'echo'), (Keyword, "$"),
(String.Double, r'"])\""'), (Punctuation, "("),
(Punctuation, ']')]) (Name.Builtin, "cd"),
(Punctuation, ")"),
(Punctuation, ")"),
],
)
check_token(
r'print(![echo "])\""])',
[
(Keyword, "print"),
(Keyword, "!"),
(Punctuation, "["),
(Name.Builtin, "echo"),
(String.Double, r'"])\""'),
(Punctuation, "]"),
],
)
def test_path(tmpdir): def test_path(tmpdir):
test_dir = str(tmpdir.mkdir('xonsh-test-highlight-path')) test_dir = str(tmpdir.mkdir("xonsh-test-highlight-path"))
check_token('cd {}'.format(test_dir), [(Name.Builtin, 'cd'), check_token(
(Name.Constant, test_dir)]) "cd {}".format(test_dir), [(Name.Builtin, "cd"), (Name.Constant, test_dir)]
check_token('cd {}-xxx'.format(test_dir), [(Name.Builtin, 'cd'), )
(Text, check_token(
'{}-xxx'.format(test_dir)) "cd {}-xxx".format(test_dir),
]) [(Name.Builtin, "cd"), (Text, "{}-xxx".format(test_dir))],
check_token('cd X={}'.format(test_dir), [(Name.Constant, test_dir)]) )
check_token("cd X={}".format(test_dir), [(Name.Constant, test_dir)])
with builtins.__xonsh_env__.swap(AUTO_CD=True): with builtins.__xonsh_env__.swap(AUTO_CD=True):
check_token(test_dir, [(Name.Constant, test_dir)]) check_token(test_dir, [(Name.Constant, test_dir)])
def test_subproc_args(): def test_subproc_args():
check_token('cd 192.168.0.1', [(Text, '192.168.0.1')]) check_token("cd 192.168.0.1", [(Text, "192.168.0.1")])
def test_backtick(): def test_backtick():
check_token(r'echo g`.*\w+`', [(String.Affix, 'g'), check_token(
(String.Backtick, '`'), r"echo g`.*\w+`",
(String.Regex, '.'), [
(String.Regex, '*'), (String.Affix, "g"),
(String.Escape, r'\w'), (String.Backtick, "`"),
]) (String.Regex, "."),
(String.Regex, "*"),
(String.Escape, r"\w"),
],
)
def test_macro(): def test_macro():
check_token(r'g!(42, *, 65)', [(Name, 'g'), check_token(
(Keyword, '!'), r"g!(42, *, 65)",
(Punctuation, '('), [(Name, "g"), (Keyword, "!"), (Punctuation, "("), (Number.Integer, "42")],
(Number.Integer, '42')]) )
check_token(r'echo! hello world', [(Name.Builtin, 'echo'), check_token(
(Keyword, '!'), r"echo! hello world",
(String, "hello world")]) [(Name.Builtin, "echo"), (Keyword, "!"), (String, "hello world")],
check_token(r'bash -c ! export var=42; echo $var', )
[(Name.Builtin, 'bash'), check_token(
(Text, '-c'), r"bash -c ! export var=42; echo $var",
(Keyword, '!'), [
(String, 'export var=42; echo $var'), (Name.Builtin, "bash"),
]) (Text, "-c"),
(Keyword, "!"),
(String, "export var=42; echo $var"),
],
)

View file

@ -3,7 +3,7 @@ import pytest
try: try:
import prompt_toolkit # NOQA import prompt_toolkit # NOQA
except ImportError: except ImportError:
pytest.mark.skip(msg='prompt_toolkit is not available') pytest.mark.skip(msg="prompt_toolkit is not available")
from xonsh.ptk2.history import PromptToolkitHistory from xonsh.ptk2.history import PromptToolkitHistory
@ -14,12 +14,12 @@ from tools import skip_if_lt_ptk2
def history_obj(): def history_obj():
"""Instantiate `PromptToolkitHistory` and append a line string""" """Instantiate `PromptToolkitHistory` and append a line string"""
hist = PromptToolkitHistory(load_prev=False) hist = PromptToolkitHistory(load_prev=False)
hist.append_string('line10') hist.append_string("line10")
return hist return hist
@skip_if_lt_ptk2 @skip_if_lt_ptk2
def test_obj(history_obj): def test_obj(history_obj):
assert ['line10'] == history_obj.get_strings() assert ["line10"] == history_obj.get_strings()
assert len(history_obj) == 1 assert len(history_obj) == 1
assert ['line10'] == [x for x in history_obj] assert ["line10"] == [x for x in history_obj]

View file

@ -14,29 +14,32 @@ from xonsh.tools import ON_WINDOWS
from tools import DummyEnv, skip_if_lt_ptk2 from tools import DummyEnv, skip_if_lt_ptk2
Context = namedtuple('Context', ['indent', 'buffer', 'accept', 'cli', 'cr']) Context = namedtuple("Context", ["indent", "buffer", "accept", "cli", "cr"])
@pytest.yield_fixture(scope='module') @pytest.yield_fixture(scope="module")
def ctx(): def ctx():
"""Context in which the ptk multiline functionality will be tested.""" """Context in which the ptk multiline functionality will be tested."""
builtins.__xonsh_env__ = DummyEnv() builtins.__xonsh_env__ = DummyEnv()
builtins.__xonsh_env__['INDENT'] = ' ' builtins.__xonsh_env__["INDENT"] = " "
from xonsh.ptk2.key_bindings import carriage_return from xonsh.ptk2.key_bindings import carriage_return
ptk_buffer = Buffer() ptk_buffer = Buffer()
ptk_buffer.accept_action = MagicMock(name='accept') ptk_buffer.accept_action = MagicMock(name="accept")
cli = MagicMock(name='cli', spec=Application) cli = MagicMock(name="cli", spec=Application)
yield Context(indent=' ', yield Context(
buffer=ptk_buffer, indent=" ",
accept=ptk_buffer.accept_action, buffer=ptk_buffer,
cli=cli, accept=ptk_buffer.accept_action,
cr=carriage_return) cli=cli,
cr=carriage_return,
)
del builtins.__xonsh_env__ del builtins.__xonsh_env__
@skip_if_lt_ptk2 @skip_if_lt_ptk2
def test_colon_indent(ctx): def test_colon_indent(ctx):
document = Document('for i in range(5):') document = Document("for i in range(5):")
ctx.buffer.set_document(document) ctx.buffer.set_document(document)
ctx.cr(ctx.buffer, ctx.cli) ctx.cr(ctx.buffer, ctx.cli)
assert ctx.buffer.document.current_line == ctx.indent assert ctx.buffer.document.current_line == ctx.indent
@ -44,12 +47,12 @@ def test_colon_indent(ctx):
@skip_if_lt_ptk2 @skip_if_lt_ptk2
def test_dedent(ctx): def test_dedent(ctx):
document = Document('\n'+ctx.indent+'pass') document = Document("\n" + ctx.indent + "pass")
ctx.buffer.set_document(document) ctx.buffer.set_document(document)
ctx.cr(ctx.buffer, ctx.cli) ctx.cr(ctx.buffer, ctx.cli)
assert ctx.buffer.document.current_line == '' assert ctx.buffer.document.current_line == ""
document = Document('\n'+2*ctx.indent+'continue') document = Document("\n" + 2 * ctx.indent + "continue")
ctx.buffer.set_document(document) ctx.buffer.set_document(document)
ctx.cr(ctx.buffer, ctx.cli) ctx.cr(ctx.buffer, ctx.cli)
assert ctx.buffer.document.current_line == ctx.indent assert ctx.buffer.document.current_line == ctx.indent
@ -57,17 +60,17 @@ def test_dedent(ctx):
@skip_if_lt_ptk2 @skip_if_lt_ptk2
def test_nodedent(ctx): def test_nodedent(ctx):
'''don't dedent if first line of ctx.buffer''' """don't dedent if first line of ctx.buffer"""
mock = MagicMock(return_value=True) mock = MagicMock(return_value=True)
with patch('xonsh.ptk2.key_bindings.can_compile', mock): with patch("xonsh.ptk2.key_bindings.can_compile", mock):
document = Document('pass') document = Document("pass")
ctx.buffer.set_document(document) ctx.buffer.set_document(document)
ctx.cr(ctx.buffer, ctx.cli) ctx.cr(ctx.buffer, ctx.cli)
assert ctx.accept.mock_calls is not None assert ctx.accept.mock_calls is not None
mock = MagicMock(return_value=True) mock = MagicMock(return_value=True)
with patch('xonsh.ptk2.key_bindings.can_compile', mock): with patch("xonsh.ptk2.key_bindings.can_compile", mock):
document = Document(ctx.indent+'pass') document = Document(ctx.indent + "pass")
ctx.buffer.set_document(document) ctx.buffer.set_document(document)
ctx.cr(ctx.buffer, ctx.cli) ctx.cr(ctx.buffer, ctx.cli)
assert ctx.accept.mock_calls is not None assert ctx.accept.mock_calls is not None
@ -75,21 +78,21 @@ def test_nodedent(ctx):
@skip_if_lt_ptk2 @skip_if_lt_ptk2
def test_continuation_line(ctx): def test_continuation_line(ctx):
document = Document('\nsecond line') document = Document("\nsecond line")
ctx.buffer.set_document(document) ctx.buffer.set_document(document)
ctx.cr(ctx.buffer, ctx.cli) ctx.cr(ctx.buffer, ctx.cli)
assert ctx.buffer.document.current_line == '' assert ctx.buffer.document.current_line == ""
@skip_if_lt_ptk2 @skip_if_lt_ptk2
def test_trailing_slash(ctx): def test_trailing_slash(ctx):
mock = MagicMock(return_value=True) mock = MagicMock(return_value=True)
with patch('xonsh.ptk2.key_bindings.can_compile', mock): with patch("xonsh.ptk2.key_bindings.can_compile", mock):
document = Document('this line will \\') document = Document("this line will \\")
ctx.buffer.set_document(document) ctx.buffer.set_document(document)
ctx.cr(ctx.buffer, ctx.cli) ctx.cr(ctx.buffer, ctx.cli)
if not ON_WINDOWS: if not ON_WINDOWS:
assert ctx.buffer.document.current_line == '' assert ctx.buffer.document.current_line == ""
else: else:
assert ctx.accept.mock_calls is not None assert ctx.accept.mock_calls is not None
@ -97,18 +100,18 @@ def test_trailing_slash(ctx):
@skip_if_lt_ptk2 @skip_if_lt_ptk2
def test_cant_compile_newline(ctx): def test_cant_compile_newline(ctx):
mock = MagicMock(return_value=False) mock = MagicMock(return_value=False)
with patch('xonsh.ptk2.key_bindings.can_compile', mock): with patch("xonsh.ptk2.key_bindings.can_compile", mock):
document = Document('for i in (1, 2, ') document = Document("for i in (1, 2, ")
ctx.buffer.set_document(document) ctx.buffer.set_document(document)
ctx.cr(ctx.buffer, ctx.cli) ctx.cr(ctx.buffer, ctx.cli)
assert ctx.buffer.document.current_line == '' assert ctx.buffer.document.current_line == ""
@skip_if_lt_ptk2 @skip_if_lt_ptk2
def test_can_compile_and_executes(ctx): def test_can_compile_and_executes(ctx):
mock = MagicMock(return_value=True) mock = MagicMock(return_value=True)
with patch('xonsh.ptk2.key_bindings.can_compile', mock): with patch("xonsh.ptk2.key_bindings.can_compile", mock):
document = Document('ls') document = Document("ls")
ctx.buffer.set_document(document) ctx.buffer.set_document(document)
ctx.cr(ctx.buffer, ctx.cli) ctx.cr(ctx.buffer, ctx.cli)
assert ctx.accept.mock_calls is not None assert ctx.accept.mock_calls is not None

View file

@ -14,7 +14,7 @@ def foo(x, y, z):
pass pass
def bar(wakka='wow', jawaka='mom'): def bar(wakka="wow", jawaka="mom"):
pass pass
@ -26,26 +26,29 @@ def always_true(x, y):
return True return True
BASE_CTX = {'foo': foo, 'bar': bar, 'baz': baz} BASE_CTX = {"foo": foo, "bar": bar, "baz": baz}
FOO_ARGS = {'x=', 'y=', 'z='} FOO_ARGS = {"x=", "y=", "z="}
BAR_ARGS = {'wakka=', 'jawaka='} BAR_ARGS = {"wakka=", "jawaka="}
BAZ_ARGS = {'sonata=', 'artica='} BAZ_ARGS = {"sonata=", "artica="}
@pytest.mark.parametrize('line, end, exp', [ @pytest.mark.parametrize(
('foo(', 4, FOO_ARGS), # I have no idea why this one needs to be first "line, end, exp",
('foo()', 3, set()), [
('foo()', 4, FOO_ARGS), ("foo(", 4, FOO_ARGS), # I have no idea why this one needs to be first
('foo()', 5, set()), ("foo()", 3, set()),
('foo(x, ', 6, FOO_ARGS), ("foo()", 4, FOO_ARGS),
('foo(x, )', 6, FOO_ARGS), ("foo()", 5, set()),
('bar()', 4, BAR_ARGS), ("foo(x, ", 6, FOO_ARGS),
('baz()', 4, BAZ_ARGS), ("foo(x, )", 6, FOO_ARGS),
('foo(bar(', 8, BAR_ARGS), ("bar()", 4, BAR_ARGS),
('foo(bar()', 9, FOO_ARGS), ("baz()", 4, BAZ_ARGS),
('foo(bar())', 4, FOO_ARGS), ("foo(bar(", 8, BAR_ARGS),
]) ("foo(bar()", 9, FOO_ARGS),
("foo(bar())", 4, FOO_ARGS),
],
)
def test_complete_python_signatures(line, end, exp): def test_complete_python_signatures(line, end, exp):
ctx = dict(BASE_CTX) ctx = dict(BASE_CTX)
obs = python_signature_complete('', line, end, ctx, always_true) obs = python_signature_complete("", line, end, ctx, always_true)
assert exp == obs assert exp == obs

View file

@ -12,36 +12,36 @@ from xonsh.replay import Replayer
from tools import skip_if_on_darwin from tools import skip_if_on_darwin
HISTDIR = os.path.join(os.path.dirname(__file__), 'histories') HISTDIR = os.path.join(os.path.dirname(__file__), "histories")
@pytest.yield_fixture(scope='module', autouse=True) @pytest.yield_fixture(scope="module", autouse=True)
def ctx(): def ctx():
"""Create a global Shell instance to use in all the test.""" """Create a global Shell instance to use in all the test."""
ctx = {'PATH': []} ctx = {"PATH": []}
execer = Execer(xonsh_ctx=ctx) execer = Execer(xonsh_ctx=ctx)
builtins.__xonsh_shell__ = Shell(execer=execer, ctx=ctx, shell_type='none') builtins.__xonsh_shell__ = Shell(execer=execer, ctx=ctx, shell_type="none")
yield yield
del builtins.__xonsh_shell__ del builtins.__xonsh_shell__
@skip_if_on_darwin @skip_if_on_darwin
def test_echo(): def test_echo():
histfile = os.path.join(HISTDIR, 'echo.json') histfile = os.path.join(HISTDIR, "echo.json")
hist = Replayer(histfile).replay() hist = Replayer(histfile).replay()
assert len(hist) == 2 assert len(hist) == 2
@skip_if_on_darwin @skip_if_on_darwin
def test_reecho(): def test_reecho():
histfile = os.path.join(HISTDIR, 'echo.json') histfile = os.path.join(HISTDIR, "echo.json")
hist = Replayer(histfile).replay() hist = Replayer(histfile).replay()
assert len(hist) == 2 assert len(hist) == 2
@skip_if_on_darwin @skip_if_on_darwin
def test_simple_python(): def test_simple_python():
histfile = os.path.join(HISTDIR, 'simple-python.json') histfile = os.path.join(HISTDIR, "simple-python.json")
hist = Replayer(histfile).replay() hist = Replayer(histfile).replay()
assert len(hist) == 4 assert len(hist) == 4
assert hist.inps[0].strip() == "print('The Turtles')" assert hist.inps[0].strip() == "print('The Turtles')"

File diff suppressed because it is too large Load diff

View file

@ -16,36 +16,36 @@ def test_crud(xonsh_builtins, tmpdir):
""" """
Creates a virtual environment, gets it, enumerates it, and then deletes it. Creates a virtual environment, gets it, enumerates it, and then deletes it.
""" """
xonsh_builtins.__xonsh_env__['VIRTUALENV_HOME'] = str(tmpdir) xonsh_builtins.__xonsh_env__["VIRTUALENV_HOME"] = str(tmpdir)
last_event = None last_event = None
@xonsh_builtins.events.vox_on_create @xonsh_builtins.events.vox_on_create
def create(name, **_): def create(name, **_):
nonlocal last_event nonlocal last_event
last_event = 'create', name last_event = "create", name
@xonsh_builtins.events.vox_on_delete @xonsh_builtins.events.vox_on_delete
def delete(name, **_): def delete(name, **_):
nonlocal last_event nonlocal last_event
last_event = 'delete', name last_event = "delete", name
vox = Vox() vox = Vox()
vox.create('spam') vox.create("spam")
assert stat.S_ISDIR(tmpdir.join('spam').stat().mode) assert stat.S_ISDIR(tmpdir.join("spam").stat().mode)
assert last_event == ('create', 'spam') assert last_event == ("create", "spam")
ve = vox['spam'] ve = vox["spam"]
assert ve.env == str(tmpdir.join('spam')) assert ve.env == str(tmpdir.join("spam"))
assert os.path.isdir(ve.bin) assert os.path.isdir(ve.bin)
assert 'spam' in vox assert "spam" in vox
assert 'spam' in list(vox) assert "spam" in list(vox)
del vox['spam'] del vox["spam"]
assert not tmpdir.join('spam').check() assert not tmpdir.join("spam").check()
assert last_event == ('delete', 'spam') assert last_event == ("delete", "spam")
@skip_if_on_msys @skip_if_on_msys
@ -54,30 +54,30 @@ def test_activate(xonsh_builtins, tmpdir):
""" """
Creates a virtual environment, gets it, enumerates it, and then deletes it. Creates a virtual environment, gets it, enumerates it, and then deletes it.
""" """
xonsh_builtins.__xonsh_env__['VIRTUALENV_HOME'] = str(tmpdir) xonsh_builtins.__xonsh_env__["VIRTUALENV_HOME"] = str(tmpdir)
# I consider the case that the user doesn't have a PATH set to be unreasonable # I consider the case that the user doesn't have a PATH set to be unreasonable
xonsh_builtins.__xonsh_env__.setdefault('PATH', []) xonsh_builtins.__xonsh_env__.setdefault("PATH", [])
last_event = None last_event = None
@xonsh_builtins.events.vox_on_activate @xonsh_builtins.events.vox_on_activate
def activate(name, **_): def activate(name, **_):
nonlocal last_event nonlocal last_event
last_event = 'activate', name last_event = "activate", name
@xonsh_builtins.events.vox_on_deactivate @xonsh_builtins.events.vox_on_deactivate
def deactivate(name, **_): def deactivate(name, **_):
nonlocal last_event nonlocal last_event
last_event = 'deactivate', name last_event = "deactivate", name
vox = Vox() vox = Vox()
vox.create('spam') vox.create("spam")
vox.activate('spam') vox.activate("spam")
assert xonsh_builtins.__xonsh_env__['VIRTUAL_ENV'] == vox['spam'].env assert xonsh_builtins.__xonsh_env__["VIRTUAL_ENV"] == vox["spam"].env
assert last_event == ('activate', 'spam') assert last_event == ("activate", "spam")
vox.deactivate() vox.deactivate()
assert 'VIRTUAL_ENV' not in xonsh_builtins.__xonsh_env__ assert "VIRTUAL_ENV" not in xonsh_builtins.__xonsh_env__
assert last_event == ('deactivate', 'spam') assert last_event == ("deactivate", "spam")
@skip_if_on_msys @skip_if_on_msys
@ -86,21 +86,21 @@ def test_path(xonsh_builtins, tmpdir):
""" """
Test to make sure Vox properly activates and deactivates by examining $PATH Test to make sure Vox properly activates and deactivates by examining $PATH
""" """
xonsh_builtins.__xonsh_env__['VIRTUALENV_HOME'] = str(tmpdir) xonsh_builtins.__xonsh_env__["VIRTUALENV_HOME"] = str(tmpdir)
# I consider the case that the user doesn't have a PATH set to be unreasonable # I consider the case that the user doesn't have a PATH set to be unreasonable
xonsh_builtins.__xonsh_env__.setdefault('PATH', []) xonsh_builtins.__xonsh_env__.setdefault("PATH", [])
oldpath = list(xonsh_builtins.__xonsh_env__['PATH']) oldpath = list(xonsh_builtins.__xonsh_env__["PATH"])
vox = Vox() vox = Vox()
vox.create('eggs') vox.create("eggs")
vox.activate('eggs') vox.activate("eggs")
assert oldpath != xonsh_builtins.__xonsh_env__['PATH'] assert oldpath != xonsh_builtins.__xonsh_env__["PATH"]
vox.deactivate() vox.deactivate()
assert oldpath == xonsh_builtins.__xonsh_env__['PATH'] assert oldpath == xonsh_builtins.__xonsh_env__["PATH"]
@skip_if_on_msys @skip_if_on_msys
@ -109,31 +109,33 @@ def test_crud_subdir(xonsh_builtins, tmpdir):
""" """
Creates a virtual environment, gets it, enumerates it, and then deletes it. Creates a virtual environment, gets it, enumerates it, and then deletes it.
""" """
xonsh_builtins.__xonsh_env__['VIRTUALENV_HOME'] = str(tmpdir) xonsh_builtins.__xonsh_env__["VIRTUALENV_HOME"] = str(tmpdir)
vox = Vox() vox = Vox()
vox.create('spam/eggs') vox.create("spam/eggs")
assert stat.S_ISDIR(tmpdir.join('spam', 'eggs').stat().mode) assert stat.S_ISDIR(tmpdir.join("spam", "eggs").stat().mode)
ve = vox['spam/eggs'] ve = vox["spam/eggs"]
assert ve.env == str(tmpdir.join('spam', 'eggs')) assert ve.env == str(tmpdir.join("spam", "eggs"))
assert os.path.isdir(ve.bin) assert os.path.isdir(ve.bin)
assert 'spam/eggs' in vox assert "spam/eggs" in vox
assert 'spam' not in vox assert "spam" not in vox
#assert 'spam/eggs' in list(vox) # This is NOT true on Windows # assert 'spam/eggs' in list(vox) # This is NOT true on Windows
assert 'spam' not in list(vox) assert "spam" not in list(vox)
del vox['spam/eggs'] del vox["spam/eggs"]
assert not tmpdir.join("spam", "eggs").check()
assert not tmpdir.join('spam', 'eggs').check()
try: try:
import pathlib import pathlib
except ImportError: except ImportError:
pass pass
else: else:
@skip_if_on_msys @skip_if_on_msys
@skip_if_on_conda @skip_if_on_conda
def test_crud_path(xonsh_builtins, tmpdir): def test_crud_path(xonsh_builtins, tmpdir):
@ -144,7 +146,7 @@ else:
vox = Vox() vox = Vox()
vox.create(tmp) vox.create(tmp)
assert stat.S_ISDIR(tmpdir.join('lib').stat().mode) assert stat.S_ISDIR(tmpdir.join("lib").stat().mode)
ve = vox[tmp] ve = vox[tmp]
assert ve.env == str(tmp) assert ve.env == str(tmp)
@ -161,17 +163,17 @@ def test_crud_subdir(xonsh_builtins, tmpdir):
""" """
Creates a virtual environment, gets it, enumerates it, and then deletes it. Creates a virtual environment, gets it, enumerates it, and then deletes it.
""" """
xonsh_builtins.__xonsh_env__['VIRTUALENV_HOME'] = str(tmpdir) xonsh_builtins.__xonsh_env__["VIRTUALENV_HOME"] = str(tmpdir)
vox = Vox() vox = Vox()
with pytest.raises(ValueError): with pytest.raises(ValueError):
if ON_WINDOWS: if ON_WINDOWS:
vox.create('Scripts') vox.create("Scripts")
else: else:
vox.create('bin') vox.create("bin")
with pytest.raises(ValueError): with pytest.raises(ValueError):
if ON_WINDOWS: if ON_WINDOWS:
vox.create('spameggs/Scripts') vox.create("spameggs/Scripts")
else: else:
vox.create('spameggs/bin') vox.create("spameggs/bin")

View file

@ -5,78 +5,97 @@ import os
import pytest import pytest
from xonsh.wizard import (Node, Wizard, Pass, PrettyFormatter, from xonsh.wizard import (
Message, Question, StateVisitor, FileInserter) Node,
Wizard,
Pass,
PrettyFormatter,
Message,
Question,
StateVisitor,
FileInserter,
)
TREE0 = Wizard(children=[Pass(), Message(message='yo')]) TREE0 = Wizard(children=[Pass(), Message(message="yo")])
TREE1 = Question('wakka?', {'jawaka': Pass()}) TREE1 = Question("wakka?", {"jawaka": Pass()})
def test_pretty_format_tree0(): def test_pretty_format_tree0():
exp = ('Wizard(children=[\n' exp = "Wizard(children=[\n" " Pass(),\n" " Message('yo')\n" "])"
' Pass(),\n'
" Message('yo')\n"
'])')
obs = PrettyFormatter(TREE0).visit() obs = PrettyFormatter(TREE0).visit()
assert exp == obs assert exp == obs
assert exp == str(TREE0) assert exp == str(TREE0)
assert exp.replace('\n', '') == repr(TREE0) assert exp.replace("\n", "") == repr(TREE0)
def test_pretty_format_tree1(): def test_pretty_format_tree1():
exp = ('Question(\n' exp = (
" question='wakka?',\n" "Question(\n"
' responses={\n' " question='wakka?',\n"
" 'jawaka': Pass()\n" " responses={\n"
' }\n' " 'jawaka': Pass()\n"
')') " }\n"
")"
)
obs = PrettyFormatter(TREE1).visit() obs = PrettyFormatter(TREE1).visit()
assert exp == obs assert exp == obs
assert exp == str(TREE1) assert exp == str(TREE1)
assert exp.replace('\n', '') == repr(TREE1) assert exp.replace("\n", "") == repr(TREE1)
def test_state_visitor_store(): def test_state_visitor_store():
exp = {'rick': [{}, {}, {'and': 'morty'}]} exp = {"rick": [{}, {}, {"and": "morty"}]}
sv = StateVisitor() sv = StateVisitor()
sv.store('/rick/2/and', 'morty') sv.store("/rick/2/and", "morty")
obs = sv.state obs = sv.state
assert exp == obs assert exp == obs
exp['rick'][1]['mr'] = 'meeseeks' exp["rick"][1]["mr"] = "meeseeks"
sv.store('/rick/-2/mr', 'meeseeks') sv.store("/rick/-2/mr", "meeseeks")
assert exp == obs assert exp == obs
flat_exp = {'/': {'rick': [{}, {'mr': 'meeseeks'}, {'and': 'morty'}]}, flat_exp = {
'/rick/': [{}, {'mr': 'meeseeks'}, {'and': 'morty'}], "/": {"rick": [{}, {"mr": "meeseeks"}, {"and": "morty"}]},
'/rick/0/': {}, "/rick/": [{}, {"mr": "meeseeks"}, {"and": "morty"}],
'/rick/1/': {'mr': 'meeseeks'}, "/rick/0/": {},
'/rick/1/mr': 'meeseeks', "/rick/1/": {"mr": "meeseeks"},
'/rick/2/': {'and': 'morty'}, "/rick/1/mr": "meeseeks",
'/rick/2/and': 'morty', "/rick/2/": {"and": "morty"},
} "/rick/2/and": "morty",
}
flat_obs = sv.flatten() flat_obs = sv.flatten()
assert flat_exp == flat_obs assert flat_exp == flat_obs
def dump_xonfig_env_mock(path, value): def dump_xonfig_env_mock(path, value):
name = os.path.basename(path.rstrip('/')) name = os.path.basename(path.rstrip("/"))
return '${name} = {val!r}'.format(name=name, val=value) return "${name} = {val!r}".format(name=name, val=value)
def test_tuple_store_and_write(): def test_tuple_store_and_write():
# setup # setup
sv = StateVisitor() sv = StateVisitor()
sv.store('/env/XONSH_HISTORY_SIZE', (1073741824, 'b')) sv.store("/env/XONSH_HISTORY_SIZE", (1073741824, "b"))
dump_rules = {'/': None, '/env/': None, dump_rules = {
'/env/*': dump_xonfig_env_mock, "/": None,
'/env/*/[0-9]*': None} "/env/": None,
fi = FileInserter(prefix='# XONSH WIZARD START', suffix='# XONSH WIZARD END', "/env/*": dump_xonfig_env_mock,
dump_rules=dump_rules, default_file=None, "/env/*/[0-9]*": None,
check=False, ask_filename=False) }
fi = FileInserter(
prefix="# XONSH WIZARD START",
suffix="# XONSH WIZARD END",
dump_rules=dump_rules,
default_file=None,
check=False,
ask_filename=False,
)
# run test # run test
exp = ("# XONSH WIZARD START\n" exp = (
"$XONSH_HISTORY_SIZE = (1073741824, 'b')\n" "# XONSH WIZARD START\n"
"# XONSH WIZARD END\n") "$XONSH_HISTORY_SIZE = (1073741824, 'b')\n"
"# XONSH WIZARD END\n"
)
obs = fi.dumps(sv.flatten()) obs = fi.dumps(sv.flatten())
assert exp == obs assert exp == obs

View file

@ -3,10 +3,12 @@ import sys
import pytest import pytest
from xonsh.xontribs import xontrib_metadata, xontrib_context from xonsh.xontribs import xontrib_metadata, xontrib_context
def test_load_xontrib_metadata(): def test_load_xontrib_metadata():
# Simply tests that the xontribs JSON files isn't malformed. # Simply tests that the xontribs JSON files isn't malformed.
xontrib_metadata() xontrib_metadata()
@pytest.yield_fixture @pytest.yield_fixture
def tmpmod(tmpdir): def tmpmod(tmpdir):
""" """
@ -24,45 +26,54 @@ def tmpmod(tmpdir):
for m in newmods: for m in newmods:
del sys.modules[m] del sys.modules[m]
def test_noall(tmpmod): def test_noall(tmpmod):
""" """
Tests what get's exported from a module without __all__ Tests what get's exported from a module without __all__
""" """
with tmpmod.mkdir("xontrib").join("spameggs.py").open('w') as x: with tmpmod.mkdir("xontrib").join("spameggs.py").open("w") as x:
x.write(""" x.write(
"""
spam = 1 spam = 1
eggs = 2 eggs = 2
_foobar = 3 _foobar = 3
""") """
)
ctx = xontrib_context("spameggs")
assert ctx == {"spam": 1, "eggs": 2}
ctx = xontrib_context('spameggs')
assert ctx == {'spam': 1, 'eggs': 2}
def test_withall(tmpmod): def test_withall(tmpmod):
""" """
Tests what get's exported from a module with __all__ Tests what get's exported from a module with __all__
""" """
with tmpmod.mkdir("xontrib").join("spameggs.py").open('w') as x: with tmpmod.mkdir("xontrib").join("spameggs.py").open("w") as x:
x.write(""" x.write(
"""
__all__ = 'spam', '_foobar' __all__ = 'spam', '_foobar'
spam = 1 spam = 1
eggs = 2 eggs = 2
_foobar = 3 _foobar = 3
""") """
)
ctx = xontrib_context("spameggs")
assert ctx == {"spam": 1, "_foobar": 3}
ctx = xontrib_context('spameggs')
assert ctx == {'spam': 1, '_foobar': 3}
def test_xshxontrib(tmpmod): def test_xshxontrib(tmpmod):
""" """
Test that .xsh xontribs are loadable Test that .xsh xontribs are loadable
""" """
with tmpmod.mkdir("xontrib").join("script.xsh").open('w') as x: with tmpmod.mkdir("xontrib").join("script.xsh").open("w") as x:
x.write(""" x.write(
"""
hello = 'world' hello = 'world'
""") """
)
ctx = xontrib_context('script') ctx = xontrib_context("script")
assert ctx == {'hello': 'world'} assert ctx == {"hello": "world"}

View file

@ -11,19 +11,17 @@ class TestWhich:
# use from the _which.py module. # use from the _which.py module.
def setup(self): def setup(self):
# Setup two folders with some test files. # Setup two folders with some test files.
self.testdirs = [tempfile.TemporaryDirectory(), self.testdirs = [tempfile.TemporaryDirectory(), tempfile.TemporaryDirectory()]
tempfile.TemporaryDirectory()]
if ON_WINDOWS: if ON_WINDOWS:
self.testapps = ['whichtestapp1.exe', self.testapps = ["whichtestapp1.exe", "whichtestapp2.wta"]
'whichtestapp2.wta'] self.exts = [".EXE"]
self.exts = ['.EXE']
else: else:
self.testapps = ['whichtestapp1'] self.testapps = ["whichtestapp1"]
self.exts = None self.exts = None
for app in self.testapps: for app in self.testapps:
for d in self.testdirs: for d in self.testdirs:
path = os.path.join(d.name, app) path = os.path.join(d.name, app)
open(path, 'wb').write(b'') open(path, "wb").write(b"")
os.chmod(path, 0o755) os.chmod(path, 0o755)
def teardown_module(self): def teardown_module(self):
@ -32,48 +30,49 @@ class TestWhich:
def test_whichgen(self): def test_whichgen(self):
testdir = self.testdirs[0].name testdir = self.testdirs[0].name
arg = 'whichtestapp1' arg = "whichtestapp1"
matches = list(_which.whichgen(arg, path=[testdir], exts=self.exts)) matches = list(_which.whichgen(arg, path=[testdir], exts=self.exts))
assert len(matches) == 1 assert len(matches) == 1
assert self._file_match(matches[0][0], os.path.join(testdir, arg)) assert self._file_match(matches[0][0], os.path.join(testdir, arg))
def test_whichgen_failure(self): def test_whichgen_failure(self):
testdir = self.testdirs[0].name testdir = self.testdirs[0].name
arg = 'not_a_file' arg = "not_a_file"
matches = list(_which.whichgen(arg, path=[testdir], exts=self.exts)) matches = list(_which.whichgen(arg, path=[testdir], exts=self.exts))
assert len(matches) == 0 assert len(matches) == 0
def test_whichgen_verbose(self): def test_whichgen_verbose(self):
testdir = self.testdirs[0].name testdir = self.testdirs[0].name
arg = 'whichtestapp1' arg = "whichtestapp1"
matches = list(_which.whichgen(arg, path=[testdir], exts=self.exts, matches = list(
verbose=True)) _which.whichgen(arg, path=[testdir], exts=self.exts, verbose=True)
)
assert len(matches) == 1 assert len(matches) == 1
match, from_where = matches[0] match, from_where = matches[0]
assert self._file_match(match, os.path.join(testdir, arg)) assert self._file_match(match, os.path.join(testdir, arg))
assert from_where == 'from given path element 0' assert from_where == "from given path element 0"
def test_whichgen_multiple(self): def test_whichgen_multiple(self):
testdir0 = self.testdirs[0].name testdir0 = self.testdirs[0].name
testdir1 = self.testdirs[1].name testdir1 = self.testdirs[1].name
arg = 'whichtestapp1' arg = "whichtestapp1"
matches = list(_which.whichgen(arg, path=[testdir0, testdir1], matches = list(_which.whichgen(arg, path=[testdir0, testdir1], exts=self.exts))
exts=self.exts))
assert len(matches) == 2 assert len(matches) == 2
assert self._file_match(matches[0][0], os.path.join(testdir0, arg)) assert self._file_match(matches[0][0], os.path.join(testdir0, arg))
assert self._file_match(matches[1][0], os.path.join(testdir1, arg)) assert self._file_match(matches[1][0], os.path.join(testdir1, arg))
if ON_WINDOWS: if ON_WINDOWS:
def test_whichgen_ext_failure(self): def test_whichgen_ext_failure(self):
testdir = self.testdirs[0].name testdir = self.testdirs[0].name
arg = 'whichtestapp2' arg = "whichtestapp2"
matches = list(_which.whichgen(arg, path=[testdir], exts=self.exts)) matches = list(_which.whichgen(arg, path=[testdir], exts=self.exts))
assert len(matches) == 0 assert len(matches) == 0
def test_whichgen_ext_success(self): def test_whichgen_ext_success(self):
testdir = self.testdirs[0].name testdir = self.testdirs[0].name
arg = 'whichtestapp2' arg = "whichtestapp2"
matches = list(_which.whichgen(arg, path=[testdir], exts=['.wta'])) matches = list(_which.whichgen(arg, path=[testdir], exts=[".wta"]))
assert len(matches) == 1 assert len(matches) == 1
assert self._file_match(matches[0][0], os.path.join(testdir, arg)) assert self._file_match(matches[0][0], os.path.join(testdir, arg))