1b4448afb4
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
99 lines
2.9 KiB
Go
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)
|
|
}
|
|
}
|