diff options
Diffstat (limited to 'test/t/unit')
-rw-r--r-- | test/t/unit/Makefile.am | 19 | ||||
-rw-r--r-- | test/t/unit/test_unit_count_args.py | 66 | ||||
-rw-r--r-- | test/t/unit/test_unit_expand.py | 13 | ||||
-rw-r--r-- | test/t/unit/test_unit_expand_tilde_by_ref.py | 16 | ||||
-rw-r--r-- | test/t/unit/test_unit_filedir.py | 9 | ||||
-rw-r--r-- | test/t/unit/test_unit_find_unique_completion_pair.py | 55 | ||||
-rw-r--r-- | test/t/unit/test_unit_get_comp_words_by_ref.py | 167 | ||||
-rw-r--r-- | test/t/unit/test_unit_get_cword.py | 135 | ||||
-rw-r--r-- | test/t/unit/test_unit_init_completion.py | 24 | ||||
-rw-r--r-- | test/t/unit/test_unit_ip_addresses.py | 49 | ||||
-rw-r--r-- | test/t/unit/test_unit_longopt.py | 34 | ||||
-rw-r--r-- | test/t/unit/test_unit_parse_help.py | 183 | ||||
-rw-r--r-- | test/t/unit/test_unit_parse_usage.py | 69 | ||||
-rw-r--r-- | test/t/unit/test_unit_tilde.py | 42 |
14 files changed, 881 insertions, 0 deletions
diff --git a/test/t/unit/Makefile.am b/test/t/unit/Makefile.am new file mode 100644 index 00000000..a0ab7502 --- /dev/null +++ b/test/t/unit/Makefile.am @@ -0,0 +1,19 @@ +EXTRA_DIST = \ + test_unit_count_args.py \ + test_unit_expand.py \ + test_unit_expand_tilde_by_ref.py \ + test_unit_filedir.py \ + test_unit_find_unique_completion_pair.py \ + test_unit_get_comp_words_by_ref.py \ + test_unit_get_cword.py \ + test_unit_init_completion.py \ + test_unit_ip_addresses.py \ + test_unit_longopt.py \ + test_unit_parse_help.py \ + test_unit_parse_usage.py \ + test_unit_tilde.py + +all: + +clean-local: + $(RM) -R __pycache__ diff --git a/test/t/unit/test_unit_count_args.py b/test/t/unit/test_unit_count_args.py new file mode 100644 index 00000000..c0afe736 --- /dev/null +++ b/test/t/unit/test_unit_count_args.py @@ -0,0 +1,66 @@ +import pytest + +from conftest import assert_bash_exec, TestUnitBase + + +@pytest.mark.bashcomp( + cmd=None, ignore_env=r"^[+-](args|COMP_(WORDS|CWORD|LINE|POINT))=" +) +class TestUnitCountArgs(TestUnitBase): + def _test(self, *args, **kwargs): + return self._test_unit("_count_args %s; echo $args", *args, **kwargs) + + def test_1(self, bash): + assert_bash_exec(bash, "_count_args >/dev/null") + + def test_2(self, bash): + """a b| should set args to 1""" + output = self._test(bash, "(a b)", 1, "a b", 3) + assert output == "1" + + def test_3(self, bash): + """a b|c should set args to 1""" + output = self._test(bash, "(a bc)", 1, "a bc", 3) + assert output == "1" + + def test_4(self, bash): + """a b c| should set args to 2""" + output = self._test(bash, "(a b c)", 2, "a b c", 4) + assert output == "2" + + def test_5(self, bash): + """a b| c should set args to 1""" + output = self._test(bash, "(a b c)", 1, "a b c", 3) + assert output == "1" + + def test_6(self, bash): + """a b -c| d should set args to 2""" + output = self._test(bash, "(a b -c d)", 2, "a b -c d", 6) + assert output == "2" + + def test_7(self, bash): + """a b -c d e| with -c arg excluded should set args to 2""" + output = self._test( + bash, "(a b -c d e)", 4, "a b -c d e", 10, arg='"" "@(-c|--foo)"' + ) + assert output == "2" + + def test_8(self, bash): + """a -b -c d e| with -c arg excluded + and -b included should set args to 1""" + output = self._test( + bash, + "(a -b -c d e)", + 4, + "a -b -c d e", + 11, + arg='"" "@(-c|--foo)" "-[b]"', + ) + assert output == "2" + + def test_9(self, bash): + """a -b -c d e| with -b included should set args to 3""" + output = self._test( + bash, "(a -b -c d e)", 4, "a -b -c d e", 11, arg='"" "" "-b"' + ) + assert output == "3" diff --git a/test/t/unit/test_unit_expand.py b/test/t/unit/test_unit_expand.py new file mode 100644 index 00000000..7c0a9836 --- /dev/null +++ b/test/t/unit/test_unit_expand.py @@ -0,0 +1,13 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None) +class TestUnitExpand: + def test_1(self, bash): + assert_bash_exec(bash, "_expand >/dev/null") + + def test_2(self, bash): + """Test environment non-pollution, detected at teardown.""" + assert_bash_exec(bash, "foo() { _expand; }; foo; unset foo") diff --git a/test/t/unit/test_unit_expand_tilde_by_ref.py b/test/t/unit/test_unit_expand_tilde_by_ref.py new file mode 100644 index 00000000..fbc172df --- /dev/null +++ b/test/t/unit/test_unit_expand_tilde_by_ref.py @@ -0,0 +1,16 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None) +class TestUnitExpandTildeByRef: + def test_1(self, bash): + assert_bash_exec(bash, "__expand_tilde_by_ref >/dev/null") + + def test_2(self, bash): + """Test environment non-pollution, detected at teardown.""" + assert_bash_exec( + bash, + '_x() { local aa="~"; __expand_tilde_by_ref aa; }; _x; unset _x', + ) diff --git a/test/t/unit/test_unit_filedir.py b/test/t/unit/test_unit_filedir.py new file mode 100644 index 00000000..dcd52403 --- /dev/null +++ b/test/t/unit/test_unit_filedir.py @@ -0,0 +1,9 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+COMPREPLY=") +class TestUnitFiledir: + def test_1(self, bash): + assert_bash_exec(bash, "_filedir >/dev/null") diff --git a/test/t/unit/test_unit_find_unique_completion_pair.py b/test/t/unit/test_unit_find_unique_completion_pair.py new file mode 100644 index 00000000..25cf9d3b --- /dev/null +++ b/test/t/unit/test_unit_find_unique_completion_pair.py @@ -0,0 +1,55 @@ +import pytest + +from conftest import find_unique_completion_pair + + +@pytest.mark.bashcomp(cmd=None) +class TestUnitFindUniqueCompletionPair: + def _test(self, inp: str, exp: str) -> None: + res = find_unique_completion_pair(inp.split()) + if exp: + part, cont = exp.split() + assert res == (part, part + cont) + else: + assert not exp + + def test_1(self): + self._test("a", "") + + def test_2(self): + self._test("ab", "a b") + + def test_3(self): + self._test("ab ab ab", "a b") + + def test_4(self): + self._test("a ab abcd abc", "") + + def test_5(self): + self._test("user1 user2", "") + + def test_6(self): + self._test("root username1 username2", "ro ot") + + def test_7(self): + self._test("root username21 username2", "ro ot") + + def test_8(self): + self._test( + "long_user_name lang_user_name long_usor_name", "lang_us er_name" + ) + + def test_9(self): + self._test( + "lang_user_name1 long_user_name lang_user_name long_usor_name", + "long_use r_name", + ) + + def test_10(self): + self._test("root username", "user name") + + def test_11(self): + self._test("a aladin", "ala din") + + def test_12(self): + self._test("ala aladin", "alad in") diff --git a/test/t/unit/test_unit_get_comp_words_by_ref.py b/test/t/unit/test_unit_get_comp_words_by_ref.py new file mode 100644 index 00000000..1603bad6 --- /dev/null +++ b/test/t/unit/test_unit_get_comp_words_by_ref.py @@ -0,0 +1,167 @@ +import pytest + +from conftest import assert_bash_exec, TestUnitBase + + +@pytest.mark.bashcomp( + cmd=None, ignore_env=r"^(\+(cur|prev)|[+-]COMP_(WORDS|CWORD|LINE|POINT))=" +) +class TestUnitGetCompWordsByRef(TestUnitBase): + def _test(self, bash, *args, **kwargs): + assert_bash_exec(bash, "unset cur prev") + output = self._test_unit( + "_get_comp_words_by_ref %s cur prev; echo $cur,$prev", + bash, + *args, + **kwargs + ) + return output.strip() + + def test_1(self, bash): + assert_bash_exec(bash, "_get_comp_words_by_ref cur >/dev/null") + + def test_2(self, bash): + """a b|""" + output = self._test(bash, "(a b)", 1, "a b", 3) + assert output == "b,a" + + def test_3(self, bash): + """a |""" + output = self._test(bash, "(a)", 1, "a ", 2) + assert output == ",a" + + def test_4(self, bash): + """|a""" + output = self._test(bash, "(a)", 0, "a", 0) + assert output == "," + + def test_5(self, bash): + """|a """ + output = self._test(bash, "(a)", 0, "a ", 0) + assert output == "," + + def test_6(self, bash): + """ | a """ + output = self._test(bash, "(a)", 0, " a ", 1) + assert output.strip() == "," + + def test_7(self, bash): + """a b |""" + output = self._test(bash, "(a b '')", 2, "a b ", 4) + assert output == ",b" + + def test_8(self, bash): + """a b | with WORDBREAKS -= :""" + output = self._test(bash, "(a b '')", 2, "a b ", 4, arg="-n :") + assert output == ",b" + + def test_9(self, bash): + """a b|c""" + output = self._test(bash, "(a bc)", 1, "a bc", 3) + assert output == "b,a" + + def test_10(self, bash): + """a | b""" + output = self._test(bash, "(a b)", 1, "a b", 2) + assert output == ",a" + + def test_11(self, bash): + r"""a b\ c|""" + output = self._test(bash, r"(a 'b\ c')", 1, r"a b\ c", 6) + assert output == r"b\ c,a" + + def test_12(self, bash): + r"""a\ b a\ b|""" + output = self._test(bash, r"('a\ b' 'a\ b')", 1, r"a\ b a\ b", 9) + assert output == r"a\ b,a\ b" + + def test_13(self, bash): + r"""a b\| c""" + output = self._test(bash, r"(a 'b\ c')", 1, r"a b\ c", 4) + assert output == r"b\,a" + + def test_14(self, bash): + r"""a "b\|""" + output = self._test(bash, "(a '\"b')", 1, 'a "b\\', 5) + assert output == r'"b\,a' + + def test_15(self, bash): + """a 'b c|""" + output = self._test(bash, '(a "\'b c")', 1, "a 'b c", 6) + assert output == "'b c,a" + + def test_16(self, bash): + """a "b c|""" + output = self._test(bash, r'(a "\"b c")', 1, 'a "b c', 6) + assert output == '"b c,a' + + def test_17(self, bash): + """a b:c| with WORDBREAKS += :""" + assert_bash_exec(bash, "add_comp_wordbreak_char :") + output = self._test(bash, "(a b : c)", 3, "a b:c", 5) + assert output == "c,:" + + def test_18(self, bash): + """a b:c| with WORDBREAKS -= :""" + output = self._test(bash, "(a b : c)", 3, "a b:c", 5, arg="-n :") + assert output == "b:c,a" + + def test_19(self, bash): + """a b c:| with WORDBREAKS -= :""" + output = self._test(bash, "(a b c :)", 3, "a b c:", 6, arg="-n :") + assert output == "c:,b" + + def test_20(self, bash): + r"""a b:c | with WORDBREAKS -= :""" + output = self._test(bash, "(a b : c '')", 4, "a b:c ", 6, arg="-n :") + assert output == ",b:c" + + def test_21(self, bash): + """a :| with WORDBREAKS -= :""" + output = self._test(bash, "(a :)", 1, "a :", 3, arg="-n :") + assert output == ":,a" + + def test_22(self, bash): + """a b::| with WORDBREAKS -= :""" + output = self._test(bash, "(a b ::)", 2, "a b::", 5, arg="-n :") + assert output == "b::,a" + + def test_23(self, bash): + """a -n| + + This test makes sure `_get_cword' doesn't use `echo' to return its + value, because -n might be interpreted by `echo' and thus woud not + be returned. + """ + output = self._test(bash, "(a -n)", 1, "a -n", 4) + assert output == "-n,a" + + def test_24(self, bash): + """a b>c|""" + output = self._test(bash, r"(a b \> c)", 3, "a b>c", 5) + assert output.startswith("c,") + + def test_25(self, bash): + """a b=c|""" + output = self._test(bash, "(a b = c)", 3, "a b=c", 5) + assert output.startswith("c,") + + def test_26(self, bash): + """a *|""" + output = self._test(bash, r"(a \*)", 1, "a *", 4) + assert output == "*,a" + + def test_27(self, bash): + """a $(b c|""" + output = self._test(bash, "(a '$(b c')", 1, "a $(b c", 7) + assert output == "$(b c,a" + + def test_28(self, bash): + r"""a $(b c\ d|""" + output = self._test(bash, r"(a '$(b c\ d')", 1, r"a $(b c\ d", 10) + assert output == r"$(b c\ d,a" + + def test_29(self, bash): + """a 'b&c|""" + output = self._test(bash, '(a "\'b&c")', 1, "a 'b&c", 6) + assert output == "'b&c,a" diff --git a/test/t/unit/test_unit_get_cword.py b/test/t/unit/test_unit_get_cword.py new file mode 100644 index 00000000..3042dd29 --- /dev/null +++ b/test/t/unit/test_unit_get_cword.py @@ -0,0 +1,135 @@ +import pytest + +from conftest import assert_bash_exec, TestUnitBase + + +@pytest.mark.bashcomp( + cmd=None, ignore_env=r"^[+-]COMP_(WORDS|CWORD|LINE|POINT)=" +) +class TestUnitGetCword(TestUnitBase): + def _test(self, *args, **kwargs): + return self._test_unit("_get_cword %s; echo", *args, **kwargs) + + def test_1(self, bash): + assert_bash_exec(bash, "_get_cword >/dev/null") + + def test_2(self, bash): + """a b| should return b""" + output = self._test(bash, "(a b)", 1, "a b", 3) + assert output == "b" + + def test_3(self, bash): + """a | should return nothing""" + output = self._test(bash, "(a)", 1, "a ", 2) + assert not output + + def test_4(self, bash): + """a b | should return nothing""" + output = self._test(bash, "(a b '')", 2, "a b ", 4) + assert not output + + def test_5(self, bash): + """a b | with WORDBREAKS -= : should return nothing""" + output = self._test(bash, "(a b '')", 2, "a b ", 4, arg=":") + assert not output + + def test_6(self, bash): + """a b|c should return b""" + output = self._test(bash, "(a bc)", 1, "a bc", 3) + assert output == "b" + + def test_7(self, bash): + r"""a b\ c| should return b\ c""" + output = self._test(bash, r"(a 'b\ c')", 1, r"a b\ c", 6) + assert output == r"b\ c" + + def test_8(self, bash): + r"""a b\| c should return b\ """ + output = self._test(bash, r"(a 'b\ c')", 1, r"a b\ c", 4) + assert output == "b\\" + + def test_9(self, bash): + r"""a "b\| should return "b\ """ + output = self._test(bash, "(a '\"b\\')", 1, r"a \"b\\", 5) + assert output == '"b\\' + + def test_10(self, bash): + r"""a 'b c| should return 'b c""" + output = self._test(bash, '(a "\'b c")', 1, "a 'b c", 6) + assert output == "'b c" + + def test_11(self, bash): + r"""a "b c| should return "b c""" + output = self._test(bash, "(a '\"b c')", 1, 'a "b c', 6) + assert output == '"b c' + + def test_12(self, bash): + """a b:c| with WORDBREAKS += : should return c""" + assert_bash_exec(bash, "add_comp_wordbreak_char :") + output = self._test(bash, "(a b : c)", 3, "a b:c", 5) + assert output == "c" + + def test_13(self, bash): + """a b:c| with WORDBREAKS -= : should return b:c""" + assert_bash_exec(bash, "add_comp_wordbreak_char :") + output = self._test(bash, "(a b : c)", 3, "a b:c", 5, arg=":") + assert output == "b:c" + + def test_14(self, bash): + """a b c:| with WORDBREAKS -= : should return c:""" + assert_bash_exec(bash, "add_comp_wordbreak_char :") + output = self._test(bash, "(a b c :)", 3, "a b c:", 6, arg=":") + assert output == "c:" + + def test_15(self, bash): + """a :| with WORDBREAKS -= : should return :""" + assert_bash_exec(bash, "add_comp_wordbreak_char :") + output = self._test(bash, "(a :)", 1, "a :", 3, arg=":") + assert output == ":" + + def test_16(self, bash): + """a b::| with WORDBREAKS -= : should return b::""" + assert_bash_exec(bash, "add_comp_wordbreak_char :") + output = self._test(bash, "(a b::)", 1, "a b::", 5, arg=":") + assert output == "b::" + + def test_17(self, bash): + """ + a -n| should return -n + + This test makes sure `_get_cword' doesn't use `echo' to return its + value, because -n might be interpreted by `echo' and thus woud not + be returned. + """ + output = self._test(bash, "(a -n)", 1, "a -n", 4) + assert output == "-n" + + def test_18(self, bash): + """a b>c| should return c""" + output = self._test(bash, r"(a b \> c)", 3, "a b>c", 5) + assert output == "c" + + def test_19(self, bash): + """a b=c| should return c""" + output = self._test(bash, "(a b = c)", 3, "a b=c", 5) + assert output == "c" + + def test_20(self, bash): + """a *| should return *""" + output = self._test(bash, r"(a \*)", 1, "a *", 4) + assert output == "*" + + def test_21(self, bash): + """a $(b c| should return $(b c""" + output = self._test(bash, r"(a '$(b c')", 1, "a $(b c", 7) + assert output == "$(b c" + + def test_22(self, bash): + r"""a $(b c\ d| should return $(b c\ d""" + output = self._test(bash, r"(a '$(b c\ d')", 1, r"a $(b c\ d", 10) + assert output == r"$(b c\ d" + + def test_23(self, bash): + """a 'b&c| should return 'b&c""" + output = self._test(bash, '(a "\'b&c")', 1, "a 'b&c", 6) + assert output == "'b&c" diff --git a/test/t/unit/test_unit_init_completion.py b/test/t/unit/test_unit_init_completion.py new file mode 100644 index 00000000..64f3b511 --- /dev/null +++ b/test/t/unit/test_unit_init_completion.py @@ -0,0 +1,24 @@ +import pytest + +from conftest import assert_bash_exec, TestUnitBase + + +@pytest.mark.bashcomp( + cmd=None, + ignore_env=r"^[+-](COMP(_(WORDS|CWORD|LINE|POINT)|REPLY)|" + r"cur|cword|words)=", +) +class TestUnitInitCompletion(TestUnitBase): + def test_1(self, bash): + """Test environment non-pollution, detected at teardown.""" + assert_bash_exec( + bash, + "foo() { local cur prev words cword; _init_completion; }; " + "foo; unset foo", + ) + + def test_2(self, bash): + output = self._test_unit( + "_init_completion %s; echo $cur,$prev", bash, "(a)", 0, "a", 0 + ) + assert output == "," diff --git a/test/t/unit/test_unit_ip_addresses.py b/test/t/unit/test_unit_ip_addresses.py new file mode 100644 index 00000000..cd7a38ab --- /dev/null +++ b/test/t/unit/test_unit_ip_addresses.py @@ -0,0 +1,49 @@ +import pytest + +from conftest import assert_bash_exec, in_docker + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+COMPREPLY=") +class TestUnitIpAddresses: + @pytest.fixture(scope="class") + def functions(self, request, bash): + assert_bash_exec( + bash, + "_ia() { local cur=$(_get_cword);unset COMPREPLY;" + "_ip_addresses; }", + ) + assert_bash_exec(bash, "complete -F _ia ia") + assert_bash_exec( + bash, + "_iaa() { local cur=$(_get_cword);unset COMPREPLY;" + "_ip_addresses -a; }", + ) + assert_bash_exec(bash, "complete -F _iaa iaa") + assert_bash_exec( + bash, + " _ia6() { local cur=$(_get_cword);unset COMPREPLY;" + "_ip_addresses -6; }", + ) + assert_bash_exec(bash, "complete -F _ia6 ia6") + + def test_1(self, bash): + assert_bash_exec(bash, "_ip_addresses") + + @pytest.mark.complete("iaa ") + def test_2(self, functions, completion): + """_ip_addresses -a should complete ip addresses.""" + assert completion + assert all("." in x or ":" in x for x in completion) + + @pytest.mark.complete("ia ") + def test_3(self, functions, completion): + """_ip_addresses should complete ipv4 addresses.""" + assert completion + assert all("." in x for x in completion) + + @pytest.mark.xfail(in_docker(), reason="Probably fails in docker") + @pytest.mark.complete("ia6 ") + def test_4(self, functions, completion): + """_ip_addresses -6 should complete ipv6 addresses.""" + assert completion + assert all(":" in x for x in completion) diff --git a/test/t/unit/test_unit_longopt.py b/test/t/unit/test_unit_longopt.py new file mode 100644 index 00000000..ac0ac836 --- /dev/null +++ b/test/t/unit/test_unit_longopt.py @@ -0,0 +1,34 @@ +# Based on work by Stephen Gildea, October 2010. + +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+COMPREPLY=") +class TestUnitLongopt: + @pytest.fixture(scope="class") + def functions(self, request, bash): + assert_bash_exec(bash, "_grephelp() { cat _longopt/grep--help.txt; }") + assert_bash_exec(bash, "complete -F _longopt _grephelp") + + @pytest.mark.complete("_grephelp --") + def test_1(self, functions, completion): + """First long option should be included""" + assert completion + assert all( + x in completion for x in "--quiet --recursive --text".split() + ) + + @pytest.mark.complete("_grephelp -") + def test_2(self, functions, completion): + """Only long options should be included""" + assert completion + assert all(x.startswith("--") for x in completion) + + @pytest.mark.complete("_grephelp --") + def test_3(self, functions, completion): + """Should have both ones ending with a = and ones not""" + assert completion + assert any(x.endswith("=") for x in completion) + assert any(not x.endswith("=") for x in completion) diff --git a/test/t/unit/test_unit_parse_help.py b/test/t/unit/test_unit_parse_help.py new file mode 100644 index 00000000..4a02155b --- /dev/null +++ b/test/t/unit/test_unit_parse_help.py @@ -0,0 +1,183 @@ +# Based on work by Stephen Gildea, October 2010. + +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+declare -f fn$") +class TestUnitParseHelp: + def test_1(self, bash): + assert_bash_exec(bash, "fn() { echo; }") + output = assert_bash_exec(bash, "_parse_help fn") + assert not output + + def test_2(self, bash): + assert_bash_exec(bash, "fn() { echo 'no dashes here'; }") + output = assert_bash_exec(bash, "_parse_help fn") + assert not output + + def test_3(self, bash): + assert_bash_exec(bash, "fn() { echo 'internal-dash'; }") + output = assert_bash_exec(bash, "_parse_help fn") + assert not output + + def test_4(self, bash): + assert_bash_exec(bash, "fn() { echo 'no -leading-dashes'; }") + output = assert_bash_exec(bash, "_parse_help fn") + assert not output + + def test_5(self, bash): + assert_bash_exec(bash, "fn() { echo '-one dash'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "-one".split() + + def test_6(self, bash): + assert_bash_exec(bash, "fn() { echo ' -space dash'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "-space".split() + + def test_7(self, bash): + assert_bash_exec(bash, "fn() { echo '-one -two dashes'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "-one".split() + + def test_8(self, bash): + assert_bash_exec(bash, "fn() { echo '-one,-t dashes'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "-one".split() + + def test_9(self, bash): + assert_bash_exec(bash, "fn() { echo '-one dash-inside'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "-one".split() + + def test_10(self, bash): + """Test value not included in completion.""" + assert_bash_exec(bash, "fn() { echo '--long-arg=value'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--long-arg=".split() + + def test_11(self, bash): + """Test -value not seen as option.""" + assert_bash_exec(bash, "fn() { echo '--long-arg=-value'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--long-arg=".split() + + def test_12(self, bash): + assert_bash_exec(bash, "fn() { echo '--long-arg=-value,--opt2=val'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--long-arg=".split() + + def test_13(self, bash): + assert_bash_exec(bash, "fn() { echo '-m,--mirror'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--mirror".split() + + def test_14(self, bash): + assert_bash_exec(bash, "fn() { echo '-T/--upload-file'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--upload-file".split() + + def test_15(self, bash): + assert_bash_exec(bash, "fn() { echo '-T|--upload-file'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--upload-file".split() + + def test_16(self, bash): + assert_bash_exec(bash, "fn() { echo '-f, -F, --foo'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo".split() + + def test_17(self, bash): + assert_bash_exec(bash, "fn() { echo '--foo[=bar]'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo".split() + + def test_18(self, bash): + assert_bash_exec(bash, "fn() { echo '--foo=<bar>'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo=".split() + + def test_19(self, bash): + assert_bash_exec(bash, "fn() { echo '--foo={bar,quux}'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo=".split() + + def test_20(self, bash): + assert_bash_exec(bash, "fn() { echo '--[no]foo'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo --nofoo".split() + + def test_21(self, bash): + assert_bash_exec(bash, "fn() { echo '--[no-]bar[=quux]'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--bar --no-bar".split() + + def test_22(self, bash): + assert_bash_exec(bash, "fn() { echo '--[no-]bar=quux'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--bar= --no-bar=".split() + + def test_23(self, bash): + assert_bash_exec(bash, "fn() { echo '--[dont-]foo'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo --dont-foo".split() + + def test_24(self, bash): + assert_bash_exec(bash, "fn() { echo '-[dont]x --[dont]yy'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--yy --dontyy".split() + + def test_25(self, bash): + assert_bash_exec(bash, "fn() { echo '-f FOO, --foo=FOO'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo=".split() + + def test_26(self, bash): + assert_bash_exec(bash, "fn() { echo '-f [FOO], --foo[=FOO]'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo".split() + + def test_27(self, bash): + assert_bash_exec(bash, "fn() { echo '--foo.'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo".split() + + def test_28(self, bash): + assert_bash_exec(bash, "fn() { echo '-f or --foo'; }") + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--foo".split() + + def test_29(self, bash): + """Test parsing from stdin.""" + output = assert_bash_exec( + bash, "echo '-f or --foo' | _parse_help -", want_output=True + ) + assert output.split() == "--foo".split() + + def test_30(self, bash): + """More than two dashes should not be treated as options.""" + assert_bash_exec( + bash, r"fn() { printf '%s\n' $'----\n---foo\n----- bar'; }" + ) + output = assert_bash_exec(bash, "_parse_help fn") + assert not output + + def test_31(self, bash): + assert_bash_exec( + bash, + r"fn() { printf '%s\n' " + r"'-F ERROR_FORMAT, --error-format ERROR_FORMAT'; }", + ) + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--error-format".split() + + def test_32(self, bash): + assert_bash_exec( + bash, + r"fn() { printf '%s\n' " + r"'-e CODE1,CODE2.. --exclude=CODE1,CODE2..'; }", + ) + output = assert_bash_exec(bash, "_parse_help fn", want_output=True) + assert output.split() == "--exclude=".split() diff --git a/test/t/unit/test_unit_parse_usage.py b/test/t/unit/test_unit_parse_usage.py new file mode 100644 index 00000000..f0cb7114 --- /dev/null +++ b/test/t/unit/test_unit_parse_usage.py @@ -0,0 +1,69 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+declare -f fn$") +class TestUnitParseUsage: + def test_1(self, bash): + assert_bash_exec(bash, "fn() { echo; }") + output = assert_bash_exec(bash, "_parse_usage fn") + assert not output + + def test_2(self, bash): + assert_bash_exec(bash, "fn() { echo 'no dashes here'; }") + output = assert_bash_exec(bash, "_parse_usage fn") + assert not output + + def test_3(self, bash): + assert_bash_exec(bash, "fn() { echo 'foo [-f]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "-f".split() + + def test_4(self, bash): + assert_bash_exec(bash, "fn() { echo 'bar [-aBcD] [-e X]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "-a -B -c -D -e".split() + + def test_5(self, bash): + assert_bash_exec(bash, "fn() { echo '[-[XyZ]] [--long=arg]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "-X -y -Z --long=".split() + + def test_6(self, bash): + assert_bash_exec(bash, "fn() { echo '[-s|--long]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "--long".split() + + def test_7(self, bash): + assert_bash_exec(bash, "fn() { echo '[-s, --long=arg]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "--long=".split() + + def test_8(self, bash): + assert_bash_exec(bash, "fn() { echo '[--long/-s] [-S/--longer]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "--long --longer".split() + + def test_9(self, bash): + assert_bash_exec(bash, "fn() { echo '[ -a ] [ -b foo ]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "-a -b".split() + + def test_10(self, bash): + assert_bash_exec(bash, "fn() { echo '[ -a | --aa ]'; }") + output = assert_bash_exec(bash, "_parse_usage fn", want_output=True) + assert output.split() == "--aa".split() + + def test_11(self, bash): + assert_bash_exec( + bash, "fn() { echo ----; echo ---foo; echo '----- bar'; }" + ) + output = assert_bash_exec(bash, "_parse_usage fn") + assert not output + + def test_12(self, bash): + output = assert_bash_exec( + bash, "echo '[-duh]' | _parse_usage -", want_output=True + ) + assert output.split() == "-d -u -h".split() diff --git a/test/t/unit/test_unit_tilde.py b/test/t/unit/test_unit_tilde.py new file mode 100644 index 00000000..35a4e4c6 --- /dev/null +++ b/test/t/unit/test_unit_tilde.py @@ -0,0 +1,42 @@ +import pytest + +from conftest import assert_bash_exec + + +@pytest.mark.bashcomp(cmd=None, ignore_env=r"^\+COMPREPLY=") +class TestUnitTilde: + def test_1(self, bash): + assert_bash_exec(bash, "_tilde >/dev/null") + + def test_2(self, bash): + """Test environment non-pollution, detected at teardown.""" + assert_bash_exec( + bash, 'foo() { local aa="~"; _tilde "$aa"; }; foo; unset foo' + ) + + def test_3(self, bash): + """Test for https://bugs.debian.org/766163""" + assert_bash_exec(bash, "_tilde ~-o") + + def _test_part_full(self, bash, part, full): + res = ( + assert_bash_exec( + bash, + '_tilde "~%s"; echo "${COMPREPLY[@]}"' % part, + want_output=True, + ) + .strip() + .split() + ) + assert res + assert res[0] == "~%s" % full + + def test_4(self, bash, part_full_user): + """~full should complete to ~full unmodified.""" + _, full = part_full_user + self._test_part_full(bash, full, full) + + def test_5(self, bash, part_full_user): + """~part should complete to ~full.""" + part, full = part_full_user + self._test_part_full(bash, part, full) |