Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion examples/esbuild/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ import { resolve } from 'node:path';

import { defineConfig } from 'vitest/config';

// resolve() returns backslash paths on Windows; tinyglobby (used by vitest's
// include matcher) only matches forward-slash patterns, so without normalizing
// the test file is silently never discovered on Windows ("No test files found").
const include = resolve(import.meta.dirname, 'esbuild.e2e.test.ts').replaceAll(
'\\',
'/'
);

export default defineConfig({
test: {
environment: 'node',
globals: true,
include: [resolve(import.meta.dirname, 'esbuild.e2e.test.ts')],
include: [include],
restoreMocks: true,
},
});
11 changes: 10 additions & 1 deletion examples/parcel/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@ import { resolve } from 'node:path';

import { defineConfig } from 'vitest/config';

// resolve() returns backslash paths on Windows; tinyglobby (used by vitest's
// include matcher) only matches forward-slash patterns, so without normalizing
// the test file is silently never discovered on Windows ("No test files found").
const include = resolve(import.meta.dirname, 'parcel.e2e.test.ts').replaceAll(
'\\',
'/'
);

export default defineConfig({
test: {
environment: 'node',
globals: true,
include: [resolve(import.meta.dirname, 'parcel.e2e.test.ts')],
include: [include],
restoreMocks: true,
},
});
10 changes: 9 additions & 1 deletion examples/rolldown/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ import { resolve } from 'node:path';

import { defineConfig } from 'vitest/config';

// resolve() returns backslash paths on Windows; tinyglobby (used by vitest's
// include matcher) only matches forward-slash patterns, so without normalizing
// the test file is silently never discovered on Windows ("No test files found").
const include = resolve(import.meta.dirname, 'rolldown.e2e.test.ts').replaceAll(
'\\',
'/'
);

export default defineConfig({
test: {
environment: 'node',
globals: true,
include: [resolve(import.meta.dirname, 'rolldown.e2e.test.ts')],
include: [include],
restoreMocks: true,
},
});
10 changes: 9 additions & 1 deletion examples/rollup/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ import { resolve } from 'node:path';

import { defineConfig } from 'vitest/config';

// resolve() returns backslash paths on Windows; tinyglobby (used by vitest's
// include matcher) only matches forward-slash patterns, so without normalizing
// the test file is silently never discovered on Windows ("No test files found").
const include = resolve(import.meta.dirname, 'rollup.e2e.test.ts').replaceAll(
'\\',
'/'
);

export default defineConfig({
test: {
environment: 'node',
globals: true,
include: [resolve(import.meta.dirname, 'rollup.e2e.test.ts')],
include: [include],
restoreMocks: true,
},
});
10 changes: 9 additions & 1 deletion examples/rsbuild/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ import { resolve } from 'node:path';

import { defineConfig } from 'vitest/config';

// resolve() returns backslash paths on Windows; tinyglobby (used by vitest's
// include matcher) only matches forward-slash patterns, so without normalizing
// the test file is silently never discovered on Windows ("No test files found").
const include = resolve(import.meta.dirname, 'rsbuild.e2e.test.ts').replaceAll(
'\\',
'/'
);

export default defineConfig({
test: {
environment: 'node',
globals: true,
include: [resolve(import.meta.dirname, 'rsbuild.e2e.test.ts')],
include: [include],
restoreMocks: true,
},
});
10 changes: 9 additions & 1 deletion examples/rspack/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ import { resolve } from 'node:path';

import { defineConfig } from 'vitest/config';

// resolve() returns backslash paths on Windows; tinyglobby (used by vitest's
// include matcher) only matches forward-slash patterns, so without normalizing
// the test file is silently never discovered on Windows ("No test files found").
const include = resolve(import.meta.dirname, 'rspack.e2e.test.ts').replaceAll(
'\\',
'/'
);

export default defineConfig({
test: {
environment: 'node',
globals: true,
include: [resolve(import.meta.dirname, 'rspack.e2e.test.ts')],
include: [include],
restoreMocks: true,
},
});
10 changes: 9 additions & 1 deletion examples/vite/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ import { resolve } from 'node:path';

import { defineConfig } from 'vitest/config';

