Skip to content

Commit

Permalink
test: refactor symlink tests to separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
thecodrr committed Oct 14, 2024
1 parent 243dec6 commit 4525784
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 215 deletions.
216 changes: 1 addition & 215 deletions __tests__/fdir.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,12 @@ import { test, beforeEach, TestContext, vi } from "vitest";
import path, { sep } from "path";
import { convertSlashes } from "../src/utils";
import picomatch from "picomatch";
import { apiTypes, APITypes, cwd, restricted, root } from "./utils";

beforeEach(() => {
mock.restore();
});

const mockFsWithSymlinks = {
"/sym/linked": {
"file-1": "file contents",
"file-excluded-1": "file contents",
},
"/other/dir": {
"file-2": "file contents2",
},
"/some/dir": {
fileSymlink: mock.symlink({
path: "/other/dir/file-2",
}),
fileSymlink2: mock.symlink({
path: "/other/dir/file-3",
}),
dirSymlink: mock.symlink({
path: "/sym/linked",
}),
},
};

function root() {
return process.platform === "win32" ? process.cwd().split(path.sep)[0] : "/";
}

function cwd() {
return `.${path.sep}`;
}

function restricted() {
return process.platform === "win32"
? path.join(root(), "Windows", "System32")
: "/etc";
}

function resolveSymlinkRoot(p: string) {
return process.platform === "win32"
? path.join(root(), path.normalize(p))
: p;
}

test(`crawl single depth directory with callback`, (t) => {
const api = new fdir().crawl("__tests__");

Expand All @@ -65,9 +25,6 @@ test(`crawl single depth directory with callback`, (t) => {
});
});

type APITypes = "withPromise" | "sync";
const apiTypes = ["withPromise", "sync"] as const;

async function crawl(type: APITypes, path: string, t: TestContext) {
const api = new fdir().crawl(path);
const files = await api[type]();
Expand Down Expand Up @@ -346,130 +303,6 @@ for (const type of apiTypes) {
).toBeTruthy();
});

test(`[${type}] crawl all files and include resolved symlinks`, async (t) => {
mock(mockFsWithSymlinks);

const api = new fdir().withSymlinks().crawl("/some/dir");
const files = await api[type]();
t.expect(files).toHaveLength(3);
t.expect(
files.indexOf(resolveSymlinkRoot("/sym/linked/file-1")) > -1
).toBeTruthy();
t.expect(
files.indexOf(resolveSymlinkRoot("/other/dir/file-2")) > -1
).toBeTruthy();
mock.restore();
});

test(`[${type}] crawl all files and include resolved symlinks without real paths`, async (t) => {
mock(mockFsWithSymlinks);

const api = new fdir()
.withSymlinks({ resolvePaths: false })
.crawl("/some/dir");
const files = await api[type]();
t.expect(files).toHaveLength(3);
t.expect(
files.indexOf(resolveSymlinkRoot("/some/dir/dirSymlink/file-1")) > -1
).toBeTruthy();
t.expect(
files.indexOf(
resolveSymlinkRoot("/some/dir/dirSymlink/file-excluded-1")
) > -1
).toBeTruthy();
mock.restore();
});

test(`[${type}] crawl all files and include resolved symlinks without real paths with relative paths on`, async (t) => {
mock(mockFsWithSymlinks);

const api = new fdir()
.withSymlinks({ resolvePaths: false })
.withRelativePaths()
.crawl("/some/dir");
const files = await api[type]();
t.expect(files).toHaveLength(3);
t.expect(
files.indexOf(path.join("dirSymlink", "file-1")) > -1
).toBeTruthy();
t.expect(
files.indexOf(path.join("dirSymlink", "file-excluded-1")) > -1
).toBeTruthy();
t.expect(files.indexOf("fileSymlink") > -1).toBeTruthy();
mock.restore();
});

