package prompt import ( "context" "errors" "testing" "gitea.maximumdirect.net/eric/scriptorium/internal/domain" ) func TestGoRenderer_Render(t *testing.T) { renderer := NewGoRenderer() ctx := context.Background() profile := &domain.PromptDefinition{ ID: "test-profile", Inputs: []domain.PromptInput{{Name: "transcript", Required: true}}, Templates: []domain.PromptMessageTemplate{ {Role: "system", Content: "You are a {{.role}}."}, {Role: "user", Content: "Analyze this: {{input \"transcript\"}}"}, }, } inputs := map[string]*domain.Artifact{ "transcript": {Body: []byte("The quick brown fox.")}, } vars := map[string]string{ "role": "helpful assistant", } t.Run("successful render", func(t *testing.T) { res, err := renderer.Render(ctx, profile, inputs, vars) if err != nil { t.Fatalf("unexpected error: %v", err) } if len(res.Messages) != 2 { t.Errorf("expected 2 messages, got %d", len(res.Messages)) } if res.Messages[0].Content != "You are a helpful assistant." { t.Errorf("unexpected system message: %s", res.Messages[0].Content) } if res.Messages[1].Content != "Analyze this: The quick brown fox." { t.Errorf("unexpected user message: %s", res.Messages[1].Content) } }) t.Run("missing required input", func(t *testing.T) { emptyInputs := map[string]*domain.Artifact{} _, err := renderer.Render(ctx, profile, emptyInputs, vars) if !errors.Is(err, ErrMissingRequiredInput) { t.Errorf("expected ErrMissingRequiredInput, got %v", err) } }) t.Run("unknown input in template", func(t *testing.T) { profileUnknown := &domain.PromptDefinition{ Inputs: []domain.PromptInput{{Name: "transcript", Required: true}}, Templates: []domain.PromptMessageTemplate{ {Role: "user", Content: "Hello {{input \"ghost\"}}"}, }, } _, err := renderer.Render(ctx, profileUnknown, inputs, vars) if !errors.Is(err, ErrRenderFailure) { t.Errorf("expected ErrRenderFailure, got %v", err) } if !errors.Is(err, ErrUnknownInput) { t.Errorf("expected ErrUnknownInput, got %v", err) } }) t.Run("invalid template syntax", func(t *testing.T) { profileInvalid := &domain.PromptDefinition{ Inputs: []domain.PromptInput{{Name: "transcript", Required: true}}, Templates: []domain.PromptMessageTemplate{ {Role: "user", Content: "Hello {{.unclosed"}, }, } _, err := renderer.Render(ctx, profileInvalid, inputs, vars) if !errors.Is(err, ErrInvalidTemplate) { t.Errorf("expected ErrInvalidTemplate, got %v", err) } }) t.Run("empty message role", func(t *testing.T) { profileNoRole := &domain.PromptDefinition{ Inputs: []domain.PromptInput{{Name: "transcript", Required: true}}, Templates: []domain.PromptMessageTemplate{ {Role: "", Content: "Hello"}, }, } _, err := renderer.Render(ctx, profileNoRole, inputs, vars) if !errors.Is(err, ErrInvalidMessageRole) { t.Errorf("expected ErrInvalidMessageRole, got %v", err) } }) t.Run("missing variable in template", func(t *testing.T) { profileMissingVar := &domain.PromptDefinition{ Inputs: []domain.PromptInput{{Name: "transcript", Required: true}}, Templates: []domain.PromptMessageTemplate{ {Role: "system", Content: "You are {{.missing}}"}, }, } _, err := renderer.Render(ctx, profileMissingVar, inputs, vars) if !errors.Is(err, ErrRenderFailure) { t.Errorf("expected ErrRenderFailure for missing variable, got %v", err) } }) }