package utils import ( "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" ) func TestAggregateGlobsWithSourceDir(t *testing.T) { tmpDir, err := os.MkdirTemp("", "aggregate-globs-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) // Create a subdirectory structure subDir := filepath.Join(tmpDir, "subdir") err = os.MkdirAll(subDir, 0755) assert.NoError(t, err) // Create test files testFile := filepath.Join(subDir, "test.xml") err = os.WriteFile(testFile, []byte(""), 0644) assert.NoError(t, err) commands := []ModifyCommand{ { Name: "test1", Files: []string{"subdir/*.xml"}, SourceDir: tmpDir, }, { Name: "test2", Files: []string{"*.txt"}, SourceDir: tmpDir, }, } globs := AggregateGlobs(commands) // Both should be resolved relative to tmpDir expectedSubdir := ResolvePath(filepath.Join(tmpDir, "subdir/*.xml")) expectedTxt := ResolvePath(filepath.Join(tmpDir, "*.txt")) assert.Contains(t, globs, expectedSubdir, "Should contain resolved subdir glob") assert.Contains(t, globs, expectedTxt, "Should contain resolved txt glob") assert.Len(t, globs, 2, "Should have 2 unique globs") } func TestAggregateGlobsWithAbsolutePaths(t *testing.T) { tmpDir, err := os.MkdirTemp("", "aggregate-globs-abs-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) absPath := ResolvePath(tmpDir) commands := []ModifyCommand{ { Name: "test1", Files: []string{absPath + "/*.xml"}, SourceDir: tmpDir, // SourceDir should be ignored for absolute paths }, } globs := AggregateGlobs(commands) // Absolute path should be used as-is (after ResolvePath normalization) expected := ResolvePath(absPath + "/*.xml") assert.Contains(t, globs, expected, "Should contain absolute path glob") assert.Len(t, globs, 1, "Should have 1 glob") } func TestAggregateGlobsWithoutSourceDir(t *testing.T) { cwd, err := os.Getwd() assert.NoError(t, err) commands := []ModifyCommand{ { Name: "test1", Files: []string{"*.xml"}, SourceDir: "", // No SourceDir }, } globs := AggregateGlobs(commands) // Without SourceDir, should resolve relative to CWD expected := ResolvePath(filepath.Join(cwd, "*.xml")) assert.Contains(t, globs, expected, "Should resolve relative to CWD when SourceDir is empty") } func TestAggregateGlobsConsistentRegardlessOfCWD(t *testing.T) { tmpDir, err := os.MkdirTemp("", "aggregate-globs-cwd-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) // Create test structure testFile := filepath.Join(tmpDir, "test.xml") err = os.WriteFile(testFile, []byte(""), 0644) assert.NoError(t, err) commands := []ModifyCommand{ { Name: "test", Files: []string{"test.xml"}, SourceDir: tmpDir, }, } // Get original CWD originalCwd, err := os.Getwd() assert.NoError(t, err) defer os.Chdir(originalCwd) // Test from original directory globs1 := AggregateGlobs(commands) expected1 := ResolvePath(filepath.Join(tmpDir, "test.xml")) // Change to tmpDir err = os.Chdir(tmpDir) assert.NoError(t, err) // Test from tmpDir - should produce same result globs2 := AggregateGlobs(commands) expected2 := ResolvePath(filepath.Join(tmpDir, "test.xml")) // Both should resolve to the same absolute path assert.Equal(t, expected1, expected2, "Paths should be identical regardless of CWD") assert.Contains(t, globs1, expected1, "First run should contain expected path") assert.Contains(t, globs2, expected2, "Second run should contain expected path") assert.Equal(t, globs1, globs2, "Globs should be identical regardless of CWD") } func TestAssociateFilesWithCommandsSourceDir(t *testing.T) { tmpDir, err := os.MkdirTemp("", "associate-files-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) // Create test structure subDir := filepath.Join(tmpDir, "data") err = os.MkdirAll(subDir, 0755) assert.NoError(t, err) testFile := filepath.Join(subDir, "test.xml") err = os.WriteFile(testFile, []byte(""), 0644) assert.NoError(t, err) commands := []ModifyCommand{ { Name: "test", Regex: "pattern", Lua: "expr", Files: []string{"data/test.xml"}, SourceDir: tmpDir, }, } files := []string{testFile} associations, err := AssociateFilesWithCommands(files, commands) assert.NoError(t, err) // File should be associated with command assert.Contains(t, associations, testFile, "File should be in associations") association := associations[testFile] assert.Len(t, association.Commands, 1, "Should have 1 command") assert.Equal(t, "test", association.Commands[0].Name, "Command name should match") } func TestAssociateFilesWithCommandsAbsolutePath(t *testing.T) { tmpDir, err := os.MkdirTemp("", "associate-files-abs-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) testFile := filepath.Join(tmpDir, "test.xml") err = os.WriteFile(testFile, []byte(""), 0644) assert.NoError(t, err) absPath := ResolvePath(testFile) commands := []ModifyCommand{ { Name: "test", Regex: "pattern", Lua: "expr", Files: []string{absPath}, SourceDir: tmpDir, // Should be ignored for absolute paths }, } files := []string{testFile} associations, err := AssociateFilesWithCommands(files, commands) assert.NoError(t, err) // File should be associated assert.Contains(t, associations, testFile, "File should be in associations") association := associations[testFile] assert.Len(t, association.Commands, 1, "Should have 1 command") } func TestAssociateFilesWithCommandsNoSourceDir(t *testing.T) { tmpDir, err := os.MkdirTemp("", "associate-files-no-sourcedir-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) testFile := filepath.Join(tmpDir, "test.xml") err = os.WriteFile(testFile, []byte(""), 0644) assert.NoError(t, err) // Use absolute path since we have no SourceDir absPath := ResolvePath(testFile) commands := []ModifyCommand{ { Name: "test", Regex: "pattern", Lua: "expr", Files: []string{absPath}, SourceDir: "", // No SourceDir }, } files := []string{testFile} associations, err := AssociateFilesWithCommands(files, commands) assert.NoError(t, err) // File should be associated assert.Contains(t, associations, testFile, "File should be in associations") association := associations[testFile] assert.Len(t, association.Commands, 1, "Should have 1 command") } func TestSourceDirConditionCoverage(t *testing.T) { tmpDir, err := os.MkdirTemp("", "sourcedir-condition-test-*") assert.NoError(t, err) defer os.RemoveAll(tmpDir) tests := []struct { name string glob string sourceDir string shouldResolve bool }{ { name: "Relative path with SourceDir", glob: "test.xml", sourceDir: tmpDir, shouldResolve: true, }, { name: "Absolute path with SourceDir", glob: ResolvePath(filepath.Join(tmpDir, "test.xml")), sourceDir: tmpDir, shouldResolve: false, // Should use absolute path as-is }, { name: "Relative path without SourceDir", glob: "test.xml", sourceDir: "", shouldResolve: false, // Should resolve relative to CWD }, { name: "Absolute path without SourceDir", glob: ResolvePath(filepath.Join(tmpDir, "test.xml")), sourceDir: "", shouldResolve: false, // Should use absolute path as-is }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { commands := []ModifyCommand{ { Name: "test", Files: []string{tt.glob}, SourceDir: tt.sourceDir, }, } globs := AggregateGlobs(commands) assert.Len(t, globs, 1, "Should have 1 glob") var resolvedGlob string for g := range globs { resolvedGlob = g } if tt.shouldResolve { // Should be resolved relative to SourceDir expected := ResolvePath(filepath.Join(tt.sourceDir, tt.glob)) assert.Equal(t, expected, resolvedGlob, "Should resolve relative to SourceDir") } else if filepath.IsAbs(tt.glob) { // Absolute path should be normalized but not changed expected := ResolvePath(tt.glob) assert.Equal(t, expected, resolvedGlob, "Absolute path should be normalized") } else { // Relative path without SourceDir should resolve to CWD cwd, _ := os.Getwd() expected := ResolvePath(filepath.Join(cwd, tt.glob)) assert.Equal(t, expected, resolvedGlob, "Should resolve relative to CWD") } }) } }