Files
teabot/internal/prompt/prompt_test.go
T
unkinben 1b4448afb4
ci/woodpecker/pr/test Pipeline failed
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
Add teabot daemon implementation
teabot watches Gitea repos and dispatches one-shot Claude Code sessions in
Docker containers to work issues and review PRs, acting as configurable bot
personalities.

Claude-Session: https://claude.ai/code/session_015ur3i7D2azsMAWTSVABApv
2026-07-26 23:36:21 +10:00

99 lines
2.9 KiB
Go

package prompt
import (
"strings"
"testing"
"git.unkin.net/unkin/teabot/internal/gitea"
)
func TestIssuePromptContainsContextAndConventions(t *testing.T) {
p := Issue(IssueContext{
Repo: "unkin/teabot",
PersonalityName: "implementer",
Issue: gitea.Issue{
Index: 42,
Title: "Add a flag",
Body: "Please add --verbose",
Poster: gitea.User{Login: "alice"},
HTMLURL: "https://git.unkin.net/unkin/teabot/issues/42",
},
Comments: []gitea.Comment{{Poster: gitea.User{Login: "bob"}, Body: "agreed"}},
})
mustContain(t, p, "implementer")
mustContain(t, p, "unkin/teabot")
mustContain(t, p, "Add a flag")
mustContain(t, p, "Please add --verbose")
mustContain(t, p, "Closes #42") // must instruct linking the issue
mustContain(t, p, "bob: agreed")
mustContain(t, p, "benvin/") // branch-naming convention
mustContain(t, p, "present-tense")
}
func TestIssuePromptHandlesEmptyBody(t *testing.T) {
p := Issue(IssueContext{
Repo: "a/b",
Issue: gitea.Issue{Index: 1, Title: "t"},
})
mustContain(t, p, "(no description provided)")
}
func TestPullPromptIncludesDiffAndReviewInstruction(t *testing.T) {
p := Pull(PullContext{
Repo: "unkin/teabot",
PersonalityName: "reviewer",
Pull: gitea.PullRequest{
Index: 7,
Title: "Implement thing",
Body: "does the thing",
Poster: gitea.User{Login: "carol"},
Head: gitea.Branch{Ref: "benvin/thing"},
Base: gitea.Branch{Ref: "main"},
},
Diff: "diff --git a/x b/x\n+added line\n",
})
mustContain(t, p, "reviewer")
mustContain(t, p, "PR #7")
mustContain(t, p, "does the diff actually satisfy")
mustContain(t, p, "benvin/thing -> main")
mustContain(t, p, "diff --git a/x b/x")
mustContain(t, p, "+added line")
}
func TestPullPromptTruncatesHugeDiff(t *testing.T) {
huge := strings.Repeat("x", 70000)
p := Pull(PullContext{Repo: "a/b", Pull: gitea.PullRequest{Index: 1}, Diff: huge})
mustContain(t, p, "[diff truncated]")
if len(p) > 70000 {
t.Errorf("prompt not truncated, len=%d", len(p))
}
}
func TestFollowUpIssueVsPullWording(t *testing.T) {
issueThread := []gitea.Comment{{Poster: gitea.User{Login: "a"}, Body: "first"}}
trigger := gitea.Comment{Poster: gitea.User{Login: "human"}, Body: "please tweak it"}
ip := FollowUp(FollowUpContext{
Repo: "a/b", Kind: FollowUpIssue, Index: 3, Title: "T",
URL: "u", Comments: issueThread, NewComment: trigger,
})
mustContain(t, ip, "issue #3")
mustContain(t, ip, "please tweak it")
mustContain(t, ip, "posted by human")
pp := FollowUp(FollowUpContext{
Repo: "a/b", Kind: FollowUpPull, Index: 4, Title: "T2",
URL: "u", Comments: issueThread, NewComment: trigger,
})
mustContain(t, pp, "pull request #4")
mustContain(t, pp, "check out the PR branch")
}
func mustContain(t *testing.T, haystack, needle string) {
t.Helper()
if !strings.Contains(haystack, needle) {
t.Errorf("prompt missing %q\n---\n%s", needle, haystack)
}
}