|
7 | 7 | "github.com/epilande/codegrab/internal/filesystem" |
8 | 8 | ) |
9 | 9 |
|
| 10 | +// TestBuildDisplayNodes tests the display node building. |
| 11 | +// Note: All paths use forward slashes ("/") for cross-platform compatibility. |
| 12 | +// The walker normalizes all paths to use "/" regardless of OS. |
10 | 13 | func TestBuildDisplayNodes(t *testing.T) { |
11 | 14 | m := Model{ |
12 | 15 | selected: make(map[string]bool), |
@@ -91,3 +94,60 @@ func TestBuildDisplayNodes(t *testing.T) { |
91 | 94 | t.Errorf("Expected dir1/file1.txt to be included in display nodes when dir1 is expanded") |
92 | 95 | } |
93 | 96 | } |
| 97 | + |
| 98 | +// TestBuildDisplayNodesDeeplyNested tests that deeply nested paths work correctly. |
| 99 | +// This is important for cross-platform compatibility since paths must use "/" |
| 100 | +// consistently (not os.PathSeparator which would be "\" on Windows). |
| 101 | +func TestBuildDisplayNodesDeeplyNested(t *testing.T) { |
| 102 | + m := Model{ |
| 103 | + selected: make(map[string]bool), |
| 104 | + deselected: make(map[string]bool), |
| 105 | + collapsed: make(map[string]bool), |
| 106 | + isDependency: make(map[string]bool), |
| 107 | + files: []filesystem.FileItem{ |
| 108 | + {Path: "a", IsDir: true, Level: 0}, |
| 109 | + {Path: "a/b", IsDir: true, Level: 1}, |
| 110 | + {Path: "a/b/c", IsDir: true, Level: 2}, |
| 111 | + {Path: "a/b/c/d", IsDir: true, Level: 3}, |
| 112 | + {Path: "a/b/c/d/file.txt", IsDir: false, Level: 4}, |
| 113 | + {Path: "a/b/other.txt", IsDir: false, Level: 2}, |
| 114 | + }, |
| 115 | + } |
| 116 | + |
| 117 | + m.buildDisplayNodes() |
| 118 | + |
| 119 | + // With all directories expanded (default), we should see all nodes |
| 120 | + expectedPaths := []string{ |
| 121 | + "a", |
| 122 | + "a/b", |
| 123 | + "a/b/c", |
| 124 | + "a/b/c/d", |
| 125 | + "a/b/c/d/file.txt", |
| 126 | + "a/b/other.txt", |
| 127 | + } |
| 128 | + |
| 129 | + if len(m.displayNodes) != len(expectedPaths) { |
| 130 | + t.Fatalf("Expected %d display nodes, got %d", len(expectedPaths), len(m.displayNodes)) |
| 131 | + } |
| 132 | + |
| 133 | + for i, expectedPath := range expectedPaths { |
| 134 | + if m.displayNodes[i].Path != expectedPath { |
| 135 | + t.Errorf("Node %d: expected path %q, got %q", i, expectedPath, m.displayNodes[i].Path) |
| 136 | + } |
| 137 | + } |
| 138 | + |
| 139 | + // Collapse a/b and verify children are hidden |
| 140 | + m.collapsed["a/b"] = true |
| 141 | + m.buildDisplayNodes() |
| 142 | + |
| 143 | + // Should only show a and a/b (children of a/b are hidden) |
| 144 | + if len(m.displayNodes) != 2 { |
| 145 | + t.Fatalf("Expected 2 display nodes when a/b is collapsed, got %d", len(m.displayNodes)) |
| 146 | + } |
| 147 | + if m.displayNodes[0].Path != "a" { |
| 148 | + t.Errorf("Expected first node to be 'a', got %q", m.displayNodes[0].Path) |
| 149 | + } |
| 150 | + if m.displayNodes[1].Path != "a/b" { |
| 151 | + t.Errorf("Expected second node to be 'a/b', got %q", m.displayNodes[1].Path) |
| 152 | + } |
| 153 | +} |
0 commit comments