Skip to content

Commit 042a2cf

Browse files
committed
add testcases for shlexsplit
1 parent 0fe722e commit 042a2cf

File tree

3 files changed

+198
-4
lines changed

3 files changed

+198
-4
lines changed

api/internal/plugins/execplugin/execplugin.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import (
1212
"runtime"
1313
"strings"
1414

15-
shlex "github.com/carapace-sh/carapace-shlex"
16-
1715
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
1816
"sigs.k8s.io/kustomize/api/resmap"
1917
"sigs.k8s.io/kustomize/kyaml/errors"
@@ -95,11 +93,11 @@ func (p *ExecPlugin) processOptionalArgsFields() error {
9593
return err
9694
}
9795
if c.ArgsOneLiner != "" {
98-
argsTolenSlice, err := shlex.Split(c.ArgsOneLiner)
96+
argsTolenSlice, err := ShlexSplit(c.ArgsOneLiner)
9997
if err != nil {
10098
return fmt.Errorf("failed to parse argsOneLiner: %w", err)
10199
}
102-
p.args = argsTolenSlice.Strings()
100+
p.args = argsTolenSlice
103101
}
104102
if c.ArgsFromFile != "" {
105103
content, err := p.h.Loader().Load(c.ArgsFromFile)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2019 The Kubernetes Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package execplugin
5+
6+
import (
7+
"fmt"
8+
9+
shlex "github.com/carapace-sh/carapace-shlex"
10+
)
11+
12+
func ShlexSplit(s string) ([]string, error) {
13+
// return shlexSplit(s)
14+
tokens, err := shlex.Split(s)
15+
if err != nil {
16+
return nil, fmt.Errorf("shlex split error: %w", err)
17+
}
18+
return tokens.Strings(), nil
19+
}
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
// Copyright 2019 The Kubernetes Authors.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package execplugin
5+
6+
import (
7+
"testing"
8+
9+
"github.com/stretchr/testify/assert"
10+
)
11+
12+
func TestShlexSplit(t *testing.T) {
13+
testCases := []struct {
14+
name string
15+
input string
16+
expected []string
17+
wantErr bool
18+
}{
19+
{
20+
name: "basic space separation",
21+
input: `hello world`,
22+
expected: []string{"hello", "world"},
23+
wantErr: false,
24+
},
25+
{
26+
name: "double quoted string",
27+
input: `"hello world"`,
28+
expected: []string{"hello world"},
29+
wantErr: false,
30+
},
31+
{
32+
name: "single quoted string",
33+
input: `'hello world'`,
34+
expected: []string{"hello world"},
35+
wantErr: false,
36+
},
37+
{
38+
name: "mixed quotes and words",
39+
input: `hello "world test"`,
40+
expected: []string{"hello", "world test"},
41+
wantErr: false,
42+
},
43+
{
44+
name: "single quotes with spaces",
45+
input: `hello 'world test'`,
46+
expected: []string{"hello", "world test"},
47+
wantErr: false,
48+
},
49+
{
50+
name: "nested quotes - single in double",
51+
input: `"hello 'nested' world"`,
52+
expected: []string{"hello 'nested' world"},
53+
wantErr: false,
54+
},
55+
{
56+
name: "nested quotes - double in single",
57+
input: `'hello "nested" world'`,
58+
expected: []string{"hello \"nested\" world"},
59+
wantErr: false,
60+
},
61+
{
62+
name: "escaped space",
63+
input: `hello\ world`,
64+
expected: []string{"hello world"},
65+
wantErr: false,
66+
},
67+
{
68+
name: "escaped quotes in double quotes",
69+
input: `"hello \"world\""`,
70+
expected: []string{"hello \"world\""},
71+
wantErr: false,
72+
},
73+
{
74+
name: "single quote in single quotes",
75+
input: `'can'\''t'`,
76+
expected: []string{"can't"},
77+
wantErr: false,
78+
},
79+
{
80+
name: "complex argument list",
81+
input: `arg1 "arg 2" 'arg 3' arg4`,
82+
expected: []string{"arg1", "arg 2", "arg 3", "arg4"},
83+
wantErr: false,
84+
},
85+
{
86+
name: "echo command with escaped quotes",
87+
input: `echo "Hello, \"World!\""`,
88+
expected: []string{"echo", "Hello, \"World!\""},
89+
wantErr: false,
90+
},
91+
{
92+
name: "grep command with quoted search term",
93+
input: `grep -r "search term" /path/to/dir`,
94+
expected: []string{"grep", "-r", "search term", "/path/to/dir"},
95+
wantErr: false,
96+
},
97+
{
98+
name: "ls command with quoted filename",
99+
input: `ls -la "file with spaces.txt"`,
100+
expected: []string{"ls", "-la", "file with spaces.txt"},
101+
wantErr: false,
102+
},
103+
{
104+
name: "empty string",
105+
input: ``,
106+
expected: []string{""},
107+
wantErr: false,
108+
},
109+
{
110+
name: "multiple spaces",
111+
input: ` multiple spaces `,
112+
expected: []string{"multiple", "spaces", ""},
113+
wantErr: false,
114+
},
115+
{
116+
name: "with comment string",
117+
input: `echo "Hello, W#orld!" ${USER} # This is a comment`,
118+
expected: []string{"echo", "Hello, W#orld!", "${USER}"},
119+
wantErr: false,
120+
},
121+
// may cause an error in shlex at python3
122+
{
123+
name: "unclosed double quote",
124+
input: `"unclosed quote`,
125+
expected: []string{"unclosed quote"},
126+
wantErr: false,
127+
},
128+
{
129+
name: "unclosed single quote",
130+
input: `'unclosed quote`,
131+
expected: []string{"unclosed quote"},
132+
wantErr: false,
133+
},
134+
{
135+
name: "mixed unclosed quotes",
136+
input: `"mixed 'quotes`,
137+
expected: []string{"mixed 'quotes"},
138+
wantErr: false,
139+
},
140+
{
141+
name: "single quote closed with double quote",
142+
input: `"hello world'`,
143+
expected: []string{"hello world'"},
144+
wantErr: false,
145+
},
146+
{
147+
name: "double quote closed with single quote",
148+
input: `'hello world"`,
149+
expected: []string{"hello world\""},
150+
wantErr: false,
151+
},
152+
}
153+
154+
// execute each test case
155+
for _, tc := range testCases {
156+
t.Run(tc.name, func(t *testing.T) {
157+
// call the ShlexSplit function
158+
result, err := ShlexSplit(tc.input)
159+
160+
// check for expected error
161+
if tc.wantErr {
162+
if err == nil {
163+
t.Errorf("FAIL: Expected error but got none, Expected: %q\n", tc.expected)
164+
}
165+
return
166+
}
167+
168+
if assert.NoError(t, err, "FAIL: Unexpected error for input %q", tc.input) {
169+
// check if the result matches the expected output
170+
assert.Equal(t, tc.expected, result,
171+
"FAIL: Result mismatch,Input %q, Expected %q, Got: %q\n",
172+
tc.input, tc.expected, result,
173+
)
174+
}
175+
})
176+
}
177+
}

0 commit comments

Comments
 (0)