aboutsummaryrefslogtreecommitdiff
path: root/test/js/node/util
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-07-11 19:14:34 -0700
committerGravatar GitHub <noreply@github.com> 2023-07-11 19:14:34 -0700
commitcbb88672f217a90db1aa1eb29cd92d5d9035b22b (patch)
tree43a00501f3cde495967e116f0b660777051551f8 /test/js/node/util
parent1f900cff453700b19bca2acadfe26da4468c1282 (diff)
parent34b0e7a2bbd8bf8097341cdb0075d0908283e834 (diff)
downloadbun-jarred/esm-conditions.tar.gz
bun-jarred/esm-conditions.tar.zst
bun-jarred/esm-conditions.zip
Merge branch 'main' into jarred/esm-conditionsjarred/esm-conditions
Diffstat (limited to 'test/js/node/util')
-rw-r--r--test/js/node/util/test-util-types.test.js32
-rw-r--r--test/js/node/util/util-callbackify.test.js323
-rw-r--r--test/js/node/util/util.test.js17
3 files changed, 361 insertions, 11 deletions
diff --git a/test/js/node/util/test-util-types.test.js b/test/js/node/util/test-util-types.test.js
index f33ab4b1a..a75b9eac0 100644
--- a/test/js/node/util/test-util-types.test.js
+++ b/test/js/node/util/test-util-types.test.js
@@ -1,6 +1,9 @@
-const assert = require("assert");
-import { test, expect } from "bun:test";
-const types = require("util/types");
+import assert from "assert";
+import { describe, test, expect } from "bun:test";
+import def from "util/types";
+import * as ns from "util/types";
+const req = require("util/types");
+const types = def;
function inspect(val) {
return Bun.inspect(val);
@@ -52,15 +55,21 @@ for (const [value, _method] of [
assert(method in types, `Missing ${method} for ${inspect(value)}`);
assert(types[method](value), `Want ${inspect(value)} to match ${method}`);
- for (const key of Object.keys(types)) {
- if (
- ((types.isArrayBufferView(value) || types.isAnyArrayBuffer(value)) && key.includes("Array")) ||
- key === "isBoxedPrimitive"
- ) {
- continue;
- }
+ for (const [types, label] of [
+ [def, "default import"],
+ [ns, "ns import"],
+ [req, "require esm"],
+ ]) {
+ for (const key of Object.keys(types).filter(x => x !== "default")) {
+ if (
+ ((types.isArrayBufferView(value) || types.isAnyArrayBuffer(value)) && key.includes("Array")) ||
+ key === "isBoxedPrimitive"
+ ) {
+ continue;
+ }
- expect(types[key](value)).toBe(key === method);
+ expect(types[key](value)).toBe(key === method);
+ }
}
});
}
@@ -238,3 +247,4 @@ test("isBoxedPrimitive", () => {
});
}
}
+// */
diff --git a/test/js/node/util/util-callbackify.test.js b/test/js/node/util/util-callbackify.test.js
new file mode 100644
index 000000000..38c20f5c0
--- /dev/null
+++ b/test/js/node/util/util-callbackify.test.js
@@ -0,0 +1,323 @@
+import { callbackify } from "util";
+import { createTest } from "node-harness";
+
+const { describe, expect, it, createCallCheckCtx } = createTest(import.meta.path);
+
+const values = [
+ "hello world",
+ null,
+ undefined,
+ false,
+ 0,
+ {},
+ { key: "value" },
+ Symbol("I am a symbol"),
+ function ok() {},
+ ["array", "with", 4, "values"],
+ new Error("boo"),
+];
+
+describe("util.callbackify", () => {
+ describe("rejection reason", () => {
+ for (const value of values) {
+ it(`callback is async function, value is ${String(value)}`, done => {
+ const { mustCall } = createCallCheckCtx(done);
+ async function asyncFn() {
+ return Promise.reject(value);
+ }
+
+ const cbAsyncFn = callbackify(asyncFn);
+ cbAsyncFn(
+ mustCall((err, ret) => {
+ try {
+ expect(ret).toBeUndefined();
+ if (err instanceof Error) {
+ if ("reason" in err) {
+ expect(!value).toBeTrue();
+ expect(err.code).toStrictEqual("ERR_FALSY_VALUE_REJECTION");
+ expect(err.reason).toStrictEqual(value);
+ } else {
+ expect(String(value)).toEndWith(err.message);
+ }
+ } else {
+ expect(err).toStrictEqual(value);
+ }
+
+ done();
+ } catch (error) {
+ done(error);
+ }
+ }),
+ );
+ });
+
+ it(`callback is promise, value is ${String(value)}`, done => {
+ const { mustCall } = createCallCheckCtx(done);
+ function promiseFn() {
+ return Promise.reject(value);
+ }
+ const obj = {};
+ Object.defineProperty(promiseFn, "name", {
+ value: obj,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+ });
+
+ const cbPromiseFn = callbackify(promiseFn);
+ try {
+ expect(promiseFn.name).toStrictEqual(obj);
+ } catch (error) {
+ done(error);
+ }
+
+ cbPromiseFn(
+ mustCall((err, ret) => {
+ try {
+ expect(ret).toBeUndefined();
+ if (err instanceof Error) {
+ if ("reason" in err) {
+ expect(!value).toBeTrue();
+ expect(err.code).toStrictEqual("ERR_FALSY_VALUE_REJECTION");
+ expect(err.reason).toStrictEqual(value);
+ } else {
+ expect(String(value)).toEndWith(err.message);
+ }
+ } else {
+ expect(err).toStrictEqual(value);
+ }
+
+ done();
+ } catch (error) {
+ done(error);
+ }
+ }),
+ );
+ });
+
+ it(`callback is thenable, value is ${String(value)}`, done => {
+ const { mustCall } = createCallCheckCtx(done);
+ function thenableFn() {
+ return {
+ then(onRes, onRej) {
+ onRej(value);
+ },
+ };
+ }
+
+ const cbThenableFn = callbackify(thenableFn);
+ cbThenableFn(
+ mustCall((err, ret) => {
+ try {
+ expect(ret).toBeUndefined();
+ if (err instanceof Error) {
+ if ("reason" in err) {
+ expect(!value).toBeTrue();
+ expect(err.code).toStrictEqual("ERR_FALSY_VALUE_REJECTION");
+ expect(err.reason).toStrictEqual(value);
+ } else {
+ expect(String(value)).toEndWith(err.message);
+ }
+ } else {
+ expect(err).toStrictEqual(value);
+ }
+
+ done();
+ } catch (error) {
+ done(error);
+ }
+ }),
+ );
+ });
+ }
+ });
+
+ describe("return value", () => {
+ for (const value of values) {
+ it(`callback is async function, value is ${String(value)}`, done => {
+ const { mustSucceed } = createCallCheckCtx(done);
+ async function asyncFn() {
+ return value;
+ }
+
+ const cbAsyncFn = callbackify(asyncFn);
+ cbAsyncFn(
+ mustSucceed(ret => {
+ try {
+ expect(ret).toStrictEqual(value);
+ expect(ret).toStrictEqual(value);
+
+ done();
+ } catch (error) {
+ done(error);
+ }
+ }),
+ );
+ });
+
+ it(`callback is promise, value is ${String(value)}`, done => {
+ const { mustSucceed } = createCallCheckCtx(done);
+ function promiseFn() {
+ return Promise.resolve(value);
+ }
+
+ const cbPromiseFn = callbackify(promiseFn);
+ cbPromiseFn(
+ mustSucceed(ret => {
+ try {
+ expect(ret).toStrictEqual(value);
+ done();
+ } catch (error) {
+ done(error);
+ }
+ }),
+ );
+ });
+
+ it(`callback is thenable, value is ${String(value)}`, done => {
+ const { mustSucceed } = createCallCheckCtx(done);
+ function thenableFn() {
+ return {
+ then(onRes, onRej) {
+ onRes(value);
+ },
+ };
+ }
+
+ const cbThenableFn = callbackify(thenableFn);
+ cbThenableFn(
+ mustSucceed(ret => {
+ try {
+ expect(ret).toStrictEqual(value);
+ done();
+ } catch (error) {
+ done(error);
+ }
+ }),
+ );
+ });
+ }
+ });
+
+ describe("arguments", () => {
+ for (const value of values) {
+ it(`callback is async function, value is ${String(value)}`, done => {
+ const { mustSucceed } = createCallCheckCtx(done);
+ async function asyncFn(arg) {
+ try {
+ expect(arg).toStrictEqual(value);
+ } catch (error) {
+ done(error);
+ }
+ return arg;
+ }
+
+ const cbAsyncFn = callbackify(asyncFn);
+ cbAsyncFn(
+ value,
+ mustSucceed(ret => {
+ try {
+ expect(ret).toStrictEqual(value);
+ done();
+ } catch (error) {
+ done(error);
+ }
+ }),
+ );
+ });
+
+ it(`callback is promise, value is ${String(value)}`, done => {
+ const { mustSucceed } = createCallCheckCtx(done);
+ function promiseFn(arg) {
+ try {
+ expect(arg).toStrictEqual(value);
+ } catch (error) {
+ done(error);
+ }
+
+ return Promise.resolve(arg);
+ }
+ const obj = {};
+ Object.defineProperty(promiseFn, "length", {
+ value: obj,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+ });
+ const cbPromiseFn = callbackify(promiseFn);
+ try {
+ expect(promiseFn.length).toStrictEqual(obj);
+ } catch (error) {
+ done(error);
+ }
+
+ cbPromiseFn(
+ value,
+ mustSucceed(ret => {
+ try {
+ expect(ret).toStrictEqual(value);
+ done();
+ } catch (error) {
+ done(error);
+ }
+ }),
+ );
+ });
+ }
+ });
+
+ describe("this binding", () => {
+ const value = "hello world";
+ it("callback is sync function", done => {
+ // TODO:
+ // const { mustSucceed } = createCallCheckCtx(done);
+ const iAmThis = {
+ fn(arg) {
+ try {
+ expect(this).toStrictEqual(iAmThis);
+ } catch (error) {
+ done(error);
+ }
+ return Promise.resolve(arg);
+ },
+ };
+
+ iAmThis.cbFn = callbackify(iAmThis.fn);
+ iAmThis.cbFn(value, function (rej, ret) {
+ try {
+ expect(ret).toStrictEqual(value);
+ expect(this).toStrictEqual(iAmThis);
+
+ done();
+ } catch (error) {
+ done(error);
+ }
+ });
+ });
+
+ it("callback is async function", done => {
+ const iAmThis = {
+ async fn(arg) {
+ try {
+ expect(this).toStrictEqual(iAmThis);
+ } catch (error) {
+ done(error);
+ }
+ return Promise.resolve(arg);
+ },
+ };
+
+ iAmThis.cbFn = callbackify(iAmThis.fn);
+ iAmThis.cbFn(value, function (rej, ret) {
+ try {
+ expect(ret).toStrictEqual(value);
+ expect(this).toStrictEqual(iAmThis);
+
+ done();
+ } catch (error) {
+ done(error);
+ }
+ });
+ });
+ });
+});
diff --git a/test/js/node/util/util.test.js b/test/js/node/util/util.test.js
index 45ecffda8..741b27d19 100644
--- a/test/js/node/util/util.test.js
+++ b/test/js/node/util/util.test.js
@@ -36,6 +36,23 @@ const deepStrictEqual = (...args) => {
// Tests adapted from https://github.com/nodejs/node/blob/main/test/parallel/test-util.js
describe("util", () => {
+ it("toUSVString", () => {
+ const strings = [
+ // Lone high surrogate
+ "ab\uD800",
+ "ab\uD800c",
+ // Lone low surrogate
+ "\uDFFFab",
+ "c\uDFFFab",
+ // Well-formed
+ "abc",
+ "ab\uD83D\uDE04c",
+ ];
+ const outputs = ["ab�", "ab�c", "�ab", "c�ab", "abc", "ab😄c"];
+ for (let i = 0; i < strings.length; i++) {
+ expect(util.toUSVString(strings[i])).toBe(outputs[i]);
+ }
+ });
describe("isArray", () => {
it("all cases", () => {
strictEqual(util.isArray([]), true);