package indexgen import ( "os" "path/filepath" "regexp" "strings" "testing" ) func TestProcessDirBasic(t *testing.T) { tempDir := t.TempDir() // Create test files testFiles := []string{"test.go", "test.py", "README.md"} for _, file := range testFiles { f, err := os.Create(filepath.Join(tempDir, file)) if err != nil { t.Fatalf("Failed to create test file %s: %v", file, err) } _, err = f.WriteString("test content") if err != nil { t.Fatalf("Failed to write to file: %v", err) } f.Close() } opts := &Options{ TopDir: tempDir, OutputFile: "index.html", IncludeHidden: false, Verbose: false, } err := ProcessDir(tempDir, opts) if err != nil { t.Fatalf("ProcessDir failed: %v", err) } // Check that index.html was created indexPath := filepath.Join(tempDir, "index.html") if _, err := os.Stat(indexPath); os.IsNotExist(err) { t.Fatal("index.html was not created") } // Read and verify content content, err := os.ReadFile(indexPath) if err != nil { t.Fatalf("Failed to read index.html: %v", err) } htmlContent := string(content) // Check for HTML structure if !strings.Contains(htmlContent, "") { t.Error("index.html should contain HTML doctype") } // Check for file entries for _, file := range testFiles { if !strings.Contains(htmlContent, file) { t.Errorf("index.html should contain file %s", file) } } // Check for proper file icons if !strings.Contains(htmlContent, "#go") { t.Error("index.html should contain Go icon reference for .go files") } if !strings.Contains(htmlContent, "#py") { t.Error("index.html should contain Python icon reference for .py files") } if !strings.Contains(htmlContent, "#md") { t.Error("index.html should contain Markdown icon reference for .md files") } } func TestProcessDirRecursive(t *testing.T) { tempDir := t.TempDir() // Create test files in root f, err := os.Create(filepath.Join(tempDir, "root.txt")) if err != nil { t.Fatalf("Failed to create root file: %v", err) } f.Close() // Create subdirectory with files subDir := filepath.Join(tempDir, "subdir") err = os.Mkdir(subDir, 0755) if err != nil { t.Fatalf("Failed to create subdirectory: %v", err) } subFile, err := os.Create(filepath.Join(subDir, "sub.txt")) if err != nil { t.Fatalf("Failed to create sub file: %v", err) } subFile.Close() // Create nested subdirectory nestedDir := filepath.Join(subDir, "nested") err = os.Mkdir(nestedDir, 0755) if err != nil { t.Fatalf("Failed to create nested directory: %v", err) } nestedFile, err := os.Create(filepath.Join(nestedDir, "nested.txt")) if err != nil { t.Fatalf("Failed to create nested file: %v", err) } nestedFile.Close() opts := &Options{ TopDir: tempDir, OutputFile: "index.html", Recursive: true, IncludeHidden: false, Verbose: false, } err = ProcessDir(tempDir, opts) if err != nil { t.Fatalf("ProcessDir failed: %v", err) } // Check that index.html files were created in each directory indexPaths := []string{ filepath.Join(tempDir, "index.html"), filepath.Join(subDir, "index.html"), filepath.Join(nestedDir, "index.html"), } for _, indexPath := range indexPaths { if _, err := os.Stat(indexPath); os.IsNotExist(err) { t.Errorf("index.html was not created at %s", indexPath) } } // Check root index.html contains subdirectory rootContent, err := os.ReadFile(filepath.Join(tempDir, "index.html")) if err != nil { t.Fatalf("Failed to read root index.html: %v", err) } if !strings.Contains(string(rootContent), "subdir") { t.Error("Root index.html should contain subdirectory") } // Check sub index.html contains nested directory subContent, err := os.ReadFile(filepath.Join(subDir, "index.html")) if err != nil { t.Fatalf("Failed to read sub index.html: %v", err) } if !strings.Contains(string(subContent), "nested") { t.Error("Sub index.html should contain nested directory") } if !strings.Contains(string(subContent), "sub.txt") { t.Error("Sub index.html should contain sub.txt file") } } func TestProcessDirWithExcludeRegex(t *testing.T) { tempDir := t.TempDir() // Create test files testFiles := []string{"include.go", "exclude.tmp", "node_modules.txt"} for _, file := range testFiles { f, err := os.Create(filepath.Join(tempDir, file)) if err != nil { t.Fatalf("Failed to create test file %s: %v", file, err) } f.Close() } regex := regexp.MustCompile("(tmp|node_modules)") opts := &Options{ TopDir: tempDir, OutputFile: "index.html", ExcludeRegex: regex, IncludeHidden: false, Verbose: false, } err := ProcessDir(tempDir, opts) if err != nil { t.Fatalf("ProcessDir failed: %v", err) } // Read and verify content content, err := os.ReadFile(filepath.Join(tempDir, "index.html")) if err != nil { t.Fatalf("Failed to read index.html: %v", err) } htmlContent := string(content) // Check that included file is present if !strings.Contains(htmlContent, "include.go") { t.Error("index.html should contain include.go") } // Check that excluded files are not present if strings.Contains(htmlContent, "exclude.tmp") { t.Error("index.html should not contain exclude.tmp (excluded by regex)") } if strings.Contains(htmlContent, "node_modules.txt") { t.Error("index.html should not contain node_modules.txt (excluded by regex)") } } func TestProcessDirWithDirAppend(t *testing.T) { tempDir := t.TempDir() // Create a subdirectory subDir := filepath.Join(tempDir, "subdir") err := os.Mkdir(subDir, 0755) if err != nil { t.Fatalf("Failed to create subdirectory: %v", err) } opts := &Options{ TopDir: tempDir, OutputFile: "index.html", DirAppend: true, IncludeHidden: false, Verbose: false, } err = ProcessDir(tempDir, opts) if err != nil { t.Fatalf("ProcessDir failed: %v", err) } // Read and verify content content, err := os.ReadFile(filepath.Join(tempDir, "index.html")) if err != nil { t.Fatalf("Failed to read index.html: %v", err) } htmlContent := string(content) // Check that directory links include index.html if !strings.Contains(htmlContent, "subdir/index.html") { t.Errorf("Directory links should include index.html when DirAppend is true. Expected subdir/index.html in content") } } func TestProcessDirVerbose(t *testing.T) { tempDir := t.TempDir() // Create test file f, err := os.Create(filepath.Join(tempDir, "test.txt")) if err != nil { t.Fatalf("Failed to create test file: %v", err) } f.Close() opts := &Options{ TopDir: tempDir, OutputFile: "index.html", Verbose: true, IncludeHidden: false, } err = ProcessDir(tempDir, opts) if err != nil { t.Fatalf("ProcessDir failed: %v", err) } // Check that index.html was created indexPath := filepath.Join(tempDir, "index.html") if _, err := os.Stat(indexPath); os.IsNotExist(err) { t.Fatal("index.html was not created") } } func TestProcessDirErrorHandling(t *testing.T) { // Test with non-existent directory opts := &Options{ TopDir: "/non/existent/directory", OutputFile: "index.html", IncludeHidden: false, Verbose: false, } err := ProcessDir("/non/existent/directory", opts) if err == nil { t.Error("ProcessDir should fail with non-existent directory") } } func TestProcessDirWithSymlinks(t *testing.T) { tempDir := t.TempDir() // Create a regular file regularFile := filepath.Join(tempDir, "regular.txt") f, err := os.Create(regularFile) if err != nil { t.Fatalf("Failed to create regular file: %v", err) } _, err = f.WriteString("content") if err != nil { t.Fatalf("Failed to write to file: %v", err) } f.Close() // Create a symlink to the file (skip on Windows) symlinkFile := filepath.Join(tempDir, "symlink.txt") err = os.Symlink(regularFile, symlinkFile) if err != nil { // Skip symlink tests on systems that don't support them t.Skipf("Skipping symlink test: %v", err) } opts := &Options{ TopDir: tempDir, OutputFile: "index.html", IncludeHidden: false, Verbose: false, } err = ProcessDir(tempDir, opts) if err != nil { t.Fatalf("ProcessDir failed: %v", err) } // Read and verify content content, err := os.ReadFile(filepath.Join(tempDir, "index.html")) if err != nil { t.Fatalf("Failed to read index.html: %v", err) } htmlContent := string(content) // Check that both regular file and symlink are present if !strings.Contains(htmlContent, "regular.txt") { t.Error("index.html should contain regular file") } if !strings.Contains(htmlContent, "symlink.txt") { t.Error("index.html should contain symlink file") } // Check that symlink has appropriate icon if !strings.Contains(htmlContent, "#symlink") { t.Error("index.html should contain symlink icon for symlinked file") } }