From 7252fd45289a91478974a846582b3bd522dfa094 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Weslley=20Ara=C3=BAjo?=
<46850407+wellwelwel@users.noreply.github.com>
Date: Sun, 24 Mar 2024 01:56:43 -0300
Subject: [PATCH] fix(assert): allow custom message for `ifError` (#147)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Thanks to @kusmin for the idea π€
---
README.md | 11 +-
src/modules/assert-promise.ts | 6 +-
src/modules/assert.ts | 8 +-
test/unit/asser-promise-no-message.test.ts | 191 +++++++
test/unit/assert-no-message.test.ts | 188 +++++++
test/unit/assert-promise.test.ts | 385 ++++++++++----
test/unit/assert.test.ts | 566 +++++++++++----------
7 files changed, 956 insertions(+), 399 deletions(-)
create mode 100644 test/unit/asser-promise-no-message.test.ts
create mode 100644 test/unit/assert-no-message.test.ts
diff --git a/README.md b/README.md
index a3f740a9..65396bb7 100644
--- a/README.md
+++ b/README.md
@@ -55,11 +55,11 @@ Enjoying **Poku**? Consider giving him a star βοΈ
Less verbose
High **isolation** level per file
No eval needed π
+ No global state
**Parallel** and **Sequential** runs ππ½ππ»
**Poku** is [**100%** documented](https://poku.io/docs)
Designed to be human-friendly
- **Poku** doesn't use a global state
Compatible with **Coverage** tools
[**Node.js**][node-version-url], [**Bun**][bun-version-url] and [**Deno**][deno-version-url] compatibility π©΅
@@ -190,11 +190,10 @@ deno run npm:poku
### Helpers
-- `beforeEach` and `afterEach`
-- `test`
-- `describe` and `log`
-- `listFiles`
-- `exit`
+- [**beforeEach**](https://poku.io/docs/category/beforeeach-and-aftereach) and [**afterEach**](https://poku.io/docs/category/beforeeach-and-aftereach)
+- [**test**](https://poku.io/docs/documentation/helpers/test)
+- [**describe**](https://poku.io/docs/documentation/helpers/describe)
+- _and much more_ β¨
[**See the complete documentation**](https://poku.io/docs).
diff --git a/src/modules/assert-promise.ts b/src/modules/assert-promise.ts
index 2eb1b10a..36db0f1e 100644
--- a/src/modules/assert-promise.ts
+++ b/src/modules/assert-promise.ts
@@ -100,12 +100,16 @@ const notDeepStrictEqual = async (
});
};
-const ifError = async (value: unknown): Promise => {
+const ifError = async (
+ value: unknown,
+ message?: ParseAssertionOptions['message']
+): Promise => {
await parseAssertion(
() => {
nodeAssert.ifError(value);
},
{
+ message,
defaultMessage: 'Expected no error, but received an error',
hideDiff: true,
throw: true,
diff --git a/src/modules/assert.ts b/src/modules/assert.ts
index cf87a424..cac39a5f 100644
--- a/src/modules/assert.ts
+++ b/src/modules/assert.ts
@@ -94,13 +94,17 @@ const notDeepStrictEqual = (
});
};
-const ifError = (value: unknown, message?: string): void => {
+const ifError = (
+ value: unknown,
+ message?: ParseAssertionOptions['message']
+): void => {
parseAssertion(
() => {
nodeAssert.ifError(value);
},
{
- defaultMessage: message || 'Expected no error, but received an error',
+ message,
+ defaultMessage: 'Expected no error, but received an error',
hideDiff: true,
throw: true,
}
diff --git a/test/unit/asser-promise-no-message.test.ts b/test/unit/asser-promise-no-message.test.ts
new file mode 100644
index 00000000..b008f0ee
--- /dev/null
+++ b/test/unit/asser-promise-no-message.test.ts
@@ -0,0 +1,191 @@
+import { nodeVersion } from '../../src/helpers/get-runtime.js';
+import { assertPromise as assert, describe, test } from '../../src/index.js';
+
+describe('Assert Promise Suite (No Message)', {
+ background: false,
+ icon: 'π¬',
+});
+
+test(() => {
+ assert(true);
+ assert(1);
+ assert('string');
+ assert([]);
+ assert({});
+ assert(() => {});
+ assert(3 > 2);
+});
+
+test(() => {
+ assert.ok(true);
+ assert.ok(1);
+ assert.ok('string');
+ assert.ok([]);
+ assert.ok({});
+ assert.ok(() => {});
+ assert.ok(3 > 2);
+});
+
+test(() => {
+ assert.equal(1, 1);
+ assert.equal('text', 'text');
+ assert.equal(2 + 2, 4);
+ assert.equal('Hello'.toUpperCase(), 'HELLO');
+});
+
+test(() => {
+ assert.deepEqual({ a: 1 }, { a: 1 });
+ assert.deepEqual([1, 2], [1, 2]);
+ assert.deepEqual([2, 3, 4], [2, 3, 4]);
+ assert.deepEqual([1, 2, 3].reverse(), [3, 2, 1]);
+});
+
+test(() => {
+ assert.strictEqual(1, 1);
+ assert.strictEqual('text', 'text');
+ assert.strictEqual(2 * 2, 4);
+});
+
+test(() => {
+ assert.deepStrictEqual({ a: 1 }, { a: 1 });
+ assert.deepStrictEqual([1, 2], [1, 2]);
+ assert.deepStrictEqual({ a: 1, b: 2 }, { a: 1, b: 2 });
+});
+
+test(() => {
+ assert.doesNotThrow(() => 1 + 1);
+});
+
+test(() => {
+ assert.notEqual(1, 2);
+ assert.notEqual(2 + 2, 5);
+ assert.notEqual('Hello'.toLowerCase(), 'HELLO');
+});
+
+test(() => {
+ assert.notStrictEqual(1, true);
+ assert.notStrictEqual(1, '1');
+ assert.notStrictEqual(2 * 2, '4');
+ assert.notStrictEqual(2, '2');
+});
+
+test(() => {
+ assert.notDeepEqual({ a: 1 }, { a: 2 });
+ assert.notDeepEqual([2, 3, 4], [4, 5, 6]);
+});
+
+test(() => {
+ assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
+ assert.notDeepStrictEqual([1, 2, 3], [1, 2, '3']);
+ assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
+});
+
+const callbackFunction = (cb: (err: Error | null, result?: string) => void) => {
+ cb(null, 'no error');
+};
+
+test(() => {
+ assert.ifError(null);
+ assert.ifError(undefined);
+});
+
+test(() => {
+ if (!nodeVersion || nodeVersion > 8) {
+ const obj = { a: 1 };
+
+ const functionThatThrows = () => {
+ throw new Error('Specific error');
+ };
+
+ test(() => {
+ assert.throws(() => {
+ throw new Error('error');
+ });
+ assert.throws(() => {
+ throw new Error('Test error');
+ });
+ assert.throws(() => {
+ throw new Error('Test error');
+ });
+ assert.throws(functionThatThrows, new Error('Specific error'));
+ assert.throws(functionThatThrows, /Specific error/);
+ assert.throws(
+ functionThatThrows,
+ (err) => err instanceof Error && err.message === 'Specific error'
+ );
+ });
+
+ test(() => {
+ assert.doesNotThrow(() => {
+ obj.a = 2;
+ });
+ assert.strictEqual(obj.a, 2);
+ assert.doesNotThrow(() => {
+ return 42;
+ });
+ assert.doesNotThrow(() =>
+ callbackFunction((err) => {
+ assert.ifError(err);
+ })
+ );
+ assert.doesNotThrow(() => 42);
+ assert.doesNotThrow(() => 'no error');
+ });
+ }
+});
+
+test(() => {
+ if (!nodeVersion || nodeVersion > 12) {
+ const text = 'sample text';
+
+ test(() => {
+ assert.match(text, /sample/);
+ });
+
+ test(() => {
+ assert.doesNotMatch(text, /notpresent/);
+ assert.doesNotMatch('abc', /123/);
+ assert.doesNotMatch('', /\d/);
+ assert.doesNotMatch('abc', /\d+/);
+ });
+ }
+});
+
+test(() => {
+ if (!nodeVersion || nodeVersion > 10) {
+ const asyncFunctionThatRejects = async () =>
+ await Promise.reject(new Error('Async error'));
+
+ const asyncFunctionThatResolves = () =>
+ Promise.resolve('Resolved successfully');
+
+ const asyncFunctionThatFails = () =>
+ new Promise((_, reject) => reject(new Error('Failed')));
+
+ const asyncFunctionThatCouldReject = () =>
+ new Promise((resolve) => resolve(undefined));
+
+ test(() => {
+ assert.rejects(
+ async () => await asyncFunctionThatFails(),
+ new Error('Failed')
+ );
+ assert.rejects(asyncFunctionThatRejects, new Error('Async error'));
+ assert.rejects(
+ () => Promise.reject('Simple rejection'),
+ (err) => err === 'Simple rejection'
+ );
+ assert.rejects(asyncFunctionThatRejects, new Error('Async error'));
+ });
+
+ test(() => {
+ assert.doesNotReject(asyncFunctionThatResolves);
+ assert.doesNotReject(Promise.resolve('Immediate resolve'));
+ assert.doesNotReject(asyncFunctionThatCouldReject);
+ assert.doesNotReject(() =>
+ Promise.resolve('Async function with no rejection')
+ );
+ assert.doesNotReject(asyncFunctionThatResolves);
+ });
+ }
+});
diff --git a/test/unit/assert-no-message.test.ts b/test/unit/assert-no-message.test.ts
new file mode 100644
index 00000000..93c3fd6e
--- /dev/null
+++ b/test/unit/assert-no-message.test.ts
@@ -0,0 +1,188 @@
+import { nodeVersion } from '../../src/helpers/get-runtime.js';
+import { assert, describe, test } from '../../src/index.js';
+
+describe('Assert Suite (No Message)', { background: false, icon: 'π¬' });
+
+test(() => {
+ assert(true);
+ assert(1);
+ assert('string');
+ assert([]);
+ assert({});
+ assert(() => {});
+ assert(3 > 2);
+});
+
+test(() => {
+ assert.ok(true);
+ assert.ok(1);
+ assert.ok('string');
+ assert.ok([]);
+ assert.ok({});
+ assert.ok(() => {});
+ assert.ok(3 > 2);
+});
+
+test(() => {
+ assert.equal(1, 1);
+ assert.equal('text', 'text');
+ assert.equal(2 + 2, 4);
+ assert.equal('Hello'.toUpperCase(), 'HELLO');
+});
+
+test(() => {
+ assert.deepEqual({ a: 1 }, { a: 1 });
+ assert.deepEqual([1, 2], [1, 2]);
+ assert.deepEqual([2, 3, 4], [2, 3, 4]);
+ assert.deepEqual([1, 2, 3].reverse(), [3, 2, 1]);
+});
+
+test(() => {
+ assert.strictEqual(1, 1);
+ assert.strictEqual('text', 'text');
+ assert.strictEqual(2 * 2, 4);
+});
+
+test(() => {
+ assert.deepStrictEqual({ a: 1 }, { a: 1 });
+ assert.deepStrictEqual([1, 2], [1, 2]);
+ assert.deepStrictEqual({ a: 1, b: 2 }, { a: 1, b: 2 });
+});
+
+test(() => {
+ assert.doesNotThrow(() => 1 + 1);
+});
+
+test(() => {
+ assert.notEqual(1, 2);
+ assert.notEqual(2 + 2, 5);
+ assert.notEqual('Hello'.toLowerCase(), 'HELLO');
+});
+
+test(() => {
+ assert.notStrictEqual(1, true);
+ assert.notStrictEqual(1, '1');
+ assert.notStrictEqual(2 * 2, '4');
+ assert.notStrictEqual(2, '2');
+});
+
+test(() => {
+ assert.notDeepEqual({ a: 1 }, { a: 2 });
+ assert.notDeepEqual([2, 3, 4], [4, 5, 6]);
+});
+
+test(() => {
+ assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
+ assert.notDeepStrictEqual([1, 2, 3], [1, 2, '3']);
+ assert.notDeepStrictEqual({ a: 1 }, { a: '1' });
+});
+
+const callbackFunction = (cb: (err: Error | null, result?: string) => void) => {
+ cb(null, 'no error');
+};
+
+test(() => {
+ assert.ifError(null);
+ assert.ifError(undefined);
+});
+
+test(() => {
+ if (!nodeVersion || nodeVersion > 8) {
+ const obj = { a: 1 };
+
+ const functionThatThrows = () => {
+ throw new Error('Specific error');
+ };
+
+ test(() => {
+ assert.throws(() => {
+ throw new Error('error');
+ });
+ assert.throws(() => {
+ throw new Error('Test error');
+ });
+ assert.throws(() => {
+ throw new Error('Test error');
+ });
+ assert.throws(functionThatThrows, new Error('Specific error'));
+ assert.throws(functionThatThrows, /Specific error/);
+ assert.throws(
+ functionThatThrows,
+ (err) => err instanceof Error && err.message === 'Specific error'
+ );
+ });
+
+ test(() => {
+ assert.doesNotThrow(() => {
+ obj.a = 2;
+ });
+ assert.strictEqual(obj.a, 2);
+ assert.doesNotThrow(() => {
+ return 42;
+ });
+ assert.doesNotThrow(() =>
+ callbackFunction((err) => {
+ assert.ifError(err);
+ })
+ );
+ assert.doesNotThrow(() => 42);
+ assert.doesNotThrow(() => 'no error');
+ });
+ }
+});
+
+test(() => {
+ if (!nodeVersion || nodeVersion > 12) {
+ const text = 'sample text';
+
+ test(() => {
+ assert.match(text, /sample/);
+ });
+
+ test(() => {
+ assert.doesNotMatch(text, /notpresent/);
+ assert.doesNotMatch('abc', /123/);
+ assert.doesNotMatch('', /\d/);
+ assert.doesNotMatch('abc', /\d+/);
+ });
+ }
+});
+
+test(() => {
+ if (!nodeVersion || nodeVersion > 10) {
+ const asyncFunctionThatRejects = async () =>
+ await Promise.reject(new Error('Async error'));
+
+ const asyncFunctionThatResolves = () =>
+ Promise.resolve('Resolved successfully');
+
+ const asyncFunctionThatFails = () =>
+ new Promise((_, reject) => reject(new Error('Failed')));
+
+ const asyncFunctionThatCouldReject = () =>
+ new Promise((resolve) => resolve(undefined));
+
+ test(() => {
+ assert.rejects(
+ async () => await asyncFunctionThatFails(),
+ new Error('Failed')
+ );
+ assert.rejects(asyncFunctionThatRejects, new Error('Async error'));
+ assert.rejects(
+ () => Promise.reject('Simple rejection'),
+ (err) => err === 'Simple rejection'
+ );
+ assert.rejects(asyncFunctionThatRejects, new Error('Async error'));
+ });
+
+ test(() => {
+ assert.doesNotReject(asyncFunctionThatResolves);
+ assert.doesNotReject(Promise.resolve('Immediate resolve'));
+ assert.doesNotReject(asyncFunctionThatCouldReject);
+ assert.doesNotReject(() =>
+ Promise.resolve('Async function with no rejection')
+ );
+ assert.doesNotReject(asyncFunctionThatResolves);
+ });
+ }
+});
diff --git a/test/unit/assert-promise.test.ts b/test/unit/assert-promise.test.ts
index 75a7415d..91efaa21 100644
--- a/test/unit/assert-promise.test.ts
+++ b/test/unit/assert-promise.test.ts
@@ -1,139 +1,308 @@
import { nodeVersion } from '../../src/helpers/get-runtime.js';
-import { assertPromise as assert, describe } from '../../src/index.js';
+import { assertPromise as assert, describe, test } from '../../src/index.js';
describe('Assert (Promise) Suite', { background: false, icon: 'π¬' });
-assert.ok(true, 'ok with true');
-assert.ok(1, 'ok with 1');
+test(() => {
+ assert(true, 'ok (default) with true');
+ assert(1, 'ok (default) with 1');
+ assert('string', 'ok (default) with string');
+ assert([], 'ok (default) with empty array');
+ assert({}, 'ok (default) with empty object');
+ assert(() => {}, 'ok (default) with empty function');
+ assert(3 > 2, 'ok (default) 3 should be greater than 2');
+});
-assert.equal(1, 1, 'equal with same numbers');
-assert.equal('text', 'text', 'equal with same strings');
+test(() => {
+ assert.ok(true, 'ok with true');
+ assert.ok(1, 'ok with 1');
+ assert.ok('string', 'ok with string');
+ assert.ok([], 'ok with empty array');
+ assert.ok({}, 'ok with empty object');
+ assert.ok(() => {}, 'ok with empty function');
+ assert.ok(3 > 2, '3 should be greater than 2');
+});
-assert.deepEqual({ a: 1 }, { a: 1 }, 'deepEqual with same objects');
-assert.deepEqual([1, 2], [1, 2], 'deepEqual with same arrays');
-
-assert.strictEqual(1, 1, 'strictEqual with same numbers');
-assert.strictEqual('text', 'text', 'strictEqual with same strings');
-
-assert.deepStrictEqual({ a: 1 }, { a: 1 }, 'deepStrictEqual with same objects');
-assert.deepStrictEqual([1, 2], [1, 2], 'deepStrictEqual with same arrays');
-
-assert.notEqual(1, 2, 'notEqual with different numbers');
-
-assert.notDeepEqual({ a: 1 }, { a: 2 }, 'notDeepEqual with different objects');
-
-assert.notStrictEqual(
- 1,
- '1',
- 'notStrictEqual with loosely equal but not strictly equal values'
-);
-
-assert.notDeepStrictEqual(
- { a: 1 },
- { a: '1' },
- 'notDeepStrictEqual with loosely equal but not strictly deep equal objects'
-);
-
-(async () => {
- const trueValue = true;
- await assert.ok(trueValue, 'Should resolve to true');
-
- const oneValue = 1;
- await assert.ok(oneValue, 'Should resolve to 1');
+test(() => {
+ assert.equal(1, 1, 'equal with same numbers');
+ assert.equal('text', 'text', 'equal with same strings');
+ assert.equal(2 + 2, 4, '2 + 2 should equal 4');
+ assert.equal(
+ 'Hello'.toUpperCase(),
+ 'HELLO',
+ 'toUpperCase should convert to all upper case'
+ );
+});
- const numberOne = 1;
- await assert.equal(numberOne, 1, 'Should resolve to equal 1');
+test(() => {
+ assert.deepEqual({ a: 1 }, { a: 1 }, 'deepEqual with same objects');
+ assert.deepEqual([1, 2], [1, 2], 'deepEqual with same arrays');
+ assert.deepEqual(
+ [2, 3, 4],
+ [2, 3, 4],
+ 'Arrays [2, 3, 4] should be deeply equal'
+ );
+ assert.deepEqual(
+ [1, 2, 3].reverse(),
+ [3, 2, 1],
+ 'Reversing [1, 2, 3] should give [3, 2, 1]'
+ );
+});
- const textValue = 'text';
- await assert.equal(textValue, 'text', 'Should resolve to equal "text"');
+test(() => {
+ assert.strictEqual(1, 1, 'strictEqual with same numbers');
+ assert.strictEqual('text', 'text', 'strictEqual with same strings');
+ assert.strictEqual(2 * 2, 4, '2 * 2 should be strictly equal to 4');
+});
- const objectValue = { a: 1 };
- await assert.deepEqual(
- objectValue,
+test(() => {
+ assert.deepStrictEqual(
{ a: 1 },
- 'Should resolve to deep equal the object'
+ { a: 1 },
+ 'deepStrictEqual with same objects'
+ );
+ assert.deepStrictEqual([1, 2], [1, 2], 'deepStrictEqual with same arrays');
+ assert.deepStrictEqual(
+ { a: 1, b: 2 },
+ { a: 1, b: 2 },
+ 'Objects { a: 1, b: 2 } should be deeply and strictly equal'
);
+});
+
+test(() => {
+ assert.doesNotThrow(() => 1 + 1, 'doesNotThrow with non-throwing function');
+});
- const arrayValue = [1, 2];
- await assert.deepEqual(
- arrayValue,
- [1, 2],
- 'Should resolve to deep equal the array'
+test(() => {
+ assert.notEqual(1, 2, 'notEqual with different numbers');
+ assert.notEqual(2 + 2, 5, '2 + 2 should not equal 5');
+ assert.notEqual(
+ 'Hello'.toLowerCase(),
+ 'HELLO',
+ 'toLowerCase should not match the upper case version'
);
+});
- const strictNumber = 1;
- await assert.strictEqual(
- strictNumber,
+test(() => {
+ assert.notStrictEqual(1, true, 'notStrictEqual with different types');
+ assert.notStrictEqual(
1,
- 'Should resolve to strictly equal 1'
+ '1',
+ 'notStrictEqual with loosely equal but not strictly equal values'
);
-
- const strictText = 'text';
- await assert.strictEqual(
- strictText,
- 'text',
- 'Should resolve to strictly equal "text"'
+ assert.notStrictEqual(
+ 2 * 2,
+ '4',
+ '2 * 2 should not be strictly equal to "4"'
);
+ assert.notStrictEqual(2, '2', '2 should not be strictly equal to "2"');
+});
- const deepStrictObject = { a: 1 };
- await assert.deepStrictEqual(
- deepStrictObject,
+test(() => {
+ assert.notDeepEqual(
{ a: 1 },
- 'Should resolve to deep strictly equal the object'
+ { a: 2 },
+ 'notDeepEqual with different objects'
+ );
+ assert.notDeepEqual(
+ [2, 3, 4],
+ [4, 5, 6],
+ 'Arrays [2, 3, 4] and [4, 5, 6] should not be deeply equal'
);
+});
- const deepStrictArray = [1, 2];
- await assert.deepStrictEqual(
- deepStrictArray,
- [1, 2],
- 'Should resolve to deep strictly equal the array'
+test(() => {
+ assert.notDeepStrictEqual(
+ { a: 1 },
+ { a: '1' },
+ 'notDeepStrictEqual with loosely equal but not strictly deep equal objects'
+ );
+ assert.notDeepStrictEqual(
+ [1, 2, 3],
+ [1, 2, '3'],
+ '[1, 2, 3] should not be deeply strictly equal to [1, 2, "3"]'
);
+ assert.notDeepStrictEqual(
+ { a: 1 },
+ { a: '1' },
+ 'Objects { a: 1 } and { a: "1" } should not be deeply and strictly equal'
+ );
+});
+
+const callbackFunction = (cb: (err: Error | null, result?: string) => void) => {
+ cb(null, 'no error');
+};
+test(() => {
+ assert.ifError(null, 'ifError did not throw an error for null');
+ assert.ifError(undefined, 'ifError did not throw an error for undefined');
+});
+
+test(() => {
if (!nodeVersion || nodeVersion > 8) {
- await assert.doesNotThrow(
- () => Promise.resolve('no error'),
- 'Should not throw an error'
- );
-
- await assert.doesNotThrow(
- () => 1 + 1,
- 'doesNotThrow with non-throwing function'
- );
-
- await assert.throws(() => {
- throw new Error('error');
- }, 'throws with throwing function');
+ const obj = { a: 1 };
+
+ const functionThatThrows = () => {
+ throw new Error('Specific error');
+ };
+
+ test(() => {
+ assert.throws(() => {
+ throw new Error('error');
+ }, 'throws with throwing function');
+ assert.throws(() => {
+ throw new Error('Test error');
+ }, 'Should throw an exception for a function that generates an error');
+ assert.throws(() => {
+ throw new Error('Test error');
+ }, 'Should throw an error for a function that actually throws');
+ assert.throws(
+ functionThatThrows,
+ new Error('Specific error'),
+ 'Should throw the specific error'
+ );
+
+ assert.throws(
+ functionThatThrows,
+ /Specific error/,
+ 'Should throw an error matching the regex'
+ );
+
+ assert.throws(
+ functionThatThrows,
+ (err) => err instanceof Error && err.message === 'Specific error',
+ 'Should throw an error where the message equals the specific string'
+ );
+ });
+
+ test(() => {
+ assert.doesNotThrow(() => {
+ obj.a = 2;
+ }, 'Changing property should not throw');
+ assert.strictEqual(obj.a, 2, 'Property a should be 2 after mutation');
+
+ // Test to check functions that do or do not throw errors
+ assert.doesNotThrow(() => {
+ return 42;
+ }, 'Should not throw an exception for a function returning 42');
+
+ assert.doesNotThrow(
+ () =>
+ callbackFunction((err) => {
+ assert.ifError(err);
+ }),
+ 'Should not throw an error for a callback function that does not error'
+ );
+
+ assert.doesNotThrow(
+ () => 42,
+ 'Should not throw an error for a function returning a number'
+ );
+
+ assert.doesNotThrow(
+ () => 'no error',
+ 'Should not throw an error for a function returning a string'
+ );
+
+ assert.doesNotThrow(
+ () => 'no error',
+ 'Should not throw an error for an async function that resolves'
+ );
+ });
}
+});
- if (!nodeVersion || nodeVersion > 10) {
- await assert.rejects(
- async () => await Promise.reject(new Error('error')),
- Error('error'),
- 'Should throw an error'
- );
+test(() => {
+ if (!nodeVersion || nodeVersion > 12) {
+ const text = 'sample text';
+
+ test(() => {
+ assert.match(text, /sample/, 'Text should match the regex');
+ });
+
+ test(() => {
+ assert.doesNotMatch(
+ text,
+ /notpresent/,
+ 'Text should not match the regex'
+ );
+ assert.doesNotMatch(
+ 'abc',
+ /123/,
+ 'String "abc" should not match the pattern /123/'
+ );
+ assert.doesNotMatch(
+ '',
+ /\d/,
+ 'Empty string should not match the pattern /d/'
+ );
+ assert.doesNotMatch(
+ 'abc',
+ /\d+/,
+ 'String "abc" should not match the pattern /d+/'
+ );
+ });
}
+});
- const notEqualNumber = 1;
- await assert.notEqual(notEqualNumber, 2, 'Should resolve to not equal 2');
+test(() => {
+ if (!nodeVersion || nodeVersion > 10) {
+ const asyncFunctionThatRejects = async () =>
+ await Promise.reject(new Error('Async error'));
- const notDeepEqualObject = { a: 1 };
- await assert.notDeepEqual(
- notDeepEqualObject,
- { a: 2 },
- 'Should resolve to not deep equal the object'
- );
+ const asyncFunctionThatResolves = () =>
+ Promise.resolve('Resolved successfully');
- const notStrictEqualNumber = 1;
- await assert.notStrictEqual(
- notStrictEqualNumber,
- '2',
- 'Should resolve to not strictly equal "2"'
- );
+ const asyncFunctionThatFails = () =>
+ new Promise((_, reject) => reject(new Error('Failed')));
- const notDeepStrictEqualObject = { a: 1 };
- await assert.notDeepStrictEqual(
- notDeepStrictEqualObject,
- { a: '2' },
- 'Should resolve to not deep strictly equal the object'
- );
-})();
+ const asyncFunctionThatCouldReject = () =>
+ new Promise((resolve) => resolve(undefined));
+
+ test(() => {
+ assert.rejects(
+ async () => await asyncFunctionThatFails(),
+ new Error('Failed'),
+ 'Async function should reject with an error'
+ );
+ assert.rejects(
+ asyncFunctionThatRejects,
+ new Error('Async error'),
+ 'Should reject with an Error object with "Async error" message'
+ );
+ assert.rejects(
+ () => Promise.reject('Simple rejection'),
+ (err) => err === 'Simple rejection',
+ 'Should handle rejection with a simple string message'
+ );
+ assert.rejects(
+ asyncFunctionThatRejects,
+ new Error('Async error'),
+ 'Should reject with the specified error message'
+ );
+ });
+
+ test(() => {
+ assert.doesNotReject(
+ asyncFunctionThatResolves,
+ 'Should not reject for a function that resolves'
+ );
+ assert.doesNotReject(
+ Promise.resolve('Immediate resolve'),
+ 'Should not reject for an immediately resolving promise'
+ );
+ assert.doesNotReject(
+ asyncFunctionThatCouldReject,
+ 'Should not reject for a function that could reject but resolves instead'
+ );
+ assert.doesNotReject(
+ () => Promise.resolve('Async function with no rejection'),
+ 'Should handle async functions that do not reject'
+ );
+ assert.doesNotReject(
+ asyncFunctionThatResolves,
+ 'Should handle cases with no specific error argument in doesNotReject'
+ );
+ });
+ }
+});
diff --git a/test/unit/assert.test.ts b/test/unit/assert.test.ts
index 1f9c96ad..2f030f25 100644
--- a/test/unit/assert.test.ts
+++ b/test/unit/assert.test.ts
@@ -1,306 +1,308 @@
import { nodeVersion } from '../../src/helpers/get-runtime.js';
-import { assert, describe } from '../../src/index.js';
+import { assert, describe, test } from '../../src/index.js';
describe('Assert Suite', { background: false, icon: 'π¬' });
-assert(true, 'ok (default) with true');
-assert(1, 'ok (default) with 1');
-assert('string', 'ok (default) with string');
-assert([], 'ok (default) with empty array');
-assert({}, 'ok (default) with empty object');
-assert(() => {}, 'ok (default) with empty function');
-
-assert.ok(true, 'ok with true');
-assert.ok(1, 'ok with 1');
-assert.ok('string', 'ok with string');
-assert.ok([], 'ok with empty array');
-assert.ok({}, 'ok with empty object');
-assert.ok(() => {}, 'ok with empty function');
-
-assert.equal(1, 1, 'equal with same numbers');
-assert.equal('text', 'text', 'equal with same strings');
-
-assert.deepEqual({ a: 1 }, { a: 1 }, 'deepEqual with same objects');
-assert.deepEqual([1, 2], [1, 2], 'deepEqual with same arrays');
-
-assert.strictEqual(1, 1, 'strictEqual with same numbers');
-assert.strictEqual('text', 'text', 'strictEqual with same strings');
-
-assert.deepStrictEqual({ a: 1 }, { a: 1 }, 'deepStrictEqual with same objects');
-assert.deepStrictEqual([1, 2], [1, 2], 'deepStrictEqual with same arrays');
-
-assert.doesNotThrow(() => 1 + 1, 'doesNotThrow with non-throwing function');
-
-assert.notEqual(1, 2, 'notEqual with different numbers');
-
-assert.notStrictEqual(1, true, 'notStrictEqual with different types');
-
-assert.notDeepEqual({ a: 1 }, { a: 2 }, 'notDeepEqual with different objects');
-
-assert.notStrictEqual(
- 1,
- '1',
- 'notStrictEqual with loosely equal but not strictly equal values'
-);
-
-assert.notDeepStrictEqual(
- { a: 1 },
- { a: '1' },
- 'notDeepStrictEqual with loosely equal but not strictly deep equal objects'
-);
-
-// Simple tests to check boolean values
-assert.ok(true, 'Should be true');
-assert.ok(!false, 'Negating false should be true');
-
-// Test to check equality of numbers
-assert.equal(2 + 2, 4, '2 + 2 should equal 4');
-assert.notEqual(2 + 2, 5, '2 + 2 should not equal 5');
-
-// Test to check strict equality
-assert.strictEqual(2 * 2, 4, '2 * 2 should be strictly equal to 4');
-assert.notStrictEqual(2 * 2, '4', '2 * 2 should not be strictly equal to "4"');
-
-// Test to check deep equality
-assert.deepEqual(
- [2, 3, 4],
- [2, 3, 4],
- 'Arrays [2, 3, 4] should be deeply equal'
-);
-assert.notDeepEqual(
- [2, 3, 4],
- [4, 5, 6],
- 'Arrays [2, 3, 4] and [4, 5, 6] should not be deeply equal'
-);
-
-// Tests to check deep and strict equality
-assert.deepStrictEqual(
- { a: 1, b: 2 },
- { a: 1, b: 2 },
- 'Objects { a: 1, b: 2 } should be deeply and strictly equal'
-);
-assert.notDeepStrictEqual(
- { a: 1 },
- { a: '1' },
- 'Objects { a: 1 } and { a: "1" } should not be deeply and strictly equal'
-);
-
-// Testing numeric comparisons
-assert.ok(3 > 2, '3 should be greater than 2');
-assert.notStrictEqual(2, '2', '2 should not be strictly equal to "2"');
-
-// Testing string operations
-assert.equal(
- 'Hello'.toUpperCase(),
- 'HELLO',
- 'toUpperCase should convert to all upper case'
-);
-assert.notEqual(
- 'Hello'.toLowerCase(),
- 'HELLO',
- 'toLowerCase should not match the upper case version'
-);
-
-// Testing array operations
-assert.deepEqual(
- [1, 2, 3].reverse(),
- [3, 2, 1],
- 'Reversing [1, 2, 3] should give [3, 2, 1]'
-);
-assert.notDeepStrictEqual(
- [1, 2, 3],
- [1, 2, '3'],
- '[1, 2, 3] should not be deeply strictly equal to [1, 2, "3"]'
-);
-
-// Testing object mutations
-const obj = { a: 1 };
-
-// Testing async functions
-
-describe('ifError Test Suite', { background: false, icon: 'π¬' });
-
-assert.ifError(null, 'ifError did not throw an error for null');
-assert.ifError(undefined, 'ifError did not throw an error for undefined');
-function callbackFunction(cb: (err: Error | null, result?: string) => void) {
- // Simula uma operação que não lança um erro
- cb(null, 'no error');
-}
-if (!nodeVersion || nodeVersion > 8) {
- describe('doesNotThrow Test Suite', { background: false, icon: 'π¬' });
-
- assert.throws(() => {
- throw new Error('error');
- }, 'throws with throwing function');
-
- assert.doesNotThrow(() => {
- obj.a = 2;
- }, 'Changing property should not throw');
- assert.strictEqual(obj.a, 2, 'Property a should be 2 after mutation');
-
- // Test to check functions that do or do not throw errors
- assert.doesNotThrow(() => {
- return 42;
- }, 'Should not throw an exception for a function returning 42');
- assert.throws(() => {
- throw new Error('Test error');
- }, 'Should throw an exception for a function that generates an error');
-
- assert.doesNotThrow(
- () =>
- callbackFunction((err) => {
- assert.ifError(err);
- }),
- 'Should not throw an error for a callback function that does not error'
+test(() => {
+ assert(true, 'ok (default) with true');
+ assert(1, 'ok (default) with 1');
+ assert('string', 'ok (default) with string');
+ assert([], 'ok (default) with empty array');
+ assert({}, 'ok (default) with empty object');
+ assert(() => {}, 'ok (default) with empty function');
+ assert(3 > 2, 'ok (default) 3 should be greater than 2');
+});
+
+test(() => {
+ assert.ok(true, 'ok with true');
+ assert.ok(1, 'ok with 1');
+ assert.ok('string', 'ok with string');
+ assert.ok([], 'ok with empty array');
+ assert.ok({}, 'ok with empty object');
+ assert.ok(() => {}, 'ok with empty function');
+ assert.ok(3 > 2, '3 should be greater than 2');
+});
+
+test(() => {
+ assert.equal(1, 1, 'equal with same numbers');
+ assert.equal('text', 'text', 'equal with same strings');
+ assert.equal(2 + 2, 4, '2 + 2 should equal 4');
+ assert.equal(
+ 'Hello'.toUpperCase(),
+ 'HELLO',
+ 'toUpperCase should convert to all upper case'
);
-
- assert.doesNotThrow(
- () => 42,
- 'Should not throw an error for a function returning a number'
+});
+
+test(() => {
+ assert.deepEqual({ a: 1 }, { a: 1 }, 'deepEqual with same objects');
+ assert.deepEqual([1, 2], [1, 2], 'deepEqual with same arrays');
+ assert.deepEqual(
+ [2, 3, 4],
+ [2, 3, 4],
+ 'Arrays [2, 3, 4] should be deeply equal'
);
-
- assert.doesNotThrow(
- () => 'no error',
- 'Should not throw an error for a function returning a string'
+ assert.deepEqual(
+ [1, 2, 3].reverse(),
+ [3, 2, 1],
+ 'Reversing [1, 2, 3] should give [3, 2, 1]'
);
-
- assert.throws(() => {
- throw new Error('Test error');
- }, 'Should throw an error for a function that actually throws');
-
- assert.doesNotThrow(
- () => 'no error',
- 'Should not throw an error for an async function that resolves'
+});
+
+test(() => {
+ assert.strictEqual(1, 1, 'strictEqual with same numbers');
+ assert.strictEqual('text', 'text', 'strictEqual with same strings');
+ assert.strictEqual(2 * 2, 4, '2 * 2 should be strictly equal to 4');
+});
+
+test(() => {
+ assert.deepStrictEqual(
+ { a: 1 },
+ { a: 1 },
+ 'deepStrictEqual with same objects'
);
-
- describe('throws Test Suite', { background: false, icon: 'π¬' });
-
- const functionThatThrows = () => {
- throw new Error('Specific error');
- };
-
- assert.throws(
- functionThatThrows,
- new Error('Specific error'),
- 'Should throw the specific error'
+ assert.deepStrictEqual([1, 2], [1, 2], 'deepStrictEqual with same arrays');
+ assert.deepStrictEqual(
+ { a: 1, b: 2 },
+ { a: 1, b: 2 },
+ 'Objects { a: 1, b: 2 } should be deeply and strictly equal'
);
-
- assert.throws(
- functionThatThrows,
- /Specific error/,
- 'Should throw an error matching the regex'
+});
+
+test(() => {
+ assert.doesNotThrow(() => 1 + 1, 'doesNotThrow with non-throwing function');
+});
+
+test(() => {
+ assert.notEqual(1, 2, 'notEqual with different numbers');
+ assert.notEqual(2 + 2, 5, '2 + 2 should not equal 5');
+ assert.notEqual(
+ 'Hello'.toLowerCase(),
+ 'HELLO',
+ 'toLowerCase should not match the upper case version'
);
-
- assert.throws(
- functionThatThrows,
- // @ts-expect-error: Testing unexpected error type for demonstration
- (err) => err.message === 'Specific error',
- 'Should throw an error where the message equals the specific string'
+});
+
+test(() => {
+ assert.notStrictEqual(1, true, 'notStrictEqual with different types');
+ assert.notStrictEqual(
+ 1,
+ '1',
+ 'notStrictEqual with loosely equal but not strictly equal values'
);
-}
-
-if (!nodeVersion || nodeVersion > 12) {
- describe('match Test Suite', { background: false, icon: 'π¬' });
-
- // Testing regex matches
- const text = 'sample text';
- assert.match(text, /sample/, 'Text should match the regex');
- assert.doesNotMatch(text, /notpresent/, 'Text should not match the regex');
-
- describe('doesNotMatch Test Suite', { background: false, icon: 'π¬' });
- assert.doesNotMatch(
- 'abc',
- /123/,
- 'String "abc" should not match the pattern /123/'
- );
-
- assert.doesNotMatch(
- '',
- /\d/,
- 'Empty string should not match the pattern /d/'
+ assert.notStrictEqual(
+ 2 * 2,
+ '4',
+ '2 * 2 should not be strictly equal to "4"'
);
-
- assert.doesNotMatch(
- 'abc',
- /\d+/,
- 'String "abc" should not match the pattern /d+/'
+ assert.notStrictEqual(2, '2', '2 should not be strictly equal to "2"');
+});
+
+test(() => {
+ assert.notDeepEqual(
+ { a: 1 },
+ { a: 2 },
+ 'notDeepEqual with different objects'
);
-}
-
-if (!nodeVersion || nodeVersion > 10) {
- describe('rejects Test Suite', { background: false, icon: 'π¬' });
- const asyncFunctionThatRejects = async () => {
- await Promise.reject(new Error('Async error'));
- };
- const asyncFunctionThatFails = () =>
- new Promise((_, reject) =>
- setTimeout(() => reject(new Error('Failed')), 100)
- );
-
- assert.rejects(
- // eslint-disable-next-line require-await
- async () => asyncFunctionThatFails(),
- new Error('Failed'),
- 'Async function should reject with an error'
+ assert.notDeepEqual(
+ [2, 3, 4],
+ [4, 5, 6],
+ 'Arrays [2, 3, 4] and [4, 5, 6] should not be deeply equal'
);
- assert.rejects(
- asyncFunctionThatRejects,
- new Error('Async error'),
- 'Should reject with an Error object with "Async error" message'
+});
+
+test(() => {
+ assert.notDeepStrictEqual(
+ { a: 1 },
+ { a: '1' },
+ 'notDeepStrictEqual with loosely equal but not strictly deep equal objects'
);
- assert.rejects(
- () => Promise.reject('Simple rejection'),
- (err) => err === 'Simple rejection',
- 'Should handle rejection with a simple string message'
+ assert.notDeepStrictEqual(
+ [1, 2, 3],
+ [1, 2, '3'],
+ '[1, 2, 3] should not be deeply strictly equal to [1, 2, "3"]'
);
-
- assert.rejects(
- asyncFunctionThatRejects,
- new Error('Async error'),
- 'Should reject with the specified error message'
+ assert.notDeepStrictEqual(
+ { a: 1 },
+ { a: '1' },
+ 'Objects { a: 1 } and { a: "1" } should not be deeply and strictly equal'
);
+});
- describe('doesNotReject Test Suite', { background: false, icon: 'π¬' });
- // Test where the promise resolves successfully
- const asyncFunctionThatResolves = () => {
- return Promise.resolve('Resolved successfully');
- };
+const callbackFunction = (cb: (err: Error | null, result?: string) => void) => {
+ cb(null, 'no error');
+};
+
+test(() => {
+ assert.ifError(null, 'ifError did not throw an error for null');
+ assert.ifError(undefined, 'ifError did not throw an error for undefined');
+});
+
+test(() => {
+ if (!nodeVersion || nodeVersion > 8) {
+ const obj = { a: 1 };
+
+ const functionThatThrows = () => {
+ throw new Error('Specific error');
+ };
+
+ test(() => {
+ assert.throws(() => {
+ throw new Error('error');
+ }, 'throws with throwing function');
+ assert.throws(() => {
+ throw new Error('Test error');
+ }, 'Should throw an exception for a function that generates an error');
+ assert.throws(() => {
+ throw new Error('Test error');
+ }, 'Should throw an error for a function that actually throws');
+ assert.throws(
+ functionThatThrows,
+ new Error('Specific error'),
+ 'Should throw the specific error'
+ );
+
+ assert.throws(
+ functionThatThrows,
+ /Specific error/,
+ 'Should throw an error matching the regex'
+ );
+
+ assert.throws(
+ functionThatThrows,
+ (err) => err instanceof Error && err.message === 'Specific error',
+ 'Should throw an error where the message equals the specific string'
+ );
+ });
- // This should pass because the function resolves
- assert.doesNotReject(
- asyncFunctionThatResolves,
- 'Should not reject for a function that resolves'
- );
+ test(() => {
+ assert.doesNotThrow(() => {
+ obj.a = 2;
+ }, 'Changing property should not throw');
+ assert.strictEqual(obj.a, 2, 'Property a should be 2 after mutation');
+
+ // Test to check functions that do or do not throw errors
+ assert.doesNotThrow(() => {
+ return 42;
+ }, 'Should not throw an exception for a function returning 42');
+
+ assert.doesNotThrow(
+ () =>
+ callbackFunction((err) => {
+ assert.ifError(err);
+ }),
+ 'Should not throw an error for a callback function that does not error'
+ );
+
+ assert.doesNotThrow(
+ () => 42,
+ 'Should not throw an error for a function returning a number'
+ );
+
+ assert.doesNotThrow(
+ () => 'no error',
+ 'Should not throw an error for a function returning a string'
+ );
+
+ assert.doesNotThrow(
+ () => 'no error',
+ 'Should not throw an error for an async function that resolves'
+ );
+ });
+ }
+});
- // Test with a promise that resolves immediately
- assert.doesNotReject(
- Promise.resolve('Immediate resolve'),
- 'Should not reject for an immediately resolving promise'
- );
+test(() => {
+ if (!nodeVersion || nodeVersion > 12) {
+ const text = 'sample text';
- // Test where the promise could reject but does not
- const asyncFunctionThatCouldReject = () => {
- return new Promise((resolve) => {
- setTimeout(() => {
- resolve('Delayed resolve');
- }, 100);
+ test(() => {
+ assert.match(text, /sample/, 'Text should match the regex');
});
- };
- assert.doesNotReject(
- asyncFunctionThatCouldReject,
- 'Should not reject for a function that could reject but resolves instead'
- );
-
- // Test using async function but with no rejection happening
- assert.doesNotReject(
- () => Promise.resolve('Async function with no rejection'),
- 'Should handle async functions that do not reject'
- );
+ test(() => {
+ assert.doesNotMatch(
+ text,
+ /notpresent/,
+ 'Text should not match the regex'
+ );
+ assert.doesNotMatch(
+ 'abc',
+ /123/,
+ 'String "abc" should not match the pattern /123/'
+ );
+ assert.doesNotMatch(
+ '',
+ /\d/,
+ 'Empty string should not match the pattern /d/'
+ );
+ assert.doesNotMatch(
+ 'abc',
+ /\d+/,
+ 'String "abc" should not match the pattern /d+/'
+ );
+ });
+ }
+});
+
+test(() => {
+ if (!nodeVersion || nodeVersion > 10) {
+ const asyncFunctionThatRejects = async () =>
+ await Promise.reject(new Error('Async error'));
+
+ const asyncFunctionThatResolves = () =>
+ Promise.resolve('Resolved successfully');
+
+ const asyncFunctionThatFails = () =>
+ new Promise((_, reject) => reject(new Error('Failed')));
+
+ const asyncFunctionThatCouldReject = () =>
+ new Promise((resolve) => resolve(undefined));
+
+ test(() => {
+ assert.rejects(
+ async () => await asyncFunctionThatFails(),
+ new Error('Failed'),
+ 'Async function should reject with an error'
+ );
+ assert.rejects(
+ asyncFunctionThatRejects,
+ new Error('Async error'),
+ 'Should reject with an Error object with "Async error" message'
+ );
+ assert.rejects(
+ () => Promise.reject('Simple rejection'),
+ (err) => err === 'Simple rejection',
+ 'Should handle rejection with a simple string message'
+ );
+ assert.rejects(
+ asyncFunctionThatRejects,
+ new Error('Async error'),
+ 'Should reject with the specified error message'
+ );
+ });
- // Ensure it handles cases where no arguments are passed to doesNotReject
- assert.doesNotReject(
- asyncFunctionThatResolves,
- 'Should handle cases with no specific error argument in doesNotReject'
- );
-}
+ test(() => {
+ assert.doesNotReject(
+ asyncFunctionThatResolves,
+ 'Should not reject for a function that resolves'
+ );
+ assert.doesNotReject(
+ Promise.resolve('Immediate resolve'),
+ 'Should not reject for an immediately resolving promise'
+ );
+ assert.doesNotReject(
+ asyncFunctionThatCouldReject,
+ 'Should not reject for a function that could reject but resolves instead'
+ );
+ assert.doesNotReject(
+ () => Promise.resolve('Async function with no rejection'),
+ 'Should handle async functions that do not reject'
+ );
+ assert.doesNotReject(
+ asyncFunctionThatResolves,
+ 'Should handle cases with no specific error argument in doesNotReject'
+ );
+ });
+ }
+});