Path: blob/main/agent/planexec/template_step_test.go
3434 views
package planexec_test12import (3"github.com/kardolus/chatgpt-cli/agent/planexec"4"github.com/kardolus/chatgpt-cli/agent/types"5"testing"67. "github.com/onsi/gomega"8"github.com/sclevine/spec"9"github.com/sclevine/spec/report"10)1112func TestUnitTemplateStep(t *testing.T) {13spec.Run(t, "Testing step templating", testTemplateStep, spec.Report(report.Terminal{}))14}1516func testTemplateStep(t *testing.T, when spec.G, it spec.S) {17it.Before(func() {18RegisterTestingT(t)19})2021when("ApplyTemplate()", func() {22it("leaves fields unchanged when there are no template markers", func() {23step := types.Step{24Type: types.ToolShell,25Description: "plain desc",26Command: "echo",27Args: []string{"hi"},28}2930ctx := types.ExecContext{Goal: "g", Plan: types.Plan{}, Results: nil}3132out, err := planexec.ApplyTemplate(step, ctx)33Expect(err).NotTo(HaveOccurred())34Expect(out).To(Equal(step))35})3637it("renders Description for any step type", func() {38step := types.Step{39Type: types.ToolKind("wat"),40Description: "goal={{.Goal}}",41}4243ctx := types.ExecContext{Goal: "ship it"}44out, err := planexec.ApplyTemplate(step, ctx)4546Expect(err).NotTo(HaveOccurred())47Expect(out.Description).To(Equal("goal=ship it"))48Expect(out.Type).To(Equal(types.ToolKind("wat")))49})5051it("renders shell Command and Args", func() {52step := types.Step{53Type: types.ToolShell,54Description: "do {{.Goal}}",55Command: "echo {{.Goal}}",56Args: []string{"a={{.Goal}}", "b"},57}5859ctx := types.ExecContext{Goal: "hello"}60out, err := planexec.ApplyTemplate(step, ctx)6162Expect(err).NotTo(HaveOccurred())63Expect(out.Description).To(Equal("do hello"))64Expect(out.Command).To(Equal("echo hello"))65Expect(out.Args).To(Equal([]string{"a=hello", "b"}))66})6768it("renders llm Prompt", func() {69step := types.Step{70Type: types.ToolLLM,71Description: "ask",72Prompt: "say {{.Goal}}",73}7475ctx := types.ExecContext{Goal: "hola"}76out, err := planexec.ApplyTemplate(step, ctx)7778Expect(err).NotTo(HaveOccurred())79Expect(out.Prompt).To(Equal("say hola"))80})8182it("renders file Op/Path/Data", func() {83step := types.Step{84Type: types.ToolFiles,85Description: "write",86Op: "write",87Path: "/tmp/{{.Goal}}.txt",88Data: "payload={{.Goal}}",89}9091ctx := types.ExecContext{Goal: "x"}92out, err := planexec.ApplyTemplate(step, ctx)9394Expect(err).NotTo(HaveOccurred())95Expect(out.Path).To(Equal("/tmp/x.txt"))96Expect(out.Data).To(Equal("payload=x"))97})9899it("errors when a referenced key is missing (missingkey=error)", func() {100step := types.Step{101Type: types.ToolLLM,102Description: "desc {{.Nope}}",103Prompt: "hi",104}105106ctx := types.ExecContext{Goal: "g"}107_, err := planexec.ApplyTemplate(step, ctx)108109Expect(err).To(HaveOccurred())110Expect(err.Error()).To(ContainSubstring("render Description"))111})112113it("errors on invalid template syntax and wraps field name", func() {114step := types.Step{115Type: types.ToolShell,116Description: "ok",117Command: "{{ .Goal", // missing closing braces118Args: []string{"x"},119}120121ctx := types.ExecContext{Goal: "g"}122_, err := planexec.ApplyTemplate(step, ctx)123124Expect(err).To(HaveOccurred())125Expect(err.Error()).To(ContainSubstring("render Command"))126})127128it("wraps args index in error message (Args[i])", func() {129step := types.Step{130Type: types.ToolShell,131Description: "ok",132Command: "echo",133Args: []string{"{{ .Goal", "ok"}, // first arg invalid template134}135136ctx := types.ExecContext{Goal: "g"}137_, err := planexec.ApplyTemplate(step, ctx)138139Expect(err).To(HaveOccurred())140Expect(err.Error()).To(ContainSubstring("render Args[0]"))141})142})143}144145146