2026-11-14 17:39:17 +00:00
|
|
|
package usecase
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"errors"
|
|
|
|
|
"testing"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"go.maximumdirect.net/promptkit/internal/domain"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestPreparedNotificationChecksContextBeforeInvocation(t *testing.T) {
|
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
|
cancel()
|
|
|
|
|
called := false
|
|
|
|
|
_, err := (&Runner{}).executePreparedRun(ctx, &domain.PreparedRun{}, func(context.Context, *domain.PreparedRun) { called = true }, false, nil, "", 0, "", time.Time{}, nil)
|
|
|
|
|
if called || !errors.Is(err, context.Canceled) || !errors.Is(err, ErrLLMGenerate) {
|
|
|
|
|
t.Fatalf("called=%v error=%v", called, err)
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-11-14 17:43:40 +00:00
|
|
|
|
|
|
|
|
func TestPreparedNotificationPanicClearsClaimedPayload(t *testing.T) {
|
|
|
|
|
runner := NewRunner(&fakePromptRepo{def: promptDef(domain.FormatText, domain.ValidationNone, 0)},
|
|
|
|
|
&fakeExecutionProfileRepo{profiles: map[string]*domain.ExecutionProfile{"exec": defaultExecutionProfile()}},
|
|
|
|
|
defaultArtifactReader(), defaultRenderer(), &fakeLLM{resp: &domain.GenerateResponse{Content: "ok"}}, nil, nil)
|
|
|
|
|
handle, err := runner.PrepareExecution(context.Background(), domain.RunRequest{PromptID: "p", ProfileID: "exec", Inputs: singleInputRef(), OnPrepared: func(context.Context, *domain.PreparedRun) { panic("notification") }})
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
payload := handle.payload
|
|
|
|
|
func() {
|
|
|
|
|
defer func() {
|
|
|
|
|
if recover() == nil {
|
|
|
|
|
t.Error("expected panic")
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
_, _ = runner.RunPrepared(context.Background(), handle)
|
|
|
|
|
}()
|
|
|
|
|
if payload.prepared != nil || payload.onPrepared != nil || payload.directKey != "" || handle.payload != nil {
|
|
|
|
|
t.Fatal("claimed payload retained private state")
|
|
|
|
|
}
|
|
|
|
|
}
|