108 lines
3.0 KiB
Go
108 lines
3.0 KiB
Go
package service
|
||
|
||
import (
|
||
"os"
|
||
"testing"
|
||
|
||
"github.com/topfans/backend/pkg/logger"
|
||
)
|
||
|
||
// TestMain 初始化全局 logger(避免 CalculateLikeBetRevenue 内部 logger.Logger.Debug 触发 nil panic)
|
||
func TestMain(m *testing.M) {
|
||
_ = logger.Init(logger.Config{
|
||
ServiceName: "task-service-test",
|
||
Environment: "test",
|
||
LogLevel: "error", // 测试环境只输出错误日志
|
||
})
|
||
os.Exit(m.Run())
|
||
}
|
||
|
||
// TestCalculateLikeBetRevenue_TableDriven 表驱动测试
|
||
// 公式:R2 = (1 + (N - i)) × R3,其中 R3=1,封顶 100
|
||
// - N = totalLikes(藏品下架时的总点赞数)
|
||
// - i = betOrder(第几位押注者,1=第一个点赞)
|
||
func TestCalculateLikeBetRevenue_TableDriven(t *testing.T) {
|
||
tests := []struct {
|
||
name string
|
||
totalLikes int
|
||
betOrder int
|
||
want int64
|
||
}{
|
||
// 边界
|
||
{"zero_likes", 0, 1, 0},
|
||
{"zero_bet_order", 10, 0, 0},
|
||
{"negative_bet_order", 10, -1, 0},
|
||
|
||
// N=1:第一个(且唯一)点赞者拿 1 水晶
|
||
{"n1_bet1", 1, 1, 1},
|
||
|
||
// N=2:第一个拿 2,第二个拿 1
|
||
{"n2_bet1", 2, 1, 2},
|
||
{"n2_bet2", 2, 2, 1},
|
||
|
||
// N=10:单调递减 10,9,8,...,1
|
||
{"n10_bet1", 10, 1, 10},
|
||
{"n10_bet5", 10, 5, 6},
|
||
{"n10_bet10", 10, 10, 1},
|
||
|
||
// N=30:第 1 个 = 30,...,封顶应该发生在第 1 个(=30)附近
|
||
// 注:公式 (1 + N - i) * 1,第一个点赞 = 1+N-1 = N = 30,未超过 100
|
||
{"n30_bet1", 30, 1, 30},
|
||
{"n30_bet30", 30, 30, 1},
|
||
|
||
// N=50:第 1 个 = 50,未到封顶
|
||
{"n50_bet1", 50, 1, 50},
|
||
{"n50_bet2", 50, 2, 49},
|
||
|
||
// N=100:第 1 个 = 100,正好到封顶
|
||
{"n100_bet1", 100, 1, 100},
|
||
|
||
// N=101:第 1 个 = 101,应被封顶到 100
|
||
{"n101_bet1_cap", 101, 1, 100},
|
||
// 封顶附近
|
||
{"n150_bet51", 150, 51, 100}, // 1+(150-51) = 100,正好
|
||
{"n150_bet1", 150, 1, 100}, // 1+(150-1)=150,封顶到 100
|
||
|
||
// 大数
|
||
{"n1000_bet1_cap", 1000, 1, 100},
|
||
{"n1000_bet950", 1000, 950, 51}, // 1+(1000-950)=51,未到封顶
|
||
}
|
||
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
got := CalculateLikeBetRevenue(tt.totalLikes, tt.betOrder)
|
||
if got != tt.want {
|
||
t.Errorf("CalculateLikeBetRevenue(%d, %d) = %d, want %d",
|
||
tt.totalLikes, tt.betOrder, got, tt.want)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// TestCalculateLikeBetRevenue_MonotonicDecreasing 单调递减:
|
||
// 同一个 totalLikes 下,betOrder 越大,金额越小(或封顶后持平)
|
||
func TestCalculateLikeBetRevenue_MonotonicDecreasing(t *testing.T) {
|
||
const totalLikes = 50
|
||
prev := int64(999999)
|
||
for i := 1; i <= totalLikes; i++ {
|
||
got := CalculateLikeBetRevenue(totalLikes, i)
|
||
if got > prev {
|
||
t.Errorf("betOrder=%d: got %d > prev %d (must be non-increasing)",
|
||
i, got, prev)
|
||
}
|
||
prev = got
|
||
}
|
||
}
|
||
|
||
// TestCalculateLikeBetRevenue_NeverExceedCap 封顶验证:任何 (N, i) 都 <= 100
|
||
func TestCalculateLikeBetRevenue_NeverExceedCap(t *testing.T) {
|
||
for n := 1; n <= 1000; n += 37 {
|
||
for i := 1; i <= n; i += 13 {
|
||
got := CalculateLikeBetRevenue(n, i)
|
||
if got > 100 {
|
||
t.Errorf("CalculateLikeBetRevenue(%d, %d) = %d > 100 (cap)",
|
||
n, i, got)
|
||
}
|
||
}
|
||
}
|
||
} |