// resolve() returns backslash paths on Windows; tinyglobby (used by vitest's
// include matcher) only matches forward-slash patterns, so without normalizing
// the test file is silently never discovered on Windows ("No test files found").
const include = resolve(import.meta.dirname, 'vite.e2e.test.ts').replaceAll(
'\\',
'/'
);

export default defineConfig({
test: {
environment: 'node',
globals: true,
include: [resolve(import.meta.dirname, 'vite.e2e.test.ts')],
include: [include],
restoreMocks: true,
},
});
10 changes: 9 additions & 1 deletion examples/webpack/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ import { resolve } from 'node:path';

import { defineConfig } from 'vitest/config';

// resolve() returns backslash paths on Windows; tinyglobby (used by vitest's
// include matcher) only matches forward-slash patterns, so without normalizing
// the test file is silently never discovered on Windows ("No test files found").
const include = resolve(import.meta.dirname, 'webpack.e2e.test.ts').replaceAll(
'\\',
'/'
);

export default defineConfig({
test: {
environment: 'node',
globals: true,
include: [resolve(import.meta.dirname, 'webpack.e2e.test.ts')],
include: [include],
restoreMocks: true,
},
});
13 changes: 10 additions & 3 deletions packages/core/__tests__/correctness.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { spawnSync } from 'node:child_process';
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join, resolve } from 'node:path';
import { join, resolve, sep } from 'node:path';

import fft from '../src/index.js';

// `import.meta.dirname` is OS-native (backslash on Windows), so `resolve()`
// also returns backslash on Windows. Snapshot fixture paths and CLI args
// must be POSIX-style — sourcemap `sources[]` and tinyglobby's include
// matchers expect forward-slash.
const toPosix =
sep === '\\' ? (p: string) => p.replaceAll('\\', '/') : (p: string) => p;

