828c2c5fa0
build / build (push) Successful in 1m6s
使用完整筛选范围的当前有效结论计算覆盖率和正确率,人工优先,失效与对应待确认/未评估/不计入排除;零分母返回null,界面展示原始分子分母和排除构成,前端拒绝不守恒或比例不一致的响应。 验证:make verify退出码0,Go658及前端257通过,91项声明可选集成跳过;隔离PG、三包竞态及合成/真实只读源浏览器验证通过。无新增迁移,不接AI模型,不改绩效,不写源库;本批未推送或部署,8088运行版保持0.1.21。
45 lines
2.1 KiB
Go
45 lines
2.1 KiB
Go
package qaopsquality
|
|
|
|
import (
|
|
"encoding/json"
|
|
"knowledge-governance/internal/dobotaiops"
|
|
"math"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestQualityRatesUseEffectiveCurrentConclusionsAndExplicitDenominators(t *testing.T) {
|
|
views := map[string]View{}
|
|
for i, fields := range []Fields{{Coverage: "covered", Correctness: "correct"}, {Coverage: "covered", Correctness: "incorrect"}, {Coverage: "covered", Correctness: "pending"}, {Coverage: "uncovered"}, {Coverage: "partial", Correctness: "correct"}, {Coverage: "pending", Correctness: "correct"}, {}, {Coverage: "excluded", Correctness: "pending"}, {Coverage: "covered", Correctness: "correct"}, {Coverage: "covered"}} {
|
|
state := "reviewed"
|
|
if i == 3 || i == 6 {
|
|
state = "unreviewed"
|
|
}
|
|
if i == 8 {
|
|
state = "stale"
|
|
}
|
|
views[string(rune('a'+i))] = View{State: state, Effective: fields, Automatic: Check{Result: dobotaiops.CheckAnswerCoverage("暂无已发布")}}
|
|
}
|
|
r := ComputeRates(views)
|
|
if r.PolicyVersion != "quality-rates-human-first-v1" || r.Coverage.Numerator != 4 || r.Coverage.Denominator != 6 || r.Correctness.Numerator != 1 || r.Correctness.Denominator != 2 {
|
|
t.Fatal("effective decisions, partial or exclusion scopes incorrect", r)
|
|
}
|
|
if r.Coverage.Percent == nil || math.Abs(*r.Coverage.Percent-100*float64(4)/6) > 1e-10 || r.Correctness.Percent == nil || *r.Correctness.Percent != 50 {
|
|
t.Fatal("ratio value disagrees with raw counts")
|
|
}
|
|
b := r.Breakdown
|
|
if b.Covered+b.Uncovered+b.Partial+b.Pending+b.Unassessed+b.Excluded+b.Stale != len(views) || b.CoveredCorrect+b.CoveredIncorrect+b.CoveredPending+b.CoveredUnassessed != b.Covered {
|
|
t.Fatal("denominator breakdown not conserved")
|
|
}
|
|
if got := Summarize(views); got.Rates.Coverage.Denominator != 6 {
|
|
t.Fatal("scope summary did not consume the one shared calculation")
|
|
}
|
|
}
|
|
func TestQualityRatesEmptyScopeHasNullPercent(t *testing.T) {
|
|
r := ComputeRates(map[string]View{})
|
|
raw, _ := json.Marshal(r)
|
|
if r.Coverage.Percent != nil || r.Correctness.Percent != nil || strings.Count(string(raw), `"percent":null`) != 2 {
|
|
t.Fatal("zero denominator fabricated zero or full rate")
|
|
}
|
|
}
|