Files
sofmani/appconfig/installer_data_test.go
2026-03-24 17:04:43 +02:00

283 lines
8.2 KiB
Go
Executable File

package appconfig
import (
"sort"
"testing"
"github.com/chenasraf/sofmani/platform"
"github.com/stretchr/testify/assert"
yamlPkg "gopkg.in/yaml.v3"
)
func TestInstallerData_Environ(t *testing.T) {
t.Run("returns empty slice when both Env and PlatformEnv are nil", func(t *testing.T) {
data := &InstallerData{}
result := data.Environ()
assert.NotNil(t, result)
assert.Empty(t, result)
})
t.Run("returns Env values when only Env is set", func(t *testing.T) {
env := map[string]string{"KEY": "value", "OTHER": "test"}
data := &InstallerData{
Env: &env,
}
result := data.Environ()
sort.Strings(result) // Sort for consistent comparison
assert.Len(t, result, 2)
assert.Contains(t, result, "KEY=value")
assert.Contains(t, result, "OTHER=test")
})
t.Run("returns PlatformEnv values for current platform", func(t *testing.T) {
macEnv := map[string]string{"PLATFORM": "macos"}
linuxEnv := map[string]string{"PLATFORM": "linux"}
data := &InstallerData{
PlatformEnv: &platform.PlatformMap[map[string]string]{
MacOS: &macEnv,
Linux: &linuxEnv,
},
}
result := data.Environ()
// Result depends on current platform
if len(result) > 0 {
assert.Contains(t, result[0], "PLATFORM=")
}
})
t.Run("combines Env and PlatformEnv", func(t *testing.T) {
env := map[string]string{"COMMON": "value"}
macEnv := map[string]string{"SPECIFIC": "mac"}
data := &InstallerData{
Env: &env,
PlatformEnv: &platform.PlatformMap[map[string]string]{
MacOS: &macEnv,
},
}
result := data.Environ()
assert.Contains(t, result, "COMMON=value")
// SPECIFIC will only appear on macOS
})
t.Run("PlatformEnv overrides Env for same key", func(t *testing.T) {
env := map[string]string{"KEY": "original"}
macEnv := map[string]string{"KEY": "platform"}
data := &InstallerData{
Env: &env,
PlatformEnv: &platform.PlatformMap[map[string]string]{
MacOS: &macEnv,
},
}
result := data.Environ()
// On macOS, KEY should be "platform"
// On other platforms, KEY should be "original"
assert.Len(t, result, 1)
assert.Contains(t, result[0], "KEY=")
})
}
func TestInstallerData_GetTagsList(t *testing.T) {
t.Run("returns list of space-separated tags", func(t *testing.T) {
tags := "python node rust"
data := &InstallerData{
Tags: &tags,
}
result := data.GetTagsList()
assert.Equal(t, []string{"python", "node", "rust"}, result)
})
t.Run("trims whitespace from tags", func(t *testing.T) {
tags := " python node rust "
data := &InstallerData{
Tags: &tags,
}
result := data.GetTagsList()
// Note: empty strings will be included for leading/trailing spaces when split
// The implementation splits and trims each part
for _, tag := range result {
assert.Equal(t, tag, trimmedTag(tag))
}
})
t.Run("returns single tag when only one is present", func(t *testing.T) {
tags := "python"
data := &InstallerData{
Tags: &tags,
}
result := data.GetTagsList()
assert.Equal(t, []string{"python"}, result)
})
t.Run("handles tags with multiple spaces between them", func(t *testing.T) {
tags := "python node"
data := &InstallerData{
Tags: &tags,
}
result := data.GetTagsList()
// Split by single space, so empty string will be in between
assert.Contains(t, result, "python")
assert.Contains(t, result, "node")
})
}
// helper to get trimmed tag
func trimmedTag(s string) string {
return s // Already trimmed by the function
}
func TestInstallerType_Constants(t *testing.T) {
t.Run("installer types have expected values", func(t *testing.T) {
assert.Equal(t, InstallerType("group"), InstallerTypeGroup)
assert.Equal(t, InstallerType("shell"), InstallerTypeShell)
assert.Equal(t, InstallerType("docker"), InstallerTypeDocker)
assert.Equal(t, InstallerType("brew"), InstallerTypeBrew)
assert.Equal(t, InstallerType("apt"), InstallerTypeApt)
assert.Equal(t, InstallerType("apk"), InstallerTypeApk)
assert.Equal(t, InstallerType("git"), InstallerTypeGit)
assert.Equal(t, InstallerType("github-release"), InstallerTypeGitHubRelease)
assert.Equal(t, InstallerType("rsync"), InstallerTypeRsync)
assert.Equal(t, InstallerType("npm"), InstallerTypeNpm)
assert.Equal(t, InstallerType("pnpm"), InstallerTypePnpm)
assert.Equal(t, InstallerType("yarn"), InstallerTypeYarn)
assert.Equal(t, InstallerType("pipx"), InstallerTypePipx)
assert.Equal(t, InstallerType("manifest"), InstallerTypeManifest)
assert.Equal(t, InstallerType("pacman"), InstallerTypePacman)
assert.Equal(t, InstallerType("yay"), InstallerTypeYay)
assert.Equal(t, InstallerType("cargo"), InstallerTypeCargo)
})
}
func TestSkipSummary_UnmarshalYAML(t *testing.T) {
t.Run("boolean true applies to both install and update", func(t *testing.T) {
yaml := `skip_summary: true`
var data InstallerData
err := parseYAML(yaml, &data)
assert.NoError(t, err)
assert.NotNil(t, data.SkipSummary)
assert.True(t, data.SkipSummary.Install)
assert.True(t, data.SkipSummary.Update)
})
t.Run("boolean false applies to both install and update", func(t *testing.T) {
yaml := `skip_summary: false`
var data InstallerData
err := parseYAML(yaml, &data)
assert.NoError(t, err)
assert.NotNil(t, data.SkipSummary)
assert.False(t, data.SkipSummary.Install)
assert.False(t, data.SkipSummary.Update)
})
t.Run("map with install only", func(t *testing.T) {
yaml := `skip_summary:
install: true`
var data InstallerData
err := parseYAML(yaml, &data)
assert.NoError(t, err)
assert.NotNil(t, data.SkipSummary)
assert.True(t, data.SkipSummary.Install)
assert.False(t, data.SkipSummary.Update)
})
t.Run("map with update only", func(t *testing.T) {
yaml := `skip_summary:
update: true`
var data InstallerData
err := parseYAML(yaml, &data)
assert.NoError(t, err)
assert.NotNil(t, data.SkipSummary)
assert.False(t, data.SkipSummary.Install)
assert.True(t, data.SkipSummary.Update)
})
t.Run("map with both install and update", func(t *testing.T) {
yaml := `skip_summary:
install: true
update: false`
var data InstallerData
err := parseYAML(yaml, &data)
assert.NoError(t, err)
assert.NotNil(t, data.SkipSummary)
assert.True(t, data.SkipSummary.Install)
assert.False(t, data.SkipSummary.Update)
})
t.Run("nil when not specified", func(t *testing.T) {
yaml := `name: test`
var data InstallerData
err := parseYAML(yaml, &data)
assert.NoError(t, err)
assert.Nil(t, data.SkipSummary)
})
}
func parseYAML(yamlStr string, v any) error {
return yamlPkg.Unmarshal([]byte(yamlStr), v)
}
func TestInstallerData_IsCategory(t *testing.T) {
t.Run("returns true when Category is set", func(t *testing.T) {
category := "Development Tools"
data := &InstallerData{
Category: &category,
}
assert.True(t, data.IsCategory())
})
t.Run("returns false when Category is nil", func(t *testing.T) {
data := &InstallerData{}
assert.False(t, data.IsCategory())
})
t.Run("returns false when Category is empty string", func(t *testing.T) {
category := ""
data := &InstallerData{
Category: &category,
}
assert.False(t, data.IsCategory())
})
t.Run("category parsed from YAML", func(t *testing.T) {
yaml := `category: System Utilities`
var data InstallerData
err := parseYAML(yaml, &data)
assert.NoError(t, err)
assert.True(t, data.IsCategory())
assert.Equal(t, "System Utilities", *data.Category)
})
t.Run("category with desc parsed from YAML", func(t *testing.T) {
yaml := `category: System Utilities
desc: These are system tools.`
var data InstallerData
err := parseYAML(yaml, &data)
assert.NoError(t, err)
assert.True(t, data.IsCategory())
assert.Equal(t, "System Utilities", *data.Category)
assert.Equal(t, "These are system tools.", *data.Desc)
})
t.Run("category with multiline desc parsed from YAML", func(t *testing.T) {
yaml := `category: Development
desc: |
First line.
Second line.`
var data InstallerData
err := parseYAML(yaml, &data)
assert.NoError(t, err)
assert.True(t, data.IsCategory())
assert.Equal(t, "Development", *data.Category)
assert.Contains(t, *data.Desc, "First line.")
assert.Contains(t, *data.Desc, "Second line.")
})
t.Run("regular installer is not a category", func(t *testing.T) {
yaml := `name: test
type: shell`
var data InstallerData
err := parseYAML(yaml, &data)
assert.NoError(t, err)
assert.False(t, data.IsCategory())
})
}