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