Files
ppgo_job/dao/common_test.go
T
lmk 610b85e3a5 refactor: 从 Beego 迁移到 GoFrame v2
- 替换 Beego 框架为 GoFrame v2
- 重构项目结构: controller/service/dao/middleware 分层
- 替换自定义 crons 包为 gcron
- 模板从 views/ 迁移到 resource/template/
- 配置从 conf/app.conf 迁移到 config.yml
- 数据库从 MySQL 切换为 SQLite (modernc.org/sqlite)
- 移除 agent/ 远程执行器(待后续迁移)
- 移除 crons/ 自定义定时器包
- 静态资源整理到 resource/static/
2026-07-09 11:06:12 +08:00

113 lines
3.0 KiB
Go

package dao
import (
"testing"
)
func TestParsePage(t *testing.T) {
tests := []struct {
name string
pageNum int
pageSize int
wantOffset int
wantLimit int
}{
{"normal first page", 1, 20, 0, 20},
{"second page", 2, 20, 20, 20},
{"page 5", 5, 10, 40, 10},
{"page 0 treated as 1", 0, 20, 0, 20},
{"negative page treated as 1", -1, 20, 0, 20},
{"page size 0 defaults to 20", 1, 0, 0, 20},
{"negative page size defaults to 20", 1, -5, 0, 20},
{"page size capped at 1000", 1, 5000, 0, 1000},
{"page size exactly 1000", 1, 1000, 0, 1000},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotOffset, gotLimit := ParsePage(tt.pageNum, tt.pageSize)
if gotOffset != tt.wantOffset {
t.Errorf("ParsePage(%d, %d) offset = %d, want %d", tt.pageNum, tt.pageSize, gotOffset, tt.wantOffset)
}
if gotLimit != tt.wantLimit {
t.Errorf("ParsePage(%d, %d) limit = %d, want %d", tt.pageNum, tt.pageSize, gotLimit, tt.wantLimit)
}
})
}
}
func TestParsePagePage3Size15(t *testing.T) {
offset, limit := ParsePage(3, 15)
if offset != 30 {
t.Errorf("offset = %d, want 30", offset)
}
if limit != 15 {
t.Errorf("limit = %d, want 15", limit)
}
}
// TestFilterLogic tests the filter pairing logic that buildFilters relies on.
// The actual buildFilters function requires a real gdb.DB connection, so we
// validate the K/V pairing semantics here directly.
func TestFilterLogic(t *testing.T) {
tests := []struct {
name string
filters []interface{}
wantOK int // expected number of valid (string, value) pairs
}{
{"nil filters", nil, 0},
{"empty filters", []interface{}{}, 0},
{"single pair", []interface{}{"status", 1}, 1},
{"two pairs", []interface{}{"status", 1, "group_id", 5}, 2},
{"odd number of args", []interface{}{"status", 1, "group_id"}, 1},
{"non-string key", []interface{}{123, "value"}, 0},
{"mixed valid and invalid", []interface{}{"status", 1, 123, "value", "group_id", 5}, 2},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
pairs := 0
if tt.filters != nil {
for k := 0; k < len(tt.filters); k += 2 {
if k+1 < len(tt.filters) {
if _, ok := tt.filters[k].(string); ok {
pairs++
}
}
}
}
if pairs != tt.wantOK {
t.Errorf("有效过滤对数量 = %d, 期望 %d", pairs, tt.wantOK)
}
})
}
// Also verify that the logic never panics on edge cases
edgeCases := []struct {
name string
filters []interface{}
}{
{"nil", nil},
{"empty", []interface{}{}},
{"odd length", []interface{}{"status", 1, "group_id"}},
{"non-string key", []interface{}{123, "value"}},
}
for _, ec := range edgeCases {
t.Run("no_panic_"+ec.name, func(t *testing.T) {
defer func() {
if r := recover(); r != nil {
t.Errorf("unexpected panic: %v", r)
}
}()
if ec.filters == nil {
return
}
for k := 0; k < len(ec.filters); k += 2 {
if k+1 < len(ec.filters) {
if _, ok := ec.filters[k].(string); ok {
_ = ec.filters[k+1]
}
}
}
})
}
}