# Files changed · PR \#9571 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/9571/diffs)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

[test: skip POSIX mode-bit assertions on a Windows host](https://git.cafe/pingdotgg/t3code/pull/9571.md)

Version: 2

Head commit: af43ec9288c60f8309c7a38bd31d57117ac3a95d

Base commit: 11da79bf1749dd38c5d89072ca3db3b5a684400f

Comparison base: 11da79bf1749dd38c5d89072ca3db3b5a684400f

Showing up to 20 entries from this revision. If the pull request changes, reopen the first page before continuing.

## apps/server/scripts/t3-sqlite-state.test.ts

Status: modified; +3; −1

```diff
@@ -7,6 +7,7 @@
 
 import * as NodeSqliteClient from "@t3tools/shared/nodeSqliteClient";
 import { runSqliteState } from "./t3-sqlite-state.ts";
+import { HostProcessPlatform } from "@t3tools/shared/hostProcess";
 import { symlinksSupported } from "@t3tools/shared/testing/symlinks";
 
 const createFixtureDatabase = Effect.fn("createSqliteStateFixtureDatabase")(function* (
@@ -89,7 +90,8 @@
           sql: "INSERT INTO fixtures (id, label) VALUES (2, 'seeded')",
         });
         assert.equal(mutation.operation, "exec");
-        if (mutation.operation === "exec") {
+        if (mutation.operation === "exec" && (yield* HostProcessPlatform) !== "win32") {
+          // NTFS has no POSIX mode bits to report.
           assert.equal((yield* fs.stat(mutation.backup)).mode & 0o777, 0o600);
         }
 
```

## apps/server/src/cli/theme.test.ts

Status: modified; +9; −4

```diff
@@ -14,7 +14,12 @@
 
 import { cli } from "../bin.ts";
 import { symlinksSupported } from "@t3tools/shared/testing/symlinks";
+import { HostProcessPlatform } from "@t3tools/shared/hostProcess";
 
+// These force a failure with chmod, which Windows ignores for directories and
+// cannot use to make a file unreadable, so the failure never happens there.
+const windowsHost = HostProcessPlatform.defaultValue() === "win32";
+
 const runCli = (args: ReadonlyArray<string>) =>
   Command.runWith(cli, { version: "0.0.0" })(args).pipe(
     Effect.provide(Layer.mergeAll(NodeServices.layer, NetService.layer, TestConsole.layer)),
@@ -161,7 +166,7 @@
   // rolled back rather than left mutating the environment's theme set. The
   // userdata directory is made read-only while themes stays writable, so the
   // failure lands after the publish -- the case the rollback exists for.
+  it.effect.skipIf(windowsHost)("rolls back a publish when the default cannot be written", () =>
-  it.effect("rolls back a publish when the default cannot be written", () =>
     Effect.gen(function* () {
       const baseDir = makeBaseDir();
       writeSettings(baseDir, {});
@@ -229,7 +234,7 @@
   // Rollback moves the previous directory entry aside and back, so even an
   // entry the watcher would never publish -- here a symlink -- comes back
   // exactly as it was when the set fails.
-  it.effect.skipIf(!symlinksSupported)(
+  it.effect.skipIf(!symlinksSupported || windowsHost)(
     "restores a non-theme destination entry when the set fails",
     () =>
       Effect.gen(function* () {
@@ -255,7 +260,7 @@
       }),
   );
 
-  it.effect("restores the previous theme when a re-publish fails to set", () =>
+  it.effect.skipIf(windowsHost)("restores the previous theme when a re-publish fails to set", () =>
     Effect.gen(function* () {
       const baseDir = makeBaseDir();
       writeSettings(baseDir, {});
@@ -352,7 +357,7 @@
 
   // An unreadable settings file must never read as "no settings": writing a
   // fresh sparse file over it would discard every key the user had.
+  it.effect.skipIf(windowsHost)("refuses to write when the settings file cannot be read", () =>
-  it.effect("refuses to write when the settings file cannot be read", () =>
     Effect.gen(function* () {
       const baseDir = makeBaseDir();
       writeSettings(baseDir, { enableProviderUpdateChecks: false });
```

## apps/server/src/keybindings.test.ts

Status: modified; +26; −22

```diff
@@ -12,6 +12,7 @@
 import * as ServerConfig from "./config.ts";
 import * as Keybindings from "./keybindings.ts";
 import { KeybindingsConfigError } from "@t3tools/contracts";
+import { HostProcessPlatform } from "@t3tools/shared/hostProcess";
 
 const KeybindingsConfigJson = Schema.fromJsonString(KeybindingsConfig);
 const encodeKeybindingsConfigJson = Schema.encodeEffect(KeybindingsConfigJson);
@@ -511,31 +512,34 @@
     }).pipe(Effect.provide(makeKeybindingsLayer())),
   );
 
-  it.effect("fails when config directory is not writable", () =>
-    Effect.gen(function* () {
-      const fs = yield* FileSystem.FileSystem;
-      const { keybindingsConfigPath } = yield* ServerConfig.ServerConfig;
-      const { dirname } = yield* Path.Path;
-      yield* writeKeybindingsConfig(keybindingsConfigPath, [
-        { key: "mod+j", command: "terminal.toggle" },
-      ]);
+  // chmod cannot make a directory unwritable on Windows, so the write succeeds.
+  it.effect.skipIf(HostProcessPlatform.defaultValue() === "win32")(
-      yield* fs.chmod(dirname(keybindingsConfigPath), 0o500);
+    "fails when config directory is not writable",
+    () =>
+      Effect.gen(function* () {
+        const fs = yield* FileSystem.FileSystem;
+        const { keybindingsConfigPath } = yield* ServerConfig.ServerConfig;
+        const { dirname } = yield* Path.Path;
+        yield* writeKeybindingsConfig(keybindingsConfigPath, [
+          { key: "mod+j", command: "terminal.toggle" },
+        ]);
+        yield* fs.chmod(dirname(keybindingsConfigPath), 0o500);
 
-      const result = yield* Effect.gen(function* () {
-        const keybindings = yield* Keybindings.Keybindings;
-        return yield* keybindings.upsertKeybindingRule({
-          key: "mod+shift+r",
-          command: "script.run-tests.run",
-        });
-      }).pipe(toDetailResult);
-      assertFailure(result, "failed to write keybindings config");
+        const result = yield* Effect.gen(function* () {
+          const keybindings = yield* Keybindings.Keybindings;
+          return yield* keybindings.upsertKeybindingRule({
+            key: "mod+shift+r",
+            command: "script.run-tests.run",
+          });
+        }).pipe(toDetailResult);
+        assertFailure(result, "failed to write keybindings config");
 
-      yield* fs.chmod(dirname(keybindingsConfigPath), 0o700);
+        yield* fs.chmod(dirname(keybindingsConfigPath), 0o700);
 
-      const persisted = yield* readKeybindingsConfig(keybindingsConfigPath);
-      const persistedView = persisted.map(({ key, command }) => ({ key, command }));
-      assert.deepEqual(persistedView, [{ key: "mod+j", command: "terminal.toggle" }]);
+        const persisted = yield* readKeybindingsConfig(keybindingsConfigPath);
-    }).pipe(Effect.provide(makeKeybindingsLayer())),
+        const persistedView = persisted.map(({ key, command }) => ({ key, command }));
+        assert.deepEqual(persistedView, [{ key: "mod+j", command: "terminal.toggle" }]);
+      }).pipe(Effect.provide(makeKeybindingsLayer())),
   );
 
   it.effect("caches loaded resolved config across repeated reads", () =>
```

## packages/shared/src/logging.test.ts

Status: modified; +6; −1

```diff
@@ -3,6 +3,7 @@
 import * as NodeOS from "node:os";
 import * as NodePath from "node:path";
 import { afterEach, describe, expect, it } from "vite-plus/test";
+import { HostProcessPlatform } from "./hostProcess.ts";
 
 import {
   RotatingFileSink,
@@ -10,6 +11,7 @@
   RotatingFileSinkError,
 } from "./logging.ts";
 
+const windowsHost = HostProcessPlatform.defaultValue() === "win32";
 const tempDirectories: string[] = [];
 
 const makeTempDirectory = (): string => {
@@ -69,7 +71,10 @@
     expect((thrown as RotatingFileSinkError).cause).toBeInstanceOf(Error);
   });
 
+  // An over-long name is the one stat failure that is neither ENOENT nor a
+  // permission problem on posix. Windows reports it as ENOENT, so the sink
+  // correctly treats it as an absent file and there is nothing to assert.
+  it.skipIf(windowsHost)("only treats a missing log file as an empty current size", () => {
-  it("only treats a missing log file as an empty current size", () => {
     const directory = makeTempDirectory();
     const filePath = NodePath.join(directory, "a".repeat(300));
 
```

## packages/shared/src/relayClient.test.ts

Status: modified; +136; −125

```diff
@@ -18,6 +18,10 @@
   makeCloudflaredRelayClient,
 } from "./relayClient.ts";
 
+// The suite runs the linux code path against the real filesystem, checking
+// POSIX exec bits that NTFS never reports; the win32 branch skips that check.
+const windowsHost = HostProcessPlatform.defaultValue() === "win32";
+
 const hostRuntimeLayer = (env: Record<string, string> = {}) =>
   Layer.mergeAll(
     Layer.succeed(HostProcessPlatform, "linux"),
@@ -63,102 +67,106 @@
   );
 
 describe("RelayClient", () => {
+  it.effect.skipIf(windowsHost)(
+    "resolves explicit overrides before managed and PATH executables",
+    () =>
+      Effect.gen(function* () {
+        const fileSystem = yield* FileSystem.FileSystem;
+        const baseDir = yield* fileSystem.makeTempDirectoryScoped({
+          prefix: "t3-cloudflared-test-",
+        });
+        const overridePath = `${baseDir}/override-cloudflared`;
+        yield* fileSystem.writeFileString(overridePath, "override");
+        yield* fileSystem.chmod(overridePath, 0o755);
+        const manager = yield* makeCloudflaredRelayClient({
+          baseDir,
-  it.effect("resolves explicit overrides before managed and PATH executables", () =>
-    Effect.gen(function* () {
-      const fileSystem = yield* FileSystem.FileSystem;
-      const baseDir = yield* fileSystem.makeTempDirectoryScoped({
-        prefix: "t3-cloudflared-test-",
-      });
-      const overridePath = `${baseDir}/override-cloudflared`;
-      yield* fileSystem.writeFileString(overridePath, "override");
-      yield* fileSystem.chmod(overridePath, 0o755);
-      const manager = yield* makeCloudflaredRelayClient({
-        baseDir,
-      });
+        });
 
-      expect(
-        yield* manager.resolve.pipe(
-          Effect.provideService(
+        expect(
+          yield* manager.resolve.pipe(
+            Effect.provideService(
+              ConfigProvider.ConfigProvider,
+              ConfigProvider.fromEnv({
+                env: { PATH: "", T3CODE_CLOUDFLARED_PATH: overridePath },
+              }),
+            ),
+          ),
+        ).toEqual({
+          status: "available",
+          executablePath: overridePath,
+          source: "override",
+          version: CLOUDFLARED_VERSION,
+        });
+      }).pipe(
+        Effect.scoped,
-            ConfigProvider.ConfigProvider,
-            ConfigProvider.fromEnv({
-              env: { PATH: "", T3CODE_CLOUDFLARED_PATH: overridePath },
-            }),
+        Effect.provide(
+          Layer.mergeAll(
+            NodeServices.layer,
+            makeHttpClientLayer(new Uint8Array()),
+            makeSpawnerLayer([]),
+            hostRuntimeLayer(),
           ),
         ),
-      ).toEqual({
-        status: "available",
-        executablePath: overridePath,
-        source: "override",
-        version: CLOUDFLARED_VERSION,
-      });
-    }).pipe(
-      Effect.scoped,
-      Effect.provide(
-        Layer.mergeAll(
-          NodeServices.layer,
-          makeHttpClientLayer(new Uint8Array()),
-          makeSpawnerLayer([]),
-          hostRuntimeLayer(),
-        ),
       ),
-    ),
   );
 
+  it.effect.skipIf(windowsHost)(
+    "downloads, verifies, validates, and atomically installs the managed executable",
+    () =>
+      Effect.gen(function* () {
+        const fileSystem = yield* FileSystem.FileSystem;
+        const baseDir = yield* fileSystem.makeTempDirectoryScoped({
+          prefix: "t3-cloudflared-test-",
-  it.effect("downloads, verifies, validates, and atomically installs the managed executable", () =>
-    Effect.gen(function* () {
-      const fileSystem = yield* FileSystem.FileSystem;
-      const baseDir = yield* fileSystem.makeTempDirectoryScoped({
-        prefix: "t3-cloudflared-test-",
-      });
+        });
+        const bytes = new TextEncoder().encode("test-cloudflared-binary");
+        const manager = yield* makeCloudflaredRelayClient({
+          baseDir,
+          releaseAsset: {
+            url: "https://example.test/cloudflared",
+            sha256: Encoding.encodeHex(sha256(bytes)),
+            archive: "binary",
+          },
+        });
-      const bytes = new TextEncoder().encode("test-cloudflared-binary");
-      const manager = yield* makeCloudflaredRelayClient({
-        baseDir,
-        releaseAsset: {
-          url: "https://example.test/cloudflared",
-          sha256: Encoding.encodeHex(sha256(bytes)),
-          archive: "binary",
-        },
-      });
 
+        const progress: Array<string> = [];
+        const installed = yield* manager.installWithProgress((event) =>
+          Effect.sync(() => {
+            if (event.type === "progress") {
+              progress.push(event.stage);
+            }
+          }),
+        );
+        const managedPath = `${baseDir}/tools/cloudflared/${CLOUDFLARED_VERSION}/linux-x64/cloudflared`;
+        expect(installed).toEqual({
+          status: "available",
+          executablePath: managedPath,
+          source: "managed",
+          version: CLOUDFLARED_VERSION,
+        });
+        expect(new TextDecoder().decode(yield* fileSystem.readFile(managedPath))).toBe(
+          "test-cloudflared-binary",
+        );
+        expect(progress).toEqual([
+          "checking",
+          "waiting_for_lock",
+          "downloading",
+          "verifying",
+          "installing",
+          "validating",
+          "activating",
+        ]);
+        expect(yield* manager.resolve).toEqual(installed);
+      }).pipe(
+        Effect.scoped,
+        Effect.provide(
+          Layer.mergeAll(
-      const progress: Array<string> = [];
-      const installed = yield* manager.installWithProgress((event) =>
-        Effect.sync(() => {
+            NodeServices.layer,
+            makeHttpClientLayer(new TextEncoder().encode("test-cloudflared-binary")),
+            makeSpawnerLayer([]),
+            hostRuntimeLayer(),
+          ),
-          if (event.type === "progress") {
-            progress.push(event.stage);
-          }
-        }),
-      );
-      const managedPath = `${baseDir}/tools/cloudflared/${CLOUDFLARED_VERSION}/linux-x64/cloudflared`;
-      expect(installed).toEqual({
-        status: "available",
-        executablePath: managedPath,
-        source: "managed",
-        version: CLOUDFLARED_VERSION,
-      });
-      expect(new TextDecoder().decode(yield* fileSystem.readFile(managedPath))).toBe(
-        "test-cloudflared-binary",
-      );
-      expect(progress).toEqual([
-        "checking",
-        "waiting_for_lock",
-        "downloading",
-        "verifying",
-        "installing",
-        "validating",
-        "activating",
-      ]);
-      expect(yield* manager.resolve).toEqual(installed);
-    }).pipe(
-      Effect.scoped,
-      Effect.provide(
-        Layer.mergeAll(
-          NodeServices.layer,
-          makeHttpClientLayer(new TextEncoder().encode("test-cloudflared-binary")),
-          makeSpawnerLayer([]),
-          hostRuntimeLayer(),
         ),
       ),
-    ),
   );
 
   it.effect("rejects downloads whose checksum does not match the pinned manifest", () =>
@@ -192,7 +200,7 @@
     ),
   );
 
-  it.effect("serializes concurrent installs within one runtime", () => {
+  it.effect.skipIf(windowsHost)("serializes concurrent installs within one runtime", () => {
     const commands: Array<string> = [];
     const bytes = new TextEncoder().encode("test-cloudflared-binary");
     return Effect.gen(function* () {
@@ -227,45 +235,48 @@
     );
   });
 
-  it.effect("observes PATH changes after the manager has been constructed", () => {
-    const env = { PATH: "" };
-    return Effect.gen(function* () {
-      const fileSystem = yield* FileSystem.FileSystem;
-      const baseDir = yield* fileSystem.makeTempDirectoryScoped({
-        prefix: "t3-cloudflared-test-",
-      });
-      const binDir = `${baseDir}/bin`;
-      const executablePath = `${binDir}/cloudflared`;
-      const manager = yield* makeCloudflaredRelayClient({
-        baseDir,
-      });
+  it.effect.skipIf(windowsHost)(
+    "observes PATH changes after the manager has been constructed",
+    () => {
+      const env = { PATH: "" };
+      return Effect.gen(function* () {
+        const fileSystem = yield* FileSystem.FileSystem;
+        const baseDir = yield* fileSystem.makeTempDirectoryScoped({
+          prefix: "t3-cloudflared-test-",
+        });
+        const binDir = `${baseDir}/bin`;
+        const executablePath = `${binDir}/cloudflared`;
+        const manager = yield* makeCloudflaredRelayClient({
+          baseDir,
+        });
 
+        expect(yield* manager.resolve).toEqual({
+          status: "missing",
+          version: CLOUDFLARED_VERSION,
-      expect(yield* manager.resolve).toEqual({
-        status: "missing",
-        version: CLOUDFLARED_VERSION,
-      });
+        });
 
-      yield* fileSystem.makeDirectory(binDir);
-      yield* fileSystem.writeFileString(executablePath, "cloudflared");
-      yield* fileSystem.chmod(executablePath, 0o755);
-      env.PATH = binDir;
+        yield* fileSystem.makeDirectory(binDir);
+        yield* fileSystem.writeFileString(executablePath, "cloudflared");
+        yield* fileSystem.chmod(executablePath, 0o755);
+        env.PATH = binDir;
 
+        expect(yield* manager.resolve).toEqual({
+          status: "available",
+          executablePath,
-      expect(yield* manager.resolve).toEqual({
-        status: "available",
-        executablePath,
-        source: "path",
-        version: CLOUDFLARED_VERSION,
-      });
-    }).pipe(
-      Effect.scoped,
-      Effect.provide(
-        Layer.mergeAll(
-          NodeServices.layer,
-          makeHttpClientLayer(new Uint8Array()),
-          makeSpawnerLayer([]),
-          hostRuntimeLayer(env),
+          source: "path",
+          version: CLOUDFLARED_VERSION,
+        });
+      }).pipe(
+        Effect.scoped,
+        Effect.provide(
+          Layer.mergeAll(
+            NodeServices.layer,
+            makeHttpClientLayer(new Uint8Array()),
+            makeSpawnerLayer([]),
+            hostRuntimeLayer(env),
+          ),
         ),
-      ),
-    );
-  });
+      );
+    },
+  );
 });
```
