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) }) } }