167 lines
3.8 KiB
Go
167 lines
3.8 KiB
Go
package cassandra
|
||
|
||
import (
|
||
"reflect"
|
||
"testing"
|
||
"time"
|
||
|
||
"github.com/stretchr/testify/assert"
|
||
|
||
"github.com/gocql/gocql"
|
||
)
|
||
|
||
func TestGetCqlTag(t *testing.T) {
|
||
monkey := &MonkeyEntity{
|
||
// 為了測試用,欄位內容可以不給值
|
||
ID: gocql.TimeUUID(),
|
||
Name: "TestMonkey",
|
||
UpdateAt: time.Now(),
|
||
CreateAt: time.Now(),
|
||
}
|
||
|
||
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: "",
|
||
},
|
||
}
|
||
|
||
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)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// -------------------- 測試函式 --------------------
|
||
|
||
// 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)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
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)
|
||
}
|
||
})
|
||
}
|
||
}
|