83 lines
2.8 KiB
Go
83 lines
2.8 KiB
Go
package creator
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestComputeWorkGrowth(t *testing.T) {
|
|
now := time.Date(2026, 9, 27, 12, 0, 0, 0, time.UTC)
|
|
likes := func(at time.Time, value int64) MetricPoint {
|
|
return MetricPoint{CollectedAt: at, Likes: &value}
|
|
}
|
|
tooOld := now.Add(-72 * time.Hour)
|
|
|
|
t.Run("full baseline inside window", func(t *testing.T) {
|
|
points := []MetricPoint{
|
|
likes(tooOld, 100),
|
|
likes(now.Add(-25*time.Hour), 200), // 窗口起点前最近点 → 基线
|
|
likes(now.Add(-2*time.Hour), 500),
|
|
}
|
|
growth := computeWorkGrowth(points, now, 24)
|
|
if growth.Likes == nil || *growth.Likes != 300 || growth.Coverage != "full" {
|
|
t.Fatalf("unexpected growth: %+v", growth)
|
|
}
|
|
})
|
|
|
|
t.Run("partial when only one point", func(t *testing.T) {
|
|
points := []MetricPoint{likes(now.Add(-2*time.Hour), 500)}
|
|
growth := computeWorkGrowth(points, now, 24)
|
|
if growth.Likes == nil || *growth.Likes != 0 || growth.Coverage != "partial" {
|
|
t.Fatalf("unexpected growth: %+v", growth)
|
|
}
|
|
})
|
|
|
|
t.Run("partial falls back to first point", func(t *testing.T) {
|
|
points := []MetricPoint{likes(now.Add(-20*time.Hour), 100), likes(now.Add(-2*time.Hour), 500)}
|
|
growth := computeWorkGrowth(points, now, 24)
|
|
// 两个点都在窗口内、窗口前无基线 → 以首点近似,partial。
|
|
if growth.Likes == nil || *growth.Likes != 400 || growth.Coverage != "partial" {
|
|
t.Fatalf("unexpected growth: %+v likes=%v", growth, *growth.Likes)
|
|
}
|
|
})
|
|
|
|
t.Run("old pre-window baseline counts as full", func(t *testing.T) {
|
|
points := []MetricPoint{likes(tooOld, 100), likes(now.Add(-2*time.Hour), 500)}
|
|
growth := computeWorkGrowth(points, now, 24)
|
|
// 窗口前存在真实基线(72h 前)→ full;增量跨 72h 但可比。
|
|
if growth.Likes == nil || *growth.Likes != 400 || growth.Coverage != "full" {
|
|
t.Fatalf("unexpected growth: %+v", growth)
|
|
}
|
|
})
|
|
|
|
t.Run("no points", func(t *testing.T) {
|
|
if growth := (WorkGrowth{}); computeWorkGrowth(nil, now, 24) != growth {
|
|
t.Fatal("empty points must yield zero growth")
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestApplyWorkGrowthFilterPreservesOrderAndFilters(t *testing.T) {
|
|
mk := func(id string, growth int64) (Work, WorkGrowth) {
|
|
value := growth
|
|
return Work{ID: id}, WorkGrowth{Likes: &value, Coverage: "full"}
|
|
}
|
|
w1, g1 := mk("a", 100)
|
|
w2, g2 := mk("b", 900)
|
|
w3, _ := mk("c", 0) // 无采样点:不附加增速
|
|
works := []Work{w1, w2, w3}
|
|
growth := map[string]WorkGrowth{"a": g1, "b": g2}
|
|
|
|
min := int64(50)
|
|
filtered, err := ApplyWorkGrowthFilter(works, growth, WorkGrowthFilter{Hours: 24, MinLikes: &min})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(filtered) != 2 || filtered[0].ID != "a" || filtered[1].ID != "b" {
|
|
t.Fatalf("unexpected filter/order result: %+v", filtered)
|
|
}
|
|
if filtered[0].LikesGrowth == nil || *filtered[0].LikesGrowth != 100 {
|
|
t.Fatalf("growth not attached: %+v", filtered[0])
|
|
}
|
|
}
|