blockchain/internal/lib/cassandra/utils_test.go

167 lines
3.8 KiB
Go
Raw Normal View History

2025-08-05 23:41:29 +00:00
package cassandra
import (
"reflect"
"testing"
2025-08-06 07:08:32 +00:00
"time"
"github.com/stretchr/testify/assert"
"github.com/gocql/gocql"
2025-08-05 23:41:29 +00:00
)
2025-08-06 07:08:32 +00:00
func TestGetCqlTag(t *testing.T) {
monkey := &MonkeyEntity{
// 為了測試用,欄位內容可以不給值
ID: gocql.TimeUUID(),
Name: "TestMonkey",
UpdateAt: time.Now(),
CreateAt: time.Now(),
2025-08-05 23:41:29 +00:00
}
2025-08-06 07:08:32 +00:00
tests := []struct {
name string
model interface{}
fieldPtr interface{}
expected string
expectPanic bool
}{
{
name: "取得 Name 的 cql tag",
model: monkey,
fieldPtr: &monkey.Name,
expected: "name",
},
{
name: "取得 ID 的 cql tag",
model: monkey,
fieldPtr: &monkey.ID,
expected: "id",
},
{
name: "取得 UpdateAt 的 cql tag",
model: monkey,
fieldPtr: &monkey.UpdateAt,
expected: "update_at",
},
{
name: "取得 CreateAt 的 cql tag",
model: monkey,
fieldPtr: &monkey.CreateAt,
expected: "create_at",
},
{
name: "找不到對應欄位,回傳空字串",
model: monkey,
fieldPtr: new(int), // 傳入與 MonkeyEntity 無關的欄位指標
expected: "",
},
{
name: "非指向 struct 的 model應該 panic",
model: MonkeyEntity{}, // 非指針
fieldPtr: &monkey.Name,
expected: "",
},
2025-08-05 23:41:29 +00:00
}
2025-08-06 07:08:32 +00:00
for _, tt := range tests {
tt := tt // 捕捉迴圈變數
t.Run(tt.name, func(t *testing.T) {
// 如果預期會 panic則用 recover 進行驗證
if tt.expectPanic {
defer func() {
if r := recover(); r == nil {
t.Errorf("預期測試案例 %q 發生 panic但實際並未 panic", tt.name)
}
}()
_ = GetCqlTag(tt.model, tt.fieldPtr)
} else {
result := GetCqlTag(tt.model, tt.fieldPtr)
if result != tt.expected {
t.Errorf("測試案例 %q: 預期 %q, 但得到 %q", tt.name, tt.expected, result)
}
2025-08-05 23:41:29 +00:00
}
})
}
}
2025-08-06 07:08:32 +00:00
// -------------------- 測試函式 --------------------
2025-08-05 23:41:29 +00:00
// TestToSnakeCase 測試 toSnakeCase 函式
func TestToSnakeCase(t *testing.T) {
testCases := []struct {
input string
expected string
}{
{"CamelCase", "camel_case"},
{"snake_case", "snake_case"},
{"HttpServer", "http_server"},
{"A", "a"},
{"Already_Snake", "already__snake"}, // 依照實作,"Already_Snake" 轉換後會產生 double underscore
}
for _, tc := range testCases {
t.Run(tc.input, func(t *testing.T) {
result := toSnakeCase(tc.input)
assert.Equal(t, tc.expected, result)
})
}
}
func TestIsZero(t *testing.T) {
type testCase struct {
name string
input any
expected bool
}
tests := []testCase{
{"zero int", 0, true},
{"non-zero int", 42, false},
{"zero string", "", true},
{"non-zero string", "hello", false},
{"zero bool", false, true},
{"non-zero bool", true, false},
{"nil slice", []string(nil), true},
{"empty slice", []string{}, false},
{"nil pointer", (*int)(nil), true},
{"non-nil pointer", new(int), false},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
v := reflect.ValueOf(tc.input)
actual := isZero(v)
if actual != tc.expected {
t.Errorf("isZero(%v) = %v; want %v", tc.input, actual, tc.expected)
}
})
}
}
2025-08-06 07:08:32 +00:00
func TestContains(t *testing.T) {
type testCase struct {
name string
list []string
target string
expected bool
}
tests := []testCase{
{"contains first", []string{"a", "b", "c"}, "a", true},
{"contains middle", []string{"a", "b", "c"}, "b", true},
{"contains last", []string{"a", "b", "c"}, "c", true},
{"not contains", []string{"a", "b", "c"}, "d", false},
{"empty list", []string{}, "a", false},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
actual := contains(tc.list, tc.target)
if actual != tc.expected {
t.Errorf("contains(%v, %q) = %v; want %v", tc.list, tc.target, actual, tc.expected)
}
})
}
}