On windows fs.realpathSync and fs.realpath (async) can disagree on
8.3 short-name canonicalization. The github actions windows runner
exposes this: fs.realpathSync returns "C:\Users\RUNNER~1\..."
while fs.realpath returns "C:\Users\runneradmin\...". Tests that
compare a sync helper's output against await fs.realpath fail with
the same path printed in two forms.
Compare against fs.realpathSync (imported as realpathSync from
node:fs) on both sides so the test exercises the same canonical
form regardless of which short-name configuration the runner has.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Run the check job on windows-latest in addition to ubuntu so the
windows code paths (no O_NOFOLLOW, node fallbacks for fd-relative
ops, ACL inspection) are exercised on every PR rather than only
documented.
Make the test suite pass on the new windows runner by addressing
the platform-specific failures:
- Long happy-path tests that mix supported (mkdir, write, read) and
unsupported (stat, list, move, exists) operations are guarded
with skipIf(process.platform === "win32") since the pinned
filesystem helper throws "unsupported-platform" on win32 by
design (src/pinned-python.ts).
- Short focused tests where the unsupported operation is the whole
point (pinned-python, pinned-write-fallback-coverage,
write-boundary-bypass symlink-move) split into runIf(non-win32)
and runIf(win32) tests, with the windows variant asserting
unsupported-platform.
- The expectFsSafeCode helper accepts unsupported-platform on
windows; new expectedFsSafeCode helper substitutes for
per-rejects.toMatchObject sites where the windows code differs
from posix (e.g. path-alias / not-found returning
unsupported-platform via the helper layer).
- secure-file-reads test split into a posix happy-path runIf and a
windows runIf that asserts permission-unverified, since ACL
inspection has no portable equivalent on windows
(src/secure-file.ts:177).
- safeFileURLToPath test uses hardcoded platform-specific input/
output instead of building the URL via pathToFileURL+fileURLToPath
so the assertion verifies the function directly.
- Fix expandHomePrefix to normalize path separators by splitting via
path.normalize + path.sep and rejoining via path.join. Apply the
same segment-based check to resolveHomeRelativePath and
resolveOsHomeRelativePath. Drop input.trim() — whitespace is a
valid filename character on both platforms and env-var inputs are
already trimmed upstream via normalizeOptionalString.
- coverage-more's "normalizes empty temp names" decomposes the
result with path.dirname/path.basename instead of regex-matching
a path-separator literal.
- extracted-helpers' path-helpers test builds its root with
path.resolve so the drive letter is present on windows.
- additional-boundary-bypass guards its "..\evil.txt" sanitizer
assertion behind a non-win32 check (windows reserves "\" as a
path separator and cannot have it in a filename).
- coverage-more's sibling temp test guards just the posix file-mode
assertion (stat.mode & 0o777 === 0o600), which has no analog on
windows. The syncing behaviour the test actually targets still
runs on both platforms.
- Raise test/new-primitives.test.ts size budget to 1500 to
accommodate the secure-file-reads test split.
After: 253 passed, 1 failed, 66 skipped on windows-11-arm64. The
single remaining failure is a separate library-side gap (a
SAFE_REJECTED_SUSPICIOUS_WRITE_PAYLOADS payload resolves on windows
instead of rejecting) and will be tracked in a follow-up.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>