test(`[${type}] crawl all files and include resolved symlinks with real paths with relative paths on`, async (t) => {
mock({
"../../sym/linked": {
"file-1": "file contents",
"file-excluded-1": "file contents",
},
"../../other/dir": {
"file-2": "file contents2",
},
"some/dir": {
fileSymlink: mock.symlink({
path: "../../../../other/dir/file-2",
}),
fileSymlink2: mock.symlink({
path: "../../../../other/dir/file-3",
}),
dirSymlink: mock.symlink({
path: "../../../../sym/linked",
}),
},
});
const api = new fdir()
.withSymlinks()
.withRelativePaths()
.crawl("./some/dir");
const files = await api[type]();
t.expect(files.sort()).toStrictEqual([
path.join("..", "..", "..", "..", "other", "dir", "file-2"),
path.join("..", "..", "..", "..", "sym", "linked", "file-1"),
path.join("..", "..", "..", "..", "sym", "linked", "file-excluded-1"),
]);
mock.restore();
});

test("crawl all files and include resolved symlinks with exclusions", async (t) => {
mock(mockFsWithSymlinks);
const api = new fdir()
.withSymlinks()
.exclude((_name, path) => path === resolveSymlinkRoot("/sym/linked/"))
.crawl("/some/dir");
const files = await api[type]();
t.expect(files).toHaveLength(1);
t.expect(
files.indexOf(resolveSymlinkRoot("/other/dir/file-2")) > -1
).toBeTruthy();
mock.restore();
});

test(`[${type}] crawl all files and include unresolved symlinks`, async (t) => {
mock(mockFsWithSymlinks);

const api = new fdir().withDirs().crawl("/some/dir");
const files = await api[type]();
t.expect(files).toHaveLength(4);

t.expect(files.indexOf(path.normalize("/some/dir/")) > -1).toBeTruthy();
t.expect(files.indexOf("fileSymlink") > -1).toBeTruthy();
t.expect(files.indexOf("fileSymlink2") > -1).toBeTruthy();
t.expect(files.indexOf("dirSymlink") > -1).toBeTruthy();
mock.restore();
});

test(`[${type}] crawl all files and exclude symlinks`, async (t) => {
mock(mockFsWithSymlinks);

const api = new fdir({ excludeSymlinks: true }).crawl("/some/dir");
const files = await api[type]();
t.expect(files).toHaveLength(0);
mock.restore();
});

