项目文件夹

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

93 行
2.9 KiB
Go

package rerank
import (
"reflect"
"testing"
"github.com/zzet/gortex/internal/graph"
)
func cand(id string, textRank, vectorRank int) *Candidate {
return &Candidate{Node: &graph.Node{ID: id}, TextRank: textRank, VectorRank: vectorRank}
}
func TestSelectCentralitySeeds(t *testing.T) {
cands := []*Candidate{
cand("c", 2, -1),
cand("a", 0, -1),
cand("b", 1, -1),
cand("v", -1, 0), // vector-only, best vector rank
cand("z", -1, -1),
}
got := selectCentralitySeeds(cands, 3)
want := []string{"a", "v", "b"} // ranks 0, 0, 1 — ties break on ID
if !reflect.DeepEqual(got, want) {
t.Fatalf("seeds = %v, want %v", got, want)
}
}
func TestProximitySignalNormalisesAndScores(t *testing.T) {
cands := []*Candidate{
cand("a", 0, -1),
cand("b", 1, -1),
cand("c", 2, -1),
}
called := false
ctx := &Context{
Centrality: func(seeds []string) map[string]float64 {
called = true
// seeds should be the top-ranked candidates.
if len(seeds) == 0 || seeds[0] != "a" {
t.Errorf("unexpected seeds %v", seeds)
}
// Raw, un-normalised scores; prepare must rescale to [0,1].
return map[string]float64{"a": 10, "b": 5, "c": 0}
},
}
ctx.prepare(cands)
if !called {
t.Fatal("Centrality closure was not invoked")
}
sig := ProximitySignal{}
if got := sig.Contribute("", cands[0], ctx); got != 1.0 {
t.Fatalf("proximity(a) = %v, want 1.0 (batch max)", got)
}
if got := sig.Contribute("", cands[1], ctx); got != 0.5 {
t.Fatalf("proximity(b) = %v, want 0.5", got)
}
if got := sig.Contribute("", cands[2], ctx); got != 0 {
t.Fatalf("proximity(c) = %v, want 0 (zero raw dropped)", got)
}
}
func TestProximitySignalNilProviderDegrades(t *testing.T) {
cands := []*Candidate{cand("a", 0, -1)}
ctx := &Context{} // no Centrality wired
ctx.prepare(cands)
if got := (ProximitySignal{}).Contribute("", cands[0], ctx); got != 0 {
t.Fatalf("proximity with no provider = %v, want 0", got)
}
}
func TestProximityClassMultiplier(t *testing.T) {
// Concept queries lean hardest on proximity; path/symbol dampen it.
concept := ClassWeightMultiplier(QueryClassConcept, SignalProximity)
path := ClassWeightMultiplier(QueryClassPath, SignalProximity)
symbol := ClassWeightMultiplier(QueryClassSymbol, SignalProximity)
if !(concept > symbol && symbol > path) {
t.Fatalf("expected concept(%.2f) > symbol(%.2f) > path(%.2f)", concept, symbol, path)
}
if concept <= 1.0 {
t.Fatalf("concept proximity multiplier should boost (>1.0), got %.2f", concept)
}
// Continuous lever: NL anchor reproduces the concept boost, the
// most BM25-leaning anchor reproduces the path damping.
if nl := continuousClassMultiplier(AlphaNL, SignalProximity); nl != concept {
t.Fatalf("continuous NL proximity = %.3f, want concept %.3f", nl, concept)
}
if p := continuousClassMultiplier(AlphaPath, SignalProximity); p != path {
t.Fatalf("continuous path proximity = %.3f, want path %.3f", p, path)
}
}