Files

106 lines
2.4 KiB
Go

package tools
import (
"reflect"
"testing"
)
func TestShellSplitPatterns(t *testing.T) {
tests := []struct {
name string
command string
patterns []string
always []string
ok bool // false = ожидаем nil (непарсится -> безопасный отказ)
}{
{
name: "single command",
command: "cat /etc/hosts",
patterns: []string{"cat /etc/hosts"},
always: []string{"cat *"},
ok: true,
},
{
name: "chain with &&",
command: "git status && git log",
patterns: []string{"git status", "git log"},
always: []string{"git status *", "git log *"},
ok: true,
},
{
name: "chain with semicolon hides destructive",
command: "cat /etc/hosts; rm -rf /",
patterns: []string{"cat /etc/hosts", "rm -rf /"},
always: []string{"cat *", "rm *"},
ok: true,
},
{
name: "pipe",
command: "ps aux | grep sshd",
patterns: []string{"ps aux", "grep sshd"},
always: []string{"ps aux *", "grep sshd *"},
ok: true,
},
{
name: "command substitution",
command: "echo $(rm -rf /tmp)",
patterns: []string{"echo $(rm -rf /tmp)", "rm -rf /tmp"},
always: []string{"echo *", "rm *"},
ok: true,
},
{
name: "sh -c hides destructive",
command: "sh -c 'rm -rf /'",
patterns: []string{"sh -c 'rm -rf /'", "rm -rf /"},
always: []string{"sh *", "rm *"},
ok: true,
},
{
name: "quoted semicolon not split",
command: "echo 'a;b'",
patterns: []string{"echo 'a;b'"},
always: []string{"echo *"},
ok: true,
},
{
name: "redirection",
command: "echo hi > /etc/foo",
patterns: []string{"echo hi > /etc/foo"},
always: []string{"echo *"},
ok: true,
},
{
name: "unbalanced quote -> nil",
command: "echo 'unterminated",
patterns: nil,
always: nil,
ok: false,
},
{
name: "empty",
command: "",
patterns: nil,
always: nil,
ok: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p, a := shellSplitPatterns(tt.command)
if !tt.ok {
if p != nil || a != nil {
t.Fatalf("expected nil patterns/always, got %v / %v", p, a)
}
return
}
if !reflect.DeepEqual(p, tt.patterns) {
t.Fatalf("patterns = %v, want %v", p, tt.patterns)
}
if !reflect.DeepEqual(a, tt.always) {
t.Fatalf("always = %v, want %v", a, tt.always)
}
})
}
}