test(`[${type}] crawl all files and invert path separator`, async (t) => {
const api = new fdir()
.withPathSeparator(sep === "/" ? "\\" : "/")
Expand All @@ -479,53 +312,6 @@ for (const type of apiTypes) {
t.expect(files.every((f) => !f.includes(sep))).toBeTruthy();
});

test(`[${type}] crawl all files (including symlinks)`, async (t) => {
mock({
"/other/dir": {
"file-3": "somefile",
},
"/some/dir": {
fileSymlink: mock.symlink({
path: "/other/dir/file-3",
}),
},
});

const api = new fdir().withErrors().withSymlinks().crawl("/some/dir");
const files = await api[type]();
t.expect(
files.indexOf(resolveSymlinkRoot("/other/dir/file-3")) > -1
).toBeTruthy();
mock.restore();
});

test(`[${type}] crawl all files (including symlinks without real paths)`, async (t) => {
mock({
"/other/dir": {
"file-3": "somefile",
},
"/some/dir": {
fileSymlink: mock.symlink({
path: "/other/dir/file-3",
}),
},
});

const api = new fdir()
.withErrors()
.withSymlinks({ resolvePaths: false })
.crawl("/some/dir");

await api[type]();

const files = await api[type]();
t.expect(
files.indexOf(resolveSymlinkRoot("/some/dir/fileSymlink")) > -1
).toBeTruthy();

mock.restore();
});

test(`[${type}] crawl files that match using a custom glob`, async (t) => {
const globFunction = vi.fn((glob: string | string[]) => {
return (test: string): boolean => test.endsWith(".js");
Expand Down
142 changes: 142 additions & 0 deletions __tests__/symlinks.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { afterAll, beforeAll, beforeEach, describe, test } from "vitest";
import { apiTypes, normalize, root } from "./utils";
import mock from "mock-fs";
import { fdir, Options } from "../src";
import path from "path";

const mockFsWithSymlinks = {
"../../sym-relative/linked": {
"file-1": "file contents",
"file-excluded-1": "file contents",
},
"../../other-relative/dir": {
"file-2": "file contents2",
},
"relative/dir": {
fileSymlink: mock.symlink({
path: "../../../../other-relative/dir/file-2",
}),
fileSymlink2: mock.symlink({
path: "../../../../other-relative/dir/file-3",
}),
dirSymlink: mock.symlink({
path: "../../../../sym-relative/linked",
}),
},

"/sym/linked": {
"file-1": "file contents",
"file-excluded-1": "file contents",
},
"/other/dir": {
"file-2": "file contents2",
},
"/some/dir": {
fileSymlink: mock.symlink({
path: "/other/dir/file-2",
}),
fileSymlink2: mock.symlink({
path: "/other/dir/file-3",
}),
dirSymlink: mock.symlink({
path: "/sym/linked",
}),
},
};

for (const type of apiTypes) {
describe.concurrent(type, () => {
beforeAll(() => {
mock(mockFsWithSymlinks);
});

afterAll(() => {
mock.restore();
});

test(`resolve symlinks`, async (t) => {
const api = new fdir().withSymlinks().crawl("/some/dir");
const files = await api[type]();
t.expect(files.sort()).toStrictEqual(
normalize([
"/other/dir/file-2",
"/sym/linked/file-1",
"/sym/linked/file-excluded-1",
])
);
});

test(`resolve symlinks (real paths: false)`, async (t) => {
const api = new fdir()
.withSymlinks({ resolvePaths: false })
.crawl("/some/dir");
const files = await api[type]();
t.expect(files.sort()).toStrictEqual(
normalize([
"/some/dir/dirSymlink/file-1",
"/some/dir/dirSymlink/file-excluded-1",
"/some/dir/fileSymlink",
])
);
});

test(`resolve symlinks (real paths: false, relative paths: true)`, async (t) => {
const api = new fdir()
.withSymlinks({ resolvePaths: false })
.withRelativePaths()
.crawl("/some/dir");
const files = await api[type]();
t.expect(files.sort()).toStrictEqual(
normalize([
"dirSymlink/file-1",
"dirSymlink/file-excluded-1",
"fileSymlink",
])
);
});

test(`crawl all files and include resolved symlinks with real paths with relative paths on`, async (t) => {
const api = new fdir()
.withSymlinks()
.withRelativePaths()
.crawl("./relative/dir");
const files = await api[type]();
t.expect(files.sort()).toStrictEqual(
normalize([
"../../../../other-relative/dir/file-2",
"../../../../sym-relative/linked/file-1",
"../../../../sym-relative/linked/file-excluded-1",
])
);
});

test("resolve symlinks (exclude /sym/linked/)", async (t) => {
const api = new fdir()
.withSymlinks()
.exclude((_name, path) => path === resolveSymlinkRoot("/sym/linked/"))
.crawl("/some/dir");
const files = await api[type]();
t.expect(files.sort()).toStrictEqual(normalize(["/other/dir/file-2"]));
});

test(`do not resolve symlinks`, async (t) => {
const api = new fdir().crawl("/some/dir");
const files = await api[type]();
t.expect(files.sort()).toStrictEqual(
normalize(["dirSymlink", "fileSymlink", "fileSymlink2"])
);
});

test(`exclude symlinks`, async (t) => {
const api = new fdir({ excludeSymlinks: true }).crawl("/some/dir");
const files = await api[type]();
t.expect(files).toHaveLength(0);
});
});
}

function resolveSymlinkRoot(p: string) {
return process.platform === "win32"
? path.join(root(), path.normalize(p))
: p;
}
Loading

0 comments on commit 4525784

Please sign in to comment.