1# -*- coding: utf-8 -*- 2"""Tests the xonsh builtins.""" 3from __future__ import unicode_literals, print_function 4import os 5import re 6import builtins 7import types 8from ast import AST 9 10import pytest 11 12from xonsh import built_ins 13from xonsh.built_ins import ( 14 reglob, 15 pathsearch, 16 helper, 17 superhelper, 18 ensure_list_of_strs, 19 list_of_strs_or_callables, 20 list_of_list_of_strs_outer_product, 21 regexsearch, 22 globsearch, 23 expand_path, 24 convert_macro_arg, 25 in_macro_call, 26 call_macro, 27 enter_macro, 28) 29from xonsh.environ import Env 30 31from tools import skip_if_on_windows 32 33 34HOME_PATH = os.path.expanduser("~") 35 36 37@pytest.fixture(autouse=True) 38def xonsh_execer_autouse(xonsh_execer): 39 return xonsh_execer 40 41 42@pytest.mark.parametrize("testfile", reglob("test_.*")) 43def test_reglob_tests(testfile): 44 assert testfile.startswith("test_") 45 46 47@pytest.fixture 48def home_env(xonsh_builtins): 49 """Set `__xonsh_env__ ` to a new Env instance on `xonsh_builtins`""" 50 xonsh_builtins.__xonsh_env__ = Env(HOME=HOME_PATH) 51 return xonsh_builtins 52 53 54@skip_if_on_windows 55def test_repath_backslash(home_env): 56 exp = os.listdir(HOME_PATH) 57 exp = {p for p in exp if re.match(r"\w\w.*", p)} 58 exp = {os.path.join(HOME_PATH, p) for p in exp} 59 obs = set(pathsearch(regexsearch, r"~/\w\w.*")) 60 assert exp == obs 61 62 63@skip_if_on_windows 64def test_repath_HOME_PATH_itself(home_env): 65 exp = HOME_PATH 66 obs = pathsearch(regexsearch, "~") 67 assert 1 == len(obs) 68 assert exp == obs[0] 69 70 71@skip_if_on_windows 72def test_repath_HOME_PATH_contents(home_env): 73 exp = os.listdir(HOME_PATH) 74 exp = {os.path.join(HOME_PATH, p) for p in exp} 75 obs = set(pathsearch(regexsearch, "~/.*")) 76 assert exp == obs 77 78 79@skip_if_on_windows 80def test_repath_HOME_PATH_var(home_env): 81 exp = HOME_PATH 82 obs = pathsearch(regexsearch, "$HOME") 83 assert 1 == len(obs) 84 assert exp == obs[0] 85 86 87@skip_if_on_windows 88def test_repath_HOME_PATH_var_brace(home_env): 89 exp = HOME_PATH 90 obs = pathsearch(regexsearch, '${"HOME"}') 91 assert 1 == len(obs) 92 assert exp == obs[0] 93 94 95def test_helper_int(home_env): 96 helper(int, "int") 97 98 99def test_helper_helper(home_env): 100 helper(helper, "helper") 101 102 103def test_helper_env(home_env): 104 helper(Env, "Env") 105 106 107def test_superhelper_int(home_env): 108 superhelper(int, "int") 109 110 111def test_superhelper_helper(home_env): 112 superhelper(helper, "helper") 113 114 115def test_superhelper_env(home_env): 116 superhelper(Env, "Env") 117 118 119@pytest.mark.parametrize( 120 "exp, inp", [(["yo"], "yo"), (["yo"], ["yo"]), (["42"], 42), (["42"], [42])] 121) 122def test_ensure_list_of_strs(exp, inp): 123 obs = ensure_list_of_strs(inp) 124 assert exp == obs 125 126 127f = lambda x: 20 128 129 130@pytest.mark.parametrize( 131 "exp, inp", 132 [ 133 (["yo"], "yo"), 134 (["yo"], ["yo"]), 135 (["42"], 42), 136 (["42"], [42]), 137 ([f], f), 138 ([f], [f]), 139 ], 140) 141def test_list_of_strs_or_callables(exp, inp): 142 obs = list_of_strs_or_callables(inp) 143 assert exp == obs 144 145 146@pytest.mark.parametrize( 147 "inp, exp", 148 [ 149 (["x", ["y", "z"]], ["xy", "xz"]), 150 (["x", ["y", "z"], ["a"]], ["xya", "xza"]), 151 ([["y", "z"], ["a", "b"]], ["ya", "yb", "za", "zb"]), 152 ], 153) 154def test_list_of_list_of_strs_outer_product(xonsh_builtins, inp, exp): 155 obs = list_of_list_of_strs_outer_product(inp) 156 assert exp == obs 157 158 159@pytest.mark.parametrize( 160 "s", 161 [ 162 "~", 163 "~/", 164 "x=~/place", 165 "x=one:~/place", 166 "x=one:~/place:~/yo", 167 "x=~/one:~/place:~/yo", 168 ], 169) 170def test_expand_path(s, home_env): 171 if os.sep != "/": 172 s = s.replace("/", os.sep) 173 if os.pathsep != ":": 174 s = s.replace(":", os.pathsep) 175 assert expand_path(s) == s.replace("~", HOME_PATH) 176 177 178@pytest.mark.parametrize("kind", [str, "s", "S", "str", "string"]) 179def test_convert_macro_arg_str(kind): 180 raw_arg = "value" 181 arg = convert_macro_arg(raw_arg, kind, None, None) 182 assert arg is raw_arg 183 184 185@pytest.mark.parametrize("kind", [AST, "a", "Ast"]) 186def test_convert_macro_arg_ast(kind): 187 raw_arg = "42" 188 arg = convert_macro_arg(raw_arg, kind, {}, None) 189 assert isinstance(arg, AST) 190 191 192@pytest.mark.parametrize("kind", [types.CodeType, compile, "c", "code", "compile"]) 193def test_convert_macro_arg_code(kind): 194 raw_arg = "42" 195 arg = convert_macro_arg(raw_arg, kind, {}, None) 196 assert isinstance(arg, types.CodeType) 197 198 199@pytest.mark.parametrize("kind", [eval, None, "v", "eval"]) 200def test_convert_macro_arg_eval(kind): 201 # literals 202 raw_arg = "42" 203 arg = convert_macro_arg(raw_arg, kind, {}, None) 204 assert arg == 42 205 # exprs 206 raw_arg = "x + 41" 207 arg = convert_macro_arg(raw_arg, kind, {}, {"x": 1}) 208 assert arg == 42 209 210 211@pytest.mark.parametrize("kind", [exec, "x", "exec"]) 212def test_convert_macro_arg_exec(kind): 213 # at global scope 214 raw_arg = "def f(x, y):\n return x + y" 215 glbs = {} 216 arg = convert_macro_arg(raw_arg, kind, glbs, None) 217 assert arg is None 218 assert "f" in glbs 219 assert glbs["f"](1, 41) == 42 220 # at local scope 221 raw_arg = "def g(z):\n return x + z\ny += 42" 222 glbs = {"x": 40} 223 locs = {"y": 1} 224 arg = convert_macro_arg(raw_arg, kind, glbs, locs) 225 assert arg is None 226 assert "g" in locs 227 assert locs["g"](1) == 41 228 assert "y" in locs 229 assert locs["y"] == 43 230 231 232@pytest.mark.parametrize("kind", [type, "t", "type"]) 233def test_convert_macro_arg_eval(kind): 234 # literals 235 raw_arg = "42" 236 arg = convert_macro_arg(raw_arg, kind, {}, None) 237 assert arg is int 238 # exprs 239 raw_arg = "x + 41" 240 arg = convert_macro_arg(raw_arg, kind, {}, {"x": 1}) 241 assert arg is int 242 243 244def test_in_macro_call(): 245 def f(): 246 pass 247 248 with in_macro_call(f, True, True): 249 assert f.macro_globals 250 assert f.macro_locals 251 assert not hasattr(f, "macro_globals") 252 assert not hasattr(f, "macro_locals") 253 254 255@pytest.mark.parametrize("arg", ["x", "42", "x + y"]) 256def test_call_macro_str(arg): 257 def f(x: str): 258 return x 259 260 rtn = call_macro(f, [arg], None, None) 261 assert rtn is arg 262 263 264@pytest.mark.parametrize("arg", ["x", "42", "x + y"]) 265def test_call_macro_ast(arg): 266 def f(x: AST): 267 return x 268 269 rtn = call_macro(f, [arg], {}, None) 270 assert isinstance(rtn, AST) 271 272 273@pytest.mark.parametrize("arg", ["x", "42", "x + y"]) 274def test_call_macro_code(arg): 275 def f(x: compile): 276 return x 277 278 rtn = call_macro(f, [arg], {}, None) 279 assert isinstance(rtn, types.CodeType) 280 281 282@pytest.mark.parametrize("arg", ["x", "42", "x + y"]) 283def test_call_macro_eval(arg): 284 def f(x: eval): 285 return x 286 287 rtn = call_macro(f, [arg], {"x": 42, "y": 0}, None) 288 assert rtn == 42 289 290 291@pytest.mark.parametrize( 292 "arg", ["if y:\n pass", "if 42:\n pass", "if x + y:\n pass"] 293) 294def test_call_macro_exec(arg): 295 def f(x: exec): 296 return x 297 298 rtn = call_macro(f, [arg], {"x": 42, "y": 0}, None) 299 assert rtn is None 300 301 302@pytest.mark.parametrize("arg", ["x", "42", "x + y"]) 303def test_call_macro_raw_arg(arg): 304 def f(x: str): 305 return x 306 307 rtn = call_macro(f, ["*", arg], {"x": 42, "y": 0}, None) 308 assert rtn == 42 309 310 311@pytest.mark.parametrize("arg", ["x", "42", "x + y"]) 312def test_call_macro_raw_kwarg(arg): 313 def f(x: str): 314 return x 315 316 rtn = call_macro(f, ["*", "x=" + arg], {"x": 42, "y": 0}, None) 317 assert rtn == 42 318 319 320@pytest.mark.parametrize("arg", ["x", "42", "x + y"]) 321def test_call_macro_raw_kwargs(arg): 322 def f(x: str): 323 return x 324 325 rtn = call_macro(f, ["*", '**{"x" :' + arg + "}"], {"x": 42, "y": 0}, None) 326 assert rtn == 42 327 328 329def test_enter_macro(): 330 obj = lambda: None 331 rtn = enter_macro(obj, "wakka", True, True) 332 assert obj is rtn 333 assert obj.macro_block == "wakka" 334 assert obj.macro_globals 335 assert obj.macro_locals 336