mirror of
https://github.com/xonsh/xonsh.git
synced 2025-03-04 08:24:40 +01:00
120 lines
3.8 KiB
Python
120 lines
3.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""Tests the xonfig command.
|
|
Actually, just a down payment on a full test.
|
|
Currently exercises only these options:
|
|
- xonfig info
|
|
- xonfig jupyter_kernel
|
|
|
|
"""
|
|
import os
|
|
import re
|
|
import sys
|
|
import json
|
|
import pytest # noqa F401
|
|
|
|
from xonsh.tools import ON_WINDOWS
|
|
from xonsh.xonfig import XONFIG_MAIN_ACTIONS, xonfig_main
|
|
|
|
|
|
def test_xonfg_help(capsys, xonsh_builtins):
|
|
"""verify can invoke it, and usage knows about all the options"""
|
|
with pytest.raises(SystemExit):
|
|
xonfig_main(["-h"])
|
|
capout = capsys.readouterr().out
|
|
pat = re.compile(r"^usage:\s*xonfig[^\n]*{([\w,-]+)}", re.MULTILINE)
|
|
m = pat.match(capout)
|
|
assert m[1]
|
|
verbs = set(v.strip().lower() for v in m[1].split(","))
|
|
exp = set(v.lower() for v in XONFIG_MAIN_ACTIONS)
|
|
assert verbs == exp
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"args", [([]), (["info",]),], # NOQA E231
|
|
)
|
|
def test_xonfig_info(args, xonsh_builtins):
|
|
"""info works, and reports no jupyter if none in environment"""
|
|
capout = xonfig_main(args)
|
|
assert capout.startswith("+---")
|
|
assert capout.endswith("---+\n")
|
|
pat = re.compile(r".*on jupyter\s+\|\s+false", re.MULTILINE | re.IGNORECASE)
|
|
m = pat.search(capout)
|
|
assert m
|
|
|
|
|
|
def strip_sep(path: str) -> str:
|
|
"""remove all path separators from argument"""
|
|
retval = path.replace(os.sep, "")
|
|
if ON_WINDOWS:
|
|
retval = retval.replace(os.altsep, "")
|
|
return retval
|
|
|
|
|
|
@pytest.fixture
|
|
def fake_lib(monkeypatch):
|
|
"""insulate sys.modules from hacking test modules may do with it.
|
|
Apparently, monkeypath.syspath_prepend() doesn't flush
|
|
imported modules, so they're still visible in other test cases.
|
|
"""
|
|
|
|
# get absolute path to fake_lib, assuming this test file itself is in same folder.
|
|
fake_lib_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "fake_lib"))
|
|
monkeypatch.syspath_prepend(fake_lib_path)
|
|
yield
|
|
|
|
# monkeypatch will have restored sys.path, but it's up to us to purge the imported modules
|
|
fake_packages = tuple(f.name for f in os.scandir(fake_lib_path) if os.path.isdir(f))
|
|
modules_to_delete = []
|
|
|
|
for (m, mod) in sys.modules.items():
|
|
if m.startswith(fake_packages):
|
|
if mod.__file__.startswith(fake_lib_path):
|
|
modules_to_delete.append(m) # can't modify collection while iterating
|
|
|
|
for m in modules_to_delete:
|
|
del sys.modules[m]
|
|
|
|
|
|
def test_xonfig_kernel_with_jupyter(monkeypatch, capsys, fake_lib, xonsh_builtins):
|
|
cap_args = None
|
|
cap_spec = None
|
|
|
|
import jupyter_client.kernelspec # from fake_lib, hopefully.
|
|
|
|
def mock_install_kernel_spec(*args, **kwargs): # arg[0] is self
|
|
nonlocal cap_args
|
|
nonlocal cap_spec
|
|
cap_args = dict(args=args, kw=kwargs)
|
|
spec_file = os.path.join(args[1], "kernel.json")
|
|
cap_spec = json.load(open(spec_file, "r"))
|
|
|
|
def mock_get_kernel_spec(*args, **kwargs):
|
|
raise jupyter_client.kernelspec.NoSuchKernel
|
|
|
|
monkeypatch.setattr(
|
|
jupyter_client.kernelspec.KernelSpecManager,
|
|
"install_kernel_spec",
|
|
value=mock_install_kernel_spec,
|
|
raising=False,
|
|
)
|
|
monkeypatch.setattr(
|
|
jupyter_client.kernelspec.KernelSpecManager,
|
|
"get_kernel_spec",
|
|
value=mock_get_kernel_spec,
|
|
raising=False,
|
|
)
|
|
|
|
rc = xonfig_main(["jupyter-kernel"])
|
|
assert rc == 0
|
|
capout = capsys.readouterr().out
|
|
assert "Jupyter" in capout
|
|
assert "xonsh" == cap_args["args"][2]
|
|
assert cap_spec
|
|
assert cap_spec["language"] == "xonsh"
|
|
assert strip_sep(cap_spec["argv"][0]) == strip_sep(sys.executable)
|
|
assert cap_spec["argv"][2] == "xonsh.jupyter_kernel"
|
|
|
|
|
|
def test_xonfig_kernel_no_jupyter(capsys, xonsh_builtins):
|
|
with pytest.raises(ImportError):
|
|
rc = xonfig_main(["jupyter-kernel"]) # noqa F841
|