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