[新增] 添加数据库迁移和 GORM 模型验证测试,确保所有模型均已注册

This commit is contained in:
ryan
2026-06-01 10:33:50 +08:00
parent bd7f008322
commit f034b73a47
+76
View File
@@ -2,7 +2,13 @@ package model
import (
"encoding/json"
"go/ast"
"go/parser"
"go/token"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
"time"
@@ -515,3 +521,73 @@ func TestEnsureDatabaseSchemaUpToDateAddsNodeIPManualOverride(t *testing.T) {
t.Fatalf("unexpected schema version: got %d want %d", version, currentDatabaseSchemaVersion)
}
}
func TestAllRegisteredMigrationsHaveValidationDefined(t *testing.T) {
ctx := databaseSchemaMigrationContext{}
for _, migration := range databaseSchemaMigrations() {
err := ctx.ValidateDatabaseSchemaVersion(nil, "sqlite", migration.toVersion)
if err != nil && strings.Contains(err.Error(), "is not defined") {
t.Fatalf("Validation is not defined in migrations.go for registered migration version v%d: %v", migration.toVersion, err)
}
}
}
func TestAllGORMModelsAreRegistered(t *testing.T) {
// 1. Gather all registered model names
registeredNames := make(map[string]bool)
for _, item := range registeredModels() {
name := reflect.TypeOf(item).Elem().Name()
registeredNames[name] = true
}
for _, item := range schemaMetadataModels() {
name := reflect.TypeOf(item).Elem().Name()
registeredNames[name] = true
}
// 2. Parse all .go files in model/ package
fset := token.NewFileSet()
pkgs, err := parser.ParseDir(fset, ".", func(info os.FileInfo) bool {
// Only parse .go files, exclude _test.go files and subdirectories
return !info.IsDir() && strings.HasSuffix(info.Name(), ".go") && !strings.HasSuffix(info.Name(), "_test.go")
}, 0)
if err != nil {
t.Fatalf("failed to parse directory: %v", err)
}
for _, pkg := range pkgs {
for _, file := range pkg.Files {
for _, decl := range file.Decls {
genDecl, ok := decl.(*ast.GenDecl)
if !ok || genDecl.Tok != token.TYPE {
continue
}
for _, spec := range genDecl.Specs {
typeSpec, ok := spec.(*ast.TypeSpec)
if !ok {
continue
}
structType, ok := typeSpec.Type.(*ast.StructType)
if !ok {
continue
}
// Verify if this struct has any field with a `gorm:"..."` tag
isGORMModel := false
for _, field := range structType.Fields.List {
if field.Tag != nil && strings.Contains(field.Tag.Value, "gorm:") {
isGORMModel = true
break
}
}
if isGORMModel {
structName := typeSpec.Name.Name
if !registeredNames[structName] {
t.Errorf("Model struct %q is defined with GORM tags but is NOT registered in registeredModels() or schemaMetadataModels() in model/main.go!", structName)
}
}
}
}
}
}
}