From: Chris Duncan Date: Sat, 6 Sep 2025 04:54:04 +0000 (-0700) Subject: Change assert to class to improve type-checking reliably. X-Git-Tag: v0.10.5~24^2~11 X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=c2433b99f27a0be35ebba8d2e4165d86a47b0b2f;p=libnemo.git Change assert to class to improve type-checking reliably. --- diff --git a/test/GLOBALS.mjs b/test/GLOBALS.mjs index 2f718e5..8388c0c 100644 --- a/test/GLOBALS.mjs +++ b/test/GLOBALS.mjs @@ -195,78 +195,108 @@ export const test = NodeTestTest != null } } -export const assert = { - ok: (bool) => { - if (typeof bool !== 'boolean') { - throw new Error('Invalid assertion') - } - if (!bool) { - throw new Error(`test result falsy`, { cause: bool }) - } - return true - }, - exists: (a) => { +export class assert { + + /** + * @template T + * @param {T} a + * @returns {asserts a is NonNullable} + */ + static exists (a) { if (a == null) { throw new Error(`argument is ${typeof a}`) } - return a != null - }, - equal: (a, b) => { + } + + /** + * @template T, U + * @param {(T | U)} a + * @param {U} b + * @returns {asserts a is U} + */ + static equal (a, b) { if (a == null || b == null) { throw new Error(`assert.equal() will not compare null or undefined`) } if (a !== b) { throw new Error(`${a} not equal to ${b}`) } - return a === b - }, - notEqual: (a, b) => { + } + + /** + * @template T, U + * @param {(T | U)} a + * @param {U} b + * @returns {asserts a is NonNullable} + */ + static notEqual (a, b) { if (a == null || b == null) { throw new Error(`assert.notEqual() will not compare null or undefined`) } if (a === b) { throw new Error(`${a} equals ${b}`) } - return a !== b - }, - nullish: (a) => { + } + + /** + * @param {unknown} a + * @returns {asserts a is null | undefined} + */ + static nullish (a) { if (a != null) { const type = /^[aeiou]/i.test(typeof a) ? `an ${typeof a}` : `a ${typeof a}` throw new Error(`argument exists and is ${type}`) } - return a == null - }, - rejects: async (fn, msg) => { + } + + /** + * @param {unknown} bool + * @returns {asserts bool} + */ + static ok (bool) { + if (typeof bool !== 'boolean') { + throw new Error('Invalid assertion') + } + if (!bool) { + throw new Error(`test result falsy`, { cause: bool }) + } + } + + static async rejects (fn, msg) { if (fn.constructor.name === 'AsyncFunction') { fn = fn() } if (fn instanceof Promise) { try { await fn - } catch (err) { - return true - } - throw new Error(msg ?? 'expected async function to reject') + throw new Error(msg ?? 'expected async function to reject') + } catch {} } else { throw new Error(msg ?? 'expected async function') } - }, - resolves: async (fn, msg) => { + } + + static async resolves (fn, msg) { if (fn.constructor.name === 'AsyncFunction') { fn = fn() } if (fn instanceof Promise) { try { await fn - return true } catch (err) { throw new Error(msg ?? 'expected async function to resolve') } } else { throw new Error('expected async function') } - }, - throws: (fn, msg) => { + } + + /** + * @param {unknown} fn + * @param {any} msg + * @returns {asserts fn is Function} + */ + static throws (fn, msg) { if (typeof fn !== 'function') { throw new Error('expected function') } @@ -275,9 +305,7 @@ export const assert = { } try { fn() - } catch (err) { - return true - } - throw new Error(msg ?? `expected function to throw an exception`) + throw new Error(msg ?? `expected function to throw an exception`) + } catch {} } }