Skip to content

Commit 57bd0ca

Browse files
committed
refactor(filesystem): add unit tests and change of joinPath implementation
1 parent 263fa12 commit 57bd0ca

2 files changed

Lines changed: 61 additions & 11 deletions

File tree

packages/filesystem/utils.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { describe, expect, it } from "vitest";
2+
import { joinPath } from "./utils";
3+
4+
describe("joinPath", () => {
5+
it("joins relative path segments as an absolute normalized path", () => {
6+
expect(joinPath("path1", "path2")).toBe("/path1/path2");
7+
});
8+
9+
it("does not create duplicate slashes when segments already contain slashes", () => {
10+
expect(joinPath("/path1", "/path2")).toBe("/path1/path2");
11+
expect(joinPath("/path1/", "/path2/")).toBe("/path1/path2");
12+
expect(joinPath("path1/", "path2/")).toBe("/path1/path2");
13+
expect(joinPath("/path1/", "path2")).toBe("/path1/path2");
14+
});
15+
16+
it("keeps root-relative behavior when the first segment is empty", () => {
17+
expect(joinPath("", "file.txt")).toBe("/file.txt");
18+
expect(joinPath("", "dir", "file.txt")).toBe("/dir/file.txt");
19+
});
20+
21+
it("handles root path segments", () => {
22+
expect(joinPath("/", "file.txt")).toBe("/file.txt");
23+
expect(joinPath("/", "dir", "file.txt")).toBe("/dir/file.txt");
24+
});
25+
26+
it("skips empty path segments", () => {
27+
expect(joinPath("dir", "", "file.txt")).toBe("/dir/file.txt");
28+
expect(joinPath("", "dir", "", "file.txt", "")).toBe("/dir/file.txt");
29+
});
30+
31+
it("returns empty string when no meaningful path is provided", () => {
32+
expect(joinPath()).toBe("");
33+
expect(joinPath("")).toBe("");
34+
expect(joinPath("", "")).toBe("");
35+
expect(joinPath("/")).toBe("");
36+
expect(joinPath("/", "")).toBe("");
37+
});
38+
39+
it("normalizes multiple adjacent slashes inside segments", () => {
40+
expect(joinPath("//path1//", "//path2//")).toBe("/path1/path2");
41+
expect(joinPath("path1//nested", "path2")).toBe("/path1/nested/path2");
42+
});
43+
});

packages/filesystem/utils.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
export function joinPath(...paths: string[]): string {
2-
let path = "";
3-
for (let value of paths) {
4-
if (!value) {
2+
let result = "";
3+
4+
for (const path of paths) {
5+
if (!path) {
56
continue;
67
}
7-
if (!value.startsWith("/")) {
8-
if (path) {
9-
value = `/${value}`;
8+
9+
let start = 0;
10+
11+
for (let i = 0; i <= path.length; i++) {
12+
if (i !== path.length && path[i] !== "/") {
13+
continue;
1014
}
15+
16+
if (i > start) {
17+
result += `/${path.slice(start, i)}`;
18+
}
19+
20+
start = i + 1;
1121
}
12-
if (value.endsWith("/")) {
13-
value = value.substring(0, value.length - 1);
14-
}
15-
path += value;
1622
}
17-
return path;
23+
24+
return result;
1825
}

0 commit comments

Comments
 (0)