forked from Gitlink/gitlink-cli
70 lines
2.1 KiB
Go
70 lines
2.1 KiB
Go
package interactive
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/gitlink-org/gitlink-cli/shortcuts/common"
|
|
)
|
|
|
|
// TestExecutor_UsesRealRuntimeContext verifies that Execute builds the
|
|
// RuntimeContext via NewRuntimeContext (which initializes Client/Format/etc.)
|
|
// rather than a bare struct literal that leaves Client == nil.
|
|
//
|
|
// Regression: previously Execute did `&common.RuntimeContext{Args: args}`,
|
|
// so any command calling ctx.CallAPI panicked with a nil pointer dereference
|
|
// inside the executor goroutine, which swallowed the execResultMsg and left
|
|
// the REPL showing no output at all.
|
|
func TestExecutor_UsesRealRuntimeContext(t *testing.T) {
|
|
called := false
|
|
s := &common.Shortcut{
|
|
Name: "probe",
|
|
Run: func(ctx *common.RuntimeContext) error {
|
|
called = true
|
|
// A real command uses ctx.Client / ctx.Format. If Execute built the
|
|
// context correctly, Client must be non-nil and Format non-empty.
|
|
if ctx.Client == nil {
|
|
t.Error("ctx.Client is nil — Execute did not use NewRuntimeContext")
|
|
}
|
|
if ctx.Format == "" {
|
|
t.Error("ctx.Format is empty — Execute did not initialize format")
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
|
|
exec := &Executor{}
|
|
out, err := exec.Execute(s, map[string]string{})
|
|
if err != nil {
|
|
t.Fatalf("Execute() error = %v", err)
|
|
}
|
|
if !called {
|
|
t.Fatal("Run was not invoked")
|
|
}
|
|
if out != "" {
|
|
t.Fatalf("expected empty output, got %q", out)
|
|
}
|
|
}
|
|
|
|
// TestExecutor_PanicDoesNotCorruptStdout verifies that if a command panics,
|
|
// Execute recovers, returns the panic as an error, and — critically — restores
|
|
// os.Stdout so the REPL is not left with stdout pointing at a closed pipe.
|
|
func TestExecutor_PanicDoesNotCorruptStdout(t *testing.T) {
|
|
original := os.Stdout
|
|
s := &common.Shortcut{
|
|
Name: "boom",
|
|
Run: func(ctx *common.RuntimeContext) error {
|
|
panic("simulated command failure")
|
|
},
|
|
}
|
|
|
|
exec := &Executor{}
|
|
_, err := exec.Execute(s, map[string]string{})
|
|
if err == nil {
|
|
t.Fatal("expected Execute to return an error for a panicking command")
|
|
}
|
|
if os.Stdout != original {
|
|
t.Fatal("os.Stdout was not restored after a panic — REPL would be left broken")
|
|
}
|
|
}
|