164 lines
4.4 KiB
Go
164 lines
4.4 KiB
Go
package scriptorium
|
|
|
|
import (
|
|
"context"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestRenderConstructsCommand(t *testing.T) {
|
|
commands := &fakeCommands{result: CommandResult{Stdout: []byte(`{"ok":true}`)}}
|
|
runner := Runner{
|
|
Binary: "/usr/local/bin/scriptorium",
|
|
ConfigPath: "/etc/scriptorium.yml",
|
|
Profile: "weather",
|
|
Timeout: time.Minute,
|
|
Commands: commands,
|
|
}
|
|
|
|
result, err := runner.Render(context.Background(), RenderRequest{
|
|
PromptID: "weather.daily_report",
|
|
DataPackagePath: "/tmp/data_package.yaml",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Render() error = %v", err)
|
|
}
|
|
|
|
wantArgs := []string{
|
|
"render",
|
|
"--config", "/etc/scriptorium.yml",
|
|
"--profile", "weather",
|
|
"--prompt", "weather.daily_report",
|
|
"--input", "data_package=/tmp/data_package.yaml",
|
|
"--format", "json",
|
|
}
|
|
if commands.name != "/usr/local/bin/scriptorium" {
|
|
t.Fatalf("command name = %q, want custom binary", commands.name)
|
|
}
|
|
if !reflect.DeepEqual(commands.args, wantArgs) {
|
|
t.Fatalf("args = %#v, want %#v", commands.args, wantArgs)
|
|
}
|
|
if !reflect.DeepEqual(result.Command, append([]string{"/usr/local/bin/scriptorium"}, wantArgs...)) {
|
|
t.Fatalf("result command = %#v, want full argv", result.Command)
|
|
}
|
|
}
|
|
|
|
func TestRenderReturnsResultForNonzeroExit(t *testing.T) {
|
|
runner := Runner{
|
|
Commands: &fakeCommands{
|
|
result: CommandResult{
|
|
Stderr: []byte("missing input"),
|
|
ExitCode: 1,
|
|
},
|
|
},
|
|
}
|
|
|
|
result, err := runner.Render(context.Background(), RenderRequest{
|
|
PromptID: "weather.daily_report",
|
|
DataPackagePath: "/tmp/data_package.yaml",
|
|
})
|
|
if err == nil {
|
|
t.Fatal("Render() error = nil, want nonzero exit error")
|
|
}
|
|
if result == nil {
|
|
t.Fatal("Render() result = nil, want captured result")
|
|
}
|
|
if result.ExitCode != 1 {
|
|
t.Fatalf("ExitCode = %d, want 1", result.ExitCode)
|
|
}
|
|
if !strings.Contains(err.Error(), "missing input") {
|
|
t.Fatalf("error = %q, want stderr context", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestRunConstructsCommand(t *testing.T) {
|
|
commands := &fakeCommands{result: CommandResult{Stderr: []byte("wrote report")}}
|
|
runner := Runner{
|
|
Binary: "/usr/local/bin/scriptorium",
|
|
ConfigPath: "/etc/scriptorium.yml",
|
|
Profile: "weather",
|
|
Timeout: 45 * time.Second,
|
|
Commands: commands,
|
|
}
|
|
|
|
result, err := runner.Run(context.Background(), RunRequest{
|
|
PromptID: "weather.daily_report",
|
|
DataPackagePath: "/tmp/data_package.yaml",
|
|
OutputPath: "/tmp/daily.md",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("Run() error = %v", err)
|
|
}
|
|
|
|
wantArgs := []string{
|
|
"run",
|
|
"--config", "/etc/scriptorium.yml",
|
|
"--profile", "weather",
|
|
"--prompt", "weather.daily_report",
|
|
"--input", "data_package=/tmp/data_package.yaml",
|
|
"--out", "/tmp/daily.md",
|
|
}
|
|
if commands.name != "/usr/local/bin/scriptorium" {
|
|
t.Fatalf("command name = %q, want custom binary", commands.name)
|
|
}
|
|
if !reflect.DeepEqual(commands.args, wantArgs) {
|
|
t.Fatalf("args = %#v, want %#v", commands.args, wantArgs)
|
|
}
|
|
if commands.timeout != 45*time.Second {
|
|
t.Fatalf("timeout = %s, want 45s", commands.timeout)
|
|
}
|
|
if !reflect.DeepEqual(result.Command, append([]string{"/usr/local/bin/scriptorium"}, wantArgs...)) {
|
|
t.Fatalf("result command = %#v, want full argv", result.Command)
|
|
}
|
|
if result.OutputPath != "/tmp/daily.md" {
|
|
t.Fatalf("OutputPath = %q, want /tmp/daily.md", result.OutputPath)
|
|
}
|
|
}
|
|
|
|
func TestRunReturnsResultForValidationExit(t *testing.T) {
|
|
runner := Runner{
|
|
Commands: &fakeCommands{
|
|
result: CommandResult{
|
|
Stdout: []byte("# Daily Report\n"),
|
|
Stderr: []byte("validation failed"),
|
|
ExitCode: 2,
|
|
},
|
|
},
|
|
}
|
|
|
|
result, err := runner.Run(context.Background(), RunRequest{
|
|
PromptID: "weather.daily_report",
|
|
DataPackagePath: "/tmp/data_package.yaml",
|
|
OutputPath: "/tmp/daily.md",
|
|
})
|
|
if err == nil {
|
|
t.Fatal("Run() error = nil, want nonzero exit error")
|
|
}
|
|
if result == nil {
|
|
t.Fatal("Run() result = nil, want captured result")
|
|
}
|
|
if result.ExitCode != 2 {
|
|
t.Fatalf("ExitCode = %d, want 2", result.ExitCode)
|
|
}
|
|
if !strings.Contains(err.Error(), "validation failed") {
|
|
t.Fatalf("error = %q, want stderr context", err.Error())
|
|
}
|
|
}
|
|
|
|
type fakeCommands struct {
|
|
name string
|
|
args []string
|
|
timeout time.Duration
|
|
result CommandResult
|
|
err error
|
|
}
|
|
|
|
func (f *fakeCommands) Run(_ context.Context, name string, args []string, timeout time.Duration) (CommandResult, error) {
|
|
f.name = name
|
|
f.args = append([]string{}, args...)
|
|
f.timeout = timeout
|
|
return f.result, f.err
|
|
}
|