feat: 添加构建器测试框架和Linux包测试用例
This commit is contained in:
parent
c022153bcd
commit
189cf664cd
4
go.mod
4
go.mod
|
|
@ -6,21 +6,23 @@ require (
|
|||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/cobra v1.9.1
|
||||
github.com/spf13/viper v1.16.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/spf13/afero v1.9.5 // indirect
|
||||
github.com/spf13/cast v1.5.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/stretchr/testify v1.8.4 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
|
|
|
|||
5
go.sum
5
go.sum
|
|
@ -46,7 +46,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
|
|||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
|
|
@ -155,14 +154,10 @@ github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM=
|
|||
github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ=
|
||||
github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA=
|
||||
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
|
||||
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
|
||||
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
|
||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc=
|
||||
|
|
|
|||
|
|
@ -0,0 +1,181 @@
|
|||
package builder
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"git.kingecg.top/kingecg/installerbuilder/internal/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// 创建一个测试用的构建器实现
|
||||
type MockBuilder struct {
|
||||
name string
|
||||
supportedPlatforms []string
|
||||
supportedFormats []string
|
||||
buildFunc func() error
|
||||
}
|
||||
|
||||
func (b *MockBuilder) Build() error {
|
||||
if b.buildFunc != nil {
|
||||
return b.buildFunc()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *MockBuilder) Name() string {
|
||||
return b.name
|
||||
}
|
||||
|
||||
func (b *MockBuilder) SupportedPlatforms() []string {
|
||||
return b.supportedPlatforms
|
||||
}
|
||||
|
||||
func (b *MockBuilder) SupportedFormats() []string {
|
||||
return b.supportedFormats
|
||||
}
|
||||
|
||||
func TestRegisterAndGetBuilder(t *testing.T) {
|
||||
// 清理注册的构建器
|
||||
builderFactories = make(map[string]BuilderFactory)
|
||||
|
||||
// 注册一个测试构建器
|
||||
RegisterBuilder("test-builder", func(cfg *config.Config, outputDir string) Builder {
|
||||
return &MockBuilder{
|
||||
name: "Test Builder",
|
||||
supportedPlatforms: []string{"test-platform"},
|
||||
supportedFormats: []string{"test-format"},
|
||||
}
|
||||
})
|
||||
|
||||
// 测试获取已注册的构建器
|
||||
cfg := &config.Config{Name: "TestApp", Version: "1.0.0"}
|
||||
builder, err := GetBuilder("test-builder", cfg, "output")
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, builder)
|
||||
assert.Equal(t, "Test Builder", builder.Name())
|
||||
assert.Equal(t, []string{"test-platform"}, builder.SupportedPlatforms())
|
||||
assert.Equal(t, []string{"test-format"}, builder.SupportedFormats())
|
||||
|
||||
// 测试获取未注册的构建器
|
||||
_, err = GetBuilder("non-existent", cfg, "output")
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "未找到名为 'non-existent' 的构建器")
|
||||
}
|
||||
|
||||
func TestBuildAll(t *testing.T) {
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建配置文件
|
||||
configPath := filepath.Join(tempDir, "config.yaml")
|
||||
configContent := `
|
||||
name: TestApp
|
||||
version: 1.0.0
|
||||
description: Test Application
|
||||
author: Test Author
|
||||
license: MIT
|
||||
|
||||
build:
|
||||
outputDir: dist
|
||||
targets:
|
||||
- windows
|
||||
- linux
|
||||
formats:
|
||||
- msi
|
||||
- deb
|
||||
`
|
||||
err = os.WriteFile(configPath, []byte(configContent), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 清理注册的构建器
|
||||
builderFactories = make(map[string]BuilderFactory)
|
||||
|
||||
// 注册测试构建器
|
||||
RegisterBuilder("windows-msi", func(cfg *config.Config, outputDir string) Builder {
|
||||
return &MockBuilder{
|
||||
name: "Windows MSI Builder",
|
||||
supportedPlatforms: []string{"windows"},
|
||||
supportedFormats: []string{"msi"},
|
||||
}
|
||||
})
|
||||
|
||||
RegisterBuilder("linux-deb", func(cfg *config.Config, outputDir string) Builder {
|
||||
return &MockBuilder{
|
||||
name: "Linux DEB Builder",
|
||||
supportedPlatforms: []string{"linux"},
|
||||
supportedFormats: []string{"deb"},
|
||||
}
|
||||
})
|
||||
|
||||
// 测试成功构建
|
||||
opts := BuildOptions{
|
||||
ConfigPath: configPath,
|
||||
OutputDir: filepath.Join(tempDir, "output"),
|
||||
Targets: []string{"windows", "linux"},
|
||||
Formats: []string{"msi", "deb"},
|
||||
Parallel: 2,
|
||||
}
|
||||
|
||||
err = BuildAll(opts)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 测试构建失败
|
||||
RegisterBuilder("windows-msi", func(cfg *config.Config, outputDir string) Builder {
|
||||
return &MockBuilder{
|
||||
name: "Windows MSI Builder",
|
||||
supportedPlatforms: []string{"windows"},
|
||||
supportedFormats: []string{"msi"},
|
||||
buildFunc: func() error { return errors.New("构建失败") },
|
||||
}
|
||||
})
|
||||
|
||||
err = BuildAll(opts)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "构建过程中发生")
|
||||
assert.Contains(t, err.Error(), "构建失败")
|
||||
|
||||
// 测试无效配置
|
||||
opts.ConfigPath = filepath.Join(tempDir, "nonexistent.yaml")
|
||||
err = BuildAll(opts)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "加载配置失败")
|
||||
|
||||
// 测试无构建任务
|
||||
opts.ConfigPath = configPath
|
||||
opts.Targets = []string{"invalid-platform"}
|
||||
err = BuildAll(opts)
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "没有可构建的任务")
|
||||
}
|
||||
|
||||
func TestIsFormatSupportedForTarget(t *testing.T) {
|
||||
tests := []struct {
|
||||
target string
|
||||
format string
|
||||
expected bool
|
||||
}{
|
||||
{"windows", "msi", true},
|
||||
{"windows", "zip", true},
|
||||
{"windows", "deb", false},
|
||||
{"windows", "rpm", false},
|
||||
{"linux", "deb", true},
|
||||
{"linux", "rpm", true},
|
||||
{"linux", "tar.gz", true},
|
||||
{"linux", "msi", false},
|
||||
{"invalid", "msi", false},
|
||||
{"windows", "invalid", false},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.target+"-"+tt.format, func(t *testing.T) {
|
||||
result := isFormatSupportedForTarget(tt.target, tt.format)
|
||||
assert.Equal(t, tt.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,296 @@
|
|||
package linux
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"git.kingecg.top/kingecg/installerbuilder/internal/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDEBBuilder_Name(t *testing.T) {
|
||||
cfg := &config.Config{Name: "TestApp", Version: "1.0.0"}
|
||||
builder := NewDEBBuilder(cfg, "output")
|
||||
assert.Equal(t, "Linux DEB Builder", builder.Name())
|
||||
}
|
||||
|
||||
func TestDEBBuilder_SupportedPlatforms(t *testing.T) {
|
||||
cfg := &config.Config{Name: "TestApp", Version: "1.0.0"}
|
||||
builder := NewDEBBuilder(cfg, "output")
|
||||
platforms := builder.SupportedPlatforms()
|
||||
assert.Equal(t, []string{"linux"}, platforms)
|
||||
}
|
||||
|
||||
func TestDEBBuilder_SupportedFormats(t *testing.T) {
|
||||
cfg := &config.Config{Name: "TestApp", Version: "1.0.0"}
|
||||
builder := NewDEBBuilder(cfg, "output")
|
||||
formats := builder.SupportedFormats()
|
||||
assert.Equal(t, []string{"deb"}, formats)
|
||||
}
|
||||
|
||||
func TestDEBBuilder_CreateDebStructure(t *testing.T) {
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "deb-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
}
|
||||
|
||||
// 创建DEB构建器
|
||||
builder := NewDEBBuilder(cfg, tempDir)
|
||||
|
||||
// 测试创建DEB包结构
|
||||
err = builder.createDebStructure(tempDir)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证目录结构
|
||||
debianDir := filepath.Join(tempDir, "DEBIAN")
|
||||
_, err = os.Stat(debianDir)
|
||||
assert.NoError(t, err)
|
||||
|
||||
installDir := filepath.Join(tempDir, "usr", "local", "bin")
|
||||
_, err = os.Stat(installDir)
|
||||
assert.NoError(t, err)
|
||||
|
||||
docDir := filepath.Join(tempDir, "usr", "share", "doc", "TestApp")
|
||||
_, err = os.Stat(docDir)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestDEBBuilder_CreateControlFile(t *testing.T) {
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "deb-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建DEBIAN目录
|
||||
debianDir := filepath.Join(tempDir, "DEBIAN")
|
||||
err = os.MkdirAll(debianDir, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
Platforms: config.PlatformsConfig{
|
||||
Linux: config.LinuxConfig{
|
||||
Deb: config.LinuxDebConfig{
|
||||
Section: "utils",
|
||||
Priority: "optional",
|
||||
Architecture: "amd64",
|
||||
Depends: []string{"libc6", "libstdc++6"},
|
||||
Recommends: []string{"curl"},
|
||||
Suggests: []string{"wget"},
|
||||
Conflicts: []string{"old-package"},
|
||||
Replaces: []string{"legacy-package"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 创建DEB构建器
|
||||
builder := NewDEBBuilder(cfg, tempDir)
|
||||
|
||||
// 测试创建控制文件
|
||||
err = builder.createControlFile(tempDir)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证控制文件是否存在
|
||||
controlFile := filepath.Join(tempDir, "DEBIAN", "control")
|
||||
_, err = os.Stat(controlFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 读取控制文件内容
|
||||
content, err := os.ReadFile(controlFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证文件内容
|
||||
contentStr := string(content)
|
||||
assert.Contains(t, contentStr, "Package: TestApp")
|
||||
assert.Contains(t, contentStr, "Version: 1.0.0")
|
||||
assert.Contains(t, contentStr, "Section: utils")
|
||||
assert.Contains(t, contentStr, "Priority: optional")
|
||||
assert.Contains(t, contentStr, "Architecture: amd64")
|
||||
assert.Contains(t, contentStr, "Maintainer: Test Author")
|
||||
assert.Contains(t, contentStr, "Description: Test Application")
|
||||
assert.Contains(t, contentStr, "Depends: libc6, libstdc++6")
|
||||
assert.Contains(t, contentStr, "Recommends: curl")
|
||||
assert.Contains(t, contentStr, "Suggests: wget")
|
||||
assert.Contains(t, contentStr, "Conflicts: old-package")
|
||||
assert.Contains(t, contentStr, "Replaces: legacy-package")
|
||||
}
|
||||
|
||||
func TestDEBBuilder_CreateScripts(t *testing.T) {
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "deb-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建DEBIAN目录
|
||||
debianDir := filepath.Join(tempDir, "DEBIAN")
|
||||
err = os.MkdirAll(debianDir, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试脚本源文件
|
||||
scriptDir := filepath.Join(tempDir, "scripts")
|
||||
err = os.MkdirAll(scriptDir, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
preinstScript := filepath.Join(scriptDir, "preinst.sh")
|
||||
err = os.WriteFile(preinstScript, []byte("#!/bin/sh\necho 'Pre-install script'"), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Contents: config.ContentsConfig{
|
||||
Scripts: []config.ScriptConfig{
|
||||
{
|
||||
Type: "preinstall",
|
||||
Content: "#!/bin/sh\necho 'Pre-install script'",
|
||||
},
|
||||
{
|
||||
Type: "postinstall",
|
||||
Source: preinstScript,
|
||||
},
|
||||
{
|
||||
Type: "preuninstall",
|
||||
Content: "echo 'Pre-uninstall script'", // 没有shebang
|
||||
},
|
||||
{
|
||||
Type: "invalid",
|
||||
Content: "echo 'Invalid script'",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 创建DEB构建器
|
||||
builder := NewDEBBuilder(cfg, tempDir)
|
||||
|
||||
// 测试创建脚本文件
|
||||
err = builder.createScripts(tempDir)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证脚本文件是否存在
|
||||
preinstFile := filepath.Join(tempDir, "DEBIAN", "preinst")
|
||||
_, err = os.Stat(preinstFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
postinstFile := filepath.Join(tempDir, "DEBIAN", "postinst")
|
||||
_, err = os.Stat(postinstFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
prermFile := filepath.Join(tempDir, "DEBIAN", "prerm")
|
||||
_, err = os.Stat(prermFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 读取脚本文件内容
|
||||
content, err := os.ReadFile(preinstFile)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, string(content), "#!/bin/sh")
|
||||
assert.Contains(t, string(content), "echo 'Pre-install script'")
|
||||
|
||||
content, err = os.ReadFile(prermFile)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, string(content), "#!/bin/sh")
|
||||
assert.Contains(t, string(content), "echo 'Pre-uninstall script'")
|
||||
}
|
||||
|
||||
func TestDEBBuilder_Build(t *testing.T) {
|
||||
// 跳过实际构建测试,因为它需要dpkg-deb工具
|
||||
t.Skip("跳过实际构建测试,因为它需要dpkg-deb工具")
|
||||
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "deb-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建输出目录
|
||||
outputDir := filepath.Join(tempDir, "output")
|
||||
err = os.MkdirAll(outputDir, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
Platforms: config.PlatformsConfig{
|
||||
Linux: config.LinuxConfig{
|
||||
Deb: config.LinuxDebConfig{
|
||||
Section: "utils",
|
||||
Priority: "optional",
|
||||
Architecture: "amd64",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 创建DEB构建器
|
||||
builder := NewDEBBuilder(cfg, outputDir)
|
||||
|
||||
// 测试构建
|
||||
err = builder.Build()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证输出文件是否存在
|
||||
outputFile := filepath.Join(outputDir, "TestApp_1.0.0_amd64.deb")
|
||||
_, err = os.Stat(outputFile)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestDEBBuilder_BuildDeb(t *testing.T) {
|
||||
// 跳过实际构建测试,因为它需要dpkg-deb工具
|
||||
t.Skip("跳过实际构建测试,因为它需要dpkg-deb工具")
|
||||
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "deb-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建输出目录
|
||||
outputDir := filepath.Join(tempDir, "output")
|
||||
err = os.MkdirAll(outputDir, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
}
|
||||
|
||||
// 创建DEB构建器
|
||||
builder := NewDEBBuilder(cfg, outputDir)
|
||||
|
||||
// 创建DEB包结构
|
||||
err = builder.createDebStructure(tempDir)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 创建控制文件
|
||||
err = builder.createControlFile(tempDir)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 测试构建DEB包
|
||||
outputFile := filepath.Join(outputDir, "TestApp_1.0.0_amd64.deb")
|
||||
err = builder.buildDeb(tempDir, outputFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证输出文件是否存在
|
||||
_, err = os.Stat(outputFile)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
|
@ -0,0 +1,306 @@
|
|||
package linux
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"git.kingecg.top/kingecg/installerbuilder/internal/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestRPMBuilder_Name(t *testing.T) {
|
||||
cfg := &config.Config{Name: "TestApp", Version: "1.0.0"}
|
||||
builder := NewRPMBuilder(cfg, "output")
|
||||
assert.Equal(t, "Linux RPM Builder", builder.Name())
|
||||
}
|
||||
|
||||
func TestRPMBuilder_SupportedPlatforms(t *testing.T) {
|
||||
cfg := &config.Config{Name: "TestApp", Version: "1.0.0"}
|
||||
builder := NewRPMBuilder(cfg, "output")
|
||||
platforms := builder.SupportedPlatforms()
|
||||
assert.Equal(t, []string{"linux"}, platforms)
|
||||
}
|
||||
|
||||
func TestRPMBuilder_SupportedFormats(t *testing.T) {
|
||||
cfg := &config.Config{Name: "TestApp", Version: "1.0.0"}
|
||||
builder := NewRPMBuilder(cfg, "output")
|
||||
formats := builder.SupportedFormats()
|
||||
assert.Equal(t, []string{"rpm"}, formats)
|
||||
}
|
||||
|
||||
func TestRPMBuilder_CreateSourceTarball(t *testing.T) {
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "rpm-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建源代码目录
|
||||
sourceDir := filepath.Join(tempDir, "SOURCES", "TestApp-1.0.0")
|
||||
err = os.MkdirAll(sourceDir, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试文件
|
||||
testFile := filepath.Join(sourceDir, "test.txt")
|
||||
err = os.WriteFile(testFile, []byte("test content"), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
}
|
||||
|
||||
// 创建RPM构建器
|
||||
builder := NewRPMBuilder(cfg, tempDir)
|
||||
|
||||
// 测试创建源代码压缩包
|
||||
tarFile := filepath.Join(tempDir, "SOURCES", "TestApp-1.0.0.tar.gz")
|
||||
err = builder.createSourceTarball(sourceDir, tarFile)
|
||||
|
||||
// 由于createSourceTarball需要执行tar命令,可能在测试环境中不可用,所以我们跳过错误检查
|
||||
if err != nil {
|
||||
t.Skip("跳过tar命令测试,可能在测试环境中不可用")
|
||||
}
|
||||
|
||||
// 验证压缩包是否存在
|
||||
_, err = os.Stat(tarFile)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestRPMBuilder_CreateSpecFile(t *testing.T) {
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "rpm-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建SPECS目录
|
||||
specsDir := filepath.Join(tempDir, "SPECS")
|
||||
err = os.MkdirAll(specsDir, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试脚本源文件
|
||||
scriptDir := filepath.Join(tempDir, "scripts")
|
||||
err = os.MkdirAll(scriptDir, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
preinstScript := filepath.Join(scriptDir, "preinst.sh")
|
||||
err = os.WriteFile(preinstScript, []byte("#!/bin/sh\necho 'Pre-install script'"), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
Platforms: config.PlatformsConfig{
|
||||
Linux: config.LinuxConfig{
|
||||
Rpm: config.LinuxRpmConfig{
|
||||
Group: "Applications/System",
|
||||
URL: "https://example.com",
|
||||
Requires: []string{"glibc", "libstdc++"},
|
||||
Provides: []string{"testapp"},
|
||||
Conflicts: []string{"old-package"},
|
||||
Obsoletes: []string{"legacy-package"},
|
||||
AutoReqProv: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
Contents: config.ContentsConfig{
|
||||
Scripts: []config.ScriptConfig{
|
||||
{
|
||||
Type: "preinstall",
|
||||
Content: "#!/bin/sh\necho 'Pre-install script'",
|
||||
},
|
||||
{
|
||||
Type: "postinstall",
|
||||
Source: preinstScript,
|
||||
},
|
||||
{
|
||||
Type: "preuninstall",
|
||||
Content: "echo 'Pre-uninstall script'",
|
||||
},
|
||||
{
|
||||
Type: "postuninstall",
|
||||
Content: "echo 'Post-uninstall script'",
|
||||
},
|
||||
{
|
||||
Type: "invalid",
|
||||
Content: "echo 'Invalid script'",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 创建RPM构建器
|
||||
builder := NewRPMBuilder(cfg, tempDir)
|
||||
|
||||
// 测试创建SPEC文件
|
||||
specFile := filepath.Join(specsDir, "TestApp.spec")
|
||||
err = builder.createSpecFile(specFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证SPEC文件是否存在
|
||||
_, err = os.Stat(specFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 读取SPEC文件内容
|
||||
content, err := os.ReadFile(specFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证文件内容
|
||||
contentStr := string(content)
|
||||
assert.Contains(t, contentStr, "Name: TestApp")
|
||||
assert.Contains(t, contentStr, "Version: 1.0.0")
|
||||
assert.Contains(t, contentStr, "Summary: Test Application")
|
||||
assert.Contains(t, contentStr, "Group: Applications/System")
|
||||
assert.Contains(t, contentStr, "License: MIT")
|
||||
assert.Contains(t, contentStr, "URL: https://example.com")
|
||||
assert.Contains(t, contentStr, "Requires: glibc, libstdc++")
|
||||
assert.Contains(t, contentStr, "Provides: testapp")
|
||||
assert.Contains(t, contentStr, "Conflicts: old-package")
|
||||
assert.Contains(t, contentStr, "Obsoletes: legacy-package")
|
||||
assert.Contains(t, contentStr, "%pre")
|
||||
assert.Contains(t, contentStr, "%post")
|
||||
assert.Contains(t, contentStr, "%preun")
|
||||
assert.Contains(t, contentStr, "%postun")
|
||||
}
|
||||
|
||||
func TestRPMBuilder_Build(t *testing.T) {
|
||||
// 跳过实际构建测试,因为它需要rpmbuild工具
|
||||
t.Skip("跳过实际构建测试,因为它需要rpmbuild工具")
|
||||
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "rpm-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建输出目录
|
||||
outputDir := filepath.Join(tempDir, "output")
|
||||
err = os.MkdirAll(outputDir, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
Platforms: config.PlatformsConfig{
|
||||
Linux: config.LinuxConfig{
|
||||
Rpm: config.LinuxRpmConfig{
|
||||
Group: "Applications/System",
|
||||
URL: "https://example.com",
|
||||
AutoReqProv: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 创建RPM构建器
|
||||
builder := NewRPMBuilder(cfg, outputDir)
|
||||
|
||||
// 测试构建
|
||||
err = builder.Build()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证输出文件是否存在
|
||||
outputFile := filepath.Join(outputDir, "TestApp-1.0.0.x86_64.rpm")
|
||||
_, err = os.Stat(outputFile)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestRPMBuilder_BuildRpm(t *testing.T) {
|
||||
// 跳过实际构建测试,因为它需要rpmbuild工具
|
||||
t.Skip("跳过实际构建测试,因为它需要rpmbuild工具")
|
||||
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "rpm-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建RPM构建目录结构
|
||||
buildDirs := []string{
|
||||
filepath.Join(tempDir, "BUILD"),
|
||||
filepath.Join(tempDir, "RPMS"),
|
||||
filepath.Join(tempDir, "SOURCES"),
|
||||
filepath.Join(tempDir, "SPECS"),
|
||||
filepath.Join(tempDir, "SRPMS"),
|
||||
}
|
||||
|
||||
for _, dir := range buildDirs {
|
||||
err = os.MkdirAll(dir, 0755)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// 创建输出目录
|
||||
outputDir := filepath.Join(tempDir, "output")
|
||||
err = os.MkdirAll(outputDir, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
}
|
||||
|
||||
// 创建RPM构建器
|
||||
builder := NewRPMBuilder(cfg, outputDir)
|
||||
|
||||
// 创建SPEC文件
|
||||
specFile := filepath.Join(tempDir, "SPECS", "TestApp.spec")
|
||||
err = builder.createSpecFile(specFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 测试构建RPM包
|
||||
outputFile := filepath.Join(outputDir, "TestApp-1.0.0.x86_64.rpm")
|
||||
err = builder.buildRpm(tempDir, specFile, outputFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证输出文件是否存在
|
||||
_, err = os.Stat(outputFile)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestCopyFile(t *testing.T) {
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "rpm-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建源文件
|
||||
srcFile := filepath.Join(tempDir, "source.txt")
|
||||
err = os.WriteFile(srcFile, []byte("test content"), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建目标文件路径
|
||||
dstFile := filepath.Join(tempDir, "destination.txt")
|
||||
|
||||
// 测试复制文件
|
||||
err = copyFile(srcFile, dstFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证目标文件是否存在
|
||||
_, err = os.Stat(dstFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 读取目标文件内容
|
||||
content, err := os.ReadFile(dstFile)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "test content", string(content))
|
||||
|
||||
// 测试复制不存在的文件
|
||||
err = copyFile(filepath.Join(tempDir, "nonexistent.txt"), dstFile)
|
||||
assert.Error(t, err)
|
||||
|
||||
// 测试复制到无效路径
|
||||
err = copyFile(srcFile, "/invalid/path/file.txt")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
package windows
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"git.kingecg.top/kingecg/installerbuilder/internal/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestMSIBuilder_Name(t *testing.T) {
|
||||
cfg := &config.Config{Name: "TestApp", Version: "1.0.0"}
|
||||
builder := NewMSIBuilder(cfg, "output")
|
||||
assert.Equal(t, "Windows MSI Builder", builder.Name())
|
||||
}
|
||||
|
||||
func TestMSIBuilder_SupportedPlatforms(t *testing.T) {
|
||||
cfg := &config.Config{Name: "TestApp", Version: "1.0.0"}
|
||||
builder := NewMSIBuilder(cfg, "output")
|
||||
platforms := builder.SupportedPlatforms()
|
||||
assert.Equal(t, []string{"windows"}, platforms)
|
||||
}
|
||||
|
||||
func TestMSIBuilder_SupportedFormats(t *testing.T) {
|
||||
cfg := &config.Config{Name: "TestApp", Version: "1.0.0"}
|
||||
builder := NewMSIBuilder(cfg, "output")
|
||||
formats := builder.SupportedFormats()
|
||||
assert.Equal(t, []string{"msi"}, formats)
|
||||
}
|
||||
|
||||
func TestMSIBuilder_CreateWixSource(t *testing.T) {
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "msi-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
Platforms: config.PlatformsConfig{
|
||||
Windows: config.WindowsConfig{
|
||||
Msi: config.WindowsMsiConfig{
|
||||
Manufacturer: "Test Manufacturer",
|
||||
UpgradeCode: "12345678-1234-1234-1234-123456789012",
|
||||
InstallDir: "TestApp",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 创建MSI构建器
|
||||
builder := NewMSIBuilder(cfg, tempDir)
|
||||
|
||||
// 测试创建WiX源文件
|
||||
wixFile := filepath.Join(tempDir, "installer.wxs")
|
||||
err = builder.createWixSource(wixFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证文件是否存在
|
||||
_, err = os.Stat(wixFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 读取文件内容
|
||||
content, err := os.ReadFile(wixFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证文件内容
|
||||
contentStr := string(content)
|
||||
assert.Contains(t, contentStr, `Name="TestApp"`)
|
||||
assert.Contains(t, contentStr, `Version="1.0.0"`)
|
||||
assert.Contains(t, contentStr, `Manufacturer="Test Manufacturer"`)
|
||||
assert.Contains(t, contentStr, `UpgradeCode="12345678-1234-1234-1234-123456789012"`)
|
||||
assert.Contains(t, contentStr, `Description="Test Application"`)
|
||||
assert.Contains(t, contentStr, `Name="TestApp"`)
|
||||
}
|
||||
|
||||
func TestMSIBuilder_Build(t *testing.T) {
|
||||
// 跳过实际构建测试,因为它需要WiX工具集
|
||||
t.Skip("跳过实际构建测试,因为它需要WiX工具集")
|
||||
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "msi-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建输出目录
|
||||
outputDir := filepath.Join(tempDir, "output")
|
||||
err = os.MkdirAll(outputDir, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
Platforms: config.PlatformsConfig{
|
||||
Windows: config.WindowsConfig{
|
||||
Msi: config.WindowsMsiConfig{
|
||||
Manufacturer: "Test Manufacturer",
|
||||
UpgradeCode: "12345678-1234-1234-1234-123456789012",
|
||||
InstallDir: "TestApp",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 创建MSI构建器
|
||||
builder := NewMSIBuilder(cfg, outputDir)
|
||||
|
||||
// 测试构建
|
||||
err = builder.Build()
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证输出文件是否存在
|
||||
outputFile := filepath.Join(outputDir, "TestApp-1.0.0.msi")
|
||||
_, err = os.Stat(outputFile)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestMSIBuilder_CompileWixSource(t *testing.T) {
|
||||
// 跳过实际编译测试,因为它需要WiX工具集
|
||||
t.Skip("跳过实际编译测试,因为它需要WiX工具集")
|
||||
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "msi-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
}
|
||||
|
||||
// 创建MSI构建器
|
||||
builder := NewMSIBuilder(cfg, tempDir)
|
||||
|
||||
// 创建WiX源文件
|
||||
wixFile := filepath.Join(tempDir, "installer.wxs")
|
||||
err = builder.createWixSource(wixFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 测试编译WiX源文件
|
||||
objFile := filepath.Join(tempDir, "installer.wixobj")
|
||||
err = builder.compileWixSource(wixFile, objFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证输出文件是否存在
|
||||
_, err = os.Stat(objFile)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestMSIBuilder_LinkMsi(t *testing.T) {
|
||||
// 跳过实际链接测试,因为它需要WiX工具集
|
||||
t.Skip("跳过实际链接测试,因为它需要WiX工具集")
|
||||
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "msi-builder-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建输出目录
|
||||
outputDir := filepath.Join(tempDir, "output")
|
||||
err = os.MkdirAll(outputDir, 0755)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &config.Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
}
|
||||
|
||||
// 创建MSI构建器
|
||||
builder := NewMSIBuilder(cfg, outputDir)
|
||||
|
||||
// 创建WiX源文件
|
||||
wixFile := filepath.Join(tempDir, "installer.wxs")
|
||||
err = builder.createWixSource(wixFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 编译WiX源文件
|
||||
objFile := filepath.Join(tempDir, "installer.wixobj")
|
||||
err = builder.compileWixSource(wixFile, objFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 测试链接生成MSI
|
||||
msiFile := filepath.Join(outputDir, "TestApp-1.0.0.msi")
|
||||
err = builder.linkMsi(objFile, msiFile)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证输出文件是否存在
|
||||
_, err = os.Stat(msiFile)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
|
@ -0,0 +1,254 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestLoadConfig(t *testing.T) {
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "config-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建有效的YAML配置文件
|
||||
validYAML := `
|
||||
name: TestApp
|
||||
version: 1.0.0
|
||||
description: Test Application
|
||||
author: Test Author
|
||||
license: MIT
|
||||
|
||||
build:
|
||||
outputDir: dist
|
||||
targets:
|
||||
- windows
|
||||
- linux
|
||||
formats:
|
||||
- msi
|
||||
- deb
|
||||
|
||||
contents:
|
||||
files:
|
||||
- source: test.txt
|
||||
destination: test.txt
|
||||
mode: "0644"
|
||||
scripts:
|
||||
- type: preinstall
|
||||
content: "echo 'Pre-install script'"
|
||||
- type: postinstall
|
||||
source: scripts/post-install.sh
|
||||
`
|
||||
validYAMLPath := filepath.Join(tempDir, "valid.yaml")
|
||||
err = os.WriteFile(validYAMLPath, []byte(validYAML), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建无效的YAML配置文件
|
||||
invalidYAML := `
|
||||
name: TestApp
|
||||
version: 1.0.0
|
||||
invalid_field: value
|
||||
`
|
||||
invalidYAMLPath := filepath.Join(tempDir, "invalid.yaml")
|
||||
err = os.WriteFile(invalidYAMLPath, []byte(invalidYAML), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 创建有效的JSON配置文件
|
||||
validJSON := `{
|
||||
"name": "TestApp",
|
||||
"version": "1.0.0",
|
||||
"description": "Test Application",
|
||||
"author": "Test Author",
|
||||
"license": "MIT",
|
||||
"build": {
|
||||
"outputDir": "dist",
|
||||
"targets": ["windows", "linux"],
|
||||
"formats": ["msi", "deb"]
|
||||
},
|
||||
"contents": {
|
||||
"files": [
|
||||
{
|
||||
"source": "test.txt",
|
||||
"destination": "test.txt",
|
||||
"mode": "0644"
|
||||
}
|
||||
],
|
||||
"scripts": [
|
||||
{
|
||||
"type": "preinstall",
|
||||
"content": "echo 'Pre-install script'"
|
||||
},
|
||||
{
|
||||
"type": "postinstall",
|
||||
"source": "scripts/post-install.sh"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
validJSONPath := filepath.Join(tempDir, "valid.json")
|
||||
err = os.WriteFile(validJSONPath, []byte(validJSON), 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 测试用例
|
||||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
wantErr bool
|
||||
checkCfg func(*Config)
|
||||
}{
|
||||
{
|
||||
name: "Valid YAML config",
|
||||
path: validYAMLPath,
|
||||
wantErr: false,
|
||||
checkCfg: func(cfg *Config) {
|
||||
assert.Equal(t, "TestApp", cfg.Name)
|
||||
assert.Equal(t, "1.0.0", cfg.Version)
|
||||
assert.Equal(t, "Test Application", cfg.Description)
|
||||
assert.Equal(t, "Test Author", cfg.Author)
|
||||
assert.Equal(t, "MIT", cfg.License)
|
||||
assert.Equal(t, "dist", cfg.Build.OutputDir)
|
||||
assert.Contains(t, cfg.Build.Targets, "windows")
|
||||
assert.Contains(t, cfg.Build.Targets, "linux")
|
||||
assert.Contains(t, cfg.Build.Formats, "msi")
|
||||
assert.Contains(t, cfg.Build.Formats, "deb")
|
||||
assert.Len(t, cfg.Contents.Files, 1)
|
||||
assert.Equal(t, "test.txt", cfg.Contents.Files[0].Source)
|
||||
assert.Equal(t, "test.txt", cfg.Contents.Files[0].Destination)
|
||||
assert.Equal(t, "0644", cfg.Contents.Files[0].Mode)
|
||||
assert.Len(t, cfg.Contents.Scripts, 2)
|
||||
assert.Equal(t, "preinstall", cfg.Contents.Scripts[0].Type)
|
||||
assert.Equal(t, "echo 'Pre-install script'", cfg.Contents.Scripts[0].Content)
|
||||
assert.Equal(t, "postinstall", cfg.Contents.Scripts[1].Type)
|
||||
assert.Equal(t, "scripts/post-install.sh", cfg.Contents.Scripts[1].Source)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Valid JSON config",
|
||||
path: validJSONPath,
|
||||
wantErr: false,
|
||||
checkCfg: func(cfg *Config) {
|
||||
assert.Equal(t, "TestApp", cfg.Name)
|
||||
assert.Equal(t, "1.0.0", cfg.Version)
|
||||
assert.Equal(t, "Test Application", cfg.Description)
|
||||
assert.Equal(t, "Test Author", cfg.Author)
|
||||
assert.Equal(t, "MIT", cfg.License)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Invalid YAML config",
|
||||
path: invalidYAMLPath,
|
||||
wantErr: false, // 不会报错,但会有警告
|
||||
checkCfg: func(cfg *Config) {
|
||||
assert.Equal(t, "TestApp", cfg.Name)
|
||||
assert.Equal(t, "1.0.0", cfg.Version)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Non-existent file",
|
||||
path: filepath.Join(tempDir, "nonexistent.yaml"),
|
||||
wantErr: true,
|
||||
checkCfg: func(cfg *Config) {
|
||||
assert.Nil(t, cfg)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
cfg, err := LoadConfig(tt.path)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
assert.NoError(t, err)
|
||||
tt.checkCfg(cfg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSaveConfig(t *testing.T) {
|
||||
// 创建临时测试目录
|
||||
tempDir, err := os.MkdirTemp("", "config-test-*")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
// 创建测试配置
|
||||
cfg := &Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
Build: BuildConfig{
|
||||
OutputDir: "dist",
|
||||
Targets: []string{"windows", "linux"},
|
||||
Formats: []string{"msi", "deb"},
|
||||
},
|
||||
Contents: ContentsConfig{
|
||||
Files: []FileConfig{
|
||||
{
|
||||
Source: "test.txt",
|
||||
Destination: "test.txt",
|
||||
Mode: "0644",
|
||||
},
|
||||
},
|
||||
Scripts: []ScriptConfig{
|
||||
{
|
||||
Type: "preinstall",
|
||||
Content: "echo 'Pre-install script'",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// 测试YAML保存
|
||||
yamlPath := filepath.Join(tempDir, "config.yaml")
|
||||
err = SaveConfig(cfg, yamlPath)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证保存的YAML文件
|
||||
loadedCfg, err := LoadConfig(yamlPath)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, cfg.Name, loadedCfg.Name)
|
||||
assert.Equal(t, cfg.Version, loadedCfg.Version)
|
||||
assert.Equal(t, cfg.Description, loadedCfg.Description)
|
||||
assert.Equal(t, cfg.Build.OutputDir, loadedCfg.Build.OutputDir)
|
||||
assert.ElementsMatch(t, cfg.Build.Targets, loadedCfg.Build.Targets)
|
||||
assert.ElementsMatch(t, cfg.Build.Formats, loadedCfg.Build.Formats)
|
||||
assert.Len(t, loadedCfg.Contents.Files, 1)
|
||||
assert.Equal(t, cfg.Contents.Files[0].Source, loadedCfg.Contents.Files[0].Source)
|
||||
assert.Equal(t, cfg.Contents.Files[0].Destination, loadedCfg.Contents.Files[0].Destination)
|
||||
assert.Equal(t, cfg.Contents.Files[0].Mode, loadedCfg.Contents.Files[0].Mode)
|
||||
assert.Len(t, loadedCfg.Contents.Scripts, 1)
|
||||
assert.Equal(t, cfg.Contents.Scripts[0].Type, loadedCfg.Contents.Scripts[0].Type)
|
||||
assert.Equal(t, cfg.Contents.Scripts[0].Content, loadedCfg.Contents.Scripts[0].Content)
|
||||
|
||||
// 测试JSON保存
|
||||
jsonPath := filepath.Join(tempDir, "config.json")
|
||||
err = SaveConfig(cfg, jsonPath)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// 验证保存的JSON文件
|
||||
loadedCfg, err = LoadConfig(jsonPath)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, cfg.Name, loadedCfg.Name)
|
||||
assert.Equal(t, cfg.Version, loadedCfg.Version)
|
||||
assert.Equal(t, cfg.Description, loadedCfg.Description)
|
||||
|
||||
// 测试无效路径
|
||||
err = SaveConfig(cfg, "/invalid/path/config.yaml")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestDefaultConfig(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
assert.NotEmpty(t, cfg.Name)
|
||||
assert.NotEmpty(t, cfg.Version)
|
||||
assert.NotEmpty(t, cfg.Build.OutputDir)
|
||||
assert.NotEmpty(t, cfg.Build.Targets)
|
||||
assert.NotEmpty(t, cfg.Build.Formats)
|
||||
}
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestValidate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config *Config
|
||||
strict bool
|
||||
wantValid bool
|
||||
wantErrors int
|
||||
}{
|
||||
{
|
||||
name: "Valid config",
|
||||
config: &Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
Build: BuildConfig{
|
||||
OutputDir: "dist",
|
||||
Targets: []string{"windows", "linux"},
|
||||
Formats: []string{"msi", "deb"},
|
||||
},
|
||||
Contents: ContentsConfig{
|
||||
Files: []FileConfig{
|
||||
{
|
||||
Source: "test.txt",
|
||||
Destination: "test.txt",
|
||||
Mode: "0644",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
strict: true,
|
||||
wantValid: true,
|
||||
wantErrors: 0,
|
||||
},
|
||||
{
|
||||
name: "Missing name",
|
||||
config: &Config{
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
Build: BuildConfig{
|
||||
OutputDir: "dist",
|
||||
Targets: []string{"windows", "linux"},
|
||||
Formats: []string{"msi", "deb"},
|
||||
},
|
||||
},
|
||||
strict: true,
|
||||
wantValid: false,
|
||||
wantErrors: 1,
|
||||
},
|
||||
{
|
||||
name: "Missing version",
|
||||
config: &Config{
|
||||
Name: "TestApp",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
Build: BuildConfig{
|
||||
OutputDir: "dist",
|
||||
Targets: []string{"windows", "linux"},
|
||||
Formats: []string{"msi", "deb"},
|
||||
},
|
||||
},
|
||||
strict: true,
|
||||
wantValid: false,
|
||||
wantErrors: 1,
|
||||
},
|
||||
{
|
||||
name: "Invalid target",
|
||||
config: &Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
Build: BuildConfig{
|
||||
OutputDir: "dist",
|
||||
Targets: []string{"windows", "invalid"},
|
||||
Formats: []string{"msi", "deb"},
|
||||
},
|
||||
},
|
||||
strict: true,
|
||||
wantValid: false,
|
||||
wantErrors: 1,
|
||||
},
|
||||
{
|
||||
name: "Invalid format",
|
||||
config: &Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
Build: BuildConfig{
|
||||
OutputDir: "dist",
|
||||
Targets: []string{"windows", "linux"},
|
||||
Formats: []string{"msi", "invalid"},
|
||||
},
|
||||
},
|
||||
strict: true,
|
||||
wantValid: false,
|
||||
wantErrors: 1,
|
||||
},
|
||||
{
|
||||
name: "Missing optional fields in non-strict mode",
|
||||
config: &Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Build: BuildConfig{
|
||||
Targets: []string{"windows"},
|
||||
Formats: []string{"msi"},
|
||||
},
|
||||
},
|
||||
strict: false,
|
||||
wantValid: true,
|
||||
wantErrors: 0,
|
||||
},
|
||||
{
|
||||
name: "Missing optional fields in strict mode",
|
||||
config: &Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Build: BuildConfig{
|
||||
Targets: []string{"windows"},
|
||||
Formats: []string{"msi"},
|
||||
},
|
||||
},
|
||||
strict: true,
|
||||
wantValid: false,
|
||||
wantErrors: 3, // 缺少描述、作者和许可证
|
||||
},
|
||||
{
|
||||
name: "Invalid script type",
|
||||
config: &Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
Build: BuildConfig{
|
||||
OutputDir: "dist",
|
||||
Targets: []string{"windows"},
|
||||
Formats: []string{"msi"},
|
||||
},
|
||||
Contents: ContentsConfig{
|
||||
Scripts: []ScriptConfig{
|
||||
{
|
||||
Type: "invalid",
|
||||
Content: "echo 'Invalid script'",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
strict: true,
|
||||
wantValid: false,
|
||||
wantErrors: 1,
|
||||
},
|
||||
{
|
||||
name: "Empty script",
|
||||
config: &Config{
|
||||
Name: "TestApp",
|
||||
Version: "1.0.0",
|
||||
Description: "Test Application",
|
||||
Author: "Test Author",
|
||||
License: "MIT",
|
||||
Build: BuildConfig{
|
||||
OutputDir: "dist",
|
||||
Targets: []string{"windows"},
|
||||
Formats: []string{"msi"},
|
||||
},
|
||||
Contents: ContentsConfig{
|
||||
Scripts: []ScriptConfig{
|
||||
{
|
||||
Type: "preinstall",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
strict: true,
|
||||
wantValid: false,
|
||||
wantErrors: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := tt.config.Validate(tt.strict)
|
||||
assert.Equal(t, tt.wantValid, result.Valid)
|
||||
assert.Equal(t, tt.wantErrors, len(result.Errors))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidationResult_String(t *testing.T) {
|
||||
// 测试空错误列表
|
||||
result := ValidationResult{
|
||||
Valid: true,
|
||||
Errors: []ValidationError{},
|
||||
}
|
||||
assert.Equal(t, "配置有效", result.String())
|
||||
|
||||
// 测试单个错误
|
||||
result = ValidationResult{
|
||||
Valid: false,
|
||||
Errors: []ValidationError{
|
||||
{Field: "test", Message: "错误1"},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, "配置无效: 错误1", result.String())
|
||||
|
||||
// 测试多个错误
|
||||
result = ValidationResult{
|
||||
Valid: false,
|
||||
Errors: []ValidationError{
|
||||
{Message: "错误1"},
|
||||
{Message: "错误2"},
|
||||
{Message: "错误3"},
|
||||
},
|
||||
}
|
||||
assert.Equal(t, "配置无效: 错误1, 错误2, 错误3", result.String())
|
||||
}
|
||||
Loading…
Reference in New Issue