package DB import ( "path/filepath" "strings" "testing" ) // TestQueryUnknownFieldReturnsError 回归测试: Where / OrderBy / Select 传了 // 不存在的字段名, 执行入口 (Find / First / Count / Scan) 必须返回带字段名的 // 错误, 而不是静默给出错数据: // - Where("不存在的字段","!=",x): != 翻成 Not(Eq(...)), 未知字段的 Eq 恒 false, // 取反恒 true —— 旧实现静默返回全表; // - OrderBy("不存在的字段"): 旧实现静默不排序。 // // 这是有意为之的行为变更 (以前"未知字段静默查不到"), README 的字段名约定 // 一节已同步更新。 func TestQueryUnknownFieldReturnsError(t *testing.T) { db, err := Open(filepath.Join(t.TempDir(), "q_unknown.db")) if err != nil { t.Fatalf("打开: %v", err) } defer func() { _ = db.Close() }() db.SetAutoCommitDelay(0) tbl, err := UseTable[biRow](db, "qunk") if err != nil { t.Fatalf("建表: %v", err) } for i := 0; i < 20; i++ { if err := tbl.Insert(biMake(i)); err != nil { t.Fatalf("预置 %d: %v", i, err) } } if err := db.Commit(); err != nil { t.Fatalf("提交: %v", err) } assertUnknownField := func(what string, err error) { t.Helper() if err == nil { t.Fatalf("%s: 应返回未知字段错误, 却返回 nil", what) } if !strings.Contains(err.Error(), "NotAField") { t.Fatalf("%s: 错误应包含字段名 NotAField, 得到: %v", what, err) } } // != 是最危险的入口: 旧实现静默返回全表 (20 行), 必须报错 rows, err := tbl.Where("NotAField", "!=", int64(1)).Find() if err == nil { t.Fatalf("Where(!=) 未知字段: 应报错, 实际静默返回 %d 行 (全表)", len(rows)) } assertUnknownField("Where(!=).Find", err) // 其余执行入口同样要拦 _, err = tbl.Where("NotAField", "=", int64(1)).Find() assertUnknownField("Where(=).Find", err) _, err = tbl.Where("NotAField", "=", int64(1)).First() assertUnknownField("Where.First", err) _, err = tbl.Where("NotAField", "=", int64(1)).Count() assertUnknownField("Where.Count", err) err = tbl.Query().Where("NotAField", "=", int64(1)).Scan(func(*biRow) bool { return true }) assertUnknownField("Where.Scan", err) // OrderBy: 旧实现静默不排序 _, err = tbl.Query().OrderBy("NotAField").Find() assertUnknownField("Query.OrderBy.Find", err) _, err = tbl.OrderBy("NotAField").Find() assertUnknownField("Table.OrderBy.Find", err) // Select 投影未知列 _, err = tbl.Query().Select("NotAField").Find() assertUnknownField("Select.Find", err) // 多错聚合: Where 与 OrderBy 都传错字段, 两条错误都要能在 err 里看到 _, err = tbl.Query().Where("BadWhere", "=", 1).OrderBy("BadOrder").Find() if err == nil { t.Fatal("多错聚合: 应报错") } if !strings.Contains(err.Error(), "BadWhere") || !strings.Contains(err.Error(), "BadOrder") { t.Fatalf("多错聚合: 错误应同时包含 BadWhere 与 BadOrder, 得到: %v", err) } // 对照: 合法字段照常工作, 行为不受校验影响 got, err := tbl.Query().Where("Age", ">", int64(0)).OrderBy("Age").Limit(5).Find() if err != nil { t.Fatalf("合法字段查询应正常: %v", err) } if len(got) != 5 { t.Fatalf("合法字段查询: 期望 5 行, 实际 %d", len(got)) } // 列名显式改过时, 自定义列名是合法入口 (不是未知字段) if _, err := tbl.Where("Age", "=", int64(20)).Count(); err != nil { t.Fatalf("Age 索引列查询应正常: %v", err) } }