879 lines
20 KiB
Go
879 lines
20 KiB
Go
package main
|
||
|
||
import (
|
||
"os"
|
||
"path/filepath"
|
||
"strings"
|
||
"testing"
|
||
)
|
||
|
||
// TestLoadConfigFile 测试配置文件加载
|
||
func TestLoadConfigFile(t *testing.T) {
|
||
// 创建临时目录
|
||
tmpDir := t.TempDir()
|
||
|
||
// 测试 YAML 配置文件
|
||
t.Run("YAML配置文件", func(t *testing.T) {
|
||
yamlContent := `package: example
|
||
structName: Article
|
||
tableName: articles
|
||
description: 文章管理
|
||
businessDB: ""
|
||
abbreviation: article
|
||
options:
|
||
gvaModel: true
|
||
autoMigrate: true
|
||
generateWeb: true
|
||
generateServer: true
|
||
fields:
|
||
- fieldName: Title
|
||
fieldDesc: 标题
|
||
fieldType: string
|
||
fieldJson: title
|
||
columnName: title
|
||
form: true
|
||
table: true
|
||
require: true
|
||
`
|
||
yamlPath := filepath.Join(tmpDir, "test.yaml")
|
||
if err := os.WriteFile(yamlPath, []byte(yamlContent), 0644); err != nil {
|
||
t.Fatalf("创建测试文件失败: %v", err)
|
||
}
|
||
|
||
config, err := loadConfigFile(yamlPath)
|
||
if err != nil {
|
||
t.Fatalf("加载 YAML 配置失败: %v", err)
|
||
}
|
||
|
||
if config.Package != "example" {
|
||
t.Errorf("Package = %s, 期望 example", config.Package)
|
||
}
|
||
if config.StructName != "Article" {
|
||
t.Errorf("StructName = %s, 期望 Article", config.StructName)
|
||
}
|
||
if config.TableName != "articles" {
|
||
t.Errorf("TableName = %s, 期望 articles", config.TableName)
|
||
}
|
||
if len(config.Fields) != 1 {
|
||
t.Errorf("Fields 数量 = %d, 期望 1", len(config.Fields))
|
||
}
|
||
})
|
||
|
||
// 测试 JSON 配置文件
|
||
t.Run("JSON配置文件", func(t *testing.T) {
|
||
jsonContent := `{
|
||
"package": "user",
|
||
"structName": "User",
|
||
"tableName": "users",
|
||
"description": "用户管理",
|
||
"options": {
|
||
"gvaModel": true,
|
||
"generateWeb": true,
|
||
"generateServer": true
|
||
}
|
||
}`
|
||
jsonPath := filepath.Join(tmpDir, "test.json")
|
||
if err := os.WriteFile(jsonPath, []byte(jsonContent), 0644); err != nil {
|
||
t.Fatalf("创建测试文件失败: %v", err)
|
||
}
|
||
|
||
config, err := loadConfigFile(jsonPath)
|
||
if err != nil {
|
||
t.Fatalf("加载 JSON 配置失败: %v", err)
|
||
}
|
||
|
||
if config.Package != "user" {
|
||
t.Errorf("Package = %s, 期望 user", config.Package)
|
||
}
|
||
if config.StructName != "User" {
|
||
t.Errorf("StructName = %s, 期望 User", config.StructName)
|
||
}
|
||
})
|
||
|
||
// 测试不支持的文件格式
|
||
t.Run("不支持的文件格式", func(t *testing.T) {
|
||
txtPath := filepath.Join(tmpDir, "test.txt")
|
||
if err := os.WriteFile(txtPath, []byte("invalid"), 0644); err != nil {
|
||
t.Fatalf("创建测试文件失败: %v", err)
|
||
}
|
||
|
||
_, err := loadConfigFile(txtPath)
|
||
if err == nil {
|
||
t.Error("期望返回错误,但没有")
|
||
}
|
||
if !strings.Contains(err.Error(), "不支持的配置文件格式") {
|
||
t.Errorf("错误信息应包含 '不支持的配置文件格式', 实际: %v", err)
|
||
}
|
||
})
|
||
|
||
// 测试文件不存在
|
||
t.Run("文件不存在", func(t *testing.T) {
|
||
_, err := loadConfigFile(filepath.Join(tmpDir, "nonexistent.yaml"))
|
||
if err == nil {
|
||
t.Error("期望返回错误,但没有")
|
||
}
|
||
})
|
||
}
|
||
|
||
// TestValidateConfig 测试配置验证
|
||
func TestValidateConfig(t *testing.T) {
|
||
testCases := []struct {
|
||
name string
|
||
config *AutoCodeConfig
|
||
expectError bool
|
||
errorMsg string
|
||
}{
|
||
{
|
||
name: "有效配置",
|
||
config: &AutoCodeConfig{
|
||
Package: "example",
|
||
StructName: "Article",
|
||
TableName: "articles",
|
||
},
|
||
expectError: false,
|
||
},
|
||
{
|
||
name: "缺少包名",
|
||
config: &AutoCodeConfig{
|
||
Package: "",
|
||
StructName: "Article",
|
||
TableName: "articles",
|
||
},
|
||
expectError: true,
|
||
errorMsg: "包名不能为空",
|
||
},
|
||
{
|
||
name: "缺少结构体名",
|
||
config: &AutoCodeConfig{
|
||
Package: "example",
|
||
StructName: "",
|
||
TableName: "articles",
|
||
},
|
||
expectError: true,
|
||
errorMsg: "结构体名不能为空",
|
||
},
|
||
{
|
||
name: "缺少表名",
|
||
config: &AutoCodeConfig{
|
||
Package: "example",
|
||
StructName: "Article",
|
||
TableName: "",
|
||
},
|
||
expectError: true,
|
||
errorMsg: "表名不能为空",
|
||
},
|
||
}
|
||
|
||
for _, tc := range testCases {
|
||
t.Run(tc.name, func(t *testing.T) {
|
||
err := validateConfig(tc.config)
|
||
if tc.expectError {
|
||
if err == nil {
|
||
t.Error("期望返回错误,但没有")
|
||
} else if !strings.Contains(err.Error(), tc.errorMsg) {
|
||
t.Errorf("错误信息应包含 '%s', 实际: %v", tc.errorMsg, err)
|
||
}
|
||
} else {
|
||
if err != nil {
|
||
t.Errorf("不期望错误,但得到: %v", err)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// TestBuildConfigFromFlags 测试从命令行参数构建配置
|
||
func TestBuildConfigFromFlags(t *testing.T) {
|
||
// 设置全局变量
|
||
tableName = "articles"
|
||
packageName = "example"
|
||
structName = "Article"
|
||
desc = "文章管理"
|
||
dbName = "test_db"
|
||
noWeb = false
|
||
noServer = false
|
||
|
||
config := buildConfigFromFlags()
|
||
|
||
if config.Package != "example" {
|
||
t.Errorf("Package = %s, 期望 example", config.Package)
|
||
}
|
||
if config.StructName != "Article" {
|
||
t.Errorf("StructName = %s, 期望 Article", config.StructName)
|
||
}
|
||
if config.TableName != "articles" {
|
||
t.Errorf("TableName = %s, 期望 articles", config.TableName)
|
||
}
|
||
if config.Description != "文章管理" {
|
||
t.Errorf("Description = %s, 期望 文章管理", config.Description)
|
||
}
|
||
if config.BusinessDB != "test_db" {
|
||
t.Errorf("BusinessDB = %s, 期望 test_db", config.BusinessDB)
|
||
}
|
||
// 验证默认选项
|
||
if !config.Options.GvaModel {
|
||
t.Error("GvaModel 应该默认为 true")
|
||
}
|
||
if !config.Options.AutoMigrate {
|
||
t.Error("AutoMigrate 应该默认为 true")
|
||
}
|
||
if !config.Options.GenerateWeb {
|
||
t.Error("GenerateWeb 应该默认为 true")
|
||
}
|
||
if !config.Options.GenerateServer {
|
||
t.Error("GenerateServer 应该默认为 true")
|
||
}
|
||
|
||
// 重置全局变量
|
||
tableName = ""
|
||
packageName = ""
|
||
structName = ""
|
||
desc = ""
|
||
dbName = ""
|
||
}
|
||
|
||
// TestApplyFlagOverrides 测试命令行参数覆盖
|
||
func TestApplyFlagOverrides(t *testing.T) {
|
||
config := &AutoCodeConfig{
|
||
Options: AutoCodeOptions{
|
||
GenerateWeb: true,
|
||
GenerateServer: true,
|
||
OnlyTemplate: false,
|
||
IsAdd: false,
|
||
IsTree: false,
|
||
TreeJson: "",
|
||
},
|
||
}
|
||
|
||
// 测试 noWeb 覆盖
|
||
noWeb = true
|
||
applyFlagOverrides(config)
|
||
if config.Options.GenerateWeb {
|
||
t.Error("GenerateWeb 应该被覆盖为 false")
|
||
}
|
||
noWeb = false
|
||
|
||
// 测试 noServer 覆盖
|
||
config.Options.GenerateServer = true
|
||
noServer = true
|
||
applyFlagOverrides(config)
|
||
if config.Options.GenerateServer {
|
||
t.Error("GenerateServer 应该被覆盖为 false")
|
||
}
|
||
noServer = false
|
||
|
||
// 测试 onlyTemplate 覆盖
|
||
onlyTemplate = true
|
||
applyFlagOverrides(config)
|
||
if !config.Options.OnlyTemplate {
|
||
t.Error("OnlyTemplate 应该被覆盖为 true")
|
||
}
|
||
onlyTemplate = false
|
||
|
||
// 测试 isAdd 覆盖
|
||
isAdd = true
|
||
applyFlagOverrides(config)
|
||
if !config.Options.IsAdd {
|
||
t.Error("IsAdd 应该被覆盖为 true")
|
||
}
|
||
isAdd = false
|
||
|
||
// 测试 isTree 覆盖
|
||
isTree = true
|
||
treeJson = "name"
|
||
applyFlagOverrides(config)
|
||
if !config.Options.IsTree {
|
||
t.Error("IsTree 应该被覆盖为 true")
|
||
}
|
||
if config.Options.TreeJson != "name" {
|
||
t.Errorf("TreeJson = %s, 期望 name", config.Options.TreeJson)
|
||
}
|
||
isTree = false
|
||
treeJson = ""
|
||
}
|
||
|
||
// TestHasRequiredFlags 测试必要参数检查
|
||
func TestHasRequiredFlags(t *testing.T) {
|
||
// 重置全局变量
|
||
tableName = ""
|
||
packageName = ""
|
||
structName = ""
|
||
|
||
// 测试缺少参数
|
||
if hasRequiredFlags() {
|
||
t.Error("缺少参数时应返回 false")
|
||
}
|
||
|
||
// 测试只有部分参数
|
||
tableName = "articles"
|
||
if hasRequiredFlags() {
|
||
t.Error("只有 tableName 时应返回 false")
|
||
}
|
||
|
||
packageName = "example"
|
||
if hasRequiredFlags() {
|
||
t.Error("缺少 structName 时应返回 false")
|
||
}
|
||
|
||
// 测试所有参数都有
|
||
structName = "Article"
|
||
if !hasRequiredFlags() {
|
||
t.Error("所有参数都有时应返回 true")
|
||
}
|
||
|
||
// 重置
|
||
tableName = ""
|
||
packageName = ""
|
||
structName = ""
|
||
}
|
||
|
||
// TestBoolToStr 测试布尔值转字符串
|
||
func TestBoolToStr(t *testing.T) {
|
||
if boolToStr(true) != "是" {
|
||
t.Error("true 应该转换为 '是'")
|
||
}
|
||
if boolToStr(false) != "否" {
|
||
t.Error("false 应该转换为 '否'")
|
||
}
|
||
}
|
||
|
||
// TestGetWorkingDir 测试获取工作目录
|
||
func TestGetWorkingDir(t *testing.T) {
|
||
// 测试默认情况
|
||
outputDir = ""
|
||
dir := getWorkingDir()
|
||
if dir == "" {
|
||
t.Error("工作目录不应为空")
|
||
}
|
||
|
||
// 测试指定输出目录
|
||
outputDir = "/custom/path"
|
||
dir = getWorkingDir()
|
||
if dir != "/custom/path" {
|
||
t.Errorf("工作目录 = %s, 期望 /custom/path", dir)
|
||
}
|
||
|
||
// 重置
|
||
outputDir = ""
|
||
}
|
||
|
||
// TestGetTemplateDir 测试获取模板目录
|
||
func TestGetTemplateDir(t *testing.T) {
|
||
// 测试默认情况
|
||
templateDir = ""
|
||
dir := getTemplateDir()
|
||
if dir != "resource/package" {
|
||
t.Errorf("模板目录 = %s, 期望 resource/package", dir)
|
||
}
|
||
|
||
// 测试指定模板目录
|
||
templateDir = "/custom/templates"
|
||
dir = getTemplateDir()
|
||
if dir != "/custom/templates" {
|
||
t.Errorf("模板目录 = %s, 期望 /custom/templates", dir)
|
||
}
|
||
|
||
// 重置
|
||
templateDir = ""
|
||
}
|
||
|
||
// TestToCamelCase 测试驼峰命名转换
|
||
func TestToCamelCase(t *testing.T) {
|
||
testCases := []struct {
|
||
input string
|
||
expected string
|
||
}{
|
||
{"user_name", "UserName"},
|
||
{"article_status", "ArticleStatus"},
|
||
{"id", "Id"},
|
||
{"created_at", "CreatedAt"},
|
||
{"", ""},
|
||
{"simple", "Simple"},
|
||
{"a_b_c", "ABC"},
|
||
}
|
||
|
||
for _, tc := range testCases {
|
||
result := toCamelCase(tc.input)
|
||
if result != tc.expected {
|
||
t.Errorf("toCamelCase(%s) = %s, 期望 %s", tc.input, result, tc.expected)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestToLowerCamelCase 测试小驼峰命名转换
|
||
func TestToLowerCamelCase(t *testing.T) {
|
||
testCases := []struct {
|
||
input string
|
||
expected string
|
||
}{
|
||
{"user_name", "userName"},
|
||
{"article_status", "articleStatus"},
|
||
{"id", "id"},
|
||
{"created_at", "createdAt"},
|
||
{"", ""},
|
||
{"simple", "simple"},
|
||
}
|
||
|
||
for _, tc := range testCases {
|
||
result := toLowerCamelCase(tc.input)
|
||
if result != tc.expected {
|
||
t.Errorf("toLowerCamelCase(%s) = %s, 期望 %s", tc.input, result, tc.expected)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestIsSystemField 测试系统字段判断
|
||
func TestIsSystemField(t *testing.T) {
|
||
systemFields := []string{
|
||
"id", "ID", "Id",
|
||
"created_at", "CREATED_AT",
|
||
"updated_at", "UPDATED_AT",
|
||
"deleted_at", "DELETED_AT",
|
||
"create_time", "update_time", "delete_time",
|
||
"created_by", "updated_by", "deleted_by",
|
||
}
|
||
|
||
for _, field := range systemFields {
|
||
if !isSystemField(field) {
|
||
t.Errorf("isSystemField(%s) 应该返回 true", field)
|
||
}
|
||
}
|
||
|
||
nonSystemFields := []string{
|
||
"title", "content", "status", "name", "email",
|
||
}
|
||
|
||
for _, field := range nonSystemFields {
|
||
if isSystemField(field) {
|
||
t.Errorf("isSystemField(%s) 应该返回 false", field)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestMapDBTypeToGoType 测试数据库类型到 Go 类型映射
|
||
func TestMapDBTypeToGoType(t *testing.T) {
|
||
testCases := []struct {
|
||
dbType string
|
||
expected string
|
||
}{
|
||
// 整数类型
|
||
{"int", "int"},
|
||
{"INT", "int"},
|
||
{"integer", "int"},
|
||
{"smallint", "int"},
|
||
{"mediumint", "int"},
|
||
{"tinyint", "int"},
|
||
{"bigint", "int64"},
|
||
{"BIGINT", "int64"},
|
||
// 浮点类型
|
||
{"float", "float64"},
|
||
{"double", "float64"},
|
||
{"decimal", "float64"},
|
||
{"numeric", "float64"},
|
||
{"real", "float64"},
|
||
// 布尔类型
|
||
{"bool", "bool"},
|
||
{"boolean", "bool"},
|
||
// 时间类型
|
||
{"date", "time.Time"},
|
||
{"datetime", "time.Time"},
|
||
{"timestamp", "time.Time"},
|
||
{"time", "time.Time"},
|
||
// JSON 类型
|
||
{"json", "datatypes.JSON"},
|
||
{"jsonb", "datatypes.JSON"},
|
||
// 文本类型
|
||
{"text", "string"},
|
||
{"longtext", "string"},
|
||
{"mediumtext", "string"},
|
||
{"tinytext", "string"},
|
||
{"varchar", "string"},
|
||
{"char", "string"},
|
||
{"character varying", "string"},
|
||
// 二进制类型
|
||
{"blob", "[]byte"},
|
||
{"longblob", "[]byte"},
|
||
{"mediumblob", "[]byte"},
|
||
{"tinyblob", "[]byte"},
|
||
{"bytea", "[]byte"},
|
||
// 未知类型
|
||
{"unknown", "string"},
|
||
}
|
||
|
||
for _, tc := range testCases {
|
||
result := mapDBTypeToGoType(tc.dbType)
|
||
if result != tc.expected {
|
||
t.Errorf("mapDBTypeToGoType(%s) = %s, 期望 %s", tc.dbType, result, tc.expected)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestFormatDataTypeLong 测试数据类型长度格式化
|
||
func TestFormatDataTypeLong(t *testing.T) {
|
||
testCases := []struct {
|
||
dataType string
|
||
dataTypeLong string
|
||
expected string
|
||
}{
|
||
{"varchar", "255", "varchar(255)"},
|
||
{"int", "11", "int(11)"},
|
||
{"decimal", "10,2", "decimal(10,2)"},
|
||
{"text", "", "text"},
|
||
{"text", "0", "text"},
|
||
{"text", "<nil>", "text"},
|
||
}
|
||
|
||
for _, tc := range testCases {
|
||
result := formatDataTypeLong(tc.dataType, tc.dataTypeLong)
|
||
if result != tc.expected {
|
||
t.Errorf("formatDataTypeLong(%s, %s) = %s, 期望 %s", tc.dataType, tc.dataTypeLong, result, tc.expected)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestBoolToYesNo 测试布尔值转是/否
|
||
func TestBoolToYesNo(t *testing.T) {
|
||
if boolToYesNo(true) != "是" {
|
||
t.Error("true 应该转换为 '是'")
|
||
}
|
||
if boolToYesNo(false) != "否" {
|
||
t.Error("false 应该转换为 '否'")
|
||
}
|
||
}
|
||
|
||
// TestGetTemplateList 测试获取模板列表
|
||
func TestGetTemplateList(t *testing.T) {
|
||
config := &AutoCodeConfig{
|
||
Package: "example",
|
||
StructName: "Article",
|
||
Options: AutoCodeOptions{
|
||
GenerateServer: true,
|
||
GenerateWeb: true,
|
||
},
|
||
}
|
||
|
||
templates := getTemplateList(config)
|
||
|
||
// 验证后端模板数量
|
||
serverCount := 0
|
||
webCount := 0
|
||
for _, tpl := range templates {
|
||
if tpl.Type == "server" {
|
||
serverCount++
|
||
} else if tpl.Type == "web" {
|
||
webCount++
|
||
}
|
||
}
|
||
|
||
if serverCount == 0 {
|
||
t.Error("应该有后端模板")
|
||
}
|
||
if webCount == 0 {
|
||
t.Error("应该有前端模板")
|
||
}
|
||
|
||
// 测试只生成后端
|
||
config.Options.GenerateWeb = false
|
||
templates = getTemplateList(config)
|
||
webCount = 0
|
||
for _, tpl := range templates {
|
||
if tpl.Type == "web" {
|
||
webCount++
|
||
}
|
||
}
|
||
if webCount != 0 {
|
||
t.Error("不应该有前端模板")
|
||
}
|
||
|
||
// 测试只生成前端
|
||
config.Options.GenerateServer = false
|
||
config.Options.GenerateWeb = true
|
||
templates = getTemplateList(config)
|
||
serverCount = 0
|
||
for _, tpl := range templates {
|
||
if tpl.Type == "server" {
|
||
serverCount++
|
||
}
|
||
}
|
||
if serverCount != 0 {
|
||
t.Error("不应该有后端模板")
|
||
}
|
||
}
|
||
|
||
// TestBuildTemplateData 测试构建模板数据
|
||
func TestBuildTemplateData(t *testing.T) {
|
||
config := &AutoCodeConfig{
|
||
Package: "example",
|
||
StructName: "Article",
|
||
TableName: "articles",
|
||
Description: "文章管理",
|
||
BusinessDB: "test_db",
|
||
Abbreviation: "article",
|
||
Options: AutoCodeOptions{
|
||
GvaModel: true,
|
||
AutoMigrate: true,
|
||
IsTree: false,
|
||
},
|
||
Fields: []AutoCodeField{
|
||
{
|
||
FieldName: "Title",
|
||
FieldDesc: "标题",
|
||
FieldType: "string",
|
||
FieldJson: "title",
|
||
ColumnName: "title",
|
||
Form: true,
|
||
Table: true,
|
||
PrimaryKey: false,
|
||
},
|
||
{
|
||
FieldName: "ID",
|
||
FieldDesc: "主键",
|
||
FieldType: "uint",
|
||
FieldJson: "ID",
|
||
ColumnName: "id",
|
||
PrimaryKey: true,
|
||
},
|
||
},
|
||
}
|
||
|
||
data := buildTemplateData(config)
|
||
|
||
// 验证基本字段
|
||
if data["Package"] != "example" {
|
||
t.Errorf("Package = %v, 期望 example", data["Package"])
|
||
}
|
||
if data["StructName"] != "Article" {
|
||
t.Errorf("StructName = %v, 期望 Article", data["StructName"])
|
||
}
|
||
if data["TableName"] != "articles" {
|
||
t.Errorf("TableName = %v, 期望 articles", data["TableName"])
|
||
}
|
||
if data["Description"] != "文章管理" {
|
||
t.Errorf("Description = %v, 期望 文章管理", data["Description"])
|
||
}
|
||
|
||
// 验证主键字段
|
||
primaryField, ok := data["PrimaryField"]
|
||
if !ok {
|
||
t.Error("应该有 PrimaryField")
|
||
}
|
||
// 类型断言检查
|
||
if pf, ok := primaryField.(map[string]interface{}); ok {
|
||
if pf["FieldName"] != "ID" {
|
||
t.Errorf("PrimaryField.FieldName = %v, 期望 ID", pf["FieldName"])
|
||
}
|
||
}
|
||
|
||
// 验证选项
|
||
if data["GvaModel"] != true {
|
||
t.Error("GvaModel 应该为 true")
|
||
}
|
||
if data["AutoMigrate"] != true {
|
||
t.Error("AutoMigrate 应该为 true")
|
||
}
|
||
}
|
||
|
||
// TestRootCmdHelp 测试根命令帮助信息
|
||
func TestRootCmdHelp(t *testing.T) {
|
||
// 验证根命令的基本属性
|
||
if rootCmd.Use != "kra-gen" {
|
||
t.Errorf("rootCmd.Use = %s, 期望 kra-gen", rootCmd.Use)
|
||
}
|
||
if rootCmd.Short == "" {
|
||
t.Error("rootCmd.Short 不应为空")
|
||
}
|
||
if rootCmd.Long == "" {
|
||
t.Error("rootCmd.Long 不应为空")
|
||
}
|
||
if !strings.Contains(rootCmd.Long, "KRA") {
|
||
t.Error("rootCmd.Long 应包含 'KRA'")
|
||
}
|
||
if !strings.Contains(rootCmd.Long, "代码生成") {
|
||
t.Error("rootCmd.Long 应包含 '代码生成'")
|
||
}
|
||
}
|
||
|
||
// TestVersionCmd 测试版本命令
|
||
func TestVersionCmd(t *testing.T) {
|
||
// 验证版本命令存在
|
||
found := false
|
||
for _, cmd := range rootCmd.Commands() {
|
||
if cmd.Use == "version" {
|
||
found = true
|
||
if cmd.Short == "" {
|
||
t.Error("version 命令的 Short 不应为空")
|
||
}
|
||
break
|
||
}
|
||
}
|
||
if !found {
|
||
t.Error("应该有 version 子命令")
|
||
}
|
||
|
||
// 验证版本变量
|
||
if version == "" {
|
||
t.Error("version 变量不应为空")
|
||
}
|
||
}
|
||
|
||
// TestListCmd 测试列表命令
|
||
func TestListCmd(t *testing.T) {
|
||
// 验证 list 命令存在
|
||
found := false
|
||
for _, cmd := range rootCmd.Commands() {
|
||
if cmd.Use == "list [templates|packages|databases]" {
|
||
found = true
|
||
if cmd.Short == "" {
|
||
t.Error("list 命令的 Short 不应为空")
|
||
}
|
||
break
|
||
}
|
||
}
|
||
if !found {
|
||
t.Error("应该有 list 子命令")
|
||
}
|
||
}
|
||
|
||
// TestListTemplates 测试列出模板功能
|
||
func TestListTemplates(t *testing.T) {
|
||
// 这个函数只是打印输出,验证它不会 panic
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
t.Errorf("listTemplates() panic: %v", r)
|
||
}
|
||
}()
|
||
// 函数执行不应该 panic
|
||
// listTemplates() 会打印到 stdout,这里只验证不会崩溃
|
||
}
|
||
|
||
// TestListPackages 测试列出包功能
|
||
func TestListPackages(t *testing.T) {
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
t.Errorf("listPackages() panic: %v", r)
|
||
}
|
||
}()
|
||
}
|
||
|
||
// TestListDatabases 测试列出数据库功能
|
||
func TestListDatabases(t *testing.T) {
|
||
defer func() {
|
||
if r := recover(); r != nil {
|
||
t.Errorf("listDatabases() panic: %v", r)
|
||
}
|
||
}()
|
||
}
|
||
|
||
// TestAutoCodeFieldConversion 测试字段配置转换
|
||
func TestAutoCodeFieldConversion(t *testing.T) {
|
||
field := AutoCodeField{
|
||
FieldName: "Title",
|
||
FieldDesc: "标题",
|
||
FieldType: "string",
|
||
FieldJson: "title",
|
||
ColumnName: "title",
|
||
DataTypeLong: "varchar(255)",
|
||
Form: true,
|
||
Table: true,
|
||
Desc: true,
|
||
Excel: false,
|
||
Require: true,
|
||
DefaultValue: "",
|
||
ErrorText: "标题不能为空",
|
||
Clearable: true,
|
||
Sort: false,
|
||
FieldSearchType: "LIKE",
|
||
FieldSearchHide: false,
|
||
DictType: "",
|
||
DataSource: nil,
|
||
FieldIndexType: "",
|
||
PrimaryKey: false,
|
||
}
|
||
|
||
// 验证字段属性
|
||
if field.FieldName != "Title" {
|
||
t.Errorf("FieldName = %s, 期望 Title", field.FieldName)
|
||
}
|
||
if !field.Form {
|
||
t.Error("Form 应该为 true")
|
||
}
|
||
if !field.Table {
|
||
t.Error("Table 应该为 true")
|
||
}
|
||
if !field.Require {
|
||
t.Error("Require 应该为 true")
|
||
}
|
||
if field.FieldSearchType != "LIKE" {
|
||
t.Errorf("FieldSearchType = %s, 期望 LIKE", field.FieldSearchType)
|
||
}
|
||
}
|
||
|
||
// TestAutoCodeOptionsDefaults 测试选项默认值
|
||
func TestAutoCodeOptionsDefaults(t *testing.T) {
|
||
options := AutoCodeOptions{
|
||
GvaModel: true,
|
||
AutoMigrate: true,
|
||
AutoCreateResource: false,
|
||
AutoCreateApiToSql: true,
|
||
AutoCreateMenuToSql: true,
|
||
AutoCreateBtnAuth: true,
|
||
OnlyTemplate: false,
|
||
IsTree: false,
|
||
TreeJson: "",
|
||
IsAdd: false,
|
||
GenerateWeb: true,
|
||
GenerateServer: true,
|
||
}
|
||
|
||
// 验证默认值
|
||
if !options.GvaModel {
|
||
t.Error("GvaModel 默认应该为 true")
|
||
}
|
||
if !options.AutoMigrate {
|
||
t.Error("AutoMigrate 默认应该为 true")
|
||
}
|
||
if !options.GenerateWeb {
|
||
t.Error("GenerateWeb 默认应该为 true")
|
||
}
|
||
if !options.GenerateServer {
|
||
t.Error("GenerateServer 默认应该为 true")
|
||
}
|
||
if options.OnlyTemplate {
|
||
t.Error("OnlyTemplate 默认应该为 false")
|
||
}
|
||
if options.IsAdd {
|
||
t.Error("IsAdd 默认应该为 false")
|
||
}
|
||
}
|
||
|
||
// TestDataSourceConfig 测试数据源配置
|
||
func TestDataSourceConfig(t *testing.T) {
|
||
ds := DataSource{
|
||
DBName: "test_db",
|
||
Table: "categories",
|
||
Label: "name",
|
||
Value: "id",
|
||
Association: 1,
|
||
HasDeletedAt: true,
|
||
}
|
||
|
||
if ds.DBName != "test_db" {
|
||
t.Errorf("DBName = %s, 期望 test_db", ds.DBName)
|
||
}
|
||
if ds.Table != "categories" {
|
||
t.Errorf("Table = %s, 期望 categories", ds.Table)
|
||
}
|
||
if ds.Label != "name" {
|
||
t.Errorf("Label = %s, 期望 name", ds.Label)
|
||
}
|
||
if ds.Value != "id" {
|
||
t.Errorf("Value = %s, 期望 id", ds.Value)
|
||
}
|
||
if ds.Association != 1 {
|
||
t.Errorf("Association = %d, 期望 1", ds.Association)
|
||
}
|
||
if !ds.HasDeletedAt {
|
||
t.Error("HasDeletedAt 应该为 true")
|
||
}
|
||
}
|