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