314 lines
7.2 KiB
Go
314 lines
7.2 KiB
Go
package utils
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestAggregateGlobsWithDuplicates(t *testing.T) {
|
|
commands := []ModifyCommand{
|
|
{Files: []string{"*.txt", "*.md"}},
|
|
{Files: []string{"*.txt", "*.go"}}, // *.txt is duplicate
|
|
{Files: []string{"test/**/*.xml"}},
|
|
}
|
|
|
|
globs := AggregateGlobs(commands)
|
|
|
|
// Should deduplicate
|
|
assert.Equal(t, 4, len(globs))
|
|
// AggregateGlobs resolves paths, which uses forward slashes internally
|
|
assert.Contains(t, globs, ResolvePath("*.txt"))
|
|
assert.Contains(t, globs, ResolvePath("*.md"))
|
|
assert.Contains(t, globs, ResolvePath("*.go"))
|
|
assert.Contains(t, globs, ResolvePath("test/**/*.xml"))
|
|
}
|
|
|
|
func TestExpandGlobsWithActualFiles(t *testing.T) {
|
|
// Create temp dir with test files
|
|
tmpDir, err := os.MkdirTemp("", "glob-test-*")
|
|
assert.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Create test files
|
|
testFile1 := filepath.Join(tmpDir, "test1.txt")
|
|
testFile2 := filepath.Join(tmpDir, "test2.txt")
|
|
testFile3 := filepath.Join(tmpDir, "test.md")
|
|
|
|
os.WriteFile(testFile1, []byte("test"), 0644)
|
|
os.WriteFile(testFile2, []byte("test"), 0644)
|
|
os.WriteFile(testFile3, []byte("test"), 0644)
|
|
|
|
// Change to temp directory so glob pattern can find files
|
|
origDir, _ := os.Getwd()
|
|
defer os.Chdir(origDir)
|
|
os.Chdir(tmpDir)
|
|
|
|
// Test expanding globs using ResolvePath to normalize the pattern
|
|
globs := map[string]struct{}{
|
|
ResolvePath("*.txt"): {},
|
|
}
|
|
|
|
files, err := ExpandGlobs(globs)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 2, len(files))
|
|
}
|
|
|
|
func TestSplitPatternWithTilde(t *testing.T) {
|
|
pattern := "~/test/*.txt"
|
|
static, pat := SplitPattern(pattern)
|
|
|
|
// Should expand ~
|
|
assert.NotEqual(t, "~", static)
|
|
assert.Contains(t, pat, "*.txt")
|
|
}
|
|
|
|
func TestLoadCommandsWithDisabled(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "disabled-test-*")
|
|
assert.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
yamlContent := `
|
|
variables:
|
|
test: "value"
|
|
|
|
commands:
|
|
- name: "enabled_cmd"
|
|
regex: "test"
|
|
lua: "v1 * 2"
|
|
files: ["*.txt"]
|
|
- name: "disabled_cmd"
|
|
regex: "test2"
|
|
lua: "v1 * 3"
|
|
files: ["*.txt"]
|
|
disable: true
|
|
`
|
|
|
|
yamlFile := filepath.Join(tmpDir, "test.yml")
|
|
err = os.WriteFile(yamlFile, []byte(yamlContent), 0644)
|
|
assert.NoError(t, err)
|
|
|
|
// Change to temp directory so LoadCommands can find the file with a simple pattern
|
|
origDir, _ := os.Getwd()
|
|
defer os.Chdir(origDir)
|
|
os.Chdir(tmpDir)
|
|
|
|
commands, variables, err := LoadCommands([]string{"test.yml"})
|
|
assert.NoError(t, err)
|
|
|
|
// Should only load enabled command
|
|
assert.Equal(t, 1, len(commands))
|
|
assert.Equal(t, "enabled_cmd", commands[0].Name)
|
|
|
|
// Should still load variables
|
|
assert.Equal(t, 1, len(variables))
|
|
}
|
|
|
|
func TestFilterCommandsByName(t *testing.T) {
|
|
commands := []ModifyCommand{
|
|
{Name: "test_multiply"},
|
|
{Name: "test_divide"},
|
|
{Name: "other_command"},
|
|
{Name: "test_add"},
|
|
}
|
|
|
|
// Filter by "test"
|
|
filtered := FilterCommands(commands, "test")
|
|
assert.Equal(t, 3, len(filtered))
|
|
|
|
// Filter by multiple
|
|
filtered = FilterCommands(commands, "multiply,divide")
|
|
assert.Equal(t, 2, len(filtered))
|
|
}
|
|
|
|
func TestCountGlobsBeforeDedup(t *testing.T) {
|
|
commands := []ModifyCommand{
|
|
{Files: []string{"*.txt", "*.md", "*.go"}},
|
|
{Files: []string{"*.xml"}},
|
|
{Files: []string{"test/**/*.txt", "data/**/*.json"}},
|
|
}
|
|
|
|
count := CountGlobsBeforeDedup(commands)
|
|
assert.Equal(t, 6, count)
|
|
}
|
|
|
|
func TestMatchesWithMemoization(t *testing.T) {
|
|
path := "test/file.txt"
|
|
glob := "**/*.txt"
|
|
|
|
// First call
|
|
matches1, err1 := Matches(path, glob)
|
|
assert.NoError(t, err1)
|
|
assert.True(t, matches1)
|
|
|
|
// Second call should use memo
|
|
matches2, err2 := Matches(path, glob)
|
|
assert.NoError(t, err2)
|
|
assert.Equal(t, matches1, matches2)
|
|
}
|
|
|
|
func TestValidateCommand(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
cmd ModifyCommand
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Valid command",
|
|
cmd: ModifyCommand{
|
|
Regex: "test",
|
|
Lua: "v1 * 2",
|
|
Files: []string{"*.txt"},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Valid JSON mode without regex",
|
|
cmd: ModifyCommand{
|
|
JSON: true,
|
|
Lua: "data.value = data.value * 2; modified = true",
|
|
Files: []string{"*.json"},
|
|
},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Missing regex in non-JSON mode",
|
|
cmd: ModifyCommand{
|
|
Lua: "v1 * 2",
|
|
Files: []string{"*.txt"},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Missing Lua",
|
|
cmd: ModifyCommand{
|
|
Regex: "test",
|
|
Files: []string{"*.txt"},
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Missing files",
|
|
cmd: ModifyCommand{
|
|
Regex: "test",
|
|
Lua: "v1 * 2",
|
|
},
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := tt.cmd.Validate()
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoadCommandsFromTomlWithVariables(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "toml-vars-test-*")
|
|
assert.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
tomlContent := `[variables]
|
|
multiplier = 3
|
|
prefix = "PREFIX_"
|
|
|
|
[[commands]]
|
|
name = "test_cmd"
|
|
regex = "value = !num"
|
|
lua = "v1 * multiplier"
|
|
files = ["*.txt"]
|
|
`
|
|
|
|
tomlFile := filepath.Join(tmpDir, "test.toml")
|
|
err = os.WriteFile(tomlFile, []byte(tomlContent), 0644)
|
|
assert.NoError(t, err)
|
|
|
|
// Change to temp directory so glob pattern can find the file
|
|
origDir, _ := os.Getwd()
|
|
defer os.Chdir(origDir)
|
|
os.Chdir(tmpDir)
|
|
|
|
commands, variables, err := LoadCommandsFromTomlFiles("test.toml")
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, 1, len(commands))
|
|
assert.Equal(t, 2, len(variables))
|
|
assert.Equal(t, int64(3), variables["multiplier"])
|
|
assert.Equal(t, "PREFIX_", variables["prefix"])
|
|
}
|
|
|
|
func TestConvertYAMLToTOMLSkipExisting(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "convert-skip-test-*")
|
|
assert.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
// Create YAML file
|
|
yamlContent := `
|
|
commands:
|
|
- name: "test"
|
|
regex: "value"
|
|
lua: "v1 * 2"
|
|
files: ["*.txt"]
|
|
`
|
|
yamlFile := filepath.Join(tmpDir, "test.yml")
|
|
err = os.WriteFile(yamlFile, []byte(yamlContent), 0644)
|
|
assert.NoError(t, err)
|
|
|
|
// Create TOML file (should skip conversion)
|
|
tomlFile := filepath.Join(tmpDir, "test.toml")
|
|
err = os.WriteFile(tomlFile, []byte("# existing"), 0644)
|
|
assert.NoError(t, err)
|
|
|
|
// Change to temp dir
|
|
origDir, _ := os.Getwd()
|
|
defer os.Chdir(origDir)
|
|
os.Chdir(tmpDir)
|
|
|
|
// Should skip existing TOML
|
|
err = ConvertYAMLToTOML("test.yml")
|
|
assert.NoError(t, err)
|
|
|
|
// TOML content should be unchanged
|
|
content, _ := os.ReadFile(tomlFile)
|
|
assert.Equal(t, "# existing", string(content))
|
|
}
|
|
|
|
func TestLoadCommandsWithTomlExtension(t *testing.T) {
|
|
tmpDir, err := os.MkdirTemp("", "toml-ext-test-*")
|
|
assert.NoError(t, err)
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
tomlContent := `
|
|
[variables]
|
|
test_var = "value"
|
|
|
|
[[commands]]
|
|
name = "TestCmd"
|
|
regex = "test"
|
|
lua = "return true"
|
|
files = ["*.txt"]
|
|
`
|
|
tomlFile := filepath.Join(tmpDir, "test.toml")
|
|
err = os.WriteFile(tomlFile, []byte(tomlContent), 0644)
|
|
assert.NoError(t, err)
|
|
|
|
origDir, _ := os.Getwd()
|
|
defer os.Chdir(origDir)
|
|
os.Chdir(tmpDir)
|
|
|
|
// This should trigger the .toml suffix check in LoadCommands
|
|
commands, variables, err := LoadCommands([]string{"test.toml"})
|
|
assert.NoError(t, err)
|
|
assert.Len(t, commands, 1)
|
|
assert.Equal(t, "TestCmd", commands[0].Name)
|
|
assert.Len(t, variables, 1)
|
|
assert.Equal(t, "value", variables["test_var"])
|
|
}
|