ci / vet-and-test (pull_request) Successful in 1m4s
Why: Known-boundary follow-up: owner opt-in auto page suggestions on semantic task events without self-trigger from surface revisions. Evidence: go test ./internal/genui/ ./internal/runmgr/ ./internal/settings/ ./internal/app/ Impact: Default-off settings key; material/plan/todo/document hooks nudge present. Refs: docs/proposals/2026-10-12-generative-ui-auto-trigger.md Co-authored-by: Cursor <cursoragent@cursor.com>
54 lines
1.7 KiB
Go
54 lines
1.7 KiB
Go
package genui
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestAutoDefaultOff(t *testing.T) {
|
|
a := NewAuto(func(string) bool { return true }, func(string) bool { return false }, nil)
|
|
if ok, skip := a.Try("alice", "c1", "plan"); ok || skip != "opt_in_off" {
|
|
t.Fatalf("want opt_in_off, got ok=%v skip=%q", ok, skip)
|
|
}
|
|
}
|
|
|
|
func TestAutoRequiresActivation(t *testing.T) {
|
|
a := NewAuto(func(string) bool { return false }, func(string) bool { return true }, nil)
|
|
if ok, skip := a.Try("alice", "c1", "plan"); ok || skip != "activation_off" {
|
|
t.Fatalf("want activation_off, got ok=%v skip=%q", ok, skip)
|
|
}
|
|
}
|
|
|
|
func TestAutoBudgetAndCooldown(t *testing.T) {
|
|
var exhausted int
|
|
now := time.Unix(1_700_000_000, 0).UTC()
|
|
a := NewAuto(func(string) bool { return true }, func(string) bool { return true },
|
|
func(owner, kind, detail string) {
|
|
if kind == "genui.auto_present_exhausted" {
|
|
exhausted++
|
|
}
|
|
})
|
|
a.now = func() time.Time { return now }
|
|
|
|
for i := 0; i < AutoBudgetPerHour; i++ {
|
|
ok, skip := a.Try("alice", "c1", "plan")
|
|
if !ok {
|
|
t.Fatalf("shot %d should pass, skip=%q", i, skip)
|
|
}
|
|
now = now.Add(AutoCooldown + time.Second)
|
|
}
|
|
if ok, skip := a.Try("alice", "c1", "plan"); ok || skip != "budget" || exhausted != 1 {
|
|
t.Fatalf("want budget exhausted, ok=%v skip=%q exhausted=%d", ok, skip, exhausted)
|
|
}
|
|
|
|
// 冷却:同一时刻第二次拒绝
|
|
a2 := NewAuto(func(string) bool { return true }, func(string) bool { return true }, nil)
|
|
a2.now = func() time.Time { return now }
|
|
if ok, _ := a2.Try("alice", "c2", "art"); !ok {
|
|
t.Fatal("first should pass")
|
|
}
|
|
if ok, skip := a2.Try("alice", "c2", "art"); ok || skip != "cooldown" {
|
|
t.Fatalf("want cooldown, got ok=%v skip=%q", ok, skip)
|
|
}
|
|
}
|