项目文件夹

文件
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

116 行
3.9 KiB
Go

package rerank
import (
"testing"
"github.com/zzet/gortex/internal/graph"
)
func TestFileCoherenceSignal_SoloFileContributesZero(t *testing.T) {
g := newTestGraph()
a := mustNode(g, "fileA.go::A", "A", graph.KindFunction)
a.FilePath = "fileA.go"
cands := []*Candidate{candidateFor(a, 0, -1)}
ctx := &Context{Graph: g}
ctx.prepare(cands)
if got := (FileCoherenceSignal{}).Contribute("q", cands[0], ctx); got != 0 {
t.Errorf("solo-file candidate got %v, want 0", got)
}
}
func TestFileCoherenceSignal_MultiChunkFileGetsBoost(t *testing.T) {
g := newTestGraph()
// File A has 3 candidates at ranks 0, 2, 9 → strong evidence.
a1 := mustNode(g, "fileA.go::A1", "A1", graph.KindFunction)
a1.FilePath = "fileA.go"
a2 := mustNode(g, "fileA.go::A2", "A2", graph.KindFunction)
a2.FilePath = "fileA.go"
a3 := mustNode(g, "fileA.go::A3", "A3", graph.KindFunction)
a3.FilePath = "fileA.go"
// File B has 2 candidates at ranks 4, 7 → moderate evidence.
b1 := mustNode(g, "fileB.go::B1", "B1", graph.KindFunction)
b1.FilePath = "fileB.go"
b2 := mustNode(g, "fileB.go::B2", "B2", graph.KindFunction)
b2.FilePath = "fileB.go"
// File C has 1 candidate → solo, no boost.
c1 := mustNode(g, "fileC.go::C1", "C1", graph.KindFunction)
c1.FilePath = "fileC.go"
cands := []*Candidate{
candidateFor(a1, 0, -1),
candidateFor(a2, 2, -1),
candidateFor(a3, 9, -1),
candidateFor(b1, 4, -1),
candidateFor(b2, 7, -1),
candidateFor(c1, 1, -1),
}
ctx := &Context{Graph: g}
ctx.prepare(cands)
sig := FileCoherenceSignal{}
scoreA := sig.Contribute("q", cands[0], ctx)
scoreB := sig.Contribute("q", cands[3], ctx)
scoreC := sig.Contribute("q", cands[5], ctx)
// A's per-file sum = 1 + 1/3 + 1/10 = 1.433…
// B's per-file sum = 1/5 + 1/8 = 0.325
// max = A's sum → A scores 1.0, B scores 0.325/1.433 ≈ 0.227, C scores 0.
if scoreA != 1.0 {
t.Errorf("file-A leader got %v, want 1.0 (top of multi-chunk file)", scoreA)
}
if scoreB <= 0 || scoreB >= scoreA {
t.Errorf("file-B leader got %v, want a positive fraction less than file-A's %v", scoreB, scoreA)
}
if scoreC != 0 {
t.Errorf("solo-file candidate got %v, want 0", scoreC)
}
// Every candidate in a multi-chunk file gets the same per-file
// score — the signal isn't "only the leader"; it's "this file is
// strong evidence so every chunk from it benefits".
scoreA3 := sig.Contribute("q", cands[2], ctx)
if scoreA != scoreA3 {
t.Errorf("file-A non-leader got %v but leader got %v; expected equal per-file boost", scoreA3, scoreA)
}
}
func TestFileCoherenceSignal_NoFilePathOrZeroSums(t *testing.T) {
g := newTestGraph()
n := mustNode(g, "::X", "X", graph.KindFunction)
n.FilePath = ""
cands := []*Candidate{candidateFor(n, 0, -1), candidateFor(n, 1, -1)}
ctx := &Context{Graph: g}
ctx.prepare(cands)
if got := (FileCoherenceSignal{}).Contribute("q", cands[0], ctx); got != 0 {
t.Errorf("empty FilePath got %v, want 0", got)
}
// File with two candidates both at TextRank=-1 (no rank info) →
// fileScoreSum is 0 for that file → signal returns 0 (no boost).
g2 := newTestGraph()
a := mustNode(g2, "f.go::A", "A", graph.KindFunction)
a.FilePath = "f.go"
b := mustNode(g2, "f.go::B", "B", graph.KindFunction)
b.FilePath = "f.go"
cands2 := []*Candidate{candidateFor(a, -1, -1), candidateFor(b, -1, -1)}
ctx2 := &Context{Graph: g2}
ctx2.prepare(cands2)
if got := (FileCoherenceSignal{}).Contribute("q", cands2[0], ctx2); got != 0 {
t.Errorf("no-rank multi-candidate file got %v, want 0", got)
}
}
func TestFileCoherenceSignal_NilSafety(t *testing.T) {
sig := FileCoherenceSignal{}
if got := sig.Contribute("q", nil, &Context{}); got != 0 {
t.Errorf("nil candidate got %v, want 0", got)
}
if got := sig.Contribute("q", &Candidate{}, &Context{}); got != 0 {
t.Errorf("nil node got %v, want 0", got)
}
if got := sig.Contribute("q", &Candidate{Node: &graph.Node{}}, nil); got != 0 {
t.Errorf("nil context got %v, want 0", got)
}
}