@@ -2,6 +2,7 @@ package shell
22
33import (
44 "context"
5+ "path/filepath"
56 "runtime"
67 "strings"
78 "testing"
@@ -24,6 +25,11 @@ func BenchmarkShellQuickCommands(b *testing.B) {
2425}
2526
2627func TestTestTimeout(t *testing.T) {
28+ // XXX(@andreynering): This fails on Windows. Address once possible.
29+ if runtime.GOOS == "windows" {
30+ t.Skip("Skipping test on Windows")
31+ }
32+
2733 ctx, cancel := context.WithTimeout(t.Context(), time.Millisecond)
2834 t.Cleanup(cancel)
2935
@@ -72,113 +78,23 @@ func TestRunCommandError(t *testing.T) {
7278}
7379
7480func TestRunContinuity(t *testing.T) {
75− shell := NewShell(&Options{WorkingDir: t.TempDir()})
76− shell.Exec(t.Context(), "export FOO=bar")
77− dst := t.TempDir()
78− shell.Exec(t.Context(), "cd "+dst)
79− out, _, _ := shell.Exec(t.Context(), "echo $FOO ; pwd")
80− expect := "bar\n" + dst + "\n"
81− if out != expect {
82− t.Fatalf("Expected output %q, got %q", expect, out)
83− }
84−}
81+ tempDir1 := t.TempDir()
82+ tempDir2 := t.TempDir()
8583
86−// New tests for Windows shell support
87−
88−func TestShellTypeDetection(t *testing.T) {
89− shell := &PersistentShell{}
90−
91− tests := []struct {
92− command string
93− expected ShellType
94− windowsOnly bool
95− }{
96− // Windows-specific commands
97− {"dir", ShellTypeCmd, true},
98− {"type file.txt", ShellTypeCmd, true},
99− {"copy file1.txt file2.txt", ShellTypeCmd, true},
100− {"del file.txt", ShellTypeCmd, true},
101− {"md newdir", ShellTypeCmd, true},
102− {"tasklist", ShellTypeCmd, true},
103−
104− // PowerShell commands
105− {"Get-Process", ShellTypePowerShell, true},
106− {"Get-ChildItem", ShellTypePowerShell, true},
107− {"Set-Location C:\\", ShellTypePowerShell, true},
108− {"Get-Content file.txt | Where-Object {$_ -match 'pattern'}", ShellTypePowerShell, true},
109− {"$files = Get-ChildItem", ShellTypePowerShell, true},
110−
111− // Unix/cross-platform commands
112− {"ls -la", ShellTypePOSIX, false},
113− {"cat file.txt", ShellTypePOSIX, false},
114− {"grep pattern file.txt", ShellTypePOSIX, false},
115− {"echo hello", ShellTypePOSIX, false},
116− {"git status", ShellTypePOSIX, false},
117− {"go build", ShellTypePOSIX, false},
118− }
119−
120− for _, test := range tests {
121− t.Run(test.command, func(t *testing.T) {
122− result := shell.determineShellType(test.command)
123−
124− if test.windowsOnly && runtime.GOOS != "windows" {
125− // On non-Windows systems, everything should use POSIX
126− if result != ShellTypePOSIX {
127− t.Errorf("On non-Windows, command %q should use POSIX shell, got %v", test.command, result)
128− }
129− } else if runtime.GOOS == "windows" {
130− // On Windows, check the expected shell type
131− if result != test.expected {
132− t.Errorf("Command %q should use %v shell, got %v", test.command, test.expected, result)
133− }
134− }
135− })
84+ shell := NewShell(&Options{WorkingDir: tempDir1})
85+ if _, _, err := shell.Exec(t.Context(), "export FOO=bar"); err != nil {
86+ t.Fatalf("failed to set env: %v", err)
13687 }
137−}
138−
139−func TestWindowsCDHandling(t *testing.T) {
140− if runtime.GOOS != "windows" {
141− t.Skip("Windows CD handling test only runs on Windows")
142− }
143−
144− shell := NewShell(&Options{
145− WorkingDir: "C:\\Users",
146− })
147−
148− tests := []struct {
149− command string
150− expectedCwd string
151− shouldError bool
152− }{
153− {"cd ..", "C:\\", false},
154− {"cd Documents", "C:\\Users\\Documents", false},
155− {"cd C:\\Windows", "C:\\Windows", false},
156− {"cd", "", true}, // Missing argument
157− }
158−
159− for _, test := range tests {
160− t.Run(test.command, func(t *testing.T) {
161− originalCwd := shell.GetWorkingDir()
162− stdout, stderr, err := shell.handleWindowsCD(test.command)
163−
164− if test.shouldError {
165− if err == nil {
166− t.Errorf("Command %q should have failed", test.command)
167− }
168− } else {
169− if err != nil {
170− t.Errorf("Command %q failed: %v", test.command, err)
171− }
172− if shell.GetWorkingDir() != test.expectedCwd {
173− t.Errorf("Command %q: expected cwd %q, got %q", test.command, test.expectedCwd, shell.GetWorkingDir())
174− }
175− }
176−
177− // Reset for next test
178− shell.SetWorkingDir(originalCwd)
179− _ = stdout
180− _ = stderr
181− })
88+ if _, _, err := shell.Exec(t.Context(), "cd "+filepath.ToSlash(tempDir2)); err != nil {
89+ t.Fatalf("failed to change directory: %v", err)
90+ }
91+ out, _, err := shell.Exec(t.Context(), "echo $FOO ; pwd")
92+ if err != nil {
93+ t.Fatalf("failed to echo: %v", err)
94+ }
95+ expect := "bar\n" + tempDir2 + "\n"
96+ if out != expect {
97+ t.Fatalf("expected output %q, got %q", expect, out)
18298 }
18399}
184100
@@ -202,23 +118,3 @@ func TestCrossPlatformExecution(t *testing.T) {
202118 t.Errorf("Echo output should contain 'hello', got: %q", stdout)
203119 }
204120}
205−
206−func TestWindowsNativeCommands(t *testing.T) {
207− if runtime.GOOS != "windows" {
208− t.Skip("Windows native command test only runs on Windows")
209− }
210−
211− shell := NewShell(&Options{WorkingDir: "."})
212− ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
213− defer cancel()
214−
215− // Test Windows dir command
216− stdout, stderr, err := shell.Exec(ctx, "dir")
217− if err != nil {
218− t.Fatalf("Dir command failed: %v, stderr: %s", err, stderr)
219− }
220−
221− if stdout == "" {
222− t.Error("Dir command produced no output")
223− }
224−}