Compare commits

...

1 Commits

Author SHA1 Message Date
Ben Grant
42efa23a00 fix node:test options and pass test-worker-eval-typescript.js 2025-07-18 12:41:03 -07:00
5 changed files with 154 additions and 3 deletions

View File

@@ -207,9 +207,17 @@ function bunTest(ctx: SuiteContext | TestContext) {
let ctx = new TestContext(false, undefined, Bun.main, undefined);
function describe(arg0: unknown, arg1: unknown, arg2: unknown) {
const { name, fn } = createDescribe(arg0, arg1, arg2);
const { name, fn, options } = createDescribe(arg0, arg1, arg2);
const { describe } = bunTest(ctx);
describe(name, fn);
if (options.only) {
describe.only(name, fn);
} else if (options.todo) {
describe.todo(name, fn);
} else if (options.skip) {
describe.skip(name, fn);
} else {
describe(name, fn);
}
}
describe.skip = function (arg0: unknown, arg1: unknown, arg2: unknown) {
@@ -233,7 +241,15 @@ describe.only = function (arg0: unknown, arg1: unknown, arg2: unknown) {
function test(arg0: unknown, arg1: unknown, arg2: unknown) {
const { name, fn, options } = createTest(arg0, arg1, arg2);
const { test } = bunTest(ctx);
test(name, fn, options);
if (options.only) {
test.only(name, fn);
} else if (options.todo) {
test.todo(name, fn);
} else if (options.skip) {
test.skip(name, fn);
} else {
test(name, fn);
}
}
test.skip = function (arg0: unknown, arg1: unknown, arg2: unknown) {

View File

@@ -0,0 +1,70 @@
'use strict';
require('../common');
const assert = require('assert');
const { Worker } = require('worker_threads');
const { test } = require('node:test');
const { once } = require('events');
const esmHelloWorld = `
import worker from 'worker_threads';
const foo: string = 'Hello, World!';
worker.parentPort.postMessage(foo);
`;
const cjsHelloWorld = `
const { parentPort } = require('worker_threads');
const foo: string = 'Hello, World!';
parentPort.postMessage(foo);
`;
const disableTypeScriptWarningFlag = '--disable-warning=ExperimentalWarning';
// Bun intentionally does not error on some cases this test expects to error (like CJS/ESM and TypeScript syntax)
const skipErrors = typeof Bun === 'object' ? { skip: true } : { skip: false };
test('Worker eval module typescript without input-type', async () => {
const w = new Worker(esmHelloWorld, { eval: true, execArgv: [disableTypeScriptWarningFlag] });
assert.deepStrictEqual(await once(w, 'message'), ['Hello, World!']);
});
test('Worker eval module typescript with --input-type=module-typescript', async () => {
const w = new Worker(esmHelloWorld, { eval: true, execArgv: ['--input-type=module-typescript',
disableTypeScriptWarningFlag] });
assert.deepStrictEqual(await once(w, 'message'), ['Hello, World!']);
});
test('Worker eval module typescript with --input-type=commonjs-typescript', skipErrors, async () => {
const w = new Worker(esmHelloWorld, { eval: true, execArgv: ['--input-type=commonjs-typescript',
disableTypeScriptWarningFlag] });
const [err] = await once(w, 'error');
assert.strictEqual(err.name, 'SyntaxError');
assert.match(err.message, /Cannot use import statement outside a module/);
});
test('Worker eval module typescript with --input-type=module', skipErrors, async () => {
const w = new Worker(esmHelloWorld, { eval: true, execArgv: ['--input-type=module',
disableTypeScriptWarningFlag] });
const [err] = await once(w, 'error');
assert.strictEqual(err.name, 'SyntaxError');
assert.match(err.message, /Missing initializer in const declaration/);
});
test('Worker eval commonjs typescript without input-type', async () => {
const w = new Worker(cjsHelloWorld, { eval: true, execArgv: [disableTypeScriptWarningFlag] });
assert.deepStrictEqual(await once(w, 'message'), ['Hello, World!']);
});
test('Worker eval commonjs typescript with --input-type=commonjs-typescript', async () => {
const w = new Worker(cjsHelloWorld, { eval: true, execArgv: ['--input-type=commonjs-typescript',
disableTypeScriptWarningFlag] });
assert.deepStrictEqual(await once(w, 'message'), ['Hello, World!']);
});
test('Worker eval commonjs typescript with --input-type=module-typescript', skipErrors, async () => {
const w = new Worker(cjsHelloWorld, { eval: true, execArgv: ['--input-type=module-typescript',
disableTypeScriptWarningFlag] });
const [err] = await once(w, 'error');
assert.strictEqual(err.name, 'ReferenceError');
assert.match(err.message, /require is not defined in ES module scope, you can use import instead/);
});

View File

@@ -0,0 +1,22 @@
import { test, describe } from "node:test";
import assert from "node:assert";
test("skipped with option", { skip: true }, () => assert.fail());
test.skip("skipped with test.skip", () => assert.fail());
describe("describe skipped with option", { skip: true }, () => {
test("should not run", () => assert.fail());
});
describe.skip("describe skipped with describe.skip", () => {
test("should not run", () => assert.fail());
});
test("todo with option", { todo: true }, () => assert.fail());
test.todo("todo with test.todo", () => assert.fail());
describe("describe todo with option", { todo: true }, () => {
test("should not run", () => assert.fail());
});
describe.todo("describe todo with describe.todo", () => {
test("should not run", () => assert.fail());
});

View File

@@ -0,0 +1,23 @@
import { test, describe } from "node:test";
import assert from "node:assert";
test("should not run", () => assert.fail());
describe("describe should not run", () => {
test("test should not run", () => assert.fail());
});
test.only("test.only", () => {});
test("only option", { only: true }, () => {});
describe.only("describe.only", () => {
test("test", () => {});
});
describe("describe with only option", { only: true }, () => {
test("test", () => {});
});
describe.only("describe.only with test.only", () => {
test.todo("should not run", () => assert.fail()); // todo: bun runs this test but it should not
test.only("test.only", () => {});
test("only option", { only: true }, () => {});
});

View File

@@ -35,6 +35,26 @@ describe("node:test", () => {
stderr: expect.stringContaining("0 fail"),
});
});
test("should support skip option", async () => {
const { exitCode, stderr } = await runTest("05-skip-todo.js");
expect(exitCode).toBe(0);
expect(stderr).toContain("0 pass");
expect(stderr).toContain("4 skip");
expect(stderr).toContain("4 todo");
expect(stderr).toContain("0 fail");
});
test("should support only option", async () => {
const { exitCode, stderr } = await runTest("06-only.js");
expect(exitCode).toBe(0);
expect(stderr).toContain("6 pass");
expect(stderr).toContain("0 fail");
// output with "only" tests should not even mention other tests
expect(stderr).not.toContain("todo");
expect(stderr).not.toContain("skip");
expect(stderr).not.toContain("should not run");
});
});
async function runTest(filename: string) {