1import pexpect
2import pytest
3
4from conftest import PS1, TestUnitBase, assert_bash_exec
5
6
7@pytest.mark.bashcomp(
8    cmd=None, ignore_env=r"^[+-](COMP_(WORDS|CWORD|LINE|POINT)|_scp_path_esc)="
9)
10class TestUnitGetCword(TestUnitBase):
11    def _test(self, *args, **kwargs):
12        return self._test_unit("_get_cword %s; echo", *args, **kwargs)
13
14    def test_1(self, bash):
15        assert_bash_exec(
16            bash,
17            "COMP_WORDS=() COMP_CWORD= COMP_LINE= COMP_POINT= "
18            "_get_cword >/dev/null",
19        )
20
21    def test_2(self, bash):
22        """a b| should return b"""
23        output = self._test(bash, "(a b)", 1, "a b", 3)
24        assert output == "b"
25
26    def test_3(self, bash):
27        """a | should return nothing"""
28        output = self._test(bash, "(a)", 1, "a ", 2)
29        assert not output
30
31    def test_4(self, bash):
32        """a b | should return nothing"""
33        output = self._test(bash, "(a b '')", 2, "a b ", 4)
34        assert not output
35
36    def test_5(self, bash):
37        """a b | with WORDBREAKS -= : should return nothing"""
38        output = self._test(bash, "(a b '')", 2, "a b ", 4, arg=":")
39        assert not output
40
41    def test_6(self, bash):
42        """a b|c should return b"""
43        output = self._test(bash, "(a bc)", 1, "a bc", 3)
44        assert output == "b"
45
46    def test_7(self, bash):
47        r"""a b\ c| should return b\ c"""
48        output = self._test(bash, r"(a 'b\ c')", 1, r"a b\ c", 6)
49        assert output == r"b\ c"
50
51    def test_8(self, bash):
52        r"""a b\| c should return b\ """
53        output = self._test(bash, r"(a 'b\ c')", 1, r"a b\ c", 4)
54        assert output == "b\\"
55
56    def test_9(self, bash):
57        r"""a "b\| should return "b\ """
58        output = self._test(bash, "(a '\"b\\')", 1, r"a \"b\\", 5)
59        assert output == '"b\\'
60
61    def test_10(self, bash):
62        r"""a 'b c| should return 'b c"""
63        output = self._test(bash, '(a "\'b c")', 1, "a 'b c", 6)
64        assert output == "'b c"
65
66    def test_11(self, bash):
67        r"""a "b c| should return "b c"""
68        output = self._test(bash, "(a '\"b c')", 1, 'a "b c', 6)
69        assert output == '"b c'
70
71    def test_12(self, bash):
72        """a b:c| with WORDBREAKS += : should return c"""
73        assert_bash_exec(bash, "add_comp_wordbreak_char :")
74        output = self._test(bash, "(a b : c)", 3, "a b:c", 5)
75        assert output == "c"
76
77    def test_13(self, bash):
78        """a b:c| with WORDBREAKS -= : should return b:c"""
79        assert_bash_exec(bash, "add_comp_wordbreak_char :")
80        output = self._test(bash, "(a b : c)", 3, "a b:c", 5, arg=":")
81        assert output == "b:c"
82
83    def test_14(self, bash):
84        """a b c:| with WORDBREAKS -= : should return c:"""
85        assert_bash_exec(bash, "add_comp_wordbreak_char :")
86        output = self._test(bash, "(a b c :)", 3, "a b c:", 6, arg=":")
87        assert output == "c:"
88
89    def test_15(self, bash):
90        """a :| with WORDBREAKS -= : should return :"""
91        assert_bash_exec(bash, "add_comp_wordbreak_char :")
92        output = self._test(bash, "(a :)", 1, "a :", 3, arg=":")
93        assert output == ":"
94
95    def test_16(self, bash):
96        """a b::| with WORDBREAKS -= : should return b::"""
97        assert_bash_exec(bash, "add_comp_wordbreak_char :")
98        output = self._test(bash, "(a b::)", 1, "a b::", 5, arg=":")
99        assert output == "b::"
100
101    def test_17(self, bash):
102        """
103        a -n| should return -n
104
105        This test makes sure `_get_cword' doesn't use `echo' to return its
106        value, because -n might be interpreted by `echo' and thus woud not
107        be returned.
108        """
109        output = self._test(bash, "(a -n)", 1, "a -n", 4)
110        assert output == "-n"
111
112    def test_18(self, bash):
113        """a b>c| should return c"""
114        output = self._test(bash, r"(a b \> c)", 3, "a b>c", 5)
115        assert output == "c"
116
117    def test_19(self, bash):
118        """a b=c| should return c"""
119        output = self._test(bash, "(a b = c)", 3, "a b=c", 5)
120        assert output == "c"
121
122    def test_20(self, bash):
123        """a *| should return *"""
124        output = self._test(bash, r"(a \*)", 1, "a *", 4)
125        assert output == "*"
126
127    def test_21(self, bash):
128        """a $(b c| should return $(b c"""
129        output = self._test(bash, r"(a '$(b c')", 1, "a $(b c", 7)
130        assert output == "$(b c"
131
132    def test_22(self, bash):
133        r"""a $(b c\ d| should return $(b c\ d"""
134        output = self._test(bash, r"(a '$(b c\ d')", 1, r"a $(b c\ d", 10)
135        assert output == r"$(b c\ d"
136
137    def test_23(self, bash):
138        """a 'b&c| should return 'b&c"""
139        output = self._test(bash, '(a "\'b&c")', 1, "a 'b&c", 6)
140        assert output == "'b&c"
141
142    @pytest.mark.xfail(reason="TODO: non-ASCII issues with test suite?")
143    def test_24(self, bash):
144        """Index shouldn't drop below 0"""
145        bash.send("scp ääää§ se\t\r\n")
146        got = bash.expect_exact(
147            [
148                "index: substring expression < 0",
149                PS1,
150                pexpect.EOF,
151                pexpect.TIMEOUT,
152            ]
153        )
154        assert got == 1
155