319 lines
9.5 KiB
Go
319 lines
9.5 KiB
Go
package backer
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// normalizePath converts backslashes to forward slashes for cross-platform consistency.
|
|
func normalizePath(p string) string {
|
|
return strings.ReplaceAll(p, "\\", "/")
|
|
}
|
|
|
|
// normalizePathSlice normalizes all paths in a slice.
|
|
func normalizePathSlice(paths []string) []string {
|
|
result := make([]string, len(paths))
|
|
for i, p := range paths {
|
|
result[i] = normalizePath(p)
|
|
}
|
|
return result
|
|
}
|
|
|
|
// TestGetFilesFromDirectories checks if GetFilesFromDirectories returns the proper amount of strings, correct strings and no error.
|
|
func TestGetFilesFromDirectories(t *testing.T) {
|
|
testDataPath := "../../test_data"
|
|
|
|
// Log the paths we're checking for debugging
|
|
t.Logf("Checking directories: %v", []string{
|
|
filepath.Join(testDataPath, "test1", "foo"),
|
|
filepath.Join(testDataPath, "test1", "bar"),
|
|
})
|
|
|
|
var (
|
|
input = Config{
|
|
Directories: []string{
|
|
filepath.Join(testDataPath, "test1", "foo"),
|
|
filepath.Join(testDataPath, "test1", "bar"),
|
|
},
|
|
}
|
|
expectedData = []string{
|
|
filepath.Join(testDataPath, "test1", "foo"),
|
|
filepath.Join(testDataPath, "test1", "foo", "empty_dir"),
|
|
filepath.Join(testDataPath, "test1", "foo", "hello_breakfast.txt"),
|
|
filepath.Join(testDataPath, "test1", "foo", "mydir"),
|
|
filepath.Join(testDataPath, "test1", "foo", "mydir", "myfile.txt"),
|
|
filepath.Join(testDataPath, "test1", "foo", "some_text.txt"),
|
|
filepath.Join(testDataPath, "test1", "bar"),
|
|
filepath.Join(testDataPath, "test1", "bar", "goodbye.txt"),
|
|
filepath.Join(testDataPath, "test1", "bar", "goodbye.txt", "text.txt"),
|
|
filepath.Join(testDataPath, "test1", "bar", "hello.txt"),
|
|
}
|
|
)
|
|
|
|
output, err := GetFilesFromDirectories(context.Background(), input.Directories)
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got %v", err)
|
|
}
|
|
|
|
outputLen := len(output)
|
|
expectedDataLen := len(expectedData)
|
|
|
|
if outputLen != expectedDataLen {
|
|
t.Errorf("length of output of GetFilesFromDirectories() does not match length of expected data: %d vs %d", outputLen, expectedDataLen)
|
|
}
|
|
|
|
for _, filepath := range output {
|
|
normalized := normalizePath(filepath)
|
|
normalizedExpected := normalizePathSlice(expectedData)
|
|
if !slices.Contains(normalizedExpected, normalized) {
|
|
t.Errorf("expectedData data does not contain string from output: %s", filepath)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestGetFilesFromDirectoriesSingleDir tests with a single directory.
|
|
func TestGetFilesFromDirectoriesSingleDir(t *testing.T) {
|
|
testDataPath := filepath.Join("../../test_data")
|
|
output, err := GetFilesFromDirectories(context.Background(), []string{filepath.Join(testDataPath, "test1", "foo")})
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got %v", err)
|
|
}
|
|
|
|
if len(output) == 0 {
|
|
t.Error("Expected non-empty output")
|
|
}
|
|
|
|
// Should contain the directory itself
|
|
if !slices.Contains(output, filepath.Join(testDataPath, "test1", "foo")) {
|
|
t.Error("Output should contain the root directory")
|
|
}
|
|
}
|
|
|
|
// TestGetFilesFromDirectoriesEmptyDir tests with an empty directory.
|
|
func TestGetFilesFromDirectoriesEmptyDir(t *testing.T) {
|
|
// Create temp empty dir
|
|
tmpDir := t.TempDir()
|
|
|
|
output, err := GetFilesFromDirectories(context.Background(), []string{tmpDir})
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got %v", err)
|
|
}
|
|
|
|
// Should contain at least the directory itself
|
|
if len(output) != 1 {
|
|
t.Errorf("Expected 1 entry (the directory itself), got %d", len(output))
|
|
}
|
|
}
|
|
|
|
// TestGetFilesFromDirectoriesNonExistent tests with non-existent directory.
|
|
// Should log error but not fail - returns empty list.
|
|
func TestGetFilesFromDirectoriesNonExistent(t *testing.T) {
|
|
testDataPath := filepath.Join("../../test_data")
|
|
nonExistentPath := filepath.Join(testDataPath, "nonexistent", "path", "that", "does", "not", "exist")
|
|
output, err := GetFilesFromDirectories(context.Background(), []string{nonExistentPath})
|
|
|
|
// Should not return error, but logs error
|
|
if err != nil {
|
|
t.Errorf("Expected no error (logs error instead), got %v", err)
|
|
}
|
|
|
|
// Should return empty list
|
|
if len(output) != 0 {
|
|
t.Errorf("Expected empty output for non-existent directory, got %d files", len(output))
|
|
}
|
|
}
|
|
|
|
// TestGetFilesFromDirectoriesPartialFailure tests with mix of valid and invalid directories.
|
|
func TestGetFilesFromDirectoriesPartialFailure(t *testing.T) {
|
|
testDataPath := filepath.Join("../../test_data")
|
|
// Create a temp directory that exists
|
|
tmpDir := t.TempDir()
|
|
|
|
output, err := GetFilesFromDirectories(context.Background(), []string{tmpDir, filepath.Join(testDataPath, "nonexistent", "path", "that", "does", "not", "exist")})
|
|
|
|
// Should not return error, but logs error
|
|
if err != nil {
|
|
t.Errorf("Expected no error (logs error instead), got %v", err)
|
|
}
|
|
|
|
// Should return files from valid directory
|
|
if len(output) == 0 {
|
|
t.Error("Expected files from valid directory")
|
|
}
|
|
}
|
|
|
|
// TestGetFilesFromDirectoriesMultipleDirs tests multiple directories.
|
|
func TestGetFilesFromDirectoriesMultipleDirs(t *testing.T) {
|
|
testDataPath := filepath.Join("../../test_data")
|
|
output, err := GetFilesFromDirectories(context.Background(), []string{
|
|
filepath.Join(testDataPath, "test1", "foo"),
|
|
filepath.Join(testDataPath, "test1", "bar"),
|
|
})
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got %v", err)
|
|
}
|
|
|
|
// Should contain entries from both directories
|
|
hasFoo := slices.ContainsFunc(output, func(s string) bool {
|
|
return s == filepath.Join(testDataPath, "test1", "foo") || s == filepath.Join(testDataPath, "test1", "foo", "hello_breakfast.txt")
|
|
})
|
|
hasBar := slices.ContainsFunc(output, func(s string) bool {
|
|
return s == filepath.Join(testDataPath, "test1", "bar") || s == filepath.Join(testDataPath, "test1", "bar", "hello.txt")
|
|
})
|
|
|
|
if !hasFoo {
|
|
t.Error("Output should contain entries from foo directory")
|
|
}
|
|
if !hasBar {
|
|
t.Error("Output should contain entries from bar directory")
|
|
}
|
|
}
|
|
|
|
// TestGetFilesFromDirectoriesSymlink tests symlink handling.
|
|
func TestGetFilesFromDirectoriesSymlink(t *testing.T) {
|
|
// Create temp dir with symlink
|
|
tmpDir := t.TempDir()
|
|
targetFile := tmpDir + "/target.txt"
|
|
symlinkFile := tmpDir + "/link.txt"
|
|
|
|
// Create target file
|
|
if err := os.WriteFile(targetFile, []byte("test"), 0644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create symlink
|
|
if err := os.Symlink(targetFile, symlinkFile); err != nil {
|
|
t.Skip("Symlinks not supported, skipping test")
|
|
}
|
|
|
|
output, err := GetFilesFromDirectories(context.Background(), []string{tmpDir})
|
|
|
|
if err != nil {
|
|
t.Errorf("Expected no error, got %v", err)
|
|
}
|
|
|
|
// Should contain the symlink
|
|
if !slices.ContainsFunc(output, func(s string) bool {
|
|
return s == symlinkFile
|
|
}) {
|
|
t.Error("Output should contain the symlink")
|
|
}
|
|
}
|
|
|
|
func TestIsExcluded(t *testing.T) {
|
|
// Save original excludePatterns and restore after test
|
|
originalPatterns := excludePatterns
|
|
defer func() { excludePatterns = originalPatterns }()
|
|
|
|
// Test empty patterns
|
|
excludePatterns = nil
|
|
if isExcluded("/some/path") {
|
|
t.Error("Expected no exclusion with empty patterns")
|
|
}
|
|
|
|
// Test matching pattern
|
|
excludePatterns = []*regexp.Regexp{
|
|
regexp.MustCompile(`\.tmp$`),
|
|
regexp.MustCompile(`/node_modules/`),
|
|
}
|
|
if !isExcluded("/tmp/foo.tmp") {
|
|
t.Error("Expected exclusion for .tmp file")
|
|
}
|
|
if !isExcluded("/project/node_modules/package") {
|
|
t.Error("Expected exclusion for node_modules path")
|
|
}
|
|
if isExcluded("/tmp/foo.txt") {
|
|
t.Error("Expected no exclusion for .txt file")
|
|
}
|
|
}
|
|
|
|
func TestGetFilesFromDirectoriesWithExcludes(t *testing.T) {
|
|
// Save original excludePatterns and restore after test
|
|
originalPatterns := excludePatterns
|
|
defer func() { excludePatterns = originalPatterns }()
|
|
|
|
// Create a temporary directory with some files
|
|
tmpDir := t.TempDir()
|
|
// Create files that should be included
|
|
err := os.WriteFile(tmpDir+"/keep.txt", []byte("keep"), 0644)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Create files that should be excluded
|
|
err = os.WriteFile(tmpDir+"/skip.tmp", []byte("skip"), 0644)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Create a subdirectory with file
|
|
subDir := tmpDir + "/sub"
|
|
err = os.Mkdir(subDir, 0755)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
err = os.WriteFile(subDir+"/file.txt", []byte("file"), 0644)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Create a .tmp file in subdirectory
|
|
err = os.WriteFile(subDir+"/skip.tmp", []byte("skip"), 0644)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Set exclude pattern for .tmp files
|
|
excludePatterns = []*regexp.Regexp{
|
|
regexp.MustCompile(`\.tmp$`),
|
|
}
|
|
|
|
output, err := GetFilesFromDirectories(context.Background(), []string{tmpDir})
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error: %v", err)
|
|
}
|
|
|
|
// Expect entries: tmpDir, keep.txt, subDir, sub/file.txt
|
|
// Should NOT contain any .tmp files
|
|
expected := []string{
|
|
tmpDir,
|
|
tmpDir + "/keep.txt",
|
|
subDir,
|
|
subDir + "/file.txt",
|
|
}
|
|
|
|
// Normalize paths for cross-platform comparison
|
|
normalizedOutput := make([]string, len(output))
|
|
for i, p := range output {
|
|
normalizedOutput[i] = normalizePath(p)
|
|
}
|
|
normalizedExpected := make([]string, len(expected))
|
|
for i, p := range expected {
|
|
normalizedExpected[i] = normalizePath(p)
|
|
}
|
|
|
|
if len(normalizedOutput) != len(normalizedExpected) {
|
|
t.Errorf("Expected %d entries, got %d: %v", len(normalizedExpected), len(normalizedOutput), normalizedOutput)
|
|
}
|
|
for _, exp := range normalizedExpected {
|
|
found := slices.Contains(normalizedOutput, exp)
|
|
if !found {
|
|
t.Errorf("Expected entry %q not found", exp)
|
|
}
|
|
}
|
|
// Ensure no .tmp files appear
|
|
for _, path := range normalizedOutput {
|
|
if strings.HasSuffix(path, ".tmp") {
|
|
t.Errorf("Excluded file %q appeared in output", path)
|
|
}
|
|
}
|
|
}
|
|
|
|
/* vim: setlocal ft=go noet ai ts=4 sw=4 sts=4: */
|