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)
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|