Files
hotime/example/app/app_test.go
T
hoteas b254606003 fix(makecode): 树查询 showself 仅在 showall 时生效
避免 parent_id 懒加载把节点自身混入子级导致无限嵌套,并补充 department 回归用例与文档。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-22 08:58:46 +08:00

151 lines
3.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package app
import (
"encoding/json"
"os"
"path/filepath"
"strings"
"testing"
. "code.hoteas.com/golang/hotime"
)
var ProjectTest = ProjTest{
"test": TestTest,
"mysql": MysqlTest,
"dmdb": DmdbTest,
"cache": CacheTest,
"expect_demo": ExpectDemoTest,
}
var testApp *TestApp
func TestMain(m *testing.M) {
testApp = Test("config/config.json").
WorkDir("..").
Listener(func(ctx *Context) bool {
return false // 空实现:继续进控制器;需要鉴权/拦截时在此写
}).
Swagger("My API", "1.0.0").
Proj(TestProj{
"app": {
Proj: Project,
Tests: ProjectTest,
},
// 通用 CRUDcodeConfig=admin)路由由 Init 时按库表生成,这里仅挂测试
"admin": {
Proj: Proj{},
Tests: AdminDepartmentTest,
},
}).
Flows(DemoFlows)
// 仅本 example:空库时灌演示数据。须连专用测试库,勿对生产库调用。
SetupDatabase(&testApp.Db)
os.Exit(testApp.Run(m))
}
func TestApi(t *testing.T) {
testApp.RunTests(t)
}
// TestListenerChain 验证链式 Listener 在请求路径上被调用。
// 注意:TestMain 已 Chdir 到 example/,此处不再 WorkDir。
func TestListenerChain(t *testing.T) {
hit := false
app := Test("config/config.json").
Listener(func(ctx *Context) bool {
hit = true
return false
}).
Proj(TestProj{
"app": {
Proj: Project,
Tests: ProjTest{
"expect_demo": CtrTest{
"string_result": {Desc: "触发 listener", Func: func(a *Api) {
ExpectDemoTest["string_result"].Func(a)
}},
},
},
},
})
SetupDatabase(&app.Db)
app.RunTests(t)
if !hit {
t.Fatal("Listener 未被调用")
}
_ = app.Db.RollbackTestTx()
}
// TestInterruptStop 模拟提前中断:string_result 跑完后 RequestStopzzz_should_skip 应 Skip
// swagger 中 string_result 的 cases 应保留。注意:TestMain 已 Chdir 到 example/,此处不再 WorkDir。
func TestInterruptStop(t *testing.T) {
var app *TestApp
secondRan := false
app = Test("config/config.json").
Swagger("Interrupt Demo", "1.0.0").
Proj(TestProj{
"app": {
Proj: Project,
Tests: ProjTest{
"expect_demo": CtrTest{
"string_result": {Desc: "先跑并停测", Func: func(a *Api) {
ExpectDemoTest["string_result"].Func(a)
app.RequestStop()
}},
"zzz_should_skip": {Desc: "应被跳过", Func: func(a *Api) {
secondRan = true
t.Error("zzz_should_skip 在 RequestStop 后不应执行")
}},
},
},
},
})
SetupDatabase(&app.Db)
app.RunTests(t)
if secondRan {
t.Fatal("停测后仍执行了后续接口")
}
_ = app.Db.RollbackTestTx()
// 收尾写盘(中断路径下可能未跑满 GenerateSwagger,显式补一次增量合并)
if err := app.GenerateSwagger("Interrupt Demo", "1.0.0", app.Config.GetString("tpt")); err != nil {
t.Fatalf("GenerateSwagger: %v", err)
}
specPath := filepath.Join(app.Config.GetString("tpt"), "swagger", "app", "api-spec.json")
data, err := os.ReadFile(specPath)
if err != nil {
t.Fatalf("应已生成 swagger %s: %v", specPath, err)
}
var spec struct {
Endpoints []struct {
Path string `json:"path"`
Cases json.RawMessage `json:"cases"`
} `json:"endpoints"`
}
if err := json.Unmarshal(data, &spec); err != nil {
t.Fatalf("解析 api-spec 失败: %v", err)
}
found := false
for _, ep := range spec.Endpoints {
if ep.Path != "/app/expect_demo/string_result" {
continue
}
found = true
if !strings.Contains(string(ep.Cases), `"name"`) {
t.Fatalf("string_result 应保留测试 cases,实际: %s", string(ep.Cases))
}
}
if !found {
t.Fatal("swagger 中应包含已跑完的 /app/expect_demo/string_result")
}
}