diff --git a/.github/workflows/ci-module.yml b/.github/workflows/ci-module.yml index 9dc4315..54426ca 100644 --- a/.github/workflows/ci-module.yml +++ b/.github/workflows/ci-module.yml @@ -10,3 +10,5 @@ on: jobs: test: uses: hapijs/.github/.github/workflows/ci-module.yml@master + with: + min-node-version: 14 diff --git a/API.md b/API.md index cb39273..7f0f1fb 100755 --- a/API.md +++ b/API.md @@ -625,7 +625,7 @@ and compared to the provided optional requirements where: - `message` a string or regular expression matching the rejected error `message` property. Note that a string must provide a full match. -Returns the rejected error object. +Returns a promise resolving to the rejected error object. ```js const NodeUtil = require('util'); diff --git a/LICENSE.md b/LICENSE.md index 59e4358..244fd32 100755 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,7 @@ -Copyright (c) 2014-2012, Sideway Inc, and project contributors -Copyright (c) 2014, Walmart -Copyright (c) 2011-2014 Jake Luer +Copyright (c) 2014-2022, Project contributors +Copyright (c) 2014-2020, Sideway Inc +Copyright (c) 2014, Walmart +Copyright (c) 2011-2014 Jake Luer All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/lib/index.d.ts b/lib/index.d.ts index 4759610..f9de592 100755 --- a/lib/index.d.ts +++ b/lib/index.d.ts @@ -504,6 +504,16 @@ declare namespace expect { */ above(value: T): Assertion; + /** + * Asserts that the reference value is within a delta difference from the provided value. + * + * @param value - the value to compare to. + * @param delta - the delta +/- range value. + * + * @returns assertion chain object. + */ + about(value: T, delta: number): Assertion; + /** * Asserts that the reference value is greater than (>) the provided value. * @@ -616,10 +626,10 @@ declare namespace expect { * @param type - constructor function the error must be an instance of. * @param message - string or regular expression the error message must match. * - * @returns rejected value. + * @returns a promise resolving to the rejected value. */ - reject(type: Class, message?: string | RegExp): E; - reject(message?: string | RegExp): E; + reject(type: Class, message?: string | RegExp): Promise; + reject(message?: string | RegExp): Promise; /** * Asserts that the Promise reference value rejects with an exception when called. @@ -627,10 +637,10 @@ declare namespace expect { * @param type - constructor function the error must be an instance of. * @param message - string or regular expression the error message must match. * - * @returns rejected value. + * @returns a promise resolving to the rejected value. */ - rejects(type: Class, message?: string | RegExp): E; - rejects(message?: string | RegExp): E; + rejects(type: Class, message?: string | RegExp): Promise; + rejects(message?: string | RegExp): Promise; } interface Not_PromiseAssertion extends BaseAssertion { @@ -638,15 +648,15 @@ declare namespace expect { /** * Asserts that the Promise reference value rejects with an exception when called. * - * @returns null. + * @returns a promise resolving to null. */ - reject(): null; + reject(): Promise; /** * Asserts that the Promise reference value rejects with an exception when called. * - * @returns null. + * @returns a promise resolving to null. */ - rejects(): null; + rejects(): Promise; } } diff --git a/lib/index.js b/lib/index.js index c10ff4e..cd20268 100755 --- a/lib/index.js +++ b/lib/index.js @@ -50,9 +50,9 @@ internals.atUnnamedRx = /^\s*at (?:async )?(.+)\:(\d+)\:(\d+)\)?$/; exports.thrownAt = function (error) { - error = error || new Error(); + error = error ?? new Error(); const stack = typeof error.stack === 'string' ? error.stack : ''; - const frame = stack.replace(error.toString(), '').split('\n').slice(1).filter(internals.filterLocal)[0] || ''; + const frame = stack.replace(error.toString(), '').split('\n').slice(1).filter(internals.filterLocal)[0] ?? ''; const at = frame.match(frame.includes('(') ? internals.atNamedRx : internals.atUnnamedRx); return Array.isArray(at) ? { filename: at[1], @@ -83,7 +83,7 @@ exports.expect = function (value, prefix) { internals.Assertion = function (ref, prefix, location, at) { this._ref = ref; - this._prefix = prefix || ''; + this._prefix = prefix ?? ''; this._location = location; this._at = at; this._flags = {}; @@ -135,7 +135,7 @@ internals.Assertion.prototype.assert = function (result, verb, actual, expected) Error.captureStackTrace(error, this.assert); error.actual = actual; error.expected = expected; - error.at = exports.thrownAt(error) || this._at; + error.at = exports.thrownAt(error) ?? this._at; throw error; }; @@ -193,7 +193,7 @@ internals.addMethod = function (names, fn) { internals.addMethod('error', function (...args /* type, message */) { const type = args.length && typeof args[0] !== 'string' && !(args[0] instanceof RegExp) ? args[0] : Error; - const lastArg = args[1] || args[0]; + const lastArg = args[1] ?? args[0]; const message = typeof lastArg === 'string' || lastArg instanceof RegExp ? lastArg : null; const err = this._ref; @@ -296,7 +296,7 @@ internals.addMethod('length', internals.length); internals.equal = function (value, options) { - options = options || {}; + options = options ?? {}; const settings = Hoek.applyToDefaults({ prototype: exports.settings.comparePrototypes, deepFunction: true }, options); const compare = this._flags.shallow ? (a, b) => a === b @@ -356,7 +356,7 @@ internals.between = function (from, to) { internals.addMethod('between', internals.between); -internals.above = function (value, delta) { +internals.about = function (value, delta) { internals.assert(this, internals.type(this._ref) === 'number', 'Can only assert about on numbers'); internals.assert(this, internals.type(value) === 'number' && internals.type(delta) === 'number', 'About assertion requires two number arguments'); @@ -364,7 +364,7 @@ internals.above = function (value, delta) { return this.assert(Math.abs(this._ref - value) <= delta, 'be about ' + value + ' \u00b1' + delta); }; -internals.addMethod('about', internals.above); +internals.addMethod('about', internals.about); internals.instanceof = function (type) { @@ -397,7 +397,7 @@ internals.throw = function (...args /* type, message */) { internals.assert(this, !this._flags.not || !args.length, 'Cannot specify arguments when expecting not to throw'); const type = args.length && typeof args[0] !== 'string' && !(args[0] instanceof RegExp) ? args[0] : null; - const lastArg = args[1] || args[0]; + const lastArg = args[1] ?? args[0]; const message = typeof lastArg === 'string' || lastArg instanceof RegExp ? lastArg : null; let thrown = false; @@ -413,7 +413,7 @@ internals.throw = function (...args /* type, message */) { } if (message !== null) { - const error = err.message || ''; + const error = err.message ?? ''; this.assert(typeof message === 'string' ? error === message : error.match(message), 'throw an error with specified message', error, message); } @@ -433,7 +433,7 @@ internals.reject = async function (...args/* type, message */) { internals.assert(this, internals.isPromise(this._ref), 'Can only assert reject on promises'); const type = args.length && typeof args[0] !== 'string' && !(args[0] instanceof RegExp) ? args[0] : null; - const lastArg = args[1] || args[0]; + const lastArg = args[1] ?? args[0]; const message = typeof lastArg === 'string' || lastArg instanceof RegExp ? lastArg : null; let thrown = null; @@ -456,7 +456,7 @@ internals.reject = async function (...args/* type, message */) { } if (message !== null) { - const error = thrown.message || ''; + const error = thrown.message ?? ''; this.assert(typeof message === 'string' ? error === message : error.match(message), 'reject with an error with specified message', error, message); } @@ -479,7 +479,7 @@ internals.addMethod(['reject', 'rejects'], internals.reject); internals.isPromise = function (promise) { - return promise && typeof promise.then === 'function'; + return typeof promise?.then === 'function'; }; diff --git a/package.json b/package.json index 78eba7d..5ed5047 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@hapi/code", "description": "assertion library", - "version": "8.0.7", + "version": "9.0.3", "repository": "git://github.com/hapijs/code", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -19,12 +19,13 @@ ] }, "dependencies": { - "@hapi/hoek": "9.x.x" + "@hapi/hoek": "^11.0.2" }, "devDependencies": { - "@hapi/eslint-plugin": "*", - "@hapi/lab": "24.x.x", - "typescript": "~4.0.2" + "@hapi/eslint-plugin": "^6.0.0", + "@hapi/lab": "^25.0.1", + "@types/node": "^17.0.25", + "typescript": "~4.6.3" }, "scripts": { "test": "lab -t 100 -L -Y", diff --git a/test/index.js b/test/index.js index 1471f28..dbe21c8 100755 --- a/test/index.js +++ b/test/index.js @@ -586,9 +586,9 @@ describe('expect()', () => { it('invalidates assertion (anonymous type)', () => { - const Custom = function () { }; - Util.inherits(Custom, Error); - delete Custom.name; // Ensure that the type is anonymous + const Custom = class extends Error { + static name = undefined; // Ensure that the type is anonymous + }; try { Code.expect(error).to.be.an.error(Custom); diff --git a/test/index.ts b/test/index.ts index d756dd2..12e9476 100755 --- a/test/index.ts +++ b/test/index.ts @@ -186,8 +186,8 @@ Code.expect(type2).to.equal({ a: [1] }, { skip: ['c'] }); const rejection = Promise.reject(new Error('Oh no!')); -await expect.type>(Code.expect(rejection).to.reject('Oh no!')); -await expect.type>(Code.expect(rejection).rejects('Oh no!')); +expect.type>(Code.expect(rejection).to.reject('Oh no!')); +expect.type>(Code.expect(rejection).rejects('Oh no!')); class CustomError extends Error { } @@ -200,10 +200,10 @@ Code.expect(throws).to.throw(CustomError, 'Oh no!'); Code.expect(() => { }).to.not.throw().and.to.be.a.function(); const typedRejection = Promise.reject(new CustomError('Oh no!')); -await expect.type(Code.expect(typedRejection).to.reject(CustomError, 'Oh no!')); -await expect.type(Code.expect(typedRejection).rejects(CustomError, 'Oh no!')); +expect.type>(Code.expect(typedRejection).to.reject(CustomError, 'Oh no!')); +expect.type>(Code.expect(typedRejection).rejects(CustomError, 'Oh no!')); -await expect.type(Code.expect(Promise.resolve(true)).to.not.reject()); +expect.type>(Code.expect(Promise.resolve(true)).to.not.reject()); function foo(): number | undefined { return 123;