Skip to content

Commit

Permalink
feat: enhance hidden file handling with macOS support and improve tes…
Browse files Browse the repository at this point in the history
…t coverage
  • Loading branch information
mceachen committed Dec 1, 2024
1 parent 12c7907 commit 373fe52
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 35 deletions.
67 changes: 42 additions & 25 deletions src/__tests__/hidden.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { jest } from "@jest/globals";
import { execSync } from "node:child_process";
import fs from "node:fs/promises";
import path from "node:path";
import { homedir } from "node:os";
import path, { join } from "node:path";
import { statAsync } from "../fs_promises.js";
import { createHiddenPosixPath, LocalSupport } from "../hidden.js";
import {
Expand All @@ -10,7 +11,7 @@ import {
isHiddenRecursive,
setHidden,
} from "../index.js";
import { isWindows } from "../platform.js";
import { isMacOS, isWindows } from "../platform.js";
import { validateHidden } from "../test-utils/hidden-tests.js";
import { systemDrive, tmpDirNotHidden } from "../test-utils/platform.js";

Expand Down Expand Up @@ -124,7 +125,7 @@ describe("hidden file tests", () => {
});

it("should return false for root path", async () => {
expect(await isHiddenRecursive("C:\\")).toBe(false);
expect(await isHiddenRecursive(isWindows ? "C:\\" : "/")).toBe(false);
});
});

Expand All @@ -136,7 +137,8 @@ describe("hidden file tests", () => {
? testFile
: path.join(tempDir, ".to-hide.txt");

expect(await setHidden(testFile, true)).toEqual(
const hidden = await setHidden(testFile, true);
expect(hidden).toEqual(
expect.objectContaining({
pathname: expected,
}),
Expand All @@ -159,7 +161,7 @@ describe("hidden file tests", () => {
expect(hidden).toEqual(expectedHidden);
expect(await isHidden(hidden)).toBe(true);

expect(await setHidden(testFile, false)).toEqual(
expect(await setHidden(hidden, false)).toEqual(
expect.objectContaining({
pathname: testFile,
}),
Expand Down Expand Up @@ -228,7 +230,21 @@ describe("hidden file tests", () => {
},
});
});
} else {
}

if (isMacOS) {
it("should return systemFlagged for a known directory", async () => {
const result = await getHiddenMetadata(join(homedir(), "Library"));
expect(result).toEqual({
hidden: true,
dotPrefix: false,
systemFlag: true,
supported: LocalSupport,
});
});
}

if (!isWindows) {
it("should return correct metadata for normal file on POSIX", async () => {
const testFile = path.join(tempDir, "normal.txt");
await fs.writeFile(testFile, "test");
Expand All @@ -254,32 +270,29 @@ describe("hidden file tests", () => {
hidden: true,
dotPrefix: true,
systemFlag: false,
supported: {
dotPrefix: true,
systemFlag: process.platform === "darwin",
},
supported: LocalSupport,
});
});
}

it("should handle root directory", async () => {
const metadata = await getHiddenMetadata(systemDrive());
expect(metadata.hidden).toBe(false);
expect(metadata.dotPrefix).toBe(false);
if (isWindows) {
expect(metadata.supported).toEqual({
dotPrefix: false,
systemFlag: true,
});
}
expect(await getHiddenMetadata(systemDrive())).toEqual({
hidden: false,
dotPrefix: false,
systemFlag: false,
supported: LocalSupport,
});
});

it("should handle non-existent paths", async () => {
const nonExistentPath = path.join(tempDir, "does-not-exist");
const metadata = await getHiddenMetadata(nonExistentPath);
expect(metadata.hidden).toBe(false);
expect(metadata.dotPrefix).toBe(false);
expect(metadata.systemFlag).toBe(false);
expect(
await getHiddenMetadata(path.join(tempDir, "does-not-exist")),
).toEqual({
hidden: false,
dotPrefix: false,
systemFlag: false,
supported: LocalSupport,
});
});
});

Expand All @@ -297,7 +310,11 @@ describe("hidden file tests", () => {
});

// Test explicit systemFlag method
const systemFlagResult = await setHidden(testFile, true, "systemFlag");
const systemFlagResult = await setHidden(
dotPrefixResult.pathname,
true,
"systemFlag",
);

expect(systemFlagResult.actions).toEqual({
dotPrefix: false,
Expand Down
3 changes: 1 addition & 2 deletions src/fs_promises.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ export async function statAsync(

export async function canStatAsync(path: string): Promise<boolean> {
try {
await statAsync(path);
return true;
return null != (await statAsync(path));
} catch {
return false;
}
Expand Down
13 changes: 11 additions & 2 deletions src/hidden.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { rename } from "node:fs/promises";
import { basename, dirname, join } from "node:path";
import { canStatAsync } from "./fs_promises.js";
import { WrappedError } from "./error.js";
import { canStatAsync, statAsync } from "./fs_promises.js";
import { NativeBindingsFn } from "./native_bindings.js";
import { isRootDirectory, normalizePath } from "./path.js";
import { isWindows } from "./platform.js";
Expand Down Expand Up @@ -150,7 +151,9 @@ export async function getHiddenMetadata(

const dotPrefix = LocalSupport.dotPrefix && isPosixHidden(pathname);
const systemFlag =
LocalSupport.systemFlag && (await isHidden(pathname, nativeFn));
LocalSupport.systemFlag &&
(await canStatAsync(pathname)) &&
(await (await nativeFn()).isHidden(pathname));
return {
hidden: dotPrefix || systemFlag,
dotPrefix,
Expand All @@ -169,6 +172,12 @@ export async function setHidden(
) {
pathname = normalizePath(pathname);

try {
await statAsync(pathname);
} catch (err) {
throw new WrappedError("setHidden()", err);
}

const actions = {
dotPrefix: false,
systemFlag: false,
Expand Down
17 changes: 11 additions & 6 deletions src/test-utils/platform.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// src/test-utils/platform.ts

import { mkdirSync } from "node:fs";
import { homedir } from "node:os";
import { join } from "node:path";
import { env, platform } from "node:process";
import { isWindows } from "../platform.js";
import { isMacOS, isWindows } from "../platform.js";
import { toNotBlank } from "../string.js";

/**
Expand All @@ -23,9 +25,12 @@ export function systemDrive() {
}

export function tmpDirNotHidden() {
if (isWindows) {
return join(systemDrive(), "tmp");
} else {
return "/tmp";
}
const dir = isMacOS
? join(homedir(), "tmp")
: isWindows
? join(systemDrive(), "tmp")
: "/tmp";

mkdirSync(dir, { recursive: true });
return dir;
}

0 comments on commit 373fe52

Please sign in to comment.