mirror of
https://github.com/charmbracelet/crush.git
synced 2025-08-02 05:20:46 +03:00
121 lines
3.2 KiB
Go
121 lines
3.2 KiB
Go
package shell
|
|
|
|
import (
|
|
"context"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// Benchmark to measure CPU efficiency
|
|
func BenchmarkShellQuickCommands(b *testing.B) {
|
|
shell := NewShell(&Options{WorkingDir: b.TempDir()})
|
|
|
|
b.ReportAllocs()
|
|
|
|
for b.Loop() {
|
|
_, _, err := shell.Exec(context.Background(), "echo test")
|
|
exitCode := ExitCode(err)
|
|
if err != nil || exitCode != 0 {
|
|
b.Fatalf("Command failed: %v, exit code: %d", err, exitCode)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTestTimeout(t *testing.T) {
|
|
// XXX(@andreynering): This fails on Windows. Address once possible.
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip("Skipping test on Windows")
|
|
}
|
|
|
|
ctx, cancel := context.WithTimeout(t.Context(), time.Millisecond)
|
|
t.Cleanup(cancel)
|
|
|
|
shell := NewShell(&Options{WorkingDir: t.TempDir()})
|
|
_, _, err := shell.Exec(ctx, "sleep 10")
|
|
if status := ExitCode(err); status == 0 {
|
|
t.Fatalf("Expected non-zero exit status, got %d", status)
|
|
}
|
|
if !IsInterrupt(err) {
|
|
t.Fatalf("Expected command to be interrupted, but it was not")
|
|
}
|
|
if err == nil {
|
|
t.Fatalf("Expected an error due to timeout, but got none")
|
|
}
|
|
}
|
|
|
|
func TestTestCancel(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(t.Context())
|
|
cancel() // immediately cancel the context
|
|
|
|
shell := NewShell(&Options{WorkingDir: t.TempDir()})
|
|
_, _, err := shell.Exec(ctx, "sleep 10")
|
|
if status := ExitCode(err); status == 0 {
|
|
t.Fatalf("Expected non-zero exit status, got %d", status)
|
|
}
|
|
if !IsInterrupt(err) {
|
|
t.Fatalf("Expected command to be interrupted, but it was not")
|
|
}
|
|
if err == nil {
|
|
t.Fatalf("Expected an error due to cancel, but got none")
|
|
}
|
|
}
|
|
|
|
func TestRunCommandError(t *testing.T) {
|
|
shell := NewShell(&Options{WorkingDir: t.TempDir()})
|
|
_, _, err := shell.Exec(t.Context(), "nopenopenope")
|
|
if status := ExitCode(err); status == 0 {
|
|
t.Fatalf("Expected non-zero exit status, got %d", status)
|
|
}
|
|
if IsInterrupt(err) {
|
|
t.Fatalf("Expected command to not be interrupted, but it was")
|
|
}
|
|
if err == nil {
|
|
t.Fatalf("Expected an error, got nil")
|
|
}
|
|
}
|
|
|
|
func TestRunContinuity(t *testing.T) {
|
|
tempDir1 := t.TempDir()
|
|
tempDir2 := t.TempDir()
|
|
|
|
shell := NewShell(&Options{WorkingDir: tempDir1})
|
|
if _, _, err := shell.Exec(t.Context(), "export FOO=bar"); err != nil {
|
|
t.Fatalf("failed to set env: %v", err)
|
|
}
|
|
if _, _, err := shell.Exec(t.Context(), "cd "+filepath.ToSlash(tempDir2)); err != nil {
|
|
t.Fatalf("failed to change directory: %v", err)
|
|
}
|
|
out, _, err := shell.Exec(t.Context(), "echo $FOO ; pwd")
|
|
if err != nil {
|
|
t.Fatalf("failed to echo: %v", err)
|
|
}
|
|
expect := "bar\n" + tempDir2 + "\n"
|
|
if out != expect {
|
|
t.Fatalf("expected output %q, got %q", expect, out)
|
|
}
|
|
}
|
|
|
|
func TestCrossPlatformExecution(t *testing.T) {
|
|
shell := NewShell(&Options{WorkingDir: "."})
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
// Test a simple command that should work on all platforms
|
|
stdout, stderr, err := shell.Exec(ctx, "echo hello")
|
|
if err != nil {
|
|
t.Fatalf("Echo command failed: %v, stderr: %s", err, stderr)
|
|
}
|
|
|
|
if stdout == "" {
|
|
t.Error("Echo command produced no output")
|
|
}
|
|
|
|
// The output should contain "hello" regardless of platform
|
|
if !strings.Contains(strings.ToLower(stdout), "hello") {
|
|
t.Errorf("Echo output should contain 'hello', got: %q", stdout)
|
|
}
|
|
}
|