fix(test): resolve the macOS temp root through its symlink in the launcher and preview tests (#501)

Supersedes #301 by @VassagoDevteam, ported onto the current component layout with fixes from review.

Verified before merge: format, package boundaries, unit suite, build, and the browser tracking suite; a browser harness for the change where one applies; adversarial review applied.

Co-authored-by: Vassago DevTeam <[email protected]>
This commit is contained in:
Bilawal SidhuandVassago DevTeam authored and GitHub committed 2026-09-14 18:55:24 -05:00
1 parent c56ef52ce3
commit a1d0a42450
7 files changed
+99 -5

No files matched your search

+21
View File
@@ -0,0 +1,21 @@
import { mkdtemp, realpath } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import path from 'node:path';
/**
* Create a temporary directory for a test fixture, resolved to its physical
* path.
*
* The system temp directory is reached through a symlink on macOS
* (`/var` -> `/private/var`, `/tmp` -> `/private/tmp`). A test that gives the
* logical path to something that reports paths back — a launched process's
* working directory, a bundler's project root — then compares two spellings of
* the same directory and fails. Resolving the root once, here, keeps both sides
* on the physical path.
*
* @param {string} prefix - Directory name prefix, e.g. `gev-preview-`.
* @returns {Promise<string>} The fixture root, with no symlinked component.
*/
export async function makeFixtureRoot(prefix) {
return realpath(await mkdtemp(path.join(tmpdir(), prefix)));
}
+55
View File
@@ -0,0 +1,55 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { mkdir, mkdtemp, realpath, rm, symlink } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { makeFixtureRoot } from './fixtureRoot.mjs';
// Creating a symlink needs a privilege Windows does not grant by default, and
// Windows reads its temp directory from other variables than TMPDIR. The case
// therefore covers macOS and Linux; a Windows equivalent would have to build a
// directory junction and set TEMP.
const symlinkTest = process.platform === 'win32' ? test.skip : test;
symlinkTest(
'a fixture root is physical even when the temp root is a symlink',
async (t) => {
// macOS reaches its own temp directory through a symlink and Linux does
// not, so build one explicitly: without it this check would pass on the
// Linux runner while every Mac contributor still saw the failure it exists
// to prevent.
const scratch = await realpath(
await mkdtemp(path.join(tmpdir(), 'gev-fixture-root-')),
);
t.after(() => rm(scratch, { recursive: true, force: true }));
const physical = path.join(scratch, 'physical');
const viaLink = path.join(scratch, 'link');
await mkdir(physical);
await symlink(physical, viaLink);
const before = process.env.TMPDIR;
process.env.TMPDIR = viaLink;
t.after(() => {
if (before === undefined) delete process.env.TMPDIR;
else process.env.TMPDIR = before;
});
// Fail rather than pass vacuously: if the temp root is not the symlink,
// the condition under test was never set up.
assert.equal(
tmpdir(),
viaLink,
'the symlinked temp root was not in force, so nothing was exercised',
);
const root = await makeFixtureRoot('gev-fixture-case-');
assert.equal(
root,
await realpath(root),
'the fixture root still contains a symlink',
);
assert.ok(
root.startsWith(`${physical}${path.sep}`),
`${root} is not under the physical temp root ${physical}`,
);
},
);
+5 -3
View File
@@ -1,11 +1,11 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { mkdtemp, writeFile, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { writeFile, rm } from 'node:fs/promises';
import path from 'node:path';
import { build, createServer, preview } from 'vite';
import { localProviderPlugins } from '../../server/providers/local.js';
import { apiNotFoundPlugin } from '../../server/standalone/api-not-found.js';
import { makeFixtureRoot } from './fixtureRoot.mjs';
test('data providers have both hooks; credential editing stays development-only', () => {
for (const plugin of localProviderPlugins()) {
@@ -27,7 +27,9 @@ test('data providers have both hooks; credential editing stays development-only'
});
test('real dev and built-preview servers serve provider JSON and terminate unknown APIs', async (t) => {
const root = await mkdtemp(path.join(tmpdir(), 'gev-preview-'));
// Physical path: Vite's root and the files written under it must agree on one
// spelling, and macOS reaches the temp directory through a symlink.
const root = await makeFixtureRoot('gev-preview-');
t.after(() => rm(root, { recursive: true, force: true }));
await writeFile(
path.join(root, 'index.html'),