2016-06-23 12:43:44 +02:00
|
|
|
"""Tests xonsh tools."""
|
2024-01-30 12:23:50 +01:00
|
|
|
|
2016-08-02 15:59:11 +03:00
|
|
|
import datetime as dt
|
2015-05-14 19:59:16 -05:00
|
|
|
import os
|
2016-06-13 04:23:05 +03:00
|
|
|
import pathlib
|
2024-05-06 16:18:43 +02:00
|
|
|
import re
|
|
|
|
import subprocess
|
2017-06-09 21:50:38 -04:00
|
|
|
import warnings
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-06-23 12:16:20 +03:00
|
|
|
import pytest
|
|
|
|
|
2017-06-10 09:57:49 -04:00
|
|
|
from xonsh import __version__
|
2024-06-29 10:28:02 +02:00
|
|
|
from xonsh.parsers.lexer import Lexer
|
2023-07-04 22:18:37 +05:30
|
|
|
from xonsh.platform import HAS_PYGMENTS, ON_WINDOWS, PYTHON_VERSION_INFO
|
2022-03-24 00:46:50 +05:30
|
|
|
from xonsh.pytest.tools import skip_if_on_windows
|
2016-05-22 22:33:43 +02:00
|
|
|
from xonsh.tools import (
|
2018-08-30 09:18:49 -05:00
|
|
|
EnvPath,
|
2022-01-31 21:26:34 +05:30
|
|
|
all_permutations,
|
2018-08-30 09:18:49 -05:00
|
|
|
always_false,
|
|
|
|
always_true,
|
|
|
|
argvquote,
|
2022-01-31 21:26:34 +05:30
|
|
|
balanced_parens,
|
2018-08-30 09:18:49 -05:00
|
|
|
bool_or_int_to_str,
|
2020-08-20 20:11:37 -05:00
|
|
|
bool_or_none_to_str,
|
2018-08-30 09:18:49 -05:00
|
|
|
bool_to_str,
|
|
|
|
check_for_partial_string,
|
2022-01-31 21:26:34 +05:30
|
|
|
check_quotes,
|
|
|
|
deprecated,
|
2018-08-30 09:18:49 -05:00
|
|
|
dynamic_cwd_tuple_to_str,
|
2022-01-31 21:26:34 +05:30
|
|
|
ends_with_colon_token,
|
2018-08-30 09:18:49 -05:00
|
|
|
ensure_slice,
|
|
|
|
ensure_string,
|
2022-01-31 21:26:34 +05:30
|
|
|
ensure_timestamp,
|
2018-08-30 09:18:49 -05:00
|
|
|
env_path_to_str,
|
|
|
|
escape_windows_cmd_string,
|
2022-01-31 21:26:34 +05:30
|
|
|
expand_case_matching,
|
2018-08-30 09:18:49 -05:00
|
|
|
expand_path,
|
2022-01-31 21:26:34 +05:30
|
|
|
expandvars,
|
2018-08-30 09:18:49 -05:00
|
|
|
find_next_break,
|
2022-01-31 21:26:34 +05:30
|
|
|
get_line_continuation,
|
|
|
|
get_logical_line,
|
|
|
|
get_portions,
|
|
|
|
iglobpath,
|
|
|
|
is_balanced,
|
2018-08-30 09:18:49 -05:00
|
|
|
is_bool,
|
|
|
|
is_bool_or_int,
|
2020-08-20 20:11:37 -05:00
|
|
|
is_bool_or_none,
|
2018-08-30 09:18:49 -05:00
|
|
|
is_callable,
|
2022-01-31 21:26:34 +05:30
|
|
|
is_completion_mode,
|
|
|
|
is_completions_display_value,
|
2018-08-30 09:18:49 -05:00
|
|
|
is_dynamic_cwd_width,
|
|
|
|
is_env_path,
|
|
|
|
is_float,
|
|
|
|
is_int,
|
2022-01-31 21:26:34 +05:30
|
|
|
is_int_as_str,
|
2018-08-30 09:18:49 -05:00
|
|
|
is_logfile_opt,
|
2022-01-31 21:26:34 +05:30
|
|
|
is_nonstring_seq_of_strings,
|
|
|
|
is_path,
|
2022-10-04 11:46:42 -07:00
|
|
|
is_regex,
|
2022-01-31 21:26:34 +05:30
|
|
|
is_slice_as_str,
|
|
|
|
is_string,
|
2018-08-30 09:18:49 -05:00
|
|
|
is_string_or_callable,
|
2022-01-31 21:26:34 +05:30
|
|
|
is_string_seq,
|
2022-10-25 01:46:52 +11:00
|
|
|
is_tok_color_dict,
|
2022-01-31 21:26:34 +05:30
|
|
|
is_writable_file,
|
2018-08-30 09:18:49 -05:00
|
|
|
logfile_opt_to_str,
|
2022-01-31 21:26:34 +05:30
|
|
|
path_to_str,
|
|
|
|
pathsep_to_seq,
|
|
|
|
pathsep_to_set,
|
|
|
|
pathsep_to_upper_seq,
|
2024-05-06 16:18:43 +02:00
|
|
|
print_exception,
|
2022-01-31 21:26:34 +05:30
|
|
|
register_custom_style,
|
|
|
|
replace_logical_line,
|
|
|
|
seq_to_pathsep,
|
|
|
|
seq_to_upper_pathsep,
|
|
|
|
set_to_pathsep,
|
|
|
|
simple_random_choice,
|
2018-08-30 09:18:49 -05:00
|
|
|
str_to_env_path,
|
2022-01-31 21:26:34 +05:30
|
|
|
str_to_path,
|
|
|
|
subexpr_before_unbalanced,
|
2018-08-30 09:18:49 -05:00
|
|
|
subexpr_from_unbalanced,
|
|
|
|
subproc_toks,
|
2022-01-31 21:26:34 +05:30
|
|
|
swap_values,
|
2018-08-30 09:18:49 -05:00
|
|
|
to_bool,
|
|
|
|
to_bool_or_int,
|
2020-08-20 20:11:37 -05:00
|
|
|
to_bool_or_none,
|
2020-11-05 13:12:15 -08:00
|
|
|
to_completion_mode,
|
|
|
|
to_completions_display_value,
|
2022-01-31 21:26:34 +05:30
|
|
|
to_dynamic_cwd_tuple,
|
|
|
|
to_int_or_none,
|
|
|
|
to_logfile_opt,
|
2018-08-30 09:18:49 -05:00
|
|
|
)
|
2015-03-13 21:43:18 -05:00
|
|
|
|
|
|
|
LEXER = Lexer()
|
|
|
|
LEXER.build()
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
INDENT = " "
|
|
|
|
|
|
|
|
TOOLS_ENV = {"EXPAND_ENV_VARS": True, "XONSH_ENCODING_ERRORS": "strict"}
|
|
|
|
ENCODE_ENV_ONLY = {"XONSH_ENCODING_ERRORS": "strict"}
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2020-10-09 19:12:48 +03:00
|
|
|
def test_random_choice():
|
|
|
|
lst = [1, 2, 3]
|
2020-10-09 22:08:10 +03:00
|
|
|
r = simple_random_choice(lst)
|
2020-10-09 19:12:48 +03:00
|
|
|
assert r in lst
|
|
|
|
|
2020-10-09 22:08:10 +03:00
|
|
|
with pytest.raises(ValueError):
|
|
|
|
simple_random_choice(range(1010101))
|
|
|
|
|
2020-10-09 19:12:48 +03:00
|
|
|
|
2015-03-13 21:43:18 -05:00
|
|
|
def test_subproc_toks_x():
|
2018-08-30 09:18:49 -05:00
|
|
|
exp = "![x]"
|
|
|
|
obs = subproc_toks("x", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-13 21:43:18 -05:00
|
|
|
def test_subproc_toks_ls_l():
|
2018-08-30 09:18:49 -05:00
|
|
|
exp = "![ls -l]"
|
|
|
|
obs = subproc_toks("ls -l", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-13 21:43:18 -05:00
|
|
|
def test_subproc_toks_git():
|
|
|
|
s = 'git commit -am "hello doc"'
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2015-03-13 21:43:18 -05:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-13 21:43:18 -05:00
|
|
|
def test_subproc_toks_git_semi():
|
|
|
|
s = 'git commit -am "hello doc"'
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}];"
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subproc_toks(s + ";", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-13 21:43:18 -05:00
|
|
|
def test_subproc_toks_git_nl():
|
|
|
|
s = 'git commit -am "hello doc"'
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]\n"
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subproc_toks(s + "\n", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-08-27 19:35:48 -04:00
|
|
|
def test_bash_macro():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "bash -c ! export var=42; echo $var"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]\n"
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subproc_toks(s + "\n", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-08-27 19:35:48 -04:00
|
|
|
|
|
|
|
|
|
|
|
def test_python_macro():
|
|
|
|
s = 'python -c ! import os; print(os.path.abspath("/"))'
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]\n"
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subproc_toks(s + "\n", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-13 21:43:18 -05:00
|
|
|
def test_subproc_toks_indent_ls():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "ls -l"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = INDENT + f"![{s}]"
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subproc_toks(INDENT + s, mincol=len(INDENT), lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-15 01:29:25 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-15 01:29:25 -05:00
|
|
|
def test_subproc_toks_indent_ls_nl():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "ls -l"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = INDENT + f"![{s}]\n"
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subproc_toks(
|
|
|
|
INDENT + s + "\n", mincol=len(INDENT), lexer=LEXER, returnline=True
|
|
|
|
)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-30 19:27:04 -05:00
|
|
|
def test_subproc_toks_indent_ls_no_min():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "ls -l"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = INDENT + f"![{s}]"
|
2015-03-30 19:27:04 -05:00
|
|
|
obs = subproc_toks(INDENT + s, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-30 19:27:04 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-30 19:27:04 -05:00
|
|
|
def test_subproc_toks_indent_ls_no_min_nl():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "ls -l"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = INDENT + f"![{s}]\n"
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subproc_toks(INDENT + s + "\n", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-30 19:27:04 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-31 11:02:36 -05:00
|
|
|
def test_subproc_toks_indent_ls_no_min_semi():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "ls"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = INDENT + f"![{s}];"
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subproc_toks(INDENT + s + ";", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-31 11:02:36 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-31 19:40:35 -05:00
|
|
|
def test_subproc_toks_indent_ls_no_min_semi_nl():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "ls"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = INDENT + f"![{s}];\n"
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subproc_toks(INDENT + s + ";\n", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-31 19:40:35 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-13 21:43:18 -05:00
|
|
|
def test_subproc_toks_ls_comment():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "ls -l"
|
|
|
|
com = " # lets list"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]{com}"
|
2015-03-13 21:43:18 -05:00
|
|
|
obs = subproc_toks(s + com, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-13 21:43:18 -05:00
|
|
|
def test_subproc_toks_ls_42_comment():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "ls 42"
|
|
|
|
com = " # lets list"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]{com}"
|
2015-03-13 21:43:18 -05:00
|
|
|
obs = subproc_toks(s + com, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-13 21:43:18 -05:00
|
|
|
def test_subproc_toks_ls_str_comment():
|
|
|
|
s = 'ls "wakka"'
|
2018-08-30 09:18:49 -05:00
|
|
|
com = " # lets list"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]{com}"
|
2015-03-13 21:43:18 -05:00
|
|
|
obs = subproc_toks(s + com, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-02-21 14:37:03 -05:00
|
|
|
def test_subproc_toks_indent_ls_comment():
|
2018-08-30 09:18:49 -05:00
|
|
|
ind = " "
|
|
|
|
s = "ls -l"
|
|
|
|
com = " # lets list"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"{ind}![{s}]{com}"
|
2016-02-21 14:37:03 -05:00
|
|
|
obs = subproc_toks(ind + s + com, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-02-21 14:37:03 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-02-21 14:37:03 -05:00
|
|
|
def test_subproc_toks_indent_ls_str():
|
2018-08-30 09:18:49 -05:00
|
|
|
ind = " "
|
2016-02-21 14:37:03 -05:00
|
|
|
s = 'ls "wakka"'
|
2018-08-30 09:18:49 -05:00
|
|
|
com = " # lets list"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"{ind}![{s}]{com}"
|
2016-02-21 14:37:03 -05:00
|
|
|
obs = subproc_toks(ind + s + com, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-02-21 14:37:03 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-14 01:00:46 -05:00
|
|
|
def test_subproc_toks_ls_l_semi_ls_first():
|
2018-08-30 09:18:49 -05:00
|
|
|
lsdl = "ls -l"
|
|
|
|
ls = "ls"
|
2021-12-07 01:12:26 +05:30
|
|
|
s = f"{lsdl}; {ls}"
|
|
|
|
exp = f"![{lsdl}]; {ls}"
|
2015-03-14 00:40:32 -05:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, maxcol=6, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2015-03-13 21:43:18 -05:00
|
|
|
def test_subproc_toks_ls_l_semi_ls_second():
|
2018-08-30 09:18:49 -05:00
|
|
|
lsdl = "ls -l"
|
|
|
|
ls = "ls"
|
2021-12-07 01:12:26 +05:30
|
|
|
s = f"{lsdl}; {ls}"
|
|
|
|
exp = f"{lsdl}; ![{ls}]"
|
2015-03-13 21:43:18 -05:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, mincol=7, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-13 21:43:18 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-05-11 23:24:58 -04:00
|
|
|
def test_subproc_toks_hello_mom_first():
|
2015-03-14 01:00:46 -05:00
|
|
|
fst = "echo 'hello'"
|
|
|
|
sec = "echo 'mom'"
|
2021-12-07 01:12:26 +05:30
|
|
|
s = f"{fst}; {sec}"
|
|
|
|
exp = f"![{fst}]; {sec}"
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, maxcol=len(fst) + 1, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-14 01:00:46 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-05-11 23:24:58 -04:00
|
|
|
def test_subproc_toks_hello_mom_second():
|
2015-03-14 01:00:46 -05:00
|
|
|
fst = "echo 'hello'"
|
|
|
|
sec = "echo 'mom'"
|
2021-12-07 01:12:26 +05:30
|
|
|
s = f"{fst}; {sec}"
|
|
|
|
exp = f"{fst}; ![{sec}]"
|
2015-03-14 01:00:46 -05:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, mincol=len(fst), returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-14 01:00:46 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2017-02-25 12:15:56 -05:00
|
|
|
def test_subproc_toks_hello_bad_leading_single_quotes():
|
|
|
|
obs = subproc_toks('echo "hello', lexer=LEXER, returnline=True)
|
2017-02-24 23:00:06 -05:00
|
|
|
assert obs is None
|
|
|
|
|
|
|
|
|
|
|
|
def test_subproc_toks_hello_bad_trailing_single_quotes():
|
|
|
|
obs = subproc_toks('echo hello"', lexer=LEXER, returnline=True)
|
|
|
|
assert obs is None
|
|
|
|
|
|
|
|
|
|
|
|
def test_subproc_toks_hello_bad_leading_triple_quotes():
|
|
|
|
obs = subproc_toks('echo """hello', lexer=LEXER, returnline=True)
|
|
|
|
assert obs is None
|
|
|
|
|
|
|
|
|
|
|
|
def test_subproc_toks_hello_bad_trailing_triple_quotes():
|
|
|
|
obs = subproc_toks('echo hello"""', lexer=LEXER, returnline=True)
|
|
|
|
assert obs is None
|
2017-02-24 22:39:36 -05:00
|
|
|
|
|
|
|
|
2017-02-24 23:18:31 -05:00
|
|
|
def test_subproc_toks_hello_mom_triple_quotes_nl():
|
|
|
|
s = 'echo """hello\nmom"""'
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2017-02-24 23:18:31 -05:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2015-03-18 20:14:53 -05:00
|
|
|
def test_subproc_toks_comment():
|
|
|
|
exp = None
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subproc_toks("# I am a comment", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2015-03-18 20:14:53 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-04-10 23:38:12 -04:00
|
|
|
def test_subproc_toks_not():
|
2018-08-30 09:18:49 -05:00
|
|
|
exp = "not ![echo mom]"
|
|
|
|
obs = subproc_toks("not echo mom", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-04-10 23:38:12 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-04-10 23:38:12 -04:00
|
|
|
def test_subproc_toks_paren():
|
2018-08-30 09:18:49 -05:00
|
|
|
exp = "(![echo mom])"
|
|
|
|
obs = subproc_toks("(echo mom)", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-04-10 23:38:12 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-04-10 23:38:12 -04:00
|
|
|
def test_subproc_toks_paren_ws():
|
2018-08-30 09:18:49 -05:00
|
|
|
exp = "(![echo mom]) "
|
|
|
|
obs = subproc_toks("(echo mom) ", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-04-10 23:38:12 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-04-10 23:38:12 -04:00
|
|
|
def test_subproc_toks_not_paren():
|
2018-08-30 09:18:49 -05:00
|
|
|
exp = "not (![echo mom])"
|
|
|
|
obs = subproc_toks("not (echo mom)", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-04-10 23:38:12 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-04-10 23:38:12 -04:00
|
|
|
def test_subproc_toks_and_paren():
|
2018-08-30 09:18:49 -05:00
|
|
|
exp = "True and (![echo mom])"
|
|
|
|
obs = subproc_toks("True and (echo mom)", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-04-10 23:38:12 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-04-10 23:38:12 -04:00
|
|
|
def test_subproc_toks_paren_and_paren():
|
2018-08-30 09:18:49 -05:00
|
|
|
exp = "(![echo a]) and (echo b)"
|
|
|
|
obs = subproc_toks("(echo a) and (echo b)", maxcol=9, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-04-10 23:38:12 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-04-23 16:08:17 -03:00
|
|
|
def test_subproc_toks_semicolon_only():
|
|
|
|
exp = None
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subproc_toks(";", lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-04-23 16:08:17 -03:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-05-11 23:24:58 -04:00
|
|
|
def test_subproc_toks_pyeval():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "echo @(1+1)"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2016-05-11 23:24:58 -04:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-05-11 23:24:58 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2018-07-19 21:01:11 -04:00
|
|
|
def test_subproc_toks_pyeval_multiline_string():
|
|
|
|
s = 'echo @("""hello\nmom""")'
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2018-07-19 21:01:11 -04:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2016-05-11 23:24:58 -04:00
|
|
|
def test_subproc_toks_twopyeval():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "echo @(1+1) @(40 + 2)"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2016-05-11 23:24:58 -04:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-05-11 23:24:58 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-05-11 23:24:58 -04:00
|
|
|
def test_subproc_toks_pyeval_parens():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "echo @(1+1)"
|
2021-12-07 01:12:26 +05:30
|
|
|
inp = f"({s})"
|
|
|
|
exp = f"(![{s}])"
|
2016-05-11 23:24:58 -04:00
|
|
|
obs = subproc_toks(inp, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-05-11 23:24:58 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-05-11 23:24:58 -04:00
|
|
|
def test_subproc_toks_twopyeval_parens():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "echo @(1+1) @(40+2)"
|
2021-12-07 01:12:26 +05:30
|
|
|
inp = f"({s})"
|
|
|
|
exp = f"(![{s}])"
|
2016-05-11 23:24:58 -04:00
|
|
|
obs = subproc_toks(inp, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-05-11 23:24:58 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-05-11 23:41:14 -04:00
|
|
|
def test_subproc_toks_pyeval_nested():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "echo @(min(1, 42))"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2016-05-11 23:41:14 -04:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-05-11 23:41:14 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2019-02-13 18:49:39 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"phrase",
|
|
|
|
[
|
|
|
|
"xandy",
|
|
|
|
"xory",
|
|
|
|
"xand",
|
|
|
|
"andy",
|
|
|
|
"xor",
|
|
|
|
"ory",
|
|
|
|
"x-and",
|
|
|
|
"x-or",
|
|
|
|
"and-y",
|
|
|
|
"or-y",
|
|
|
|
"x-and-y",
|
|
|
|
"x-or-y",
|
|
|
|
"in/and/path",
|
|
|
|
"in/or/path",
|
|
|
|
],
|
|
|
|
)
|
2018-11-07 17:32:53 -05:00
|
|
|
def test_subproc_toks_and_or(phrase):
|
|
|
|
s = "echo " + phrase
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2018-11-07 17:32:53 -05:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2016-05-11 23:41:14 -04:00
|
|
|
def test_subproc_toks_pyeval_nested_parens():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "echo @(min(1, 42))"
|
2021-12-07 01:12:26 +05:30
|
|
|
inp = f"({s})"
|
|
|
|
exp = f"(![{s}])"
|
2016-05-11 23:41:14 -04:00
|
|
|
obs = subproc_toks(inp, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-05-11 23:41:14 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-05-11 23:41:14 -04:00
|
|
|
def test_subproc_toks_capstdout():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "echo $(echo bat)"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2016-05-11 23:41:14 -04:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-05-11 23:41:14 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-05-11 23:41:14 -04:00
|
|
|
def test_subproc_toks_capproc():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "echo !(echo bat)"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2016-05-11 23:41:14 -04:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-05-11 23:41:14 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-05-19 18:52:50 -04:00
|
|
|
def test_subproc_toks_pyeval_redirect():
|
|
|
|
s = 'echo @("foo") > bar'
|
2021-12-07 01:12:26 +05:30
|
|
|
inp = f"{s}"
|
|
|
|
exp = f"![{s}]"
|
2016-05-19 18:52:50 -04:00
|
|
|
obs = subproc_toks(inp, lexer=LEXER, returnline=True)
|
2016-10-18 16:36:13 -04:00
|
|
|
assert exp == obs
|
2016-05-19 18:52:50 -04:00
|
|
|
|
|
|
|
|
2017-02-25 20:15:02 -05:00
|
|
|
def test_subproc_toks_greedy_parens():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "(sort)"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2017-02-25 20:15:02 -05:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True, greedy=True)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
|
|
|
def test_subproc_toks_greedy_parens_inp():
|
2018-08-30 09:18:49 -05:00
|
|
|
s = "(sort) < input.txt"
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2017-02-25 20:15:02 -05:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True, greedy=True)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
|
|
|
def test_subproc_toks_greedy_parens_statements():
|
|
|
|
s = '(echo "abc"; sleep 1; echo "def")'
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2017-02-25 20:15:02 -05:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True, greedy=True)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
|
|
|
def test_subproc_toks_greedy_parens_statements_with_grep():
|
|
|
|
s = '(echo "abc"; sleep 1; echo "def") | grep'
|
2021-12-07 01:12:26 +05:30
|
|
|
exp = f"![{s}]"
|
2017-02-25 20:15:02 -05:00
|
|
|
obs = subproc_toks(s, lexer=LEXER, returnline=True, greedy=True)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2017-02-15 00:58:38 -05:00
|
|
|
LOGICAL_LINE_CASES = [
|
2018-08-30 09:18:49 -05:00
|
|
|
("""x = 14 + 2""", 0, "x = 14 + 2", 1),
|
|
|
|
(
|
|
|
|
"""x = \\
|
2017-02-15 00:58:38 -05:00
|
|
|
14 \\
|
|
|
|
+ 2
|
2018-08-30 09:18:49 -05:00
|
|
|
""",
|
|
|
|
0,
|
|
|
|
"x = 14 + 2",
|
|
|
|
3,
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"""y = 16
|
2017-02-15 00:58:38 -05:00
|
|
|
14 \\
|
|
|
|
+ 2
|
2018-08-30 09:18:49 -05:00
|
|
|
""",
|
|
|
|
1,
|
|
|
|
"14 + 2",
|
|
|
|
2,
|
|
|
|
),
|
|
|
|
(
|
|
|
|
'''x = """wow
|
2017-02-24 23:55:12 -05:00
|
|
|
mom"""
|
2018-08-30 09:18:49 -05:00
|
|
|
''',
|
|
|
|
0,
|
|
|
|
'x = """wow\nmom"""',
|
|
|
|
2,
|
|
|
|
),
|
|
|
|
# test from start
|
|
|
|
(
|
|
|
|
"echo --option1 value1 \\\n"
|
|
|
|
" --option2 value2 \\\n"
|
|
|
|
" --optionZ valueZ",
|
|
|
|
0,
|
|
|
|
"echo --option1 value1 --option2 value2 --optionZ valueZ",
|
|
|
|
3,
|
|
|
|
),
|
|
|
|
# test from second line
|
|
|
|
(
|
|
|
|
"echo --option1 value1 \\\n"
|
|
|
|
" --option2 value2 \\\n"
|
|
|
|
" --optionZ valueZ",
|
|
|
|
1,
|
|
|
|
"echo --option1 value1 --option2 value2 --optionZ valueZ",
|
|
|
|
3,
|
|
|
|
),
|
|
|
|
('"""\n', 0, '"""', 1),
|
2017-02-15 00:58:38 -05:00
|
|
|
]
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
|
|
|
|
@pytest.mark.parametrize("src, idx, exp_line, exp_n", LOGICAL_LINE_CASES)
|
2022-01-08 04:03:22 +05:30
|
|
|
def test_get_logical_line(src, idx, exp_line, exp_n, xession):
|
2017-02-15 00:58:38 -05:00
|
|
|
lines = src.splitlines()
|
2017-03-02 00:33:58 -05:00
|
|
|
line, n, start = get_logical_line(lines, idx)
|
2017-02-15 00:58:38 -05:00
|
|
|
assert exp_line == line
|
|
|
|
assert exp_n == n
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("src, idx, exp_line, exp_n", LOGICAL_LINE_CASES)
|
2022-01-08 04:03:22 +05:30
|
|
|
def test_replace_logical_line(src, idx, exp_line, exp_n, xession):
|
2017-02-15 00:58:38 -05:00
|
|
|
lines = src.splitlines()
|
|
|
|
logical = exp_line
|
2018-08-30 09:18:49 -05:00
|
|
|
while idx > 0 and lines[idx - 1].endswith("\\"):
|
2017-03-02 00:33:58 -05:00
|
|
|
idx -= 1
|
2017-02-15 00:58:38 -05:00
|
|
|
replace_logical_line(lines, logical, idx, exp_n)
|
2018-08-30 09:18:49 -05:00
|
|
|
exp = src.replace("\\\n", "").strip()
|
2018-12-06 13:35:43 -05:00
|
|
|
lc = get_line_continuation() + "\n"
|
|
|
|
obs = "\n".join(lines).replace(lc, "").strip()
|
2018-08-30 09:18:49 -05:00
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("f(1,10),x.y", True),
|
|
|
|
('"x"', True),
|
|
|
|
("'y'", True),
|
|
|
|
('b"x"', True),
|
|
|
|
("r'y'", True),
|
|
|
|
("f'z'", True),
|
|
|
|
('"""hello\nmom"""', True),
|
|
|
|
],
|
|
|
|
)
|
2017-02-24 22:39:36 -05:00
|
|
|
def test_check_quotes(inp, exp):
|
|
|
|
obs = check_quotes(inp)
|
|
|
|
assert exp is obs
|
|
|
|
|
2017-02-24 23:00:06 -05:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("inp", ["f(1,10),x.y"])
|
2017-02-04 17:04:12 -05:00
|
|
|
def test_is_balanced_parens(inp):
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = is_balanced(inp, "(", ")")
|
2017-02-04 17:04:12 -05:00
|
|
|
assert obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("inp", ["f(x.", "f(1,x." "f((1,10),x.y"])
|
2017-02-04 17:04:12 -05:00
|
|
|
def test_is_not_balanced_parens(inp):
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = is_balanced(inp, "(", ")")
|
2017-02-04 17:04:12 -05:00
|
|
|
assert not obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp", [("f(x.", "x."), ("f(1,x.", "x."), ("f((1,10),x.y", "x.y")]
|
|
|
|
)
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_subexpr_from_unbalanced_parens(inp, exp):
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subexpr_from_unbalanced(inp, "(", ")")
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("f(x.", "f"),
|
|
|
|
("f(1,x.", "f"),
|
|
|
|
("f((1,10),x.y", "f"),
|
|
|
|
("wakka().f((1,10),x.y", ".f"),
|
|
|
|
("wakka(f((1,10),x.y", "f"),
|
|
|
|
("wakka(jawakka().f((1,10),x.y", ".f"),
|
|
|
|
("wakka(jawakka().f((1,10),x.y)", "wakka"),
|
|
|
|
],
|
|
|
|
)
|
2017-02-04 17:35:32 -05:00
|
|
|
def test_subexpr_before_unbalanced_parens(inp, exp):
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = subexpr_before_unbalanced(inp, "(", ")")
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"line, exp",
|
|
|
|
[
|
|
|
|
("", True),
|
|
|
|
("wakka jawaka", True),
|
|
|
|
("rm *; echo hello world", True),
|
|
|
|
("()", True),
|
|
|
|
("f()", True),
|
|
|
|
("echo * yo ; echo eggs", True),
|
|
|
|
("(", False),
|
|
|
|
(")", False),
|
|
|
|
("(cmd;", False),
|
|
|
|
("cmd;)", False),
|
|
|
|
],
|
|
|
|
)
|
2017-11-08 20:54:18 -05:00
|
|
|
def test_balanced_parens(line, exp):
|
|
|
|
obs = balanced_parens(line, lexer=LEXER)
|
|
|
|
if exp:
|
|
|
|
assert obs
|
|
|
|
else:
|
|
|
|
assert not obs
|
|
|
|
|
|
|
|
|
2021-06-20 05:50:03 -04:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"line, exp",
|
|
|
|
[
|
|
|
|
("if 1:", True),
|
|
|
|
("elif 2: #comment", True),
|
|
|
|
("elif 3: #colon comment:", True),
|
|
|
|
("else: ", True),
|
|
|
|
("for s in '#not-a-comment':", True),
|
|
|
|
("", False),
|
|
|
|
("#comment", False),
|
|
|
|
("#colon comment:", False),
|
|
|
|
("print('hello')", False),
|
|
|
|
("print('hello') #colon comment:", False),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_ends_with_colon_token(line, exp):
|
|
|
|
obs = ends_with_colon_token(line, lexer=LEXER)
|
|
|
|
if exp:
|
|
|
|
assert obs
|
|
|
|
else:
|
|
|
|
assert not obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"line, mincol, exp",
|
|
|
|
[
|
|
|
|
("ls && echo a", 0, 4),
|
|
|
|
("ls && echo a", 6, None),
|
|
|
|
("ls && echo a || echo b", 6, 14),
|
|
|
|
("(ls) && echo a", 1, 4),
|
|
|
|
("not ls && echo a", 0, 8),
|
|
|
|
("not (ls) && echo a", 0, 8),
|
|
|
|
("bash -c ! export var=42; echo $var", 0, 35),
|
|
|
|
('python -c ! import os; print(os.path.abspath("/"))', 0, 51),
|
|
|
|
("echo * yo ; echo eggs", 0, 11),
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_find_next_break(line, mincol, exp):
|
|
|
|
obs = find_next_break(line, mincol=mincol, lexer=LEXER)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(42, True),
|
|
|
|
(42.0, False),
|
|
|
|
("42", False),
|
|
|
|
("42.0", False),
|
|
|
|
([42], False),
|
|
|
|
([], False),
|
|
|
|
(None, False),
|
|
|
|
("", False),
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_is_int(inp, exp):
|
|
|
|
obs = is_int(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(42.0, True),
|
|
|
|
(42.000101010010101010101001010101010001011100001101101011100, True),
|
|
|
|
(42, False),
|
|
|
|
("42", False),
|
|
|
|
("42.0", False),
|
|
|
|
([42], False),
|
|
|
|
([], False),
|
|
|
|
(None, False),
|
|
|
|
("", False),
|
|
|
|
(False, False),
|
|
|
|
(True, False),
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_is_float(inp, exp):
|
|
|
|
obs = is_float(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
|
|
|
def test_is_string_true():
|
2018-08-30 09:18:49 -05:00
|
|
|
assert is_string("42.0")
|
|
|
|
|
2016-06-24 21:21:50 +03:00
|
|
|
|
|
|
|
def test_is_string_false():
|
2016-06-22 18:06:44 -04:00
|
|
|
assert not is_string(42.0)
|
2015-10-31 13:31:52 -04:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_is_callable_true():
|
2016-06-22 18:06:44 -04:00
|
|
|
assert is_callable(lambda: 42.0)
|
2016-06-24 21:21:50 +03:00
|
|
|
|
2016-06-24 23:51:55 +03:00
|
|
|
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_is_callable_false():
|
2016-06-22 18:06:44 -04:00
|
|
|
assert not is_callable(42.0)
|
2016-06-05 17:58:21 -04:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("inp", ["42.0", lambda: 42.0])
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_is_string_or_callable_true(inp):
|
|
|
|
assert is_string_or_callable(inp)
|
|
|
|
|
2016-06-24 23:51:55 +03:00
|
|
|
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_is_string_or_callable_false():
|
2016-06-22 18:06:44 -04:00
|
|
|
assert not is_string(42.0)
|
2016-06-05 17:58:21 -04:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("inp", [42, "42"])
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_always_true(inp):
|
|
|
|
assert always_true(inp)
|
2015-05-14 19:59:16 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2020-10-10 15:07:48 +05:30
|
|
|
@pytest.mark.parametrize("inp,exp", [(42, 42), ("42", 42), ("None", None)])
|
|
|
|
def test_to_optional_int(inp, exp):
|
|
|
|
assert to_int_or_none(inp) == exp
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("inp", [42, "42"])
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_always_false(inp):
|
|
|
|
assert not always_false(inp)
|
2015-05-14 19:59:16 -05:00
|
|
|
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("inp, exp", [(42, "42"), ("42", "42")])
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_ensure_string(inp, exp):
|
|
|
|
obs = ensure_string(inp)
|
|
|
|
assert exp == obs
|
2015-05-14 19:59:16 -05:00
|
|
|
|
2016-06-24 23:51:55 +03:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("", set()),
|
|
|
|
("a", {"a"}),
|
|
|
|
(os.pathsep.join(["a", "b"]), {"a", "b"}),
|
|
|
|
(os.pathsep.join(["a", "b", "c"]), {"a", "b", "c"}),
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_pathsep_to_set(inp, exp):
|
|
|
|
obs = pathsep_to_set(inp)
|
|
|
|
assert exp == obs
|
2016-05-22 22:33:43 +02:00
|
|
|
|
2016-06-20 13:17:52 -04:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(set(), ""),
|
|
|
|
({"a"}, "a"),
|
|
|
|
({"a", "b"}, os.pathsep.join(["a", "b"])),
|
|
|
|
({"a", "b", "c"}, os.pathsep.join(["a", "b", "c"])),
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_set_to_pathsep(inp, exp):
|
|
|
|
obs = set_to_pathsep(inp, sort=(len(inp) > 1))
|
|
|
|
assert exp == obs
|
2016-06-20 13:17:52 -04:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("inp", ["42.0", ["42.0"]])
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_is_string_seq_true(inp):
|
|
|
|
assert is_string_seq(inp)
|
2016-06-20 13:17:52 -04:00
|
|
|
|
2016-06-24 23:51:55 +03:00
|
|
|
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_is_string_seq_false():
|
2016-06-23 03:30:55 +03:00
|
|
|
assert not is_string_seq([42.0])
|
2016-06-20 16:26:54 -04:00
|
|
|
|
|
|
|
|
2016-06-24 21:21:50 +03:00
|
|
|
def test_is_nonstring_seq_of_strings_true():
|
2018-08-30 09:18:49 -05:00
|
|
|
assert is_nonstring_seq_of_strings(["42.0"])
|
2016-06-29 16:58:08 +03:00
|
|
|
|
2016-06-30 23:00:00 +03:00
|
|
|
|
2016-10-18 16:36:13 -04:00
|
|
|
def test_is_nonstring_seq_of_strings_false():
|
2016-06-23 03:30:55 +03:00
|
|
|
assert not is_nonstring_seq_of_strings([42.0])
|
2016-06-21 10:56:10 -04:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("", []),
|
|
|
|
("a", ["a"]),
|
|
|
|
(os.pathsep.join(["a", "b"]), ["a", "b"]),
|
|
|
|
(os.pathsep.join(["a", "b", "c"]), ["a", "b", "c"]),
|
|
|
|
],
|
|
|
|
)
|
2016-10-18 16:36:13 -04:00
|
|
|
def test_pathsep_to_seq(inp, exp):
|
2016-06-30 23:00:00 +03:00
|
|
|
obs = pathsep_to_seq(inp)
|
|
|
|
assert exp == obs
|
2016-06-20 16:26:54 -04:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
([], ""),
|
|
|
|
(["a"], "a"),
|
|
|
|
(["a", "b"], os.pathsep.join(["a", "b"])),
|
|
|
|
(["a", "b", "c"], os.pathsep.join(["a", "b", "c"])),
|
|
|
|
],
|
|
|
|
)
|
2016-10-18 16:36:13 -04:00
|
|
|
def test_seq_to_pathsep(inp, exp):
|
2016-06-30 23:00:00 +03:00
|
|
|
obs = seq_to_pathsep(inp)
|
|
|
|
assert exp == obs
|
2016-06-20 16:26:54 -04:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("", []),
|
|
|
|
("a", ["A"]),
|
|
|
|
(os.pathsep.join(["a", "B"]), ["A", "B"]),
|
|
|
|
(os.pathsep.join(["A", "b", "c"]), ["A", "B", "C"]),
|
|
|
|
],
|
|
|
|
)
|
2016-10-18 16:36:13 -04:00
|
|
|
def test_pathsep_to_upper_seq(inp, exp):
|
2016-06-30 23:00:00 +03:00
|
|
|
obs = pathsep_to_upper_seq(inp)
|
|
|
|
assert exp == obs
|
2016-06-21 10:56:10 -04:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
([], ""),
|
|
|
|
(["a"], "A"),
|
|
|
|
(["a", "b"], os.pathsep.join(["A", "B"])),
|
|
|
|
(["a", "B", "c"], os.pathsep.join(["A", "B", "C"])),
|
|
|
|
],
|
|
|
|
)
|
2016-10-18 16:36:13 -04:00
|
|
|
def test_seq_to_upper_pathsep(inp, exp):
|
2016-06-30 23:00:00 +03:00
|
|
|
obs = seq_to_upper_pathsep(inp)
|
|
|
|
assert exp == obs
|
2016-06-21 10:56:10 -04:00
|
|
|
|
|
|
|
|
2020-09-30 23:34:51 +03:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp", [(pathlib.Path("/home/wakka"), True), ("/home/jawaka", False)]
|
|
|
|
)
|
|
|
|
def test_is_path(inp, exp):
|
|
|
|
obs = is_path(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("/home/wakka", False),
|
|
|
|
(["/home/jawaka"], False),
|
|
|
|
(EnvPath(["/home/jawaka"]), True),
|
|
|
|
(EnvPath(["jawaka"]), True),
|
|
|
|
(EnvPath(b"jawaka:wakka"), True),
|
|
|
|
],
|
|
|
|
)
|
2016-10-18 16:36:13 -04:00
|
|
|
def test_is_env_path(inp, exp):
|
2016-06-30 23:00:00 +03:00
|
|
|
obs = is_env_path(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2020-09-30 23:34:51 +03:00
|
|
|
@pytest.mark.parametrize("inp, exp", [("/tmp", pathlib.Path("/tmp")), ("", None)])
|
|
|
|
def test_str_to_path(inp, exp):
|
|
|
|
obs = str_to_path(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("/home/wakka", ["/home/wakka"]),
|
|
|
|
("/home/wakka" + os.pathsep + "/home/jawaka", ["/home/wakka", "/home/jawaka"]),
|
|
|
|
(b"/home/wakka", ["/home/wakka"]),
|
|
|
|
],
|
|
|
|
)
|
2016-06-30 23:00:00 +03:00
|
|
|
def test_str_to_env_path(inp, exp):
|
|
|
|
obs = str_to_env_path(inp)
|
|
|
|
assert exp == obs.paths
|
2016-06-21 10:56:10 -04:00
|
|
|
|
2016-06-30 23:00:00 +03:00
|
|
|
|
2023-07-04 22:18:37 +05:30
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
pytest.param(
|
|
|
|
pathlib.Path("///tmp"),
|
|
|
|
"/tmp",
|
|
|
|
marks=pytest.mark.skipif(
|
|
|
|
ON_WINDOWS and PYTHON_VERSION_INFO > (3, 11),
|
|
|
|
reason="Python 3.12 on windows changed its behavior of resolving additional slashes in paths",
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
2020-09-30 23:34:51 +03:00
|
|
|
def test_path_to_str(inp, exp):
|
|
|
|
obs = path_to_str(inp)
|
2020-10-01 00:09:48 +03:00
|
|
|
if ON_WINDOWS:
|
2020-10-05 13:56:44 +03:00
|
|
|
exp = exp.replace("/", "\\")
|
2020-09-30 23:34:51 +03:00
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(["/home/wakka"], "/home/wakka"),
|
|
|
|
(["/home/wakka", "/home/jawaka"], "/home/wakka" + os.pathsep + "/home/jawaka"),
|
|
|
|
],
|
|
|
|
)
|
2016-06-30 23:00:00 +03:00
|
|
|
def test_env_path_to_str(inp, exp):
|
|
|
|
obs = env_path_to_str(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"left, right, exp",
|
|
|
|
[
|
|
|
|
(
|
|
|
|
EnvPath(["/home/wakka"]),
|
|
|
|
["/home/jawaka"],
|
|
|
|
EnvPath(["/home/wakka", "/home/jawaka"]),
|
|
|
|
),
|
|
|
|
(["a"], EnvPath(["b"]), EnvPath(["a", "b"])),
|
|
|
|
(EnvPath(["c"]), EnvPath(["d"]), EnvPath(["c", "d"])),
|
|
|
|
],
|
|
|
|
)
|
2017-07-22 16:31:16 -04:00
|
|
|
def test_env_path_add(left, right, exp):
|
|
|
|
obs = left + right
|
|
|
|
assert is_env_path(obs)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2021-09-14 12:54:18 -04:00
|
|
|
def test_env_path_add_replace_no_dupes_front_replace_existing():
|
|
|
|
# Test replaces without dupes when added to front when adding existing entry
|
|
|
|
path = EnvPath(
|
2024-04-21 13:38:52 +02:00
|
|
|
[os.sep.join(["home", "wakka"]), os.sep.join(["home", "wakka", "bin"])]
|
2021-09-14 12:54:18 -04:00
|
|
|
)
|
2024-04-21 13:38:52 +02:00
|
|
|
path.add(os.sep.join(["home", "wakka", "bin"]), front=True, replace=True)
|
2021-09-14 12:54:18 -04:00
|
|
|
assert path == [
|
2024-04-21 13:38:52 +02:00
|
|
|
os.sep.join(["home", "wakka", "bin"]),
|
|
|
|
os.sep.join(["home", "wakka"]),
|
2021-09-14 12:54:18 -04:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def test_env_path_add_replace_no_dupes_front_replace_multiple():
|
|
|
|
# Test replaces without dupes when added to front when multiple existing occurrences
|
|
|
|
path = EnvPath(
|
|
|
|
[
|
2024-04-21 13:38:52 +02:00
|
|
|
os.sep.join(["home", "wakka"]),
|
|
|
|
os.sep.join(["home", "wakka", "bin"]),
|
|
|
|
os.sep.join(["home", "wakka", "bin"]),
|
2021-09-14 12:54:18 -04:00
|
|
|
]
|
|
|
|
)
|
2024-04-21 13:38:52 +02:00
|
|
|
path.add(os.sep.join(["home", "wakka", "bin"]), front=True, replace=True)
|
2021-09-14 12:54:18 -04:00
|
|
|
assert path == [
|
2024-04-21 13:38:52 +02:00
|
|
|
os.sep.join(["home", "wakka", "bin"]),
|
|
|
|
os.sep.join(["home", "wakka"]),
|
2021-09-14 12:54:18 -04:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def test_env_path_add_replace_no_dupes_back_replace_multiple():
|
|
|
|
# Test replaces without dupes when not added to front
|
|
|
|
path = EnvPath(
|
|
|
|
[
|
2024-04-21 13:38:52 +02:00
|
|
|
os.sep.join(["home", "wakka"]),
|
|
|
|
os.sep.join(["home", "wakka", "bin"]),
|
|
|
|
os.sep.join(["home", "wakka", "bin"]),
|
2021-09-14 12:54:18 -04:00
|
|
|
]
|
|
|
|
)
|
2024-04-21 13:38:52 +02:00
|
|
|
path.add(os.sep.join(["home", "wakka", "bin"]), front=False, replace=True)
|
2021-09-14 12:54:18 -04:00
|
|
|
assert path == [
|
2024-04-21 13:38:52 +02:00
|
|
|
os.sep.join(["home", "wakka"]),
|
|
|
|
os.sep.join(["home", "wakka", "bin"]),
|
2021-09-14 12:54:18 -04:00
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def test_env_path_add_pathlib():
|
2024-04-21 13:38:52 +02:00
|
|
|
os.sep.join(["home", "wakka", "bin"])
|
2021-09-14 12:54:18 -04:00
|
|
|
path = EnvPath(
|
|
|
|
[
|
2024-04-21 13:38:52 +02:00
|
|
|
os.sep.join(["home", "wakka"]),
|
|
|
|
os.sep.join(["home", "wakka", "bin"]),
|
|
|
|
os.sep.join(["home", "wakka", "bin"]),
|
2021-09-14 12:54:18 -04:00
|
|
|
]
|
|
|
|
)
|
|
|
|
path.add(
|
2024-04-21 13:38:52 +02:00
|
|
|
pathlib.Path(os.sep.join(["home", "wakka", "bin"])),
|
2021-09-14 12:54:18 -04:00
|
|
|
front=False,
|
|
|
|
replace=True,
|
|
|
|
)
|
|
|
|
assert path == [
|
2024-04-21 13:38:52 +02:00
|
|
|
os.sep.join(["home", "wakka"]),
|
|
|
|
os.sep.join(["home", "wakka", "bin"]),
|
2021-09-14 12:54:18 -04:00
|
|
|
]
|
|
|
|
|
|
|
|
|
2024-04-21 10:03:42 +02:00
|
|
|
def test_env_path_append_remove_pathlib_path():
|
|
|
|
path = EnvPath()
|
|
|
|
|
|
|
|
# Append-remove
|
|
|
|
path.append(os.sep.join(["home", "dino"]))
|
|
|
|
path.remove(os.sep.join(["home", "dino"]))
|
|
|
|
|
|
|
|
path.append(os.sep.join(["~", "dino"]))
|
|
|
|
path.remove(pathlib.Path(os.sep.join(["~", "dino"])))
|
|
|
|
|
|
|
|
path.append(pathlib.Path(os.sep.join(["~", "dino"])))
|
|
|
|
path.remove(pathlib.Path(os.sep.join(["~", "dino"])))
|
|
|
|
|
|
|
|
path.append(pathlib.Path(os.sep.join(["~", "dino"])))
|
|
|
|
path.remove(os.sep.join(["~", "dino"]))
|
|
|
|
|
|
|
|
path.append(
|
|
|
|
pathlib.Path(os.sep.join([str(pathlib.Path("~").expanduser()), "dino"]))
|
|
|
|
)
|
|
|
|
path.remove(os.sep.join(["~", "dino"]))
|
|
|
|
|
|
|
|
path.append(pathlib.Path(os.sep.join(["~", "dino"])))
|
|
|
|
path.remove(os.sep.join([str(pathlib.Path("~").expanduser()), "dino"]))
|
|
|
|
|
|
|
|
# Insert-remove
|
|
|
|
path.insert(0, os.sep.join(["home", "dino"]))
|
|
|
|
path.remove(os.sep.join(["home", "dino"]))
|
|
|
|
|
|
|
|
path.insert(0, os.sep.join(["~", "dino"]))
|
|
|
|
path.remove(pathlib.Path(os.sep.join(["~", "dino"])))
|
|
|
|
|
|
|
|
path.insert(0, pathlib.Path(os.sep.join(["~", "dino"])))
|
|
|
|
path.remove(pathlib.Path(os.sep.join(["~", "dino"])))
|
|
|
|
|
|
|
|
path.prepend(pathlib.Path(os.sep.join(["~", "dino"])))
|
|
|
|
path.remove(os.sep.join(["~", "dino"]))
|
|
|
|
|
|
|
|
assert path == []
|
|
|
|
|
|
|
|
|
2016-06-30 23:00:00 +03:00
|
|
|
# helper
|
|
|
|
def expand(path):
|
|
|
|
return os.path.expanduser(os.path.expandvars(path))
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
|
|
|
|
@pytest.mark.parametrize("env", [TOOLS_ENV, ENCODE_ENV_ONLY])
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("xonsh_dir", "xonsh_dir"),
|
|
|
|
(".", "."),
|
|
|
|
("../", "../"),
|
|
|
|
("~/", "~/"),
|
|
|
|
(b"~/../", "~/../"),
|
|
|
|
],
|
|
|
|
)
|
2021-05-20 15:44:26 +05:30
|
|
|
def test_env_path_getitem(inp, exp, xession, env):
|
|
|
|
xession.env = env
|
2018-08-30 09:18:49 -05:00
|
|
|
obs = EnvPath(inp)[0] # call to __getitem__
|
|
|
|
if env.get("EXPAND_ENV_VARS"):
|
2016-07-04 13:20:12 +03:00
|
|
|
assert expand(exp) == obs
|
|
|
|
else:
|
|
|
|
assert exp == obs
|
2016-06-30 23:00:00 +03:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("env", [TOOLS_ENV, ENCODE_ENV_ONLY])
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(
|
|
|
|
os.pathsep.join(["xonsh_dir", "../", ".", "~/"]),
|
|
|
|
["xonsh_dir", "../", ".", "~/"],
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"/home/wakka" + os.pathsep + "/home/jakka" + os.pathsep + "~/",
|
|
|
|
["/home/wakka", "/home/jakka", "~/"],
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
2021-05-20 15:44:26 +05:30
|
|
|
def test_env_path_multipath(inp, exp, xession, env):
|
2016-06-13 04:23:05 +03:00
|
|
|
# cases that involve path-separated strings
|
2021-05-20 15:44:26 +05:30
|
|
|
xession.env = env
|
2016-06-30 23:00:00 +03:00
|
|
|
if env == TOOLS_ENV:
|
|
|
|
obs = [i for i in EnvPath(inp)]
|
|
|
|
assert [expand(i) for i in exp] == obs
|
|
|
|
else:
|
|
|
|
obs = [i for i in EnvPath(inp)]
|
|
|
|
assert [i for i in exp] == obs
|
2016-06-21 00:52:09 +03:00
|
|
|
|
2016-06-30 23:00:00 +03:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(pathlib.Path("/home/wakka"), ["/home/wakka".replace("/", os.sep)]),
|
|
|
|
(pathlib.Path("~/"), ["~"]),
|
|
|
|
(pathlib.Path("."), ["."]),
|
|
|
|
(
|
|
|
|
["/home/wakka", pathlib.Path("/home/jakka"), "~/"],
|
|
|
|
["/home/wakka", "/home/jakka".replace("/", os.sep), "~/"],
|
|
|
|
),
|
|
|
|
(["/home/wakka", pathlib.Path("../"), "../"], ["/home/wakka", "..", "../"]),
|
|
|
|
(["/home/wakka", pathlib.Path("~/"), "~/"], ["/home/wakka", "~", "~/"]),
|
|
|
|
],
|
|
|
|
)
|
2021-05-20 15:44:26 +05:30
|
|
|
def test_env_path_with_pathlib_path_objects(inp, exp, xession):
|
|
|
|
xession.env = TOOLS_ENV
|
2016-06-30 23:00:00 +03:00
|
|
|
# iterate over EnvPath to acquire all expanded paths
|
|
|
|
obs = [i for i in EnvPath(inp)]
|
|
|
|
assert [expand(i) for i in exp] == obs
|
2016-06-24 23:51:55 +03:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
|
|
|
|
@pytest.mark.parametrize("inp", ["42.0", [42.0]])
|
2020-05-05 06:42:28 -04:00
|
|
|
def test_is_nonstring_seq_of_strings_false1(inp):
|
2016-06-24 21:21:50 +03:00
|
|
|
assert not is_nonstring_seq_of_strings(inp)
|
|
|
|
|
|
|
|
|
2016-06-24 23:51:55 +03:00
|
|
|
# helper
|
|
|
|
def mkpath(*paths):
|
|
|
|
"""Build os-dependent paths properly."""
|
|
|
|
return os.sep + os.sep.join(paths)
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(
|
|
|
|
[mkpath("home", "wakka"), mkpath("home", "jakka"), mkpath("home", "yakka")],
|
|
|
|
[mkpath("home", "wakka"), mkpath("home", "jakka")],
|
|
|
|
)
|
|
|
|
],
|
|
|
|
)
|
2016-07-02 04:53:37 +03:00
|
|
|
def test_env_path_slice_get_all_except_last_element(inp, exp):
|
2016-06-24 23:51:55 +03:00
|
|
|
obs = EnvPath(inp)[:-1]
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(
|
|
|
|
[mkpath("home", "wakka"), mkpath("home", "jakka"), mkpath("home", "yakka")],
|
|
|
|
[mkpath("home", "jakka"), mkpath("home", "yakka")],
|
|
|
|
)
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_env_path_slice_get_all_except_first_element(inp, exp):
|
|
|
|
obs = EnvPath(inp)[1:]
|
|
|
|
assert exp == obs
|
2016-06-21 00:52:09 +03:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp_a, exp_b",
|
|
|
|
[
|
|
|
|
(
|
|
|
|
[
|
|
|
|
mkpath("home", "wakka"),
|
|
|
|
mkpath("home", "jakka"),
|
|
|
|
mkpath("home", "yakka"),
|
|
|
|
mkpath("home", "takka"),
|
|
|
|
],
|
|
|
|
[mkpath("home", "wakka"), mkpath("home", "yakka")],
|
|
|
|
[mkpath("home", "jakka"), mkpath("home", "takka")],
|
|
|
|
)
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_env_path_slice_path_with_step(inp, exp_a, exp_b):
|
|
|
|
obs_a = EnvPath(inp)[0::2]
|
|
|
|
assert exp_a == obs_a
|
|
|
|
obs_b = EnvPath(inp)[1::2]
|
|
|
|
assert exp_b == obs_b
|
2016-06-21 00:52:09 +03:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(
|
|
|
|
[
|
|
|
|
mkpath("home", "wakka"),
|
|
|
|
mkpath("home", "xakka"),
|
|
|
|
mkpath("other", "zakka"),
|
|
|
|
mkpath("another", "akka"),
|
|
|
|
mkpath("home", "bakka"),
|
|
|
|
],
|
|
|
|
[mkpath("other", "zakka"), mkpath("another", "akka")],
|
|
|
|
)
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_env_path_keep_only_non_home_paths(inp, exp):
|
|
|
|
obs = EnvPath(inp)[2:4]
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("inp", [True, False])
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_is_bool_true(inp):
|
2020-05-05 06:42:28 -04:00
|
|
|
assert is_bool(inp)
|
2016-06-24 23:51:55 +03:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("inp", [1, "yooo hooo!"])
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_is_bool_false(inp):
|
2020-05-05 06:42:28 -04:00
|
|
|
assert not is_bool(inp)
|
2016-06-24 23:51:55 +03:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(True, True),
|
|
|
|
(False, False),
|
|
|
|
(None, False),
|
|
|
|
("", False),
|
|
|
|
("0", False),
|
|
|
|
("False", False),
|
|
|
|
("NONE", False),
|
|
|
|
("TRUE", True),
|
|
|
|
("1", True),
|
|
|
|
(0, False),
|
|
|
|
(1, True),
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_to_bool(inp, exp):
|
|
|
|
obs = to_bool(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("inp, exp", [(True, "1"), (False, "")])
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_bool_to_str(inp, exp):
|
|
|
|
assert bool_to_str(inp) == exp
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[(True, True), (False, True), (1, True), (0, True), ("Yolo", False), (1.0, False)],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_is_bool_or_int(inp, exp):
|
|
|
|
obs = is_bool_or_int(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(True, True),
|
|
|
|
(False, False),
|
|
|
|
(1, 1),
|
|
|
|
(0, 0),
|
|
|
|
("", False),
|
|
|
|
(0.0, False),
|
|
|
|
(1.0, True),
|
|
|
|
("T", True),
|
|
|
|
("f", False),
|
|
|
|
("0", 0),
|
|
|
|
("10", 10),
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_to_bool_or_int(inp, exp):
|
|
|
|
obs = to_bool_or_int(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("inp, exp", [(True, "1"), (False, ""), (1, "1"), (0, "0")])
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_bool_or_int_to_str(inp, exp):
|
|
|
|
obs = bool_or_int_to_str(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2020-08-20 20:11:37 -05:00
|
|
|
@pytest.mark.parametrize("inp", [True, False, None])
|
|
|
|
def test_is_bool_or_none_true(inp):
|
|
|
|
assert is_bool_or_none(inp)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("inp", [1, "yooo hooo!"])
|
|
|
|
def test_is_bool_or_none_false(inp):
|
|
|
|
assert not is_bool_or_none(inp)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(True, True),
|
|
|
|
(False, False),
|
|
|
|
(None, None),
|
|
|
|
("", False),
|
|
|
|
("0", False),
|
|
|
|
("False", False),
|
|
|
|
("NONE", None),
|
|
|
|
("TRUE", True),
|
|
|
|
("1", True),
|
|
|
|
(0, False),
|
|
|
|
(1, True),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_to_bool_or_none(inp, exp):
|
|
|
|
obs = to_bool_or_none(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("inp, exp", [(True, "1"), (False, ""), (None, "None")])
|
|
|
|
def test_bool_or_none_to_str(inp, exp):
|
|
|
|
assert bool_or_none_to_str(inp) == exp
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
2016-07-18 21:36:09 +03:00
|
|
|
(42, slice(42, 43)),
|
2016-08-29 02:45:36 +03:00
|
|
|
(0, slice(0, 1)),
|
2015-08-23 11:30:07 -04:00
|
|
|
(None, slice(None, None, None)),
|
2016-10-18 16:36:13 -04:00
|
|
|
(slice(1, 2), slice(1, 2)),
|
2018-08-30 09:18:49 -05:00
|
|
|
("-1", slice(-1, None, None)),
|
|
|
|
("42", slice(42, 43)),
|
|
|
|
("-42", slice(-42, -41)),
|
|
|
|
("1:2:3", slice(1, 2, 3)),
|
|
|
|
("1::3", slice(1, None, 3)),
|
|
|
|
(":", slice(None, None, None)),
|
|
|
|
("1:", slice(1, None, None)),
|
|
|
|
("[1:2:3]", slice(1, 2, 3)),
|
|
|
|
("(1:2:3)", slice(1, 2, 3)),
|
2016-07-23 09:53:38 +03:00
|
|
|
((4, 8, 10), slice(4, 8, 10)),
|
2018-08-30 09:18:49 -05:00
|
|
|
([10, 20], slice(10, 20)),
|
|
|
|
],
|
|
|
|
)
|
2016-07-18 21:36:09 +03:00
|
|
|
def test_ensure_slice(inp, exp):
|
|
|
|
obs = ensure_slice(inp)
|
2016-06-24 23:51:55 +03:00
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
((range(50), slice(25, 40)), list(i for i in range(25, 40))),
|
|
|
|
(
|
|
|
|
([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [slice(1, 4), slice(6, None)]),
|
|
|
|
[2, 3, 4, 7, 8, 9, 10],
|
|
|
|
),
|
|
|
|
(([1, 2, 3, 4, 5], [slice(-2, None), slice(-5, -3)]), [4, 5, 1, 2]),
|
|
|
|
],
|
|
|
|
)
|
2016-08-29 13:42:40 +03:00
|
|
|
def test_get_portions(inp, exp):
|
|
|
|
obs = get_portions(*inp)
|
|
|
|
assert list(obs) == exp
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp",
|
|
|
|
[
|
|
|
|
"42.3",
|
|
|
|
"3:asd5:1",
|
|
|
|
"test",
|
|
|
|
"6.53:100:5",
|
|
|
|
"4:-",
|
|
|
|
"2:15-:3",
|
|
|
|
"50:-:666",
|
|
|
|
object(),
|
|
|
|
[1, 5, 3, 4],
|
|
|
|
("foo"),
|
|
|
|
],
|
|
|
|
)
|
2016-07-23 13:32:24 +03:00
|
|
|
def test_ensure_slice_invalid(inp):
|
|
|
|
with pytest.raises(ValueError):
|
2020-05-05 06:42:28 -04:00
|
|
|
ensure_slice(inp)
|
2016-07-18 21:36:09 +03:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("42", True),
|
|
|
|
("42.0", False),
|
|
|
|
(42, False),
|
|
|
|
([42], False),
|
|
|
|
([], False),
|
|
|
|
(None, False),
|
|
|
|
("", False),
|
|
|
|
(False, False),
|
|
|
|
(True, False),
|
|
|
|
],
|
|
|
|
)
|
2016-07-20 15:16:46 +03:00
|
|
|
def test_is_int_as_str(inp, exp):
|
|
|
|
obs = is_int_as_str(inp)
|
|
|
|
assert exp == obs
|
2018-08-30 09:18:49 -05:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("20", False),
|
|
|
|
("20%", False),
|
|
|
|
((20, "c"), False),
|
|
|
|
((20.0, "m"), False),
|
|
|
|
((20.0, "c"), True),
|
|
|
|
((20.0, "%"), True),
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_is_dynamic_cwd_width(inp, exp):
|
|
|
|
obs = is_dynamic_cwd_width(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(42, False),
|
|
|
|
(None, False),
|
|
|
|
("42", False),
|
|
|
|
("-42", False),
|
|
|
|
(slice(1, 2, 3), False),
|
|
|
|
([], False),
|
|
|
|
(False, False),
|
|
|
|
(True, False),
|
|
|
|
("1:2:3", True),
|
|
|
|
("1::3", True),
|
|
|
|
("1:", True),
|
|
|
|
(":", True),
|
|
|
|
("[1:2:3]", True),
|
|
|
|
("(1:2:3)", True),
|
|
|
|
("r", False),
|
|
|
|
("r:11", False),
|
|
|
|
],
|
|
|
|
)
|
2016-07-20 15:16:46 +03:00
|
|
|
def test_is_slice_as_str(inp, exp):
|
|
|
|
obs = is_slice_as_str(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("throwback.log", True),
|
|
|
|
("", True),
|
|
|
|
(None, True),
|
|
|
|
(True, False),
|
|
|
|
(False, False),
|
|
|
|
(42, False),
|
|
|
|
([1, 2, 3], False),
|
|
|
|
((1, 2), False),
|
|
|
|
(("wrong", "parameter"), False),
|
2018-10-03 09:52:03 +02:00
|
|
|
pytest.param("/dev/null", True, marks=skip_if_on_windows),
|
2018-08-30 09:18:49 -05:00
|
|
|
],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_is_logfile_opt(inp, exp):
|
|
|
|
obs = is_logfile_opt(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
2016-06-10 04:56:32 +03:00
|
|
|
(True, None),
|
|
|
|
(False, None),
|
|
|
|
(1, None),
|
|
|
|
(None, None),
|
2018-08-30 09:18:49 -05:00
|
|
|
("throwback.log", "throwback.log"),
|
2018-10-03 09:52:03 +02:00
|
|
|
pytest.param("/dev/null", "/dev/null", marks=skip_if_on_windows),
|
|
|
|
pytest.param(
|
|
|
|
"/dev/nonexistent_dev",
|
2024-01-30 12:23:50 +01:00
|
|
|
(
|
|
|
|
"/dev/nonexistent_dev"
|
|
|
|
if is_writable_file("/dev/nonexistent_dev")
|
|
|
|
else None
|
|
|
|
),
|
2018-10-03 09:52:03 +02:00
|
|
|
marks=skip_if_on_windows,
|
2018-08-30 09:18:49 -05:00
|
|
|
),
|
2022-03-14 15:01:24 -04:00
|
|
|
("~/log", os.path.expanduser("~/log")),
|
2018-08-30 09:18:49 -05:00
|
|
|
],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_to_logfile_opt(inp, exp):
|
|
|
|
obs = to_logfile_opt(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
(None, ""),
|
|
|
|
("", ""),
|
|
|
|
("throwback.log", "throwback.log"),
|
|
|
|
("/dev/null", "/dev/null"),
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_logfile_opt_to_str(inp, exp):
|
|
|
|
obs = logfile_opt_to_str(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("20", (20.0, "c")),
|
|
|
|
("20%", (20.0, "%")),
|
|
|
|
((20, "c"), (20.0, "c")),
|
|
|
|
((20, "%"), (20.0, "%")),
|
|
|
|
((20.0, "c"), (20.0, "c")),
|
|
|
|
((20.0, "%"), (20.0, "%")),
|
|
|
|
("inf", (float("inf"), "c")),
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_to_dynamic_cwd_tuple(inp, exp):
|
|
|
|
obs = to_dynamic_cwd_tuple(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[((20.0, "c"), "20.0"), ((20.0, "%"), "20.0%"), ((float("inf"), "c"), "inf")],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_dynamic_cwd_tuple_to_str(inp, exp):
|
|
|
|
obs = dynamic_cwd_tuple_to_str(inp)
|
|
|
|
assert exp == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"st, esc",
|
|
|
|
[
|
|
|
|
("", ""),
|
|
|
|
("foo", "foo"),
|
|
|
|
("foo&bar", "foo^&bar"),
|
|
|
|
('foo$?-/_"\\', 'foo$?-/_^"\\'),
|
|
|
|
("^&<>|", "^^^&^<^>^|"),
|
|
|
|
("()<>", "^(^)^<^>"),
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_escape_windows_cmd_string(st, esc):
|
|
|
|
obs = escape_windows_cmd_string(st)
|
|
|
|
assert esc == obs
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"st, esc, forced",
|
|
|
|
[
|
|
|
|
("", '""', None),
|
|
|
|
("foo", "foo", '"foo"'),
|
|
|
|
(
|
|
|
|
r'arg1 "hallo, "world"" "\some\path with\spaces")',
|
|
|
|
r'"arg1 \"hallo, \"world\"\" \"\some\path with\spaces\")"',
|
|
|
|
None,
|
|
|
|
),
|
|
|
|
(
|
|
|
|
r'"argument"2" argument3 argument4',
|
|
|
|
r'"\"argument\"2\" argument3 argument4"',
|
|
|
|
None,
|
|
|
|
),
|
|
|
|
(r'"\foo\bar bar\foo\" arg', r'"\"\foo\bar bar\foo\\\" arg"', None),
|
|
|
|
(
|
|
|
|
r"\\machine\dir\file.bat",
|
|
|
|
r"\\machine\dir\file.bat",
|
|
|
|
r'"\\machine\dir\file.bat"',
|
|
|
|
),
|
|
|
|
(
|
|
|
|
r'"\\machine\dir space\file.bat"',
|
|
|
|
r'"\"\\machine\dir space\file.bat\""',
|
|
|
|
None,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
2016-10-22 14:25:34 +02:00
|
|
|
def test_argvquote(st, esc, forced):
|
2016-06-24 23:51:55 +03:00
|
|
|
obs = argvquote(st)
|
|
|
|
assert esc == obs
|
2017-01-30 18:49:41 +01:00
|
|
|
|
2016-10-22 14:25:34 +02:00
|
|
|
if forced is None:
|
|
|
|
forced = esc
|
|
|
|
obs = argvquote(st, force=True)
|
|
|
|
assert forced == obs
|
2015-05-13 23:14:31 -04:00
|
|
|
|
2016-04-22 13:16:46 +02:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("inp", ["no string here", ""])
|
2016-07-18 00:35:50 +03:00
|
|
|
def test_partial_string_none(inp):
|
|
|
|
assert check_for_partial_string(inp) == (None, None, None)
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"leaders", [(("", 0), ("not empty", 9)), (("not empty", 9), ("", 0))]
|
|
|
|
)
|
|
|
|
@pytest.mark.parametrize("prefix", ["b", "rb", "r"])
|
|
|
|
@pytest.mark.parametrize("quote", ['"', '"""'])
|
2016-07-18 00:35:50 +03:00
|
|
|
def test_partial_string(leaders, prefix, quote):
|
|
|
|
(l, l_len), (f, f_len) = leaders
|
|
|
|
s = prefix + quote
|
2018-08-30 09:18:49 -05:00
|
|
|
t = s + "test string" + quote
|
2016-07-18 00:35:50 +03:00
|
|
|
t_len = len(t)
|
|
|
|
# single string
|
|
|
|
test_string = l + t + f
|
|
|
|
obs = check_for_partial_string(test_string)
|
|
|
|
exp = l_len, l_len + t_len, s
|
|
|
|
assert obs == exp
|
|
|
|
# single partial
|
2018-08-30 09:18:49 -05:00
|
|
|
test_string = l + f + s + "test string"
|
2016-07-18 00:35:50 +03:00
|
|
|
obs = check_for_partial_string(test_string)
|
|
|
|
exp = l_len + f_len, None, s
|
|
|
|
assert obs == exp
|
|
|
|
# two strings
|
|
|
|
test_string = l + t + f + l + t + f
|
|
|
|
obs = check_for_partial_string(test_string)
|
|
|
|
exp = (l_len + t_len + f_len + l_len), (l_len + t_len + f_len + l_len + t_len), s
|
|
|
|
assert obs == exp
|
|
|
|
# one string, one partial
|
2018-08-30 09:18:49 -05:00
|
|
|
test_string = l + t + f + l + s + "test string"
|
2016-07-18 00:35:50 +03:00
|
|
|
obs = check_for_partial_string(test_string)
|
2018-08-30 09:18:49 -05:00
|
|
|
exp = l_len + t_len + f_len + l_len, None, s
|
2016-07-18 00:35:50 +03:00
|
|
|
assert obs == exp
|
2015-12-18 15:30:46 -05:00
|
|
|
|
2015-05-13 23:14:31 -04:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("yo", "[Yy][Oo]"),
|
|
|
|
("[a-f]123e", "[a-f]123[Ee]"),
|
|
|
|
("${HOME}/yo", "${HOME}/[Yy][Oo]"),
|
|
|
|
("./yo/mom", "./[Yy][Oo]/[Mm][Oo][Mm]"),
|
|
|
|
("Eßen", "[Ee][Ss]?[Ssß][Ee][Nn]"),
|
|
|
|
],
|
|
|
|
)
|
2016-06-24 23:51:55 +03:00
|
|
|
def test_expand_case_matching(inp, exp):
|
|
|
|
obs = expand_case_matching(inp)
|
|
|
|
assert exp == obs
|
2016-06-01 13:59:33 -04:00
|
|
|
|
2016-06-07 22:12:02 -04:00
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, exp",
|
|
|
|
[
|
|
|
|
("foo", "foo"),
|
|
|
|
("$foo $bar", "bar $bar"),
|
2020-10-05 13:56:44 +03:00
|
|
|
("$unk $foo $bar", "$unk bar $bar"),
|
2018-08-30 09:18:49 -05:00
|
|
|
("$foobar", "$foobar"),
|
|
|
|
("$foo $spam", "bar eggs"),
|
2020-10-05 13:56:44 +03:00
|
|
|
("$unk $foo $spam", "$unk bar eggs"),
|
|
|
|
("$unk $foo $unk $spam $unk", "$unk bar $unk eggs $unk"),
|
2018-08-30 09:18:49 -05:00
|
|
|
("$an_int$spam$a_bool", "42eggsTrue"),
|
2020-10-05 13:56:44 +03:00
|
|
|
("$unk$an_int$spam$a_bool", "$unk42eggsTrue"),
|
2022-01-21 10:16:50 +01:00
|
|
|
("bar$foo$spam$foo $an_int $none", "barbareggsbar 42 "),
|
|
|
|
("$unk bar$foo$spam$foo $an_int $none", "$unk barbareggsbar 42 "),
|
2018-08-30 09:18:49 -05:00
|
|
|
("$foo/bar", "bar/bar"),
|
2020-10-05 13:56:44 +03:00
|
|
|
("$unk/$foo/bar", "$unk/bar/bar"),
|
2018-08-30 09:18:49 -05:00
|
|
|
("${'foo'} $spam", "bar eggs"),
|
2020-10-05 13:56:44 +03:00
|
|
|
("$unk ${'unk'} ${'foo'} $spam", "$unk ${'unk'} bar eggs"),
|
2018-08-30 09:18:49 -05:00
|
|
|
("${'foo'} ${'a_bool'}", "bar True"),
|
|
|
|
("${'foo'}bar", "barbar"),
|
|
|
|
("${'foo'}/bar", "bar/bar"),
|
2020-10-05 13:56:44 +03:00
|
|
|
("${'unk'}/${'foo'}/bar", "${'unk'}/bar/bar"),
|
2018-08-30 09:18:49 -05:00
|
|
|
("${\"foo'}", "${\"foo'}"),
|
|
|
|
("$?bar", "$?bar"),
|
|
|
|
("$foo}bar", "bar}bar"),
|
|
|
|
("${'foo", "${'foo"),
|
|
|
|
(b"foo", "foo"),
|
|
|
|
(b"$foo bar", "bar bar"),
|
2020-10-05 13:56:44 +03:00
|
|
|
(b"$unk $foo bar", "$unk bar bar"),
|
2018-08-30 09:18:49 -05:00
|
|
|
(b"${'foo'}bar", "barbar"),
|
2020-10-05 13:56:44 +03:00
|
|
|
(b"${'unk'}${'foo'}bar", "${'unk'}barbar"),
|
2018-08-30 09:18:49 -05:00
|
|
|
],
|
|
|
|
)
|
2021-05-20 15:44:26 +05:30
|
|
|
def test_expandvars(inp, exp, xession):
|
2016-07-05 01:46:07 +03:00
|
|
|
"""Tweaked for xonsh cases from CPython `test_genericpath.py`"""
|
2022-01-08 04:03:22 +05:30
|
|
|
xession.env.update(
|
|
|
|
dict({"foo": "bar", "spam": "eggs", "a_bool": True, "an_int": 42, "none": None})
|
2018-08-30 09:18:49 -05:00
|
|
|
)
|
2016-07-05 01:46:07 +03:00
|
|
|
assert expandvars(inp) == exp
|
2016-08-01 15:01:17 +03:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, fmt, exp",
|
|
|
|
[
|
|
|
|
(572392800.0, None, 572392800.0),
|
|
|
|
("42.1459", None, 42.1459),
|
|
|
|
(
|
|
|
|
dt.datetime(2016, 8, 2, 13, 24),
|
|
|
|
None,
|
|
|
|
dt.datetime(2016, 8, 2, 13, 24).timestamp(),
|
|
|
|
),
|
|
|
|
("2016-8-10 16:14", None, dt.datetime(2016, 8, 10, 16, 14).timestamp()),
|
|
|
|
(
|
|
|
|
"2016/8/10 16:14:40",
|
|
|
|
"%Y/%m/%d %H:%M:%S",
|
|
|
|
dt.datetime(2016, 8, 10, 16, 14, 40).timestamp(),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
2021-05-20 15:44:26 +05:30
|
|
|
def test_ensure_timestamp(inp, fmt, exp, xession):
|
|
|
|
xession.env["XONSH_DATETIME_FORMAT"] = "%Y-%m-%d %H:%M"
|
2016-08-10 16:49:06 +03:00
|
|
|
obs = ensure_timestamp(inp, fmt)
|
2016-08-01 15:01:17 +03:00
|
|
|
assert exp == obs
|
2017-01-30 18:49:41 +01:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("expand_user", [True, False])
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"inp, expand_env_vars, exp_end",
|
|
|
|
[
|
|
|
|
("~/test.txt", True, "/test.txt"),
|
|
|
|
("~/$foo", True, "/bar"),
|
|
|
|
("~/test/$a_bool", True, "/test/True"),
|
|
|
|
("~/test/$an_int", True, "/test/42"),
|
2022-01-21 10:16:50 +01:00
|
|
|
("~/test/$none", True, "/test/"),
|
2018-08-30 09:18:49 -05:00
|
|
|
("~/$foo", False, "/$foo"),
|
|
|
|
],
|
|
|
|
)
|
2021-05-20 15:44:26 +05:30
|
|
|
def test_expand_path(expand_user, inp, expand_env_vars, exp_end, xession):
|
2018-08-30 09:18:49 -05:00
|
|
|
if os.sep != "/":
|
|
|
|
inp = inp.replace("/", os.sep)
|
|
|
|
exp_end = exp_end.replace("/", os.sep)
|
2017-01-30 18:49:41 +01:00
|
|
|
|
2022-01-08 04:03:22 +05:30
|
|
|
xession.env.update({"foo": "bar", "a_bool": True, "an_int": 42, "none": None})
|
|
|
|
xession.env["EXPAND_ENV_VARS"] = expand_env_vars
|
2017-01-30 18:49:41 +01:00
|
|
|
|
|
|
|
path = expand_path(inp, expand_user=expand_user)
|
|
|
|
|
|
|
|
if expand_user:
|
2018-08-30 09:18:49 -05:00
|
|
|
home_path = os.path.expanduser("~")
|
2017-01-30 18:49:41 +01:00
|
|
|
assert path == home_path + exp_end
|
|
|
|
else:
|
2018-08-30 09:18:49 -05:00
|
|
|
assert path == "~" + exp_end
|
2017-02-11 18:51:10 -05:00
|
|
|
|
|
|
|
|
|
|
|
def test_swap_values():
|
2018-08-30 09:18:49 -05:00
|
|
|
orig = {"x": 1}
|
|
|
|
updates = {"x": 42, "y": 43}
|
2017-02-11 18:51:10 -05:00
|
|
|
with swap_values(orig, updates):
|
2018-08-30 09:18:49 -05:00
|
|
|
assert orig["x"] == 42
|
|
|
|
assert orig["y"] == 43
|
|
|
|
assert orig["x"] == 1
|
|
|
|
assert "y" not in orig
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"arguments, expected_docstring",
|
|
|
|
[
|
|
|
|
(
|
|
|
|
{"deprecated_in": "0.5.10", "removed_in": "0.6.0"},
|
|
|
|
"my_function has been deprecated in version 0.5.10 and will be removed "
|
|
|
|
"in version 0.6.0",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
{"deprecated_in": "0.5.10"},
|
|
|
|
"my_function has been deprecated in version 0.5.10",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
{"removed_in": "0.6.0"},
|
|
|
|
"my_function has been deprecated and will be removed in version 0.6.0",
|
|
|
|
),
|
|
|
|
({}, "my_function has been deprecated"),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_deprecated_docstrings_with_empty_docstring(arguments, expected_docstring):
|
2017-06-09 21:50:38 -04:00
|
|
|
@deprecated(**arguments)
|
2018-08-30 09:18:49 -05:00
|
|
|
def my_function():
|
|
|
|
pass
|
2017-06-09 21:50:38 -04:00
|
|
|
|
|
|
|
assert my_function.__doc__ == expected_docstring
|
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"arguments, expected_docstring",
|
|
|
|
[
|
|
|
|
(
|
|
|
|
{"deprecated_in": "0.5.10", "removed_in": "0.6.0"},
|
|
|
|
"Does nothing.\n\nmy_function has been deprecated in version 0.5.10 and "
|
|
|
|
"will be removed in version 0.6.0",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
{"deprecated_in": "0.5.10"},
|
|
|
|
"Does nothing.\n\nmy_function has been deprecated in version 0.5.10",
|
|
|
|
),
|
|
|
|
(
|
|
|
|
{"removed_in": "0.6.0"},
|
|
|
|
"Does nothing.\n\nmy_function has been deprecated and will be removed "
|
|
|
|
"in version 0.6.0",
|
|
|
|
),
|
|
|
|
({}, "Does nothing.\n\nmy_function has been deprecated"),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_deprecated_docstrings_with_nonempty_docstring(arguments, expected_docstring):
|
2017-06-09 21:50:38 -04:00
|
|
|
@deprecated(**arguments)
|
|
|
|
def my_function():
|
|
|
|
"""Does nothing."""
|
|
|
|
pass
|
|
|
|
|
|
|
|
assert my_function.__doc__ == expected_docstring
|
|
|
|
|
|
|
|
|
|
|
|
def test_deprecated_warning_raised():
|
|
|
|
@deprecated()
|
2018-08-30 09:18:49 -05:00
|
|
|
def my_function():
|
|
|
|
pass
|
2017-06-09 21:50:38 -04:00
|
|
|
|
|
|
|
with warnings.catch_warnings(record=True) as warning:
|
2018-08-30 09:18:49 -05:00
|
|
|
warnings.simplefilter("always")
|
2017-06-09 21:50:38 -04:00
|
|
|
|
|
|
|
my_function()
|
|
|
|
|
|
|
|
assert issubclass(warning.pop().category, DeprecationWarning)
|
|
|
|
|
|
|
|
|
|
|
|
def test_deprecated_warning_contains_message():
|
|
|
|
@deprecated()
|
2018-08-30 09:18:49 -05:00
|
|
|
def my_function():
|
|
|
|
pass
|
2017-06-09 21:50:38 -04:00
|
|
|
|
|
|
|
with warnings.catch_warnings(record=True) as warning:
|
2018-08-30 09:18:49 -05:00
|
|
|
warnings.simplefilter("always")
|
2017-06-09 21:50:38 -04:00
|
|
|
|
|
|
|
my_function()
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
assert str(warning.pop().message) == "my_function has been deprecated"
|
2017-06-10 09:57:49 -04:00
|
|
|
|
|
|
|
|
2018-08-30 09:18:49 -05:00
|
|
|
@pytest.mark.parametrize("expired_version", ["0.1.0", __version__])
|
2017-06-10 09:57:49 -04:00
|
|
|
def test_deprecated_past_expiry_raises_assertion_error(expired_version):
|
|
|
|
@deprecated(removed_in=expired_version)
|
2018-08-30 09:18:49 -05:00
|
|
|
def my_function():
|
|
|
|
pass
|
2017-06-10 09:57:49 -04:00
|
|
|
|
|
|
|
with pytest.raises(AssertionError):
|
|
|
|
my_function()
|
2017-12-07 16:44:01 -05:00
|
|
|
|
|
|
|
|
2018-09-12 18:12:02 -04:00
|
|
|
@skip_if_on_windows
|
2021-05-20 15:44:26 +05:30
|
|
|
def test_iglobpath_no_dotfiles(xession):
|
2018-09-12 18:12:02 -04:00
|
|
|
d = os.path.dirname(__file__)
|
2018-09-12 19:19:36 -04:00
|
|
|
g = d + "/*"
|
2018-09-12 18:12:02 -04:00
|
|
|
files = list(iglobpath(g, include_dotfiles=False))
|
2018-09-12 19:19:36 -04:00
|
|
|
assert d + "/.somedotfile" not in files
|
2018-09-12 18:12:02 -04:00
|
|
|
|
|
|
|
|
|
|
|
@skip_if_on_windows
|
2021-05-20 15:44:26 +05:30
|
|
|
def test_iglobpath_dotfiles(xession):
|
2018-09-12 18:12:02 -04:00
|
|
|
d = os.path.dirname(__file__)
|
2018-09-12 19:19:36 -04:00
|
|
|
g = d + "/*"
|
2018-09-12 18:12:02 -04:00
|
|
|
files = list(iglobpath(g, include_dotfiles=True))
|
2018-09-12 19:19:36 -04:00
|
|
|
assert d + "/.somedotfile" in files
|
2018-09-12 18:12:02 -04:00
|
|
|
|
|
|
|
|
|
|
|
@skip_if_on_windows
|
2021-05-20 15:44:26 +05:30
|
|
|
def test_iglobpath_no_dotfiles_recursive(xession):
|
2018-09-12 18:12:02 -04:00
|
|
|
d = os.path.dirname(__file__)
|
2018-09-12 19:19:36 -04:00
|
|
|
g = d + "/**"
|
2018-09-12 18:12:02 -04:00
|
|
|
files = list(iglobpath(g, include_dotfiles=False))
|
2018-09-12 19:19:36 -04:00
|
|
|
assert d + "/bin/.someotherdotfile" not in files
|
2018-09-12 18:12:02 -04:00
|
|
|
|
|
|
|
|
|
|
|
@skip_if_on_windows
|
2021-05-20 15:44:26 +05:30
|
|
|
def test_iglobpath_dotfiles_recursive(xession):
|
2018-09-12 18:12:02 -04:00
|
|
|
d = os.path.dirname(__file__)
|
2018-09-12 19:19:36 -04:00
|
|
|
g = d + "/**"
|
2018-09-12 18:12:02 -04:00
|
|
|
files = list(iglobpath(g, include_dotfiles=True))
|
2018-09-12 19:19:36 -04:00
|
|
|
assert d + "/bin/.someotherdotfile" in files
|
2018-09-12 18:12:02 -04:00
|
|
|
|
|
|
|
|
2021-05-20 15:44:26 +05:30
|
|
|
def test_iglobpath_empty_str(monkeypatch, xession):
|
2017-12-07 16:44:01 -05:00
|
|
|
# makes sure that iglobpath works, even when os.scandir() and os.listdir()
|
|
|
|
# fail to return valid results, like an empty filename
|
|
|
|
def mockscandir(path):
|
2018-08-30 09:18:49 -05:00
|
|
|
yield ""
|
|
|
|
|
|
|
|
if hasattr(os, "scandir"):
|
|
|
|
monkeypatch.setattr(os, "scandir", mockscandir)
|
|
|
|
|
2017-12-07 16:44:01 -05:00
|
|
|
def mocklistdir(path):
|
2018-08-30 09:18:49 -05:00
|
|
|
return [""]
|
|
|
|
|
|
|
|
monkeypatch.setattr(os, "listdir", mocklistdir)
|
|
|
|
paths = list(iglobpath("some/path"))
|
2017-12-07 16:44:01 -05:00
|
|
|
assert len(paths) == 0
|
2019-03-06 17:49:22 -08:00
|
|
|
|
|
|
|
|
|
|
|
def test_all_permutations():
|
|
|
|
obs = {"".join(p) for p in all_permutations("ABC")}
|
|
|
|
exp = {
|
|
|
|
"A",
|
|
|
|
"B",
|
|
|
|
"C",
|
|
|
|
"AB",
|
|
|
|
"AC",
|
|
|
|
"BA",
|
|
|
|
"BC",
|
|
|
|
"CA",
|
|
|
|
"CB",
|
|
|
|
"ACB",
|
|
|
|
"CBA",
|
|
|
|
"BAC",
|
|
|
|
"CAB",
|
|
|
|
"BCA",
|
|
|
|
"ABC",
|
|
|
|
}
|
|
|
|
assert obs == exp
|
2020-10-14 15:03:30 +02:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"name, styles, refrules",
|
|
|
|
[
|
|
|
|
("test1", {}, {}), # empty styles
|
|
|
|
(
|
|
|
|
"test2",
|
|
|
|
{"Token.Literal.String.Single": "#ff0000"},
|
|
|
|
{"Token.Literal.String.Single": "#ff0000"},
|
|
|
|
), # str key
|
|
|
|
(
|
|
|
|
"test3",
|
|
|
|
{"Literal.String.Single": "#ff0000"},
|
|
|
|
{"Token.Literal.String.Single": "#ff0000"},
|
|
|
|
), # short str key
|
2021-05-20 15:44:26 +05:30
|
|
|
(
|
|
|
|
"test4",
|
|
|
|
{"RED": "#ff0000"},
|
|
|
|
{"Token.Color.RED": "#ff0000"},
|
|
|
|
), # color
|
2020-10-14 15:03:30 +02:00
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_register_custom_style(name, styles, refrules):
|
|
|
|
style = register_custom_style(name, styles)
|
|
|
|
if HAS_PYGMENTS:
|
|
|
|
assert style is not None
|
|
|
|
|
|
|
|
for rule, color in style.styles.items():
|
|
|
|
if str(rule) in refrules:
|
|
|
|
assert refrules[str(rule)] == color
|
2020-11-05 13:12:15 -08:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"val, exp",
|
|
|
|
[
|
|
|
|
("default", True),
|
|
|
|
("menu-complete", True),
|
|
|
|
("def", False),
|
|
|
|
("xonsh", False),
|
|
|
|
("men", False),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_is_completion_mode(val, exp):
|
|
|
|
assert is_completion_mode(val) is exp
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"val, exp",
|
|
|
|
[
|
|
|
|
("", "default"),
|
|
|
|
(None, "default"),
|
|
|
|
("default", "default"),
|
|
|
|
("DEfaULT", "default"),
|
|
|
|
("m", "menu-complete"),
|
|
|
|
("mEnu_COMPlete", "menu-complete"),
|
|
|
|
("menu-complete", "menu-complete"),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_to_completion_mode(val, exp):
|
|
|
|
assert to_completion_mode(val) == exp
|
|
|
|
|
|
|
|
|
2021-05-20 15:44:26 +05:30
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"val",
|
|
|
|
[
|
|
|
|
"de",
|
|
|
|
"defa_ult",
|
|
|
|
"men_",
|
|
|
|
"menu_",
|
|
|
|
],
|
|
|
|
)
|
2020-11-05 13:12:15 -08:00
|
|
|
def test_to_completion_mode_fail(val):
|
|
|
|
with pytest.warns(RuntimeWarning):
|
|
|
|
obs = to_completion_mode(val)
|
|
|
|
assert obs == "default"
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"val, exp",
|
|
|
|
[
|
|
|
|
("none", True),
|
|
|
|
("single", True),
|
|
|
|
("multi", True),
|
|
|
|
("", False),
|
|
|
|
(None, False),
|
|
|
|
("argle", False),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_is_completions_display_value(val, exp):
|
|
|
|
assert is_completions_display_value(val) == exp
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"val, exp",
|
|
|
|
[
|
|
|
|
("none", "none"),
|
|
|
|
(False, "none"),
|
|
|
|
("false", "none"),
|
|
|
|
("single", "single"),
|
2021-05-20 15:44:26 +05:30
|
|
|
("readline", "readline"), # todo: check this
|
2020-11-05 13:12:15 -08:00
|
|
|
("multi", "multi"),
|
|
|
|
(True, "multi"),
|
|
|
|
("TRUE", "multi"),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_to_completions_display_value(val, exp):
|
2021-05-20 15:44:26 +05:30
|
|
|
assert to_completions_display_value(val) == exp
|
2020-11-05 13:12:15 -08:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("val", [1, "", "argle"])
|
|
|
|
def test_to_completions_display_value_fail(val):
|
|
|
|
with pytest.warns(RuntimeWarning):
|
|
|
|
obs = to_completions_display_value(val)
|
|
|
|
assert obs == "multi"
|
2022-10-04 11:46:42 -07:00
|
|
|
|
|
|
|
|
|
|
|
def test_is_regex_true():
|
|
|
|
assert is_regex("cat")
|
|
|
|
|
|
|
|
|
|
|
|
def test_is_regex_false():
|
|
|
|
assert not is_regex("**")
|
2022-10-25 01:46:52 +11:00
|
|
|
|
|
|
|
|
|
|
|
from xonsh.style_tools import Token
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"val, exp",
|
|
|
|
[
|
|
|
|
(
|
|
|
|
{
|
|
|
|
Token.Literal.String: "bold ansigreen",
|
|
|
|
"Token.Name.Tag": "underline ansiblue",
|
|
|
|
},
|
|
|
|
True,
|
|
|
|
),
|
|
|
|
(
|
|
|
|
{
|
|
|
|
Token.Literal.String: "bold ansigreen",
|
|
|
|
1: "bold ansigreen",
|
|
|
|
},
|
|
|
|
False,
|
|
|
|
),
|
|
|
|
({1: "bold ansigreen"}, False),
|
|
|
|
(
|
|
|
|
{Token.Literal.String: "123"},
|
|
|
|
False,
|
|
|
|
),
|
|
|
|
(
|
|
|
|
{"Token.Name.Tag": 123},
|
|
|
|
False,
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_is_tok_color_dict(val, exp):
|
|
|
|
assert is_tok_color_dict(val) == exp
|
2024-05-06 16:18:43 +02:00
|
|
|
|
|
|
|
|
|
|
|
def test_print_exception_msg(xession, capsys):
|
|
|
|
xession.env["COLOR_INPUT"] = False
|
|
|
|
|
|
|
|
try:
|
|
|
|
a = 1 / 0
|
|
|
|
a += 1
|
|
|
|
except ZeroDivisionError:
|
|
|
|
print_exception(msg="MSG")
|
|
|
|
cap = capsys.readouterr()
|
|
|
|
assert cap.err.endswith("MSG\n"), f"captured_stderr = {cap.captured_stderr!r}"
|
|
|
|
|
|
|
|
|
|
|
|
def test_print_exception_error(xession, capsys):
|
|
|
|
xession.env["COLOR_INPUT"] = False
|
|
|
|
|
|
|
|
with xession.env.swap(XONSH_SHOW_TRACEBACK=False):
|
|
|
|
try:
|
|
|
|
raise subprocess.CalledProcessError(1, ["ls", "nofile"], output="nooutput")
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
print_exception(msg="MSG")
|
|
|
|
cap = capsys.readouterr()
|
|
|
|
match = "subprocess.CalledProcessError: Command .* returned non-zero exit status .*\nMSG\n"
|
|
|
|
assert re.match(
|
|
|
|
match,
|
|
|
|
cap.err,
|
|
|
|
re.MULTILINE | re.DOTALL,
|
feat: add superhelp and additional context via new FuncAlias (#5366)
### Goals
* Make callable aliases transparent.
* Catch errors in callable aliases and show the name of the source.
* Show additional attributes: thredable, capturable.
* Closes #5266
## Exception
### Before
```xsh
aliases['cd']
# <function xonsh.dirstack.cd>
aliases['trace']
# <function xonsh.aliases.trace>
aliases['null'] = lambda: 1/0
null
# ZeroDivisionError: division by zero
@aliases.register('catch')
@aliases.register('me')
@aliases.register('if')
@aliases.register('you')
@aliases.register('can')
def _exc(args, stdin, stdout):
for line in stdin.readlines():
print(line.strip() + '!', file=stdout, flush=True)
return 1/0 if 'i' in $__ALIAS_NAME else 0
echo hey | catch | me | if | you | can
# ZeroDivisionError: division by zero <--- ???
# hey!!!!!
```
### After
```xsh
aliases['cd']
# FuncAlias({'name': 'cd', 'func': 'cd'})
aliases['trace']
# FuncAlias({'name': 'trace', 'func': 'trace', '__xonsh_threadable__': False})
$XONSH_SHOW_TRACEBACK=False
$RAISE_SUBPROC_ERROR = False
aliases['null'] = lambda: 1/0
null
#Exception in thread {'cls': 'ProcProxyThread', 'name': 'Thread-15', 'func': FuncAlias({'name': 'null', 'func': '<lambda>'}), 'alias': 'null', 'pid': None}
#ZeroDivisionError: division by zero
@aliases.register('catch')
@aliases.register('me')
@aliases.register('if')
@aliases.register('you')
@aliases.register('can')
def _exc(args, stdin, stdout):
for line in stdin.readlines():
print(line.strip() + '!', file=stdout, flush=True)
return 1/0 if 'i' in $__ALIAS_NAME else 0
echo hey | catch | me | if | you | can
# Exception in thread {'cls': 'ProcProxyThread', 'name': 'Thread-8', 'func': FuncAlias({'name': 'if', 'func': '_exc'}), 'alias': 'if', 'pid': None}
# ZeroDivisionError: division by zero
# hey!!!!!
```
## Superhelp
### Before
```xsh
@aliases.register("hello")
def _alias_hello():
"""Show world."""
print('world')
hello?
# No manual entry for hello
```
### After
```xsh
@aliases.register("hello")
def _alias_hello():
"""Show world."""
print('world')
hello?
# FuncAlias({'name': 'hello', 'func': '_alias_hello'}):
# Show world.
```
## For community
⬇️ **Please click the 👍 reaction instead of leaving a `+1` or 👍
comment**
---------
Co-authored-by: a <1@1.1>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-05-13 15:11:58 +02:00
|
|
|
), f"\nAssert: {cap.err!r},\nexpected: {match!r}"
|
2024-05-06 16:18:43 +02:00
|
|
|
|
|
|
|
with xession.env.swap(XONSH_SHOW_TRACEBACK=True):
|
|
|
|
try:
|
|
|
|
raise subprocess.CalledProcessError(1, ["ls", "nofile"], output="nooutput")
|
|
|
|
except subprocess.CalledProcessError:
|
|
|
|
print_exception(msg="MSG")
|
|
|
|
cap = capsys.readouterr()
|
feat: add superhelp and additional context via new FuncAlias (#5366)
### Goals
* Make callable aliases transparent.
* Catch errors in callable aliases and show the name of the source.
* Show additional attributes: thredable, capturable.
* Closes #5266
## Exception
### Before
```xsh
aliases['cd']
# <function xonsh.dirstack.cd>
aliases['trace']
# <function xonsh.aliases.trace>
aliases['null'] = lambda: 1/0
null
# ZeroDivisionError: division by zero
@aliases.register('catch')
@aliases.register('me')
@aliases.register('if')
@aliases.register('you')
@aliases.register('can')
def _exc(args, stdin, stdout):
for line in stdin.readlines():
print(line.strip() + '!', file=stdout, flush=True)
return 1/0 if 'i' in $__ALIAS_NAME else 0
echo hey | catch | me | if | you | can
# ZeroDivisionError: division by zero <--- ???
# hey!!!!!
```
### After
```xsh
aliases['cd']
# FuncAlias({'name': 'cd', 'func': 'cd'})
aliases['trace']
# FuncAlias({'name': 'trace', 'func': 'trace', '__xonsh_threadable__': False})
$XONSH_SHOW_TRACEBACK=False
$RAISE_SUBPROC_ERROR = False
aliases['null'] = lambda: 1/0
null
#Exception in thread {'cls': 'ProcProxyThread', 'name': 'Thread-15', 'func': FuncAlias({'name': 'null', 'func': '<lambda>'}), 'alias': 'null', 'pid': None}
#ZeroDivisionError: division by zero
@aliases.register('catch')
@aliases.register('me')
@aliases.register('if')
@aliases.register('you')
@aliases.register('can')
def _exc(args, stdin, stdout):
for line in stdin.readlines():
print(line.strip() + '!', file=stdout, flush=True)
return 1/0 if 'i' in $__ALIAS_NAME else 0
echo hey | catch | me | if | you | can
# Exception in thread {'cls': 'ProcProxyThread', 'name': 'Thread-8', 'func': FuncAlias({'name': 'if', 'func': '_exc'}), 'alias': 'if', 'pid': None}
# ZeroDivisionError: division by zero
# hey!!!!!
```
## Superhelp
### Before
```xsh
@aliases.register("hello")
def _alias_hello():
"""Show world."""
print('world')
hello?
# No manual entry for hello
```
### After
```xsh
@aliases.register("hello")
def _alias_hello():
"""Show world."""
print('world')
hello?
# FuncAlias({'name': 'hello', 'func': '_alias_hello'}):
# Show world.
```
## For community
⬇️ **Please click the 👍 reaction instead of leaving a `+1` or 👍
comment**
---------
Co-authored-by: a <1@1.1>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-05-13 15:11:58 +02:00
|
|
|
match = ".*Traceback.*subprocess.CalledProcessError: Command .* returned non-zero exit status .*MSG\n"
|
2024-05-06 16:18:43 +02:00
|
|
|
assert re.match(
|
|
|
|
match,
|
|
|
|
cap.err,
|
|
|
|
re.MULTILINE | re.DOTALL,
|
feat: add superhelp and additional context via new FuncAlias (#5366)
### Goals
* Make callable aliases transparent.
* Catch errors in callable aliases and show the name of the source.
* Show additional attributes: thredable, capturable.
* Closes #5266
## Exception
### Before
```xsh
aliases['cd']
# <function xonsh.dirstack.cd>
aliases['trace']
# <function xonsh.aliases.trace>
aliases['null'] = lambda: 1/0
null
# ZeroDivisionError: division by zero
@aliases.register('catch')
@aliases.register('me')
@aliases.register('if')
@aliases.register('you')
@aliases.register('can')
def _exc(args, stdin, stdout):
for line in stdin.readlines():
print(line.strip() + '!', file=stdout, flush=True)
return 1/0 if 'i' in $__ALIAS_NAME else 0
echo hey | catch | me | if | you | can
# ZeroDivisionError: division by zero <--- ???
# hey!!!!!
```
### After
```xsh
aliases['cd']
# FuncAlias({'name': 'cd', 'func': 'cd'})
aliases['trace']
# FuncAlias({'name': 'trace', 'func': 'trace', '__xonsh_threadable__': False})
$XONSH_SHOW_TRACEBACK=False
$RAISE_SUBPROC_ERROR = False
aliases['null'] = lambda: 1/0
null
#Exception in thread {'cls': 'ProcProxyThread', 'name': 'Thread-15', 'func': FuncAlias({'name': 'null', 'func': '<lambda>'}), 'alias': 'null', 'pid': None}
#ZeroDivisionError: division by zero
@aliases.register('catch')
@aliases.register('me')
@aliases.register('if')
@aliases.register('you')
@aliases.register('can')
def _exc(args, stdin, stdout):
for line in stdin.readlines():
print(line.strip() + '!', file=stdout, flush=True)
return 1/0 if 'i' in $__ALIAS_NAME else 0
echo hey | catch | me | if | you | can
# Exception in thread {'cls': 'ProcProxyThread', 'name': 'Thread-8', 'func': FuncAlias({'name': 'if', 'func': '_exc'}), 'alias': 'if', 'pid': None}
# ZeroDivisionError: division by zero
# hey!!!!!
```
## Superhelp
### Before
```xsh
@aliases.register("hello")
def _alias_hello():
"""Show world."""
print('world')
hello?
# No manual entry for hello
```
### After
```xsh
@aliases.register("hello")
def _alias_hello():
"""Show world."""
print('world')
hello?
# FuncAlias({'name': 'hello', 'func': '_alias_hello'}):
# Show world.
```
## For community
⬇️ **Please click the 👍 reaction instead of leaving a `+1` or 👍
comment**
---------
Co-authored-by: a <1@1.1>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-05-13 15:11:58 +02:00
|
|
|
), f"\nAssert: {cap.err!r},\nexpected {match!r}"
|