aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-03-14 15:59:55 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-03-14 15:59:55 -0700
commite1921ff8c5996f325c152368e6f1ebb8226c28af (patch)
tree39a2c969314d41ec476c2a056eb8c637e78a7d41
parent2b5139aa46663241302175b5560332da55f57bb3 (diff)
downloadbun-e1921ff8c5996f325c152368e6f1ebb8226c28af.tar.gz
bun-e1921ff8c5996f325c152368e6f1ebb8226c28af.tar.zst
bun-e1921ff8c5996f325c152368e6f1ebb8226c28af.zip
Fix node test harness
-rw-r--r--test/harness.ts9
-rw-r--r--test/js/node/harness.ts395
-rw-r--r--test/js/node/net/node-net-server.test.ts9
-rw-r--r--test/js/node/readline/readline.node.test.ts4
-rw-r--r--test/js/node/readline/readline_promises.node.test.ts4
5 files changed, 232 insertions, 189 deletions
diff --git a/test/harness.ts b/test/harness.ts
index 486381cf2..9c4ce8e56 100644
--- a/test/harness.ts
+++ b/test/harness.ts
@@ -35,3 +35,12 @@ export function withoutAggressiveGC(block: () => unknown) {
Bun.unsafe.gcAggressionLevel(origGC);
}
}
+
+export function hideFromStackTrace(block: CallableFunction) {
+ Object.defineProperty(block, "name", {
+ value: "::bunternal::",
+ configurable: true,
+ enumerable: true,
+ writable: true,
+ });
+}
diff --git a/test/js/node/harness.ts b/test/js/node/harness.ts
index 227009a64..a3a7a43e5 100644
--- a/test/js/node/harness.ts
+++ b/test/js/node/harness.ts
@@ -1,201 +1,232 @@
-import { expect as expect_ } from "bun:test";
-import { gcTick } from "harness";
+import { gcTick, hideFromStackTrace } from "harness";
import assertNode from "node:assert";
type DoneCb = (err?: Error) => any;
function noop() {}
+export function createTest(path: string) {
+ const { expect, test, it, describe, beforeAll, afterAll, beforeEach, afterEach } = Bun.jest(path);
-const expect = actual => {
- gcTick();
- const ret = expect_(actual);
- gcTick();
- return ret;
-};
-
-// Assert
-export const strictEqual = (...args: Parameters<typeof assertNode.strictEqual>) => {
- assertNode.strictEqual.apply(this, args);
- expect(true).toBe(true);
-};
-
-export const notStrictEqual = (...args: Parameters<typeof assertNode.notStrictEqual>) => {
- assertNode.notStrictEqual.apply(this, args);
- expect(true).toBe(true);
-};
-
-export const deepStrictEqual = (...args: Parameters<typeof assertNode.deepStrictEqual>) => {
- assertNode.deepStrictEqual.apply(this, args);
- expect(true).toBe(true);
-};
-
-export const throws = (...args: Parameters<typeof assertNode.throws>) => {
- assertNode.throws.apply(this, args);
- expect(true).toBe(true);
-};
-
-export const ok = (...args: Parameters<typeof assertNode.ok>) => {
- assertNode.ok.apply(this, args);
- expect(true).toBe(true);
-};
-
-export const ifError = (...args: Parameters<typeof assertNode.ifError>) => {
- assertNode.ifError.apply(this, args);
- expect(true).toBe(true);
-};
-
-export const match = (...args: Parameters<typeof assertNode.match>) => {
- assertNode.match.apply(this, args);
- expect(true).toBe(true);
-};
-
-export const assert = function (...args: any[]) {
- // @ts-ignore
- assertNode(...args);
-};
-
-Object.assign(assert, {
- strictEqual,
- deepStrictEqual,
- notStrictEqual,
- throws,
- ok,
- ifError,
- match,
-});
-
-// End assert
-
-export const createCallCheckCtx = (done: DoneCb) => {
- const createDone = createDoneDotAll(done);
-
- // const mustCallChecks = [];
-
- // failed.forEach(function (context) {
- // console.log(
- // "Mismatched %s function calls. Expected %s, actual %d.",
- // context.name,
- // context.messageSegment,
- // context.actual
- // );
- // console.log(context.stack.split("\n").slice(2).join("\n"));
- // });
-
- // TODO: Implement this to be exact only
- function mustCall(fn?: (...args) => any, exact?: number) {
- return mustCallAtLeast(fn, exact);
- }
+ hideFromStackTrace(expect);
- function mustNotCall(reason: string = "function should not have been called") {
- const localDone = createDone();
- setTimeout(() => localDone(), 200);
- return () => {
- done(new Error(reason));
- };
- }
+ // Assert
+ const strictEqual = (...args: Parameters<typeof assertNode.strictEqual>) => {
+ assertNode.strictEqual(...args);
+ expect(true).toBe(true);
+ };
- function mustSucceed(fn: () => any, exact?: number) {
- return mustCall(function (err, ...args) {
- ifError(err);
- // @ts-ignore
- if (typeof fn === "function") return fn.apply(this, args as []);
- }, exact);
- }
+ const notStrictEqual = (...args: Parameters<typeof assertNode.notStrictEqual>) => {
+ assertNode.notStrictEqual(...args);
+ expect(true).toBe(true);
+ };
- function mustCallAtLeast(fn, minimum) {
- return _mustCallInner(fn, minimum, "minimum");
- }
+ const deepStrictEqual = (...args: Parameters<typeof assertNode.deepStrictEqual>) => {
+ assertNode.deepStrictEqual(...args);
+ expect(true).toBe(true);
+ };
- function _mustCallInner(fn, criteria = 1, field) {
- if (process._exiting) throw new Error("Cannot use common.mustCall*() in process exit handler");
- if (typeof fn === "number") {
- criteria = fn;
- fn = noop;
- } else if (fn === undefined) {
- fn = noop;
- }
+ const throws = (...args: Parameters<typeof assertNode.throws>) => {
+ assertNode.throws(...args);
+ expect(true).toBe(true);
+ };
+
+ const ok = (...args: Parameters<typeof assertNode.ok>) => {
+ assertNode.ok(...args);
+ expect(true).toBe(true);
+ };
+
+ const ifError = (...args: Parameters<typeof assertNode.ifError>) => {
+ assertNode.ifError(...args);
+ expect(true).toBe(true);
+ };
- if (typeof criteria !== "number") throw new TypeError(`Invalid ${field} value: ${criteria}`);
+ const match = (...args: Parameters<typeof assertNode.match>) => {
+ assertNode.match(...args);
+ expect(true).toBe(true);
+ };
- let actual = 0;
- let expected = criteria;
+ const assert = function (...args: any[]) {
+ // @ts-ignore
+ assertNode(...args);
+ };
- // mustCallChecks.push(context);
- const done = createDone();
- const _return = (...args) => {
- try {
+ hideFromStackTrace(strictEqual);
+ hideFromStackTrace(notStrictEqual);
+ hideFromStackTrace(deepStrictEqual);
+ hideFromStackTrace(throws);
+ hideFromStackTrace(ok);
+ hideFromStackTrace(ifError);
+ hideFromStackTrace(match);
+ hideFromStackTrace(assert);
+
+ Object.assign(assert, {
+ strictEqual,
+ deepStrictEqual,
+ notStrictEqual,
+ throws,
+ ok,
+ ifError,
+ match,
+ });
+
+ // End assert
+
+ const createCallCheckCtx = (done: DoneCb) => {
+ const createDone = createDoneDotAll(done);
+
+ // const mustCallChecks = [];
+
+ // failed.forEach(function (context) {
+ // console.log(
+ // "Mismatched %s function calls. Expected %s, actual %d.",
+ // context.name,
+ // context.messageSegment,
+ // context.actual
+ // );
+ // console.log(context.stack.split("\n").slice(2).join("\n"));
+ // });
+
+ // TODO: Implement this to be exact only
+ function mustCall(fn?: (...args) => any, exact?: number) {
+ return mustCallAtLeast(fn, exact);
+ }
+
+ function mustNotCall(reason: string = "function should not have been called") {
+ const localDone = createDone();
+ setTimeout(() => localDone(), 200);
+ return () => {
+ done(new Error(reason));
+ };
+ }
+
+ function mustSucceed(fn: () => any, exact?: number) {
+ return mustCall(function (err, ...args) {
+ ifError(err);
// @ts-ignore
- const result = fn.apply(this, args);
- actual++;
- if (actual >= expected) {
- done();
- }
- return result;
- } catch (err) {
- if (err instanceof Error) done(err);
- else if (err?.toString) done(new Error(err?.toString()));
- else {
- console.error("Unknown error", err);
- done(new Error("Unknown error"));
- }
+ if (typeof fn === "function") return fn(...(args as []));
+ }, exact);
+ }
+
+ function mustCallAtLeast(fn, minimum) {
+ return _mustCallInner(fn, minimum, "minimum");
+ }
+
+ function _mustCallInner(fn, criteria = 1, field) {
+ if (process._exiting) throw new Error("Cannot use common.mustCall*() in process exit handler");
+ if (typeof fn === "number") {
+ criteria = fn;
+ fn = noop;
+ } else if (fn === undefined) {
+ fn = noop;
}
+
+ if (typeof criteria !== "number") throw new TypeError(`Invalid ${field} value: ${criteria}`);
+
+ let actual = 0;
+ let expected = criteria;
+
+ // mustCallChecks.push(context);
+ const done = createDone();
+ const _return = (...args) => {
+ try {
+ // @ts-ignore
+ const result = fn(...args);
+ actual++;
+ if (actual >= expected) {
+ done();
+ }
+ return result;
+ } catch (err) {
+ if (err instanceof Error) done(err);
+ else if (err?.toString) done(new Error(err?.toString()));
+ else {
+ console.error("Unknown error", err);
+ done(new Error("Unknown error"));
+ }
+ }
+ };
+ // Function instances have own properties that may be relevant.
+ // Let's replicate those properties to the returned function.
+ // Refs: https://tc39.es/ecma262/#sec-function-instances
+ Object.defineProperties(_return, {
+ name: {
+ value: fn.name,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+ },
+ length: {
+ value: fn.length,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+ },
+ });
+ return _return;
+ }
+ return {
+ mustSucceed,
+ mustCall,
+ mustCallAtLeast,
+ mustNotCall,
};
- // Function instances have own properties that may be relevant.
- // Let's replicate those properties to the returned function.
- // Refs: https://tc39.es/ecma262/#sec-function-instances
- Object.defineProperties(_return, {
- name: {
- value: fn.name,
- writable: false,
- enumerable: false,
- configurable: true,
- },
- length: {
- value: fn.length,
- writable: false,
- enumerable: false,
- configurable: true,
- },
- });
- return _return;
+ };
+
+ function createDoneDotAll(done: DoneCb, globalTimeout?: number) {
+ let toComplete = 0;
+ let completed = 0;
+ const globalTimer = globalTimeout
+ ? setTimeout(() => {
+ console.log("Global Timeout");
+ done(new Error("Timed out!"));
+ }, globalTimeout)
+ : undefined;
+ function createDoneCb(timeout?: number) {
+ toComplete += 1;
+ const timer =
+ timeout !== undefined
+ ? setTimeout(() => {
+ console.log("Timeout");
+ done(new Error("Timed out!"));
+ }, timeout)
+ : timeout;
+ return (result?: Error) => {
+ if (timer) clearTimeout(timer);
+ if (globalTimer) clearTimeout(globalTimer);
+ if (result instanceof Error) {
+ done(result);
+ return;
+ }
+ completed += 1;
+ if (completed === toComplete) {
+ done();
+ }
+ };
+ }
+ return createDoneCb;
}
+
return {
- mustSucceed,
- mustCall,
- mustCallAtLeast,
- mustNotCall,
+ expect,
+ test,
+ it,
+ describe,
+ beforeAll,
+ afterAll,
+ beforeEach,
+ afterEach,
+ createDoneDotAll,
+ strictEqual,
+ notStrictEqual,
+ deepStrictEqual,
+ throws,
+ ok,
+ ifError,
+ createCallCheckCtx,
+ match,
+ assert,
};
-};
-
-export function createDoneDotAll(done: DoneCb, globalTimeout?: number) {
- let toComplete = 0;
- let completed = 0;
- const globalTimer = globalTimeout
- ? setTimeout(() => {
- console.log("Global Timeout");
- done(new Error("Timed out!"));
- }, globalTimeout)
- : undefined;
- function createDoneCb(timeout?: number) {
- toComplete += 1;
- const timer =
- timeout !== undefined
- ? setTimeout(() => {
- console.log("Timeout");
- done(new Error("Timed out!"));
- }, timeout)
- : timeout;
- return (result?: Error) => {
- if (timer) clearTimeout(timer);
- if (globalTimer) clearTimeout(globalTimer);
- if (result instanceof Error) {
- done(result);
- return;
- }
- completed += 1;
- if (completed === toComplete) {
- done();
- }
- };
- }
- return createDoneCb;
+}
+
+declare namespace Bun {
+ function jest(path: string): typeof import("bun:test");
}
diff --git a/test/js/node/net/node-net-server.test.ts b/test/js/node/net/node-net-server.test.ts
index bdaf289a7..063a822d5 100644
--- a/test/js/node/net/node-net-server.test.ts
+++ b/test/js/node/net/node-net-server.test.ts
@@ -1,9 +1,12 @@
-import { describe, expect, it } from "bun:test";
-import { createServer } from "net";
-import { createCallCheckCtx } from "node-harness";
+const { createServer } = require("net");
import { realpathSync } from "fs";
import { tmpdir } from "os";
import { join } from "path";
+import { createTest } from "node-harness";
+
+const { throws, assert, createDoneDotAll, beforeAll, describe, expect, it, createCallCheckCtx } = createTest(
+ import.meta.path,
+);
const socket_domain = join(realpathSync(tmpdir()), "node-net-server.sock");
diff --git a/test/js/node/readline/readline.node.test.ts b/test/js/node/readline/readline.node.test.ts
index 7dfa51ac8..a1077a799 100644
--- a/test/js/node/readline/readline.node.test.ts
+++ b/test/js/node/readline/readline.node.test.ts
@@ -1,8 +1,8 @@
-import { beforeEach, describe, it } from "bun:test";
import readline from "node:readline";
import { Writable, PassThrough } from "node:stream";
import { EventEmitter } from "node:events";
-import { createDoneDotAll, createCallCheckCtx, assert } from "node-harness";
+import { createTest } from "node-harness";
+const { beforeEach, describe, it, createDoneDotAll, createCallCheckCtx, assert } = createTest(import.meta.path);
var {
CSI,
diff --git a/test/js/node/readline/readline_promises.node.test.ts b/test/js/node/readline/readline_promises.node.test.ts
index c75d254ca..8a4ac014f 100644
--- a/test/js/node/readline/readline_promises.node.test.ts
+++ b/test/js/node/readline/readline_promises.node.test.ts
@@ -1,7 +1,7 @@
-import { describe, it } from "bun:test";
import readlinePromises from "node:readline/promises";
import { EventEmitter } from "node:events";
-import { createDoneDotAll, createCallCheckCtx, assert } from "node-harness";
+import { createTest } from "node-harness";
+const { describe, it, createDoneDotAll, createCallCheckCtx, assert } = createTest(import.meta.path);
// ----------------------------------------------------------------------------
// Helpers