130 lines
3.5 KiB
Go
130 lines
3.5 KiB
Go
package strategy
|
||
|
||
import (
|
||
"github.com/shopspring/decimal"
|
||
"reflect"
|
||
"testing"
|
||
)
|
||
|
||
// --- 表格式驅動測試 (Table-Driven Test) ---
|
||
|
||
func TestRingQD(t *testing.T) {
|
||
// 為了方便測試,預先建立幾個 decimal 數值
|
||
d10 := decimal.NewFromInt(10)
|
||
d20 := decimal.NewFromInt(20)
|
||
d30 := decimal.NewFromInt(30)
|
||
d40 := decimal.NewFromInt(40)
|
||
d50 := decimal.NewFromInt(50)
|
||
d_neg5 := decimal.NewFromInt(-5)
|
||
|
||
// 定義測試案例的結構
|
||
testCases := []struct {
|
||
name string // 測試案例的名稱
|
||
n int // ringQD 的大小
|
||
inputs []decimal.Decimal // 輸入的數值序列
|
||
wantSum decimal.Decimal // 預期的總和
|
||
wantMean decimal.Decimal // 預期的平均值
|
||
wantValues []decimal.Decimal // 預期隊列中最後的值
|
||
wantReady bool // 預期的就緒狀態
|
||
}{
|
||
{
|
||
name: "未滿載的情況",
|
||
n: 5,
|
||
inputs: []decimal.Decimal{d10, d20},
|
||
wantSum: decimal.NewFromInt(30),
|
||
wantMean: decimal.NewFromInt(15),
|
||
wantValues: []decimal.Decimal{d10, d20},
|
||
wantReady: false,
|
||
},
|
||
{
|
||
name: "剛好滿載的情況",
|
||
n: 3,
|
||
inputs: []decimal.Decimal{d10, d20, d30},
|
||
wantSum: decimal.NewFromInt(60),
|
||
wantMean: decimal.NewFromInt(20),
|
||
wantValues: []decimal.Decimal{d10, d20, d30},
|
||
wantReady: true,
|
||
},
|
||
{
|
||
name: "超出容量,舊資料被移除",
|
||
n: 3,
|
||
inputs: []decimal.Decimal{d10, d20, d30, d40, d50},
|
||
wantSum: decimal.NewFromInt(120), // 30 + 40 + 50
|
||
wantMean: decimal.NewFromInt(40),
|
||
wantValues: []decimal.Decimal{d30, d40, d50},
|
||
wantReady: true,
|
||
},
|
||
{
|
||
name: "包含零與負數",
|
||
n: 4,
|
||
inputs: []decimal.Decimal{d10, d_neg5, decimal.Zero, d30, d_neg5},
|
||
wantSum: decimal.NewFromInt(20), // -5 + 0 + 30 + (-5)
|
||
wantMean: decimal.NewFromInt(5),
|
||
wantValues: []decimal.Decimal{d_neg5, decimal.Zero, d30, d_neg5},
|
||
wantReady: true,
|
||
},
|
||
{
|
||
name: "初始為空",
|
||
n: 5,
|
||
inputs: []decimal.Decimal{},
|
||
wantSum: decimal.Zero,
|
||
wantMean: decimal.Zero,
|
||
wantValues: []decimal.Decimal{},
|
||
wantReady: false,
|
||
},
|
||
{
|
||
name: "N 為 1 的邊界情況",
|
||
n: 1,
|
||
inputs: []decimal.Decimal{d10, d20, d30},
|
||
wantSum: d30,
|
||
wantMean: d30,
|
||
wantValues: []decimal.Decimal{d30},
|
||
wantReady: true,
|
||
},
|
||
{
|
||
name: "N 為 0 的無效情況",
|
||
n: 0,
|
||
inputs: []decimal.Decimal{d10, d20, d30},
|
||
wantSum: decimal.Zero,
|
||
wantMean: decimal.Zero,
|
||
wantValues: []decimal.Decimal{},
|
||
wantReady: true,
|
||
},
|
||
}
|
||
|
||
// 遍歷所有測試案例
|
||
for _, tc := range testCases {
|
||
t.Run(tc.name, func(t *testing.T) {
|
||
// 針對每個案例建立一個新的 ringQD
|
||
q := newRingQD(tc.n)
|
||
|
||
// 依序推入資料
|
||
for _, val := range tc.inputs {
|
||
q.push(val)
|
||
}
|
||
|
||
// 驗證總和
|
||
if !q.sum.Equals(tc.wantSum) {
|
||
t.Errorf("Sum 錯誤:got %v, want %v", q.sum, tc.wantSum)
|
||
}
|
||
|
||
// 驗證平均值
|
||
gotMean := q.mean()
|
||
if !gotMean.Equals(tc.wantMean) {
|
||
t.Errorf("Mean 錯誤:got %v, want %v", gotMean, tc.wantMean)
|
||
}
|
||
|
||
// 驗證就緒狀態
|
||
if q.ready() != tc.wantReady {
|
||
t.Errorf("Ready 狀態錯誤:got %v, want %v", q.ready(), tc.wantReady)
|
||
}
|
||
|
||
// 驗證隊列中的值
|
||
gotValues := q.values()
|
||
if !reflect.DeepEqual(gotValues, tc.wantValues) {
|
||
t.Errorf("Values 錯誤:got %v, want %v", gotValues, tc.wantValues)
|
||
}
|
||
})
|
||
}
|
||
}
|