type Format = 'compact' | 'pretty' | 'preserve';
interface SnapshotCase {
fixture: string;
Expand All @@ -18,11 +25,11 @@ interface SnapshotCase {
}

function outputsDir(): string {
return resolve(import.meta.dirname, 'outputs');
return toPosix(resolve(import.meta.dirname, 'outputs'));
}

function inputsDir(): string {
return resolve(import.meta.dirname, 'inputs');
return toPosix(resolve(import.meta.dirname, 'inputs'));
}

const FULL_FIXTURE = 'source.flow';
Expand Down
45 changes: 26 additions & 19 deletions packages/core/src/cli/__tests__/run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ import { describe, expect, it, vi } from 'vitest';

import { runCli } from '../run.js';

// Use a platform-absolute fake cwd so node:path.resolve produces the same
// shape on Windows (where bare `/repo` is treated as drive-relative and
// gets the current drive prepended) and POSIX. The CLI internally normalizes
// to forward-slash, so all expected values use forward-slash regardless of
// platform.
const FAKE_CWD = process.platform === 'win32' ? 'C:/repo' : '/repo';

type RawSourceMap = import('source-map').RawSourceMap;

function createMap(file: string): RawSourceMap {
Expand All @@ -23,7 +30,7 @@ function createDeps() {

return {
deps: {
cwd: () => '/repo',
cwd: () => FAKE_CWD,
readFile,
stderr: {
write(chunk: string) {
Expand All @@ -50,15 +57,15 @@ describe('CLI runner', () => {
it('transforms a file without source maps by default', async () => {
const { deps, readFile, transform, writeFile } = createDeps();
readFile.mockImplementation(async (path) => {
if (path === '/repo/src/input.js') {
if (path === `${FAKE_CWD}/src/input.js`) {
return 'const answer: number = 42;';
}

throw new Error(`Unexpected read: ${path}`);
});
transform.mockResolvedValue({
code: 'const answer = 42;\n',
map: createMap('/repo/dist/output.js'),
map: createMap(`${FAKE_CWD}/dist/output.js`),
});

const exitCode = await runCli(
Expand All @@ -68,29 +75,29 @@ describe('CLI runner', () => {

expect(exitCode).toBe(0);
expect(transform).toHaveBeenCalledWith({
filename: '/repo/src/input.js',
filename: `${FAKE_CWD}/src/input.js`,
source: 'const answer: number = 42;',
sourcemap: false,
});
expect(writeFile).toHaveBeenCalledTimes(1);
expect(writeFile).toHaveBeenCalledWith(
'/repo/dist/output.js',
`${FAKE_CWD}/dist/output.js`,
'const answer = 42;\n'
);
});

it('writes code plus sourcemap files when --source-map is enabled', async () => {
const { deps, readFile, transform, writeFile } = createDeps();
readFile.mockImplementation(async (path) => {
if (path === '/repo/src/input.js') {
if (path === `${FAKE_CWD}/src/input.js`) {
return 'const answer: number = 42;';
}

throw new Error(`Unexpected read: ${path}`);
});
transform.mockResolvedValue({
code: 'const answer = 42;\n',
map: createMap('/repo/dist/output.js'),
map: createMap(`${FAKE_CWD}/dist/output.js`),
});

const exitCode = await runCli(
Expand All @@ -110,20 +117,20 @@ describe('CLI runner', () => {
expect(exitCode).toBe(0);
expect(transform).toHaveBeenCalledWith({
dialect: 'flow',
filename: '/repo/src/input.js',
filename: `${FAKE_CWD}/src/input.js`,
format: 'pretty',
source: 'const answer: number = 42;',
sourcemap: true,
});
expect(writeFile).toHaveBeenNthCalledWith(
1,
'/repo/dist/output.js',
`${FAKE_CWD}/dist/output.js`,
'const answer = 42;\n//# sourceMappingURL=output.js.map\n'
);
expect(writeFile).toHaveBeenNthCalledWith(
2,
'/repo/dist/output.js.map',
`${JSON.stringify(createMap('/repo/dist/output.js'), null, 2)}\n`
`${FAKE_CWD}/dist/output.js.map`,
`${JSON.stringify(createMap(`${FAKE_CWD}/dist/output.js`), null, 2)}\n`
);
});

Expand All @@ -138,7 +145,7 @@ describe('CLI runner', () => {

expect(exitCode).toBe(0);
expect(transform).toHaveBeenCalledWith({
filename: '/repo/src/input.js',
filename: `${FAKE_CWD}/src/input.js`,
source: 'const answer: number = 42;',
sourcemap: false,
});
Expand All @@ -161,7 +168,7 @@ describe('CLI runner', () => {
expect(exitCode).toBe(0);
expect(transform).toHaveBeenCalledWith({
comments: true,
filename: '/repo/src/input.js',
filename: `${FAKE_CWD}/src/input.js`,
format: 'preserve',
source: 'const answer: number = 42;',
sourcemap: false,
Expand All @@ -182,7 +189,7 @@ describe('CLI runner', () => {
expect(exitCode).toBe(0);
expect(transform).toHaveBeenCalledWith({
comments: true,
filename: '/repo/src/input.js',
filename: `${FAKE_CWD}/src/input.js`,
source: '/* keep */\nconst answer: number = 42;',
sourcemap: false,
});
Expand All @@ -192,21 +199,21 @@ describe('CLI runner', () => {

it('loads an input sourcemap file and forwards it to transform', async () => {
const { deps, readFile, transform, writeFile } = createDeps();
const inputMap = createMap('/repo/src/input.js');
const inputMap = createMap(`${FAKE_CWD}/src/input.js`);
readFile.mockImplementation(async (path) => {
if (path === '/repo/src/input.js') {
if (path === `${FAKE_CWD}/src/input.js`) {
return 'const answer: number = 42;';
}

if (path === '/repo/maps/input.js.map') {
if (path === `${FAKE_CWD}/maps/input.js.map`) {
return JSON.stringify(inputMap);
}

throw new Error(`Unexpected read: ${path}`);
});
transform.mockResolvedValue({
code: 'const answer = 42;\n',
map: createMap('/repo/dist/output.js'),
map: createMap(`${FAKE_CWD}/dist/output.js`),
});

const exitCode = await runCli(
Expand All @@ -223,7 +230,7 @@ describe('CLI runner', () => {

expect(exitCode).toBe(0);
expect(transform).toHaveBeenCalledWith({
filename: '/repo/src/input.js',
filename: `${FAKE_CWD}/src/input.js`,
inputSourceMap: inputMap,
source: 'const answer: number = 42;',
sourcemap: true,
Expand Down
Loading
Loading