- ui.go: 版本号由硬编码常量改为可注入变量( -X ...web.Version ) - 新增 service.FetchDeviceVersions: 调用 edge /v1/versions 采集 agent 版本/build_id/git_sha + media 引擎版本 + 设备模型数 - 设备详情页: 新增引擎版本/构建信息/模型数量展示 - 设备列表页: 新增版本列(含 build/git 悬停提示) - 构建脚本(3处): 注入 control 版本号(git describe) - 新增模板语法测试(43个模板防回归)
71 lines
2.7 KiB
Go
71 lines
2.7 KiB
Go
package web
|
||
|
||
import (
|
||
"embed"
|
||
"fmt"
|
||
"testing"
|
||
"text/template"
|
||
)
|
||
|
||
//go:embed ui/templates/*.html
|
||
var testTemplateFS embed.FS
|
||
|
||
// 与 ui.go 相同的函数名集合(dummy 实现,仅用于语法验证)
|
||
var testFuncs = template.FuncMap{
|
||
"add": func(a, b int) int { return a + b },
|
||
"ago": func(v any) string { return "" },
|
||
"alarmChannelSource": func(v any) any { return v },
|
||
"auditActionLabel": func(v any) any { return v },
|
||
"auditField": func(v any) any { return v },
|
||
"auditStatusLabel": func(v any) any { return v },
|
||
"displayDeviceName": func(v ...any) string { return "" },
|
||
"displayDeviceTechnicalName": func(v ...any) any { return "" },
|
||
"div": func(a, b int) int { return a / b },
|
||
"formatTime": func(v any) any { return v },
|
||
"formatTuneValue": func(v, s float64) string { return "" },
|
||
"hasString": func(a []string, b string) bool { return false },
|
||
"icon": func(name string) string { return "" },
|
||
"inputBindingRef": func(v any) any { return v },
|
||
"json": func(v any) any { return v },
|
||
"loop": func(n int) []int { return nil },
|
||
"modelTypeLabel": func(v any) any { return v },
|
||
"mul": func(a, b int) int { return a * b },
|
||
"outputBindingValue": func(v ...any) any { return "" },
|
||
"rawHTML": func(v any) any { return v },
|
||
"resourceTypeLabel": func(v any) any { return v },
|
||
"ruleLabel": func(v any) any { return v },
|
||
"serviceBindingRef": func(v any) any { return v },
|
||
"severityClass": func(v any) any { return v },
|
||
"severityLabel": func(v any) any { return v },
|
||
"shortHash": func(v any) any { return v },
|
||
"shortID": func(v any) any { return v },
|
||
"slotTypeLabel": func(v any) any { return v },
|
||
"statusClass": func(v any) any { return v },
|
||
"statusLabel": func(v any) any { return v },
|
||
"sub": func(a, b int) int { return a - b },
|
||
"taskActionLabel": func(v any) any { return v },
|
||
"taskGroupClass": func(v any) any { return v },
|
||
"taskGroupLabel": func(v any) any { return v },
|
||
"taskStatusClass": func(v any) any { return v },
|
||
"taskStatusLabel": func(v any) any { return v },
|
||
}
|
||
|
||
func TestTemplateSyntaxAll(t *testing.T) {
|
||
entries, err := testTemplateFS.ReadDir("ui/templates")
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
for _, e := range entries {
|
||
name := "ui/templates/" + e.Name()
|
||
data, err := testTemplateFS.ReadFile(name)
|
||
if err != nil {
|
||
t.Fatalf("读取 %s: %v", name, err)
|
||
}
|
||
tmpl := template.New(e.Name()).Funcs(testFuncs)
|
||
if _, err := tmpl.Parse(string(data)); err != nil {
|
||
t.Fatalf("模板语法错误 %s: %v", name, err)
|
||
}
|
||
}
|
||
fmt.Printf("全部 %d 个模板语法通过\n", len(entries))
|
||
}
|