1-- Load main.lua as a module (it exports functions when required)
2package.path = package.path .. ";./?.lua"
3local wt = dofile("src/main.lua")
4
5describe("split_path", function()
6 describe("basic paths", function()
7 it("splits absolute path into components", function()
8 local parts = wt.split_path("/home/user/project")
9 assert.are.same({ "home", "user", "project" }, parts)
10 end)
11
12 it("splits relative path into components", function()
13 local parts = wt.split_path("a/b/c")
14 assert.are.same({ "a", "b", "c" }, parts)
15 end)
16
17 it("handles single component", function()
18 local parts = wt.split_path("single")
19 assert.are.same({ "single" }, parts)
20 end)
21 end)
22
23 describe("edge cases", function()
24 it("returns empty table for root path", function()
25 local parts = wt.split_path("/")
26 assert.are.same({}, parts)
27 end)
28
29 it("returns empty table for empty string", function()
30 local parts = wt.split_path("")
31 assert.are.same({}, parts)
32 end)
33
34 it("collapses multiple slashes", function()
35 local parts = wt.split_path("/a//b///c/")
36 assert.are.same({ "a", "b", "c" }, parts)
37 end)
38
39 it("ignores trailing slash", function()
40 local parts = wt.split_path("/a/b/c/")
41 assert.are.same({ "a", "b", "c" }, parts)
42 end)
43
44 it("handles multiple leading slashes", function()
45 local parts = wt.split_path("///a/b")
46 assert.are.same({ "a", "b" }, parts)
47 end)
48 end)
49
50 describe("special characters", function()
51 it("preserves dots in path components", function()
52 local parts = wt.split_path("/home/user/.config")
53 assert.are.same({ "home", "user", ".config" }, parts)
54 end)
55
56 it("preserves hyphens in path components", function()
57 local parts = wt.split_path("/my-project/sub-dir")
58 assert.are.same({ "my-project", "sub-dir" }, parts)
59 end)
60
61 it("preserves spaces in path components", function()
62 local parts = wt.split_path("/path with/spaces here")
63 assert.are.same({ "path with", "spaces here" }, parts)
64 end)
65 end)
66end)
67
68describe("branch_to_path", function()
69 describe("nested style (default)", function()
70 it("preserves slashes in branch name", function()
71 local path = wt.branch_to_path("/repo", "feature/auth", "nested")
72 assert.are.equal("/repo/feature/auth", path)
73 end)
74
75 it("handles simple branch name", function()
76 local path = wt.branch_to_path("/repo", "main", "nested")
77 assert.are.equal("/repo/main", path)
78 end)
79
80 it("handles deeply nested branch", function()
81 local path = wt.branch_to_path("/repo", "feature/auth/oauth2", "nested")
82 assert.are.equal("/repo/feature/auth/oauth2", path)
83 end)
84 end)
85
86 describe("flat style", function()
87 it("replaces slashes with default separator", function()
88 local path = wt.branch_to_path("/repo", "feature/auth", "flat")
89 assert.are.equal("/repo/feature_auth", path)
90 end)
91
92 it("uses custom separator", function()
93 local path = wt.branch_to_path("/repo", "feature/auth", "flat", "-")
94 assert.are.equal("/repo/feature-auth", path)
95 end)
96
97 it("handles simple branch name (no slashes)", function()
98 local path = wt.branch_to_path("/repo", "main", "flat")
99 assert.are.equal("/repo/main", path)
100 end)
101
102 it("handles multiple slashes with custom separator", function()
103 local path = wt.branch_to_path("/repo", "a/b/c", "flat", ".")
104 assert.are.equal("/repo/a.b.c", path)
105 end)
106 end)
107
108 describe("edge cases", function()
109 it("handles empty branch name", function()
110 local path = wt.branch_to_path("/repo", "", "nested")
111 assert.are.equal("/repo/", path)
112 end)
113
114 it("handles root ending with slash", function()
115 local path = wt.branch_to_path("/repo/", "main", "nested")
116 -- Results in double slash - document this behavior
117 assert.are.equal("/repo//main", path)
118 end)
119
120 it("handles separator containing percent", function()
121 assert.are.equal("/repo/a%b", wt.branch_to_path("/repo", "a/b", "flat", "%"))
122 end)
123
124 it("handles branch starting with slash", function()
125 local path = wt.branch_to_path("/repo", "/feature", "nested")
126 -- Results in double slash
127 assert.are.equal("/repo//feature", path)
128 end)
129 end)
130
131 describe("common branch naming patterns", function()
132 it("handles issue-number branches", function()
133 local path = wt.branch_to_path("/repo", "847-do-a-thing", "nested")
134 assert.are.equal("/repo/847-do-a-thing", path)
135 end)
136
137 it("handles version branches", function()
138 local path = wt.branch_to_path("/repo", "release/1.2.3", "flat", "_")
139 assert.are.equal("/repo/release_1.2.3", path)
140 end)
141
142 it("handles user prefix branches", function()
143 local path = wt.branch_to_path("/repo", "user/alice/feature", "flat", "-")
144 assert.are.equal("/repo/user-alice-feature", path)
145 end)
146 end)
147end)
148
149describe("relative_path", function()
150 describe("sibling directories", function()
151 it("computes path to sibling", function()
152 local rel = wt.relative_path("/a/b", "/a/c")
153 assert.are.equal("../c", rel)
154 end)
155
156 it("computes path to sibling's child", function()
157 local rel = wt.relative_path("/a/b", "/a/c/d")
158 assert.are.equal("../c/d", rel)
159 end)
160 end)
161
162 describe("parent/child relationships", function()
163 it("computes path to child", function()
164 local rel = wt.relative_path("/a", "/a/b")
165 assert.are.equal("b", rel)
166 end)
167
168 it("computes path to deeply nested child", function()
169 local rel = wt.relative_path("/a", "/a/b/c/d")
170 assert.are.equal("b/c/d", rel)
171 end)
172
173 it("computes path to parent", function()
174 local rel = wt.relative_path("/a/b/c", "/a")
175 assert.are.equal("../..", rel)
176 end)
177 end)
178
179 describe("same path", function()
180 it("returns ./ for identical paths", function()
181 local rel = wt.relative_path("/a/b", "/a/b")
182 assert.are.equal("./", rel)
183 end)
184 end)
185
186 describe("completely different paths", function()
187 it("computes path across directory tree", function()
188 local rel = wt.relative_path("/home/alice/projects", "/var/log")
189 assert.are.equal("../../../var/log", rel)
190 end)
191 end)
192
193 describe("root paths", function()
194 it("handles from root to child", function()
195 local rel = wt.relative_path("/", "/a/b")
196 assert.are.equal("a/b", rel)
197 end)
198
199 it("handles from child to root", function()
200 local rel = wt.relative_path("/a/b", "/")
201 assert.are.equal("../..", rel)
202 end)
203 end)
204
205 describe("edge cases", function()
206 it("handles trailing slash in from path", function()
207 -- split_path normalizes trailing slashes
208 local rel = wt.relative_path("/a/b/", "/a/c")
209 assert.are.equal("../c", rel)
210 end)
211
212 it("handles paths with common deep prefix", function()
213 local rel = wt.relative_path("/repo/project/src/lib", "/repo/project/src/bin")
214 assert.are.equal("../bin", rel)
215 end)
216 end)
217
218 describe("real-world wt scenarios", function()
219 it("computes path from worktree to .bare", function()
220 local rel = wt.relative_path("/projects/myapp/feature/auth", "/projects/myapp/.bare")
221 assert.are.equal("../../.bare", rel)
222 end)
223
224 it("computes path between worktrees", function()
225 local rel = wt.relative_path("/projects/myapp/main", "/projects/myapp/feature/new")
226 assert.are.equal("../feature/new", rel)
227 end)
228 end)
229end)