mirror of
https://github.com/safedep/pmg.git
synced 2026-08-03 07:24:09 +02:00
139 lines
3.0 KiB
Go
139 lines
3.0 KiB
Go
package shellwords
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestSplit(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
want []string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "empty string",
|
|
input: "",
|
|
want: nil,
|
|
},
|
|
{
|
|
name: "whitespace only",
|
|
input: " \t\n ",
|
|
want: nil,
|
|
},
|
|
{
|
|
name: "single token",
|
|
input: "vi",
|
|
want: []string{"vi"},
|
|
},
|
|
{
|
|
name: "command with flag",
|
|
input: "code --wait",
|
|
want: []string{"code", "--wait"},
|
|
},
|
|
{
|
|
name: "collapses repeated whitespace",
|
|
input: "nvim -p \t -u NONE",
|
|
want: []string{"nvim", "-p", "-u", "NONE"},
|
|
},
|
|
{
|
|
name: "leading and trailing whitespace",
|
|
input: " vim ",
|
|
want: []string{"vim"},
|
|
},
|
|
{
|
|
name: "double-quoted path with spaces",
|
|
input: `"/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code" --wait`,
|
|
want: []string{
|
|
"/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code",
|
|
"--wait",
|
|
},
|
|
},
|
|
{
|
|
name: "single-quoted path with spaces",
|
|
input: `'/usr/local/bin/my editor' -f`,
|
|
want: []string{"/usr/local/bin/my editor", "-f"},
|
|
},
|
|
{
|
|
name: "backslash-escaped space",
|
|
input: `/usr/local/bin/my\ editor -f`,
|
|
want: []string{"/usr/local/bin/my editor", "-f"},
|
|
},
|
|
{
|
|
name: "double quote inside double quotes via backslash",
|
|
input: `code -e "say \"hi\""`,
|
|
want: []string{"code", "-e", `say "hi"`},
|
|
},
|
|
{
|
|
name: "single quotes inside double quotes are literal",
|
|
input: `vim "it's fine"`,
|
|
want: []string{"vim", "it's fine"},
|
|
},
|
|
{
|
|
name: "double quotes inside single quotes are literal",
|
|
input: `vim 'a "quote" here'`,
|
|
want: []string{"vim", `a "quote" here`},
|
|
},
|
|
{
|
|
name: "backslash inside single quotes is literal",
|
|
input: `vim 'a\b'`,
|
|
want: []string{"vim", `a\b`},
|
|
},
|
|
{
|
|
name: "non-special backslash in double quotes is literal",
|
|
input: `vim "a\b"`,
|
|
want: []string{"vim", `a\b`},
|
|
},
|
|
{
|
|
name: "adjacent quoted segments concatenate into one token",
|
|
input: `vim "foo"'bar'baz`,
|
|
want: []string{"vim", "foobarbaz"},
|
|
},
|
|
{
|
|
name: "empty double-quoted token",
|
|
input: `cmd "" arg`,
|
|
want: []string{"cmd", "", "arg"},
|
|
},
|
|
{
|
|
name: "empty single-quoted token",
|
|
input: `cmd '' arg`,
|
|
want: []string{"cmd", "", "arg"},
|
|
},
|
|
{
|
|
name: "unterminated double quote",
|
|
input: `vim "abc`,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "unterminated single quote",
|
|
input: `vim 'abc`,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "trailing backslash outside quotes",
|
|
input: `vim \`,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "trailing backslash inside double quotes",
|
|
input: `vim "abc\`,
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := Split(tt.input)
|
|
if tt.wantErr {
|
|
require.Error(t, err)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
assert.Equal(t, tt.want, got)
|
|
})
|
|
}
|
|
}
|