133 lines
3.3 KiB
Go
133 lines
3.3 KiB
Go
package strategy
|
|
|
|
import (
|
|
"github.com/shopspring/decimal"
|
|
"testing"
|
|
)
|
|
|
|
// --- SMA 的表格式驅動測試 ---
|
|
|
|
func TestSMA(t *testing.T) {
|
|
d10 := decimal.NewFromInt(10)
|
|
d20 := decimal.NewFromInt(20)
|
|
d30 := decimal.NewFromInt(30)
|
|
d40 := decimal.NewFromInt(40)
|
|
d50 := decimal.NewFromInt(50)
|
|
|
|
// 定義 Push 過程中的檢查點結構
|
|
type pushCheck struct {
|
|
wantSMA decimal.Decimal
|
|
wantOK bool
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
n uint
|
|
inputs []decimal.Decimal
|
|
pushChecks []pushCheck // 驗證每一次 Push 的回傳值
|
|
wantFinalSMA decimal.Decimal // 驗證最後 GetSMA 的回傳值
|
|
wantFinalOK bool
|
|
}{
|
|
{
|
|
name: "SMA-5 未滿載",
|
|
n: 5,
|
|
inputs: []decimal.Decimal{d10, d20, d30},
|
|
pushChecks: []pushCheck{
|
|
{decimal.Zero, false},
|
|
{decimal.Zero, false},
|
|
{decimal.Zero, false},
|
|
},
|
|
wantFinalSMA: decimal.Zero,
|
|
wantFinalOK: false,
|
|
},
|
|
{
|
|
name: "SMA-3 剛好滿載",
|
|
n: 3,
|
|
inputs: []decimal.Decimal{d10, d20, d30},
|
|
pushChecks: []pushCheck{
|
|
{decimal.Zero, false},
|
|
{decimal.Zero, false},
|
|
{decimal.NewFromInt(20), true}, // (10+20+30)/3
|
|
},
|
|
wantFinalSMA: decimal.NewFromInt(20),
|
|
wantFinalOK: true,
|
|
},
|
|
{
|
|
name: "SMA-3 滾動計算",
|
|
n: 3,
|
|
inputs: []decimal.Decimal{d10, d20, d30, d40, d50},
|
|
pushChecks: []pushCheck{
|
|
{decimal.Zero, false},
|
|
{decimal.Zero, false},
|
|
{decimal.NewFromInt(20), true}, // (10+20+30)/3
|
|
{decimal.NewFromInt(30), true}, // (20+30+40)/3
|
|
{decimal.NewFromInt(40), true}, // (30+40+50)/3
|
|
},
|
|
wantFinalSMA: decimal.NewFromInt(40),
|
|
wantFinalOK: true,
|
|
},
|
|
{
|
|
name: "SMA-1 邊界情況",
|
|
n: 1,
|
|
inputs: []decimal.Decimal{d10, d20, d30},
|
|
pushChecks: []pushCheck{
|
|
{d10, true},
|
|
{d20, true},
|
|
{d30, true},
|
|
},
|
|
wantFinalSMA: d30,
|
|
wantFinalOK: true,
|
|
},
|
|
{
|
|
name: "SMA-0 無效情況",
|
|
n: 0,
|
|
inputs: []decimal.Decimal{d10, d20, d30},
|
|
pushChecks: []pushCheck{
|
|
{decimal.Zero, false},
|
|
{decimal.Zero, false},
|
|
{decimal.Zero, false},
|
|
},
|
|
wantFinalSMA: decimal.Zero,
|
|
wantFinalOK: false,
|
|
},
|
|
{
|
|
name: "在空實例上呼叫 GetSMA",
|
|
n: 5,
|
|
inputs: []decimal.Decimal{},
|
|
pushChecks: []pushCheck{},
|
|
wantFinalSMA: decimal.Zero,
|
|
wantFinalOK: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
sma := NewSMA(tc.n)
|
|
|
|
// 驗證每一次 Push 的結果
|
|
for i, input := range tc.inputs {
|
|
gotSMA, gotOK := sma.Push(input)
|
|
// 確保 pushChecks 陣列不會索引越界
|
|
if i < len(tc.pushChecks) {
|
|
check := tc.pushChecks[i]
|
|
if gotOK != check.wantOK {
|
|
t.Errorf("Push #%d 的 OK 狀態錯誤: got %v, want %v", i+1, gotOK, check.wantOK)
|
|
}
|
|
if !gotSMA.Equals(check.wantSMA) {
|
|
t.Errorf("Push #%d 的 SMA 值錯誤: got %s, want %s", i+1, gotSMA.String(), check.wantSMA.String())
|
|
}
|
|
}
|
|
}
|
|
|
|
// 在所有 Push 操作完成後,驗證最終 GetSMA 的結果
|
|
finalSMA, finalOK := sma.GetSMA()
|
|
if finalOK != tc.wantFinalOK {
|
|
t.Errorf("最終 GetSMA 的 OK 狀態錯誤: got %v, want %v", finalOK, tc.wantFinalOK)
|
|
}
|
|
if !finalSMA.Equals(tc.wantFinalSMA) {
|
|
t.Errorf("最終 GetSMA 的 SMA 值錯誤: got %s, want %s", finalSMA.String(), tc.wantFinalSMA.String())
|
|
}
|
|
})
|
|
}
|
|
}
|