mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 13:32:50 -05:00
templates, respect XDG paths - Add Hyprland and MangoWC templates - Add GUI gaps, window radius, and border thickness overrides for niri, Hyprland, and MangoWC - Add replacement support in matugen templates for DATA_DIR, CACHE_DIR, CONFIG_DIR fixes #1274 fixes #1273
395 lines
11 KiB
Go
395 lines
11 KiB
Go
package matugen
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
mocks_utils "github.com/AvengeMedia/DankMaterialShell/core/internal/mocks/utils"
|
|
"github.com/AvengeMedia/DankMaterialShell/core/internal/utils"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestAppendConfigBinaryExists(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
shellDir := filepath.Join(tempDir, "shell")
|
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
|
t.Fatalf("failed to create configs dir: %v", err)
|
|
}
|
|
|
|
testConfig := "test config content"
|
|
configPath := filepath.Join(configsDir, "test.toml")
|
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
|
t.Fatalf("failed to write config: %v", err)
|
|
}
|
|
|
|
outFile := filepath.Join(tempDir, "output.toml")
|
|
cfgFile, err := os.Create(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to create output file: %v", err)
|
|
}
|
|
defer cfgFile.Close()
|
|
|
|
mockChecker := mocks_utils.NewMockAppChecker(t)
|
|
mockChecker.EXPECT().AnyCommandExists("sh").Return(true)
|
|
|
|
opts := &Options{ShellDir: shellDir, AppChecker: mockChecker}
|
|
|
|
appendConfig(opts, cfgFile, []string{"sh"}, nil, "test.toml")
|
|
|
|
cfgFile.Close()
|
|
output, err := os.ReadFile(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to read output: %v", err)
|
|
}
|
|
|
|
if len(output) == 0 {
|
|
t.Errorf("expected config to be written when binary exists")
|
|
}
|
|
if string(output) != testConfig+"\n" {
|
|
t.Errorf("expected %q, got %q", testConfig+"\n", string(output))
|
|
}
|
|
}
|
|
|
|
func TestAppendConfigBinaryDoesNotExist(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
shellDir := filepath.Join(tempDir, "shell")
|
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
|
t.Fatalf("failed to create configs dir: %v", err)
|
|
}
|
|
|
|
testConfig := "test config content"
|
|
configPath := filepath.Join(configsDir, "test.toml")
|
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
|
t.Fatalf("failed to write config: %v", err)
|
|
}
|
|
|
|
outFile := filepath.Join(tempDir, "output.toml")
|
|
cfgFile, err := os.Create(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to create output file: %v", err)
|
|
}
|
|
defer cfgFile.Close()
|
|
|
|
mockChecker := mocks_utils.NewMockAppChecker(t)
|
|
mockChecker.EXPECT().AnyCommandExists("nonexistent-binary-12345").Return(false)
|
|
mockChecker.EXPECT().AnyFlatpakExists().Return(false)
|
|
|
|
opts := &Options{ShellDir: shellDir, AppChecker: mockChecker}
|
|
|
|
appendConfig(opts, cfgFile, []string{"nonexistent-binary-12345"}, []string{}, "test.toml")
|
|
|
|
cfgFile.Close()
|
|
output, err := os.ReadFile(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to read output: %v", err)
|
|
}
|
|
|
|
if len(output) != 0 {
|
|
t.Errorf("expected no config when binary doesn't exist, got: %q", string(output))
|
|
}
|
|
}
|
|
|
|
func TestAppendConfigFlatpakExists(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
shellDir := filepath.Join(tempDir, "shell")
|
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
|
t.Fatalf("failed to create configs dir: %v", err)
|
|
}
|
|
|
|
testConfig := "zen config content"
|
|
configPath := filepath.Join(configsDir, "test.toml")
|
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
|
t.Fatalf("failed to write config: %v", err)
|
|
}
|
|
|
|
outFile := filepath.Join(tempDir, "output.toml")
|
|
cfgFile, err := os.Create(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to create output file: %v", err)
|
|
}
|
|
defer cfgFile.Close()
|
|
|
|
mockChecker := mocks_utils.NewMockAppChecker(t)
|
|
mockChecker.EXPECT().AnyFlatpakExists("app.zen_browser.zen").Return(true)
|
|
|
|
opts := &Options{ShellDir: shellDir, AppChecker: mockChecker}
|
|
|
|
appendConfig(opts, cfgFile, nil, []string{"app.zen_browser.zen"}, "test.toml")
|
|
|
|
cfgFile.Close()
|
|
output, err := os.ReadFile(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to read output: %v", err)
|
|
}
|
|
|
|
if len(output) == 0 {
|
|
t.Errorf("expected config to be written when flatpak exists")
|
|
}
|
|
}
|
|
|
|
func TestAppendConfigFlatpakDoesNotExist(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
shellDir := filepath.Join(tempDir, "shell")
|
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
|
t.Fatalf("failed to create configs dir: %v", err)
|
|
}
|
|
|
|
testConfig := "test config content"
|
|
configPath := filepath.Join(configsDir, "test.toml")
|
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
|
t.Fatalf("failed to write config: %v", err)
|
|
}
|
|
|
|
outFile := filepath.Join(tempDir, "output.toml")
|
|
cfgFile, err := os.Create(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to create output file: %v", err)
|
|
}
|
|
defer cfgFile.Close()
|
|
|
|
mockChecker := mocks_utils.NewMockAppChecker(t)
|
|
mockChecker.EXPECT().AnyCommandExists().Return(false)
|
|
mockChecker.EXPECT().AnyFlatpakExists("com.nonexistent.flatpak").Return(false)
|
|
|
|
opts := &Options{ShellDir: shellDir, AppChecker: mockChecker}
|
|
|
|
appendConfig(opts, cfgFile, []string{}, []string{"com.nonexistent.flatpak"}, "test.toml")
|
|
|
|
cfgFile.Close()
|
|
output, err := os.ReadFile(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to read output: %v", err)
|
|
}
|
|
|
|
if len(output) != 0 {
|
|
t.Errorf("expected no config when flatpak doesn't exist, got: %q", string(output))
|
|
}
|
|
}
|
|
|
|
func TestAppendConfigBothExist(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
shellDir := filepath.Join(tempDir, "shell")
|
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
|
t.Fatalf("failed to create configs dir: %v", err)
|
|
}
|
|
|
|
testConfig := "zen config content"
|
|
configPath := filepath.Join(configsDir, "test.toml")
|
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
|
t.Fatalf("failed to write config: %v", err)
|
|
}
|
|
|
|
outFile := filepath.Join(tempDir, "output.toml")
|
|
cfgFile, err := os.Create(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to create output file: %v", err)
|
|
}
|
|
defer cfgFile.Close()
|
|
|
|
mockChecker := mocks_utils.NewMockAppChecker(t)
|
|
mockChecker.EXPECT().AnyCommandExists("sh").Return(true)
|
|
|
|
opts := &Options{ShellDir: shellDir, AppChecker: mockChecker}
|
|
|
|
appendConfig(opts, cfgFile, []string{"sh"}, []string{"app.zen_browser.zen"}, "test.toml")
|
|
|
|
cfgFile.Close()
|
|
output, err := os.ReadFile(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to read output: %v", err)
|
|
}
|
|
|
|
if len(output) == 0 {
|
|
t.Errorf("expected config to be written when both binary and flatpak exist")
|
|
}
|
|
}
|
|
|
|
func TestAppendConfigNeitherExists(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
shellDir := filepath.Join(tempDir, "shell")
|
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
|
t.Fatalf("failed to create configs dir: %v", err)
|
|
}
|
|
|
|
testConfig := "test config content"
|
|
configPath := filepath.Join(configsDir, "test.toml")
|
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
|
t.Fatalf("failed to write config: %v", err)
|
|
}
|
|
|
|
outFile := filepath.Join(tempDir, "output.toml")
|
|
cfgFile, err := os.Create(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to create output file: %v", err)
|
|
}
|
|
defer cfgFile.Close()
|
|
|
|
mockChecker := mocks_utils.NewMockAppChecker(t)
|
|
mockChecker.EXPECT().AnyCommandExists("nonexistent-binary-12345").Return(false)
|
|
mockChecker.EXPECT().AnyFlatpakExists("com.nonexistent.flatpak").Return(false)
|
|
|
|
opts := &Options{ShellDir: shellDir, AppChecker: mockChecker}
|
|
|
|
appendConfig(opts, cfgFile, []string{"nonexistent-binary-12345"}, []string{"com.nonexistent.flatpak"}, "test.toml")
|
|
|
|
cfgFile.Close()
|
|
output, err := os.ReadFile(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to read output: %v", err)
|
|
}
|
|
|
|
if len(output) != 0 {
|
|
t.Errorf("expected no config when neither exists, got: %q", string(output))
|
|
}
|
|
}
|
|
|
|
func TestAppendConfigNoChecks(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
shellDir := filepath.Join(tempDir, "shell")
|
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
|
t.Fatalf("failed to create configs dir: %v", err)
|
|
}
|
|
|
|
testConfig := "always include"
|
|
configPath := filepath.Join(configsDir, "test.toml")
|
|
if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil {
|
|
t.Fatalf("failed to write config: %v", err)
|
|
}
|
|
|
|
outFile := filepath.Join(tempDir, "output.toml")
|
|
cfgFile, err := os.Create(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to create output file: %v", err)
|
|
}
|
|
defer cfgFile.Close()
|
|
|
|
opts := &Options{ShellDir: shellDir}
|
|
|
|
appendConfig(opts, cfgFile, nil, nil, "test.toml")
|
|
|
|
cfgFile.Close()
|
|
output, err := os.ReadFile(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to read output: %v", err)
|
|
}
|
|
|
|
if len(output) == 0 {
|
|
t.Errorf("expected config to be written when no checks specified")
|
|
}
|
|
}
|
|
|
|
func TestAppendConfigFileDoesNotExist(t *testing.T) {
|
|
tempDir := t.TempDir()
|
|
|
|
shellDir := filepath.Join(tempDir, "shell")
|
|
configsDir := filepath.Join(shellDir, "matugen", "configs")
|
|
if err := os.MkdirAll(configsDir, 0755); err != nil {
|
|
t.Fatalf("failed to create configs dir: %v", err)
|
|
}
|
|
|
|
outFile := filepath.Join(tempDir, "output.toml")
|
|
cfgFile, err := os.Create(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to create output file: %v", err)
|
|
}
|
|
defer cfgFile.Close()
|
|
|
|
opts := &Options{ShellDir: shellDir}
|
|
|
|
appendConfig(opts, cfgFile, nil, nil, "nonexistent.toml")
|
|
|
|
cfgFile.Close()
|
|
output, err := os.ReadFile(outFile)
|
|
if err != nil {
|
|
t.Fatalf("failed to read output: %v", err)
|
|
}
|
|
|
|
if len(output) != 0 {
|
|
t.Errorf("expected no config when file doesn't exist, got: %q", string(output))
|
|
}
|
|
}
|
|
|
|
func TestSubstituteVars(t *testing.T) {
|
|
configDir := utils.XDGConfigHome()
|
|
dataDir := utils.XDGDataHome()
|
|
cacheDir := utils.XDGCacheHome()
|
|
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
shellDir string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "substitutes SHELL_DIR",
|
|
input: "input_path = 'SHELL_DIR/matugen/templates/foo.conf'",
|
|
shellDir: "/home/user/shell",
|
|
expected: "input_path = '/home/user/shell/matugen/templates/foo.conf'",
|
|
},
|
|
{
|
|
name: "substitutes CONFIG_DIR",
|
|
input: "output_path = 'CONFIG_DIR/kitty/theme.conf'",
|
|
shellDir: "/home/user/shell",
|
|
expected: "output_path = '" + configDir + "/kitty/theme.conf'",
|
|
},
|
|
{
|
|
name: "substitutes DATA_DIR",
|
|
input: "output_path = 'DATA_DIR/color-schemes/theme.colors'",
|
|
shellDir: "/home/user/shell",
|
|
expected: "output_path = '" + dataDir + "/color-schemes/theme.colors'",
|
|
},
|
|
{
|
|
name: "substitutes CACHE_DIR",
|
|
input: "output_path = 'CACHE_DIR/wal/colors.json'",
|
|
shellDir: "/home/user/shell",
|
|
expected: "output_path = '" + cacheDir + "/wal/colors.json'",
|
|
},
|
|
{
|
|
name: "substitutes all dir types",
|
|
input: "'SHELL_DIR/a' 'CONFIG_DIR/b' 'DATA_DIR/c' 'CACHE_DIR/d'",
|
|
shellDir: "/shell",
|
|
expected: "'/shell/a' '" + configDir + "/b' '" + dataDir + "/c' '" + cacheDir + "/d'",
|
|
},
|
|
{
|
|
name: "no substitution when no placeholders",
|
|
input: "input_path = '/absolute/path/foo.conf'",
|
|
shellDir: "/home/user/shell",
|
|
expected: "input_path = '/absolute/path/foo.conf'",
|
|
},
|
|
{
|
|
name: "multiple SHELL_DIR occurrences",
|
|
input: "'SHELL_DIR/a' and 'SHELL_DIR/b'",
|
|
shellDir: "/shell",
|
|
expected: "'/shell/a' and '/shell/b'",
|
|
},
|
|
{
|
|
name: "only substitutes quoted paths",
|
|
input: "SHELL_DIR/unquoted and 'SHELL_DIR/quoted'",
|
|
shellDir: "/shell",
|
|
expected: "SHELL_DIR/unquoted and '/shell/quoted'",
|
|
},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
result := substituteVars(tc.input, tc.shellDir)
|
|
assert.Equal(t, tc.expected, result)
|
|
})
|
|
}
|
|
}
|