Skip to content

Commit

Permalink
test: separate tsconfig tests
Browse files Browse the repository at this point in the history
  • Loading branch information
privatenumber committed May 21, 2024
1 parent 9cf2115 commit eeaefd6
Show file tree
Hide file tree
Showing 5 changed files with 215 additions and 193 deletions.
154 changes: 34 additions & 120 deletions tests/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const React = {
createElement: (...args) => Array.from(args),
};
`;
const jsxCheck = '<><div>JSX</div></>';

export const jsxCheck = '<><div>JSX</div></>';

const preserveName = `
assert(
Expand Down Expand Up @@ -83,7 +84,39 @@ const sourcemap = {
},
};

export const expectErrors = {
'expect-errors.js': `
export const expectErrors = async (...assertions) => {
let errors = await Promise.all(
assertions.map(async ([fn, expectedError]) => {
let thrown;
try {
await fn();
} catch (error) {
thrown = error;
}
if (!thrown) {
return new Error('No error thrown');
} else if (!thrown.message.includes(expectedError)) {
return new Error(\`Message \${JSON.stringify(expectedError)} not found in \${JSON.stringify(thrown.message)}\n\${thrown.stack}\`);
}
}),
);
errors = errors.filter(Boolean);
if (errors.length > 0) {
console.error(errors);
process.exitCode = 1;
}
};
`,
};

export const files = {
...expectErrors,

'js/index.js': `
import assert from 'assert';
${syntaxLowering}
Expand Down Expand Up @@ -188,44 +221,8 @@ export const files = {
${sourcemap.test('cts')}
`,

'expect-errors.js': `
export const expectErrors = async (...assertions) => {
let errors = await Promise.all(
assertions.map(async ([fn, expectedError]) => {
let thrown;
try {
await fn();
} catch (error) {
thrown = error;
}
if (!thrown) {
return new Error('No error thrown');
} else if (!thrown.message.includes(expectedError)) {
return new Error(\`Message \${JSON.stringify(expectedError)} not found in \${JSON.stringify(thrown.message)}\n\${thrown.stack}\`);
}
}),
);
errors = errors.filter(Boolean);
if (errors.length > 0) {
console.error(errors);
process.exitCode = 1;
}
};
`,

'file.txt': 'hello',

'import-typescript-parent.js': sourcemap.tag`
import './import-typescript-child.js';
`,

'import-typescript-child.ts': sourcemap.tag`
console.log('imported');
`,

'broken-syntax.ts': 'if',

node_modules: {
Expand All @@ -244,87 +241,4 @@ export const files = {
'empty-export/index.js': 'export {}',
},
},

tsconfig: {
'file.ts': '',

'jsx.jsx': `
// tsconfig not applied to jsx because allowJs is not set
import { expectErrors } from '../expect-errors';
expectErrors(
[() => ${jsxCheck}, 'React is not defined'],
// These should throw unless allowJs is set
// [() => import ('prefix/file'), "Cannot find package 'prefix'"],
// [() => import ('paths-exact-match'), "Cannot find package 'paths-exact-match'"],
// [() => import ('file'), "Cannot find package 'file'"],
);
`,

'node_modules/tsconfig-should-not-apply': {
'package.json': JSON.stringify({
exports: {
import: './index.mjs',
default: './index.cjs',
},
}),
'index.mjs': `
import { expectErrors } from '../../../expect-errors';
expectErrors(
[() => import ('prefix/file'), "Cannot find package 'prefix'"],
[() => import ('paths-exact-match'), "Cannot find package 'paths-exact-match'"],
[() => import ('file'), "Cannot find package 'file'"],
);
`,
'index.cjs': `
const { expectErrors } = require('../../../expect-errors');
expectErrors(
[() => require('prefix/file'), "Cannot find module"],
[() => require('paths-exact-match'), "Cannot find module"],
[() => require('file'), "Cannot find module"],
);
`,
},

'index.tsx': `
${jsxCheck};
import './jsx';
// Resolves relative to baseUrl
import 'file';
// Resolves paths - exact match
import 'paths-exact-match';
// Resolves paths - prefix match
import 'prefix/file';
// Resolves paths - suffix match
import 'file/suffix';
// tsconfig should not apply to dependency
import "tsconfig-should-not-apply";
`,

'tsconfig.json': JSON.stringify({
compilerOptions: {
jsxFactory: 'Array',
jsxFragmentFactory: 'null',
baseUrl: '.',
paths: {
'paths-exact-match': ['file'],
'prefix/*': ['*'],
'*/suffix': ['*'],
},
},
}),

'tsconfig-allowJs.json': JSON.stringify({
extends: './tsconfig.json',
compilerOptions: {
allowJs: true,
},
}),
},
};
1 change: 1 addition & 0 deletions tests/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { nodeVersions } from './utils/node-versions';
await runTestSuite(import('./specs/watch'), node);
await runTestSuite(import('./specs/loaders'), node);
await runTestSuite(import('./specs/smoke'), node);
await runTestSuite(import('./specs/tsconfig'), node);
});
}
});
Expand Down
105 changes: 32 additions & 73 deletions tests/specs/smoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,19 @@ import type { NodeApis } from '../utils/tsx.js';
import { hasCoverageSourcesContent } from '../utils/coverage-sources-content.js';
import { isWindows } from '../utils/is-windows.js';
import { files } from '../fixtures.js';
import { packageTypes } from '../utils/package-types.js';

const wasmPath = path.resolve('tests/fixtures/test.wasm');
const wasmPathUrl = pathToFileURL(wasmPath).toString();

const packageTypes = [
'module',
'commonjs',
] as const;

export default testSuite(async ({ describe }, { tsx }: NodeApis) => {
describe('Smoke', ({ describe }) => {
for (const packageType of packageTypes) {
const isCommonJs = packageType === 'commonjs';

describe(packageType, ({ test, describe }) => {
test('from .js', async ({ onTestFinish, onTestFail }) => {
const fixture = await createFixture({
describe(packageType, ({ test }) => {
test('from .js', async ({ onTestFail }) => {
await using fixture = await createFixture({
'package.json': JSON.stringify({ type: packageType }),
'import-from-js.js': outdent`
import assert from 'assert';
Expand Down Expand Up @@ -133,7 +129,6 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => {
`,
...files,
});
onTestFinish(async () => await fixture.rm());

const p = await tsx(['import-from-js.js'], fixture.path);
onTestFail((error) => {
Expand All @@ -158,8 +153,8 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => {
expect(p.stderr).toBe('');
});

describe('from .ts', async ({ test, onFinish }) => {
const fixture = await createFixture({
test('from .ts', async ({ onTestFail }) => {
await using fixture = await createFixture({
'package.json': JSON.stringify({ type: packageType }),

'import-from-ts.ts': ({ fixturePath }) => outdent`
Expand Down Expand Up @@ -333,73 +328,37 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => {
`,
...files,
});
onFinish(async () => await fixture.rm());

test('import all', async ({ onTestFail }) => {
const p = await tsx(['import-from-ts.ts'], {
cwd: fixture.path,
env: {
NODE_V8_COVERAGE: 'coverage',
},
});
onTestFail((error) => {
console.error(error);
console.log(p);
});
expect(p.failed).toBe(false);
expect(p.stdout).toMatch(`"import.meta.url":"${pathToFileURL(fixture.getPath('import-from-ts.ts'))}"`);
expect(p.stdout).toMatch(`"js":{"cjsContext":${isCommonJs},"default":1,"named":2}`);
expect(p.stdout).toMatch('"json":{"default":{"loaded":"json"},"loaded":"json"}');
expect(p.stdout).toMatch('"cjs":{"default":{"named":"named"},"named":"named"}');
expect(p.stdout).toMatch(`"jsx":{"cjsContext":${isCommonJs},"jsx":[null,null,["div",null,"JSX"]]}`);
expect(p.stdout).toMatch('"pkgModule":{"default":1,"named":2}');
if (isCommonJs) {
expect(p.stdout).toMatch('"pkgCommonjs":{"default":1,"named":2}');
} else {
expect(p.stdout).toMatch('"pkgCommonjs":{"default":{"default":1,"named":2}}');
}

// By "require()"ing an ESM file, it forces it to be compiled in a CJS context
expect(p.stdout).toMatch(`"mjs":{"mjsHasCjsContext":${isCommonJs}}`);
expect(p.stderr).toBe('');

const coverageDirectory = fixture.getPath('coverage');
const coverageSourceMapCache = await hasCoverageSourcesContent(coverageDirectory);
expect(coverageSourceMapCache).toBe(true);
const p = await tsx(['import-from-ts.ts'], {
cwd: fixture.path,
env: {
NODE_V8_COVERAGE: 'coverage',
},
});

test('tsconfig', async ({ onTestFail }) => {
const pTsconfig = await tsx(['index.tsx'], fixture.getPath('tsconfig'));
onTestFail((error) => {
console.error(error);
console.log(pTsconfig);
});
expect(pTsconfig.failed).toBe(false);
expect(pTsconfig.stderr).toBe('');
expect(pTsconfig.stdout).toBe('');
onTestFail((error) => {
console.error(error);
console.log(p);
});
expect(p.failed).toBe(false);
expect(p.stdout).toMatch(`"import.meta.url":"${pathToFileURL(fixture.getPath('import-from-ts.ts'))}"`);
expect(p.stdout).toMatch(`"js":{"cjsContext":${isCommonJs},"default":1,"named":2}`);
expect(p.stdout).toMatch('"json":{"default":{"loaded":"json"},"loaded":"json"}');
expect(p.stdout).toMatch('"cjs":{"default":{"named":"named"},"named":"named"}');
expect(p.stdout).toMatch(`"jsx":{"cjsContext":${isCommonJs},"jsx":[null,null,["div",null,"JSX"]]}`);
expect(p.stdout).toMatch('"pkgModule":{"default":1,"named":2}');
if (isCommonJs) {
expect(p.stdout).toMatch('"pkgCommonjs":{"default":1,"named":2}');
} else {
expect(p.stdout).toMatch('"pkgCommonjs":{"default":{"default":1,"named":2}}');
}

test('custom tsconfig', async ({ onTestFail }) => {
const pTsconfigAllowJs = await tsx(['--tsconfig', 'tsconfig-allowJs.json', 'jsx.jsx'], fixture.getPath('tsconfig'));
onTestFail((error) => {
console.error(error);
console.log(pTsconfigAllowJs);
});
expect(pTsconfigAllowJs.failed).toBe(true);
expect(pTsconfigAllowJs.stderr).toMatch('Error: No error thrown');
expect(pTsconfigAllowJs.stdout).toBe('');
});
// By "require()"ing an ESM file, it forces it to be compiled in a CJS context
expect(p.stdout).toMatch(`"mjs":{"mjsHasCjsContext":${isCommonJs}}`);
expect(p.stderr).toBe('');

test('allowJs in tsconfig.json', async ({ onTestFail }) => {
const pTsconfigAllowJs = await tsx(['--tsconfig', 'tsconfig/tsconfig-allowJs.json', 'import-typescript-parent.js'], fixture.path);
onTestFail((error) => {
console.error(error);
console.log(pTsconfigAllowJs);
});
expect(pTsconfigAllowJs.failed).toBe(false);
expect(pTsconfigAllowJs.stderr).toBe('');
expect(pTsconfigAllowJs.stdout).toBe('imported');
});
const coverageDirectory = fixture.getPath('coverage');
const coverageSourceMapCache = await hasCoverageSourcesContent(coverageDirectory);
expect(coverageSourceMapCache).toBe(true);
});
});
}
Expand Down
Loading

0 comments on commit eeaefd6

Please sign in to comment.