blob: 40e1bb08ba1cadac49a7f5f4b6576a7dd9ef86c5 [file] [log] [blame]
Josh Bleecher Snyder495c1fa2025-05-29 00:37:22 +00001package bashkit
2
3import (
4 "reflect"
5 "testing"
6)
7
8func TestExtractCommands(t *testing.T) {
9 tests := []struct {
10 name string
11 input string
12 expected []string
13 }{
14 {
15 name: "simple command",
16 input: "ls -la",
17 expected: []string{"ls"},
18 },
19 {
20 name: "command with pipe",
21 input: "ls -la | grep test",
22 expected: []string{"ls", "grep"},
23 },
24 {
25 name: "command with logical and (builtin filtered)",
26 input: "mkdir test && cd test",
27 expected: []string{"mkdir"}, // cd is builtin, filtered out
28 },
29 {
30 name: "if statement with commands (builtin filtered)",
31 input: "if [ -f file.txt ]; then cat file.txt; fi",
32 expected: []string{"cat"}, // [ is builtin, filtered out
33 },
34 {
35 name: "variable assignment with command (builtin filtered)",
36 input: "FOO=bar echo $FOO",
37 expected: []string{}, // echo is builtin, filtered out
38 },
39 {
40 name: "script path filtered out (builtin also filtered)",
41 input: "./script.sh && echo done",
42 expected: []string{}, // echo is builtin, filtered out
43 },
44 {
45 name: "multiline script (builtin filtered)",
46 input: "python3 -c 'print(\"hello\")'\necho 'done'",
47 expected: []string{"python3"}, // echo is builtin, filtered out
48 },
49 {
50 name: "complex command chain (builtin filtered)",
51 input: "curl -s https://api.github.com | jq '.name' && echo 'done'",
52 expected: []string{"curl", "jq"}, // echo is builtin, filtered out
53 },
54 {
55 name: "builtins filtered out",
56 input: "echo 'test' && true && ls",
57 expected: []string{"ls"},
58 },
59 {
60 name: "empty command",
61 input: "",
62 expected: []string{},
63 },
64 }
65
66 for _, tt := range tests {
67 t.Run(tt.name, func(t *testing.T) {
68 result, err := ExtractCommands(tt.input)
69 if err != nil {
70 t.Fatalf("ExtractCommands() error = %v", err)
71 }
72 // Handle empty slice comparison
73 if len(result) == 0 && len(tt.expected) == 0 {
74 return // Both are empty, test passes
75 }
76 if !reflect.DeepEqual(result, tt.expected) {
77 t.Errorf("ExtractCommands() = %v, want %v", result, tt.expected)
78 }
79 })
80 }
81}
82
Josh Bleecher Snyder495c1fa2025-05-29 00:37:22 +000083func TestExtractCommandsErrorHandling(t *testing.T) {
84 // Test with syntactically invalid bash
85 invalidBash := "if [ incomplete"
86 _, err := ExtractCommands(invalidBash)
87 if err == nil {
88 t.Error("ExtractCommands() should return error for invalid bash syntax")
89 }
90}
91
92func TestExtractCommandsPathFiltering(t *testing.T) {
93 // Test that commands with paths are properly filtered out during extraction
94 tests := []struct {
95 name string
96 input string
97 expected []string
98 }{
99 {
100 name: "relative script path filtered (builtin also filtered)",
101 input: "./my-script.sh && echo 'done'",
102 expected: []string{}, // echo is builtin, filtered out
103 },
104 {
105 name: "absolute path filtered",
106 input: "/usr/bin/custom-tool --help",
107 expected: []string{},
108 },
109 {
110 name: "parent directory script filtered",
111 input: "../scripts/build.sh",
112 expected: []string{},
113 },
114 {
115 name: "home directory path filtered",
116 input: "~/.local/bin/tool",
117 expected: []string{},
118 },
119 {
120 name: "simple commands without paths included",
121 input: "curl https://example.com | jq '.name'",
122 expected: []string{"curl", "jq"},
123 },
124 {
125 name: "mixed paths and simple commands",
126 input: "./setup.sh && python3 -c 'print(\"hello\")' && /bin/ls",
127 expected: []string{"python3"},
128 },
129 }
130
131 for _, tt := range tests {
132 t.Run(tt.name, func(t *testing.T) {
133 result, err := ExtractCommands(tt.input)
134 if err != nil {
135 t.Fatalf("ExtractCommands() error = %v", err)
136 }
137 // Handle empty slice comparison
138 if len(result) == 0 && len(tt.expected) == 0 {
139 return // Both are empty, test passes
140 }
141 if !reflect.DeepEqual(result, tt.expected) {
142 t.Errorf("ExtractCommands() = %v, want %v", result, tt.expected)
143 }
144 })
145 }
146}