1# -*- coding: utf-8 -*- 2"""Tests the xonsh main function.""" 3from __future__ import unicode_literals, print_function 4from contextlib import contextmanager 5 6import builtins 7import os.path 8import sys 9 10import xonsh.main 11from xonsh.main import XonshMode 12from xonsh.environ import Env 13import pytest 14from tools import TEST_DIR 15 16 17def Shell(*args, **kwargs): 18 pass 19 20 21@pytest.fixture 22def shell(xonsh_builtins, xonsh_execer, monkeypatch): 23 """Xonsh Shell Mock""" 24 Shell.shell_type_aliases = {"rl": "readline"} 25 monkeypatch.setattr(xonsh.main, "Shell", Shell) 26 27 28def test_premain_no_arg(shell, monkeypatch): 29 monkeypatch.setattr(sys.stdin, "isatty", lambda: True) 30 xonsh.main.premain([]) 31 assert builtins.__xonsh_env__.get("XONSH_LOGIN") 32 33 34def test_premain_interactive(shell): 35 xonsh.main.premain(["-i"]) 36 assert builtins.__xonsh_env__.get("XONSH_INTERACTIVE") 37 38 39def test_premain_login_command(shell): 40 xonsh.main.premain(["-l", "-c", 'echo "hi"']) 41 assert builtins.__xonsh_env__.get("XONSH_LOGIN") 42 43 44def test_premain_login(shell): 45 xonsh.main.premain(["-l"]) 46 assert builtins.__xonsh_env__.get("XONSH_LOGIN") 47 48 49def test_premain_D(shell): 50 xonsh.main.premain(["-DTEST1=1616", "-DTEST2=LOL"]) 51 assert builtins.__xonsh_env__.get("TEST1") == "1616" 52 assert builtins.__xonsh_env__.get("TEST2") == "LOL" 53 54 55def test_premain_custom_rc(shell, tmpdir, monkeypatch): 56 monkeypatch.setattr(sys.stdin, "isatty", lambda: True) 57 builtins.__xonsh_env__ = Env(XONSH_CACHE_SCRIPTS=False) 58 f = tmpdir.join("wakkawakka") 59 f.write("print('hi')") 60 args = xonsh.main.premain(["--rc", f.strpath]) 61 assert args.mode == XonshMode.interactive 62 assert f.strpath in builtins.__xonsh_env__.get("XONSHRC") 63 64 65def test_no_rc_with_script(shell, tmpdir): 66 args = xonsh.main.premain(["tests/sample.xsh"]) 67 assert not (args.mode == XonshMode.interactive) 68 69 70def test_force_interactive_rc_with_script(shell, tmpdir): 71 args = xonsh.main.premain(["-i", "tests/sample.xsh"]) 72 assert builtins.__xonsh_env__.get("XONSH_INTERACTIVE") 73 74 75def test_force_interactive_custom_rc_with_script(shell, tmpdir): 76 """Calling a custom RC file on a script-call with the interactive flag 77 should run interactively 78 """ 79 builtins.__xonsh_env__ = Env(XONSH_CACHE_SCRIPTS=False) 80 f = tmpdir.join("wakkawakka") 81 f.write("print('hi')") 82 args = xonsh.main.premain(["-i", "--rc", f.strpath, "tests/sample.xsh"]) 83 assert args.mode == XonshMode.interactive 84 assert f.strpath in builtins.__xonsh_env__.get("XONSHRC") 85 86 87def test_custom_rc_with_script(shell, tmpdir): 88 """Calling a custom RC file on a script-call without the interactive flag 89 should not run interactively 90 """ 91 f = tmpdir.join("wakkawakka") 92 f.write("print('hi')") 93 args = xonsh.main.premain(["--rc", f.strpath, "tests/sample.xsh"]) 94 assert not (args.mode == XonshMode.interactive) 95 96 97def test_premain_no_rc(shell, tmpdir): 98 xonsh.main.premain(["--no-rc"]) 99 assert not builtins.__xonsh_env__.get("XONSHRC") 100 101 102@pytest.mark.parametrize( 103 "arg", ["", "-i", "-vERSION", "-hAALP", "TTTT", "-TT", "--TTT"] 104) 105def test_premain_with_file_argument(arg, shell): 106 xonsh.main.premain(["tests/sample.xsh", arg]) 107 assert not (builtins.__xonsh_env__.get("XONSH_INTERACTIVE")) 108 109 110def test_premain_interactive__with_file_argument(shell): 111 xonsh.main.premain(["-i", "tests/sample.xsh"]) 112 assert builtins.__xonsh_env__.get("XONSH_INTERACTIVE") 113 114 115@pytest.mark.parametrize("case", ["----", "--hep", "-TT", "--TTTT"]) 116def test_premain_invalid_arguments(shell, case, capsys): 117 with pytest.raises(SystemExit): 118 xonsh.main.premain([case]) 119 assert "unrecognized argument" in capsys.readouterr()[1] 120 121 122def test_xonsh_failback(shell, monkeypatch): 123 failback_checker = [] 124 monkeypatch.setattr(sys, "stderr", open(os.devnull, "w")) 125 126 def mocked_main(*args): 127 raise Exception("A fake failure") 128 129 monkeypatch.setattr(xonsh.main, "main_xonsh", mocked_main) 130 131 def mocked_execlp(f, *args): 132 failback_checker.append(f) 133 failback_checker.append(args[0]) 134 135 monkeypatch.setattr(os, "execlp", mocked_execlp) 136 monkeypatch.setattr(os.path, "exists", lambda x: True) 137 monkeypatch.setattr(sys, "argv", ["xonsh", "-i"]) 138 139 @contextmanager 140 def mocked_open(*args): 141 yield ["/usr/bin/xonsh", "/usr/bin/screen", "bash", "/bin/xshell"] 142 143 monkeypatch.setattr(builtins, "open", mocked_open) 144 145 xonsh.main.main() 146 assert failback_checker == ["/bin/xshell", "/bin/xshell"] 147 148 149def test_xonsh_failback_single(shell, monkeypatch): 150 class FakeFailureError(Exception): 151 pass 152 153 def mocked_main(*args): 154 raise FakeFailureError() 155 156 monkeypatch.setattr(xonsh.main, "main_xonsh", mocked_main) 157 monkeypatch.setattr(sys, "argv", ["xonsh", "-c", "echo", "foo"]) 158 monkeypatch.setattr(sys, "stderr", open(os.devnull, "w")) 159 160 with pytest.raises(FakeFailureError): 161 xonsh.main.main() 162 163 164def test_xonsh_failback_script_from_file(shell, monkeypatch): 165 checker = [] 166 167 def mocked_execlp(f, *args): 168 checker.append(f) 169 170 monkeypatch.setattr(os, "execlp", mocked_execlp) 171 172 script = os.path.join(TEST_DIR, "scripts", "raise.xsh") 173 monkeypatch.setattr(sys, "argv", ["xonsh", script]) 174 monkeypatch.setattr(sys, "stderr", open(os.devnull, "w")) 175 with pytest.raises(Exception): 176 xonsh.main.main() 177 assert len(checker) == 0 178