Files
zzet--gortex/internal/docs/docs_test.go
T
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

158 lines
4.1 KiB
Go

package docs
import (
"strings"
"testing"
"time"
"github.com/zzet/gortex/internal/graph"
)
func buildBlamedGraph(t *testing.T) *graph.Graph {
t.Helper()
g := graph.New()
now := time.Now().Unix()
staleTS := time.Now().Add(-400 * 24 * time.Hour).Unix()
g.AddNode(&graph.Node{
ID: "pkg/a.go::Recent", Kind: graph.KindFunction, Name: "Recent",
FilePath: "pkg/a.go", StartLine: 10, Language: "go",
Meta: map[string]any{
"last_authored": map[string]any{
"email": "alice@example.com", "timestamp": now,
"commit": "deadbeef1234",
},
},
})
g.AddNode(&graph.Node{
ID: "pkg/a.go::Old", Kind: graph.KindFunction, Name: "Old",
FilePath: "pkg/a.go", StartLine: 30, Language: "go",
Meta: map[string]any{
"last_authored": map[string]any{
"email": "alice@example.com", "timestamp": staleTS,
"commit": "abcd5678abcd",
},
},
})
g.AddNode(&graph.Node{
ID: "pkg/b.go::Bob", Kind: graph.KindMethod, Name: "Bob",
FilePath: "pkg/b.go", StartLine: 5, Language: "go",
Meta: map[string]any{
"last_authored": map[string]any{
"email": "bob@example.com", "timestamp": now,
"commit": "01234567",
},
},
})
return g
}
type fakeHistory struct {
events []HistoryEvent
}
func (f *fakeHistory) HistorySince(since time.Time) []HistoryEvent {
var out []HistoryEvent
for _, e := range f.events {
if e.Timestamp.After(since) {
out = append(out, e)
}
}
return out
}
func TestGenerate_AllSections(t *testing.T) {
g := buildBlamedGraph(t)
hist := &fakeHistory{events: []HistoryEvent{
{FilePath: "pkg/a.go", Kind: "modified", NodesAdded: 1, NodesRemoved: 0, Timestamp: time.Now()},
{FilePath: "pkg/b.go", Kind: "created", NodesAdded: 3, NodesRemoved: 0, Timestamp: time.Now()},
}}
bundle, err := Generate(Deps{Graph: g, History: hist}, Options{Since: 24 * time.Hour})
if err != nil {
t.Fatalf("Generate: %v", err)
}
if len(bundle.RecentChanges) != 2 {
t.Errorf("recent changes = %d, want 2", len(bundle.RecentChanges))
}
if len(bundle.OwnershipRows) != 2 {
t.Errorf("owners = %d, want 2", len(bundle.OwnershipRows))
}
if len(bundle.StaleCodeRows) != 1 {
t.Errorf("stale rows = %d, want 1", len(bundle.StaleCodeRows))
}
}
func TestGenerate_SectionsFilter(t *testing.T) {
g := buildBlamedGraph(t)
bundle, err := Generate(Deps{Graph: g},
Options{Sections: []string{"stale"}})
if err != nil {
t.Fatalf("Generate: %v", err)
}
if len(bundle.OwnershipRows) != 0 {
t.Errorf("ownership shouldn't render when not in sections; got %d", len(bundle.OwnershipRows))
}
if len(bundle.RecentChanges) != 0 {
t.Errorf("recent shouldn't render; got %d", len(bundle.RecentChanges))
}
if len(bundle.StaleCodeRows) != 1 {
t.Errorf("stale rows = %d, want 1", len(bundle.StaleCodeRows))
}
}
func TestRenderMarkdown_HasSections(t *testing.T) {
g := buildBlamedGraph(t)
bundle, err := Generate(Deps{Graph: g}, Options{})
if err != nil {
t.Fatalf("Generate: %v", err)
}
md := RenderMarkdown(bundle)
for _, want := range []string{"# Docs Bundle", "## Recent Changes", "## Ownership", "## Stale Code", "## Blame Enrichment"} {
if !strings.Contains(md, want) {
t.Errorf("markdown missing %q", want)
}
}
}
func TestRenderJSON_RoundTrips(t *testing.T) {
g := buildBlamedGraph(t)
bundle, err := Generate(Deps{Graph: g}, Options{})
if err != nil {
t.Fatalf("Generate: %v", err)
}
data, err := RenderJSON(bundle)
if err != nil {
t.Fatalf("RenderJSON: %v", err)
}
if !strings.Contains(string(data), `"sections"`) {
t.Error("JSON should include sections field")
}
}
func TestGenerate_WithBlame(t *testing.T) {
g := buildBlamedGraph(t)
called := 0
bundle, err := Generate(Deps{
Graph: g,
Blame: func() (int, map[string]int, error) {
called++
return 42, map[string]int{"gortex": 42}, nil
},
}, Options{IncludeBlame: true})
if err != nil {
t.Fatalf("Generate: %v", err)
}
if called != 1 {
t.Errorf("blame runner called %d times, want 1", called)
}
if bundle.Blame == nil || bundle.Blame.Enriched != 42 {
t.Fatalf("blame summary missing or wrong: %+v", bundle.Blame)
}
}
func TestGenerate_NilGraphFails(t *testing.T) {
if _, err := Generate(Deps{}, Options{}); err == nil {
t.Error("expected error when graph is nil")
}
}