aboutsummaryrefslogtreecommitdiff
path: root/test/bun.js/node-test-helpers.ts
diff options
context:
space:
mode:
authorGravatar Derrick Farris <mr.dcfarris@gmail.com> 2023-01-08 03:49:49 -0600
committerGravatar GitHub <noreply@github.com> 2023-01-08 01:49:49 -0800
commit94409770dece8bb9dfc23f4bdc2f240836035d87 (patch)
tree4cc627eb67c476871e84141a6c7a583e29e98309 /test/bun.js/node-test-helpers.ts
parentc505f172b84f5359aa186513f3ef7d6394bfc7b2 (diff)
downloadbun-94409770dece8bb9dfc23f4bdc2f240836035d87.tar.gz
bun-94409770dece8bb9dfc23f4bdc2f240836035d87.tar.zst
bun-94409770dece8bb9dfc23f4bdc2f240836035d87.zip
feat(node:readline): add node:readline and node:readline/promises (#1738)
* feat(readline): WIP: add readline * test(helpers): add deepStrictEqual helper * feat(readline): add readline & readline/promises to loader * fix(node:events): emit newListener on new listener added * feat(readline): finish readline cb interface, add tests * fix(stream): fix Transform.end() * fix(node-test-helpers): correct throws behavior, improve how all asserts work * feat(readline/promises): add readline/promises * feat(assert): add assert.match * test(readline): uncomment more tests * fix(readline): MaxCeil -> MathCeil 🤦 * fix(readline): export promises from node:readline * fix(readline): temp fix for circular dependency * cleanup(readline): remove console.log * fix(readline): change true -> 0 for CommonJS export * perf(readline): micro-optimizations with some getters * perf(readline): lazy load isWritable * cleanup(readline): rename debug flag env var to BUN_JS_DEBUG
Diffstat (limited to 'test/bun.js/node-test-helpers.ts')
-rw-r--r--test/bun.js/node-test-helpers.ts198
1 files changed, 198 insertions, 0 deletions
diff --git a/test/bun.js/node-test-helpers.ts b/test/bun.js/node-test-helpers.ts
new file mode 100644
index 000000000..ff7b8ece3
--- /dev/null
+++ b/test/bun.js/node-test-helpers.ts
@@ -0,0 +1,198 @@
+import { expect as expect_ } from "bun:test";
+// @ts-ignore
+import { gcTick } from "gc";
+import assertNode from "node:assert";
+
+type DoneCb = (err?: Error) => any;
+function noop() {}
+
+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 = {
+ 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);
+ }
+
+ 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
+ if (typeof fn === "function") return fn.apply(this, 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) => {
+ // @ts-ignore
+ const result = fn.apply(this, args);
+ actual++;
+ if (actual >= expected) {
+ done();
+ }
+ return result;
+ };
+ // 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,
+ };
+};
+
+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;
+}