import itertools import typing as tp from unittest import mock import pytest import xonsh.parsers.completion_context as ctx from xonsh.parsers.completion_context import ( CommandArg, CommandContext, CompletionContextParser, PythonContext, ) from xonsh.pytest.tools import ON_WINDOWS DEBUG = False MISSING = object() X = "\x00" # cursor marker PARSER: tp.Optional[CompletionContextParser] = None @pytest.fixture(scope="module", autouse=True) def parser(): global PARSER PARSER = CompletionContextParser(debug=DEBUG) patcher = None if ON_WINDOWS: # on-windows has an option for interactive sessions. Overriding the lazyObject patcher = mock.patch.object( ctx, "LINE_CONT_REPLACEMENT_DIFF", ("\\\n", "", -2), ) patcher.start() yield PARSER = None if ON_WINDOWS and patcher: patcher.stop() def parse(command, inner_index): return PARSER.parse(command, inner_index) def assert_match( commandline, command_context=MISSING, python_context=MISSING, is_main_command=False ): if X in commandline: index = commandline.index(X) commandline = commandline.replace(X, "") else: index = len(commandline) context = parse(commandline, index) if context is None: raise SyntaxError( "Failed to parse the commandline - set DEBUG = True in this file to see the error" ) if is_main_command and python_context is MISSING: python_context = PythonContext(commandline, index) if command_context is not MISSING: assert context.command == command_context if python_context is not MISSING: assert context.python == python_context COMMAND_EXAMPLES = ( (f"comm{X}", CommandContext(args=(), arg_index=0, prefix="comm")), (f" comm{X}", CommandContext(args=(), arg_index=0, prefix="comm")), (f"comm{X}and", CommandContext(args=(), arg_index=0, prefix="comm", suffix="and")), (f"command {X}", CommandContext(args=(CommandArg("command"),), arg_index=1)), (f"{X} command", CommandContext(args=(CommandArg("command"),), arg_index=0)), (f" command {X}", CommandContext(args=(CommandArg("command"),), arg_index=1)), ( f"command --{X}", CommandContext(args=(CommandArg("command"),), arg_index=1, prefix="--"), ), ( f"command a {X}", CommandContext(args=(CommandArg("command"), CommandArg("a")), arg_index=2), ), ( f"command a b{X}", CommandContext( args=(CommandArg("command"), CommandArg("a")), arg_index=2, prefix="b" ), ), ( f"command a b{X}", CommandContext( args=(CommandArg("command"), CommandArg("a")), arg_index=2, prefix="b" ), ), ( f"command {X} a", CommandContext(args=(CommandArg("command"), CommandArg("a")), arg_index=1), ), ( f"command a {X} b", CommandContext( args=(CommandArg("command"), CommandArg("a"), CommandArg("b")), arg_index=2 ), ), ( f"command -{X} b", CommandContext( args=(CommandArg("command"), CommandArg("b")), arg_index=1, prefix="-" ), ), ( f"command a {X}b", CommandContext( args=(CommandArg("command"), CommandArg("a")), arg_index=2, suffix="b" ), ), ( f"command a{X}b", CommandContext( args=(CommandArg("command"),), arg_index=1, prefix="a", suffix="b" ), ), ( f"'comm and' a{X}b", CommandContext( args=(CommandArg("comm and", opening_quote="'", closing_quote="'"),), arg_index=1, prefix="a", suffix="b", ), ), ( f"command >/dev/nul{X}", CommandContext( args=(CommandArg("command"), CommandArg(">", is_io_redir=True)), arg_index=2, prefix="/dev/nul", ), ), ( f"command 2>/dev/nul{X}", CommandContext( args=(CommandArg("command"), CommandArg("2>", is_io_redir=True)), arg_index=2, prefix="/dev/nul", ), ), ( f"command >>/dev/nul{X}", CommandContext( args=(CommandArg("command"), CommandArg(">>", is_io_redir=True)), arg_index=2, prefix="/dev/nul", ), ), ( f"command