Skip to content

Commit

Permalink
Refactor AssertError (#382)
Browse files Browse the repository at this point in the history
Co-authored-by: devin ivy <[email protected]>
  • Loading branch information
kanongil and devinivy authored Dec 13, 2022
1 parent 941a932 commit 35e613a
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 40 deletions.
14 changes: 11 additions & 3 deletions lib/assert.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
'use strict';

const AssertError = require('./error');
const Errors = require('./errors');
const Stringify = require('./stringify');


const internals = {};


module.exports = function (condition, ...args) {
const assert = module.exports = function (condition, ...args) {

if (condition) {
return;
Expand All @@ -18,5 +19,12 @@ module.exports = function (condition, ...args) {
throw args[0];
}

throw new AssertError(args);
const msgs = args
.filter((arg) => arg !== '')
.map((arg) => {

return typeof arg === 'string' ? arg : arg instanceof Error ? arg.message : Stringify(arg);
});

throw new Errors.AssertError(msgs.join(' '), assert);
};
26 changes: 0 additions & 26 deletions lib/error.js

This file was deleted.

18 changes: 18 additions & 0 deletions lib/errors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';

const internals = {};


exports.AssertError = class extends Error {

name = 'AssertError';

constructor(message, ctor) {

super(message || 'Unknown error');

if (typeof Error.captureStackTrace === 'function') { // $lab:coverage:ignore$
Error.captureStackTrace(this, ctor);
}
}
};
9 changes: 9 additions & 0 deletions lib/index.d.ts
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,15 @@ export function assert(condition: any, error: Error): asserts condition;
export function assert(condition: any, ...args: any): asserts condition;


/**
* Assertion Error as thrown from Hoek.assert().
*/
export class AssertError extends Error {

name: 'AssertError';
}


/**
* A benchmarking timer, using the internal node clock for maximum accuracy.
*/
Expand Down
4 changes: 2 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ exports.applyToDefaults = require('./applyToDefaults');

exports.assert = require('./assert');

exports.AssertError = require('./errors').AssertError;

exports.Bench = require('./bench');

exports.block = require('./block');
Expand All @@ -14,8 +16,6 @@ exports.contain = require('./contain');

exports.deepEqual = require('./deepEqual');

exports.Error = require('./error');

exports.escapeHeaderAttribute = require('./escapeHeaderAttribute');

exports.escapeHtml = require('./escapeHtml');
Expand Down
2 changes: 1 addition & 1 deletion test/esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ describe('import()', () => {
it('exposes all methods and classes as named imports', () => {

expect(Object.keys(Hoek)).to.equal([
'AssertError',
'Bench',
'Error',
'applyToDefaults',
'assert',
'block',
Expand Down
44 changes: 36 additions & 8 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2102,53 +2102,53 @@ describe('assert()', () => {
expect(() => {

Hoek.assert(false, 'my error message');
}).to.throw('my error message');
}).to.throw(Hoek.AssertError, 'my error message');
});

it('throws an Error when using assert in a test with no message', () => {

expect(() => {

Hoek.assert(false);
}).to.throw('Unknown error');
}).to.throw(Hoek.AssertError, 'Unknown error');
});

it('throws an Error when using assert in a test with multipart message', () => {

expect(() => {

Hoek.assert(false, 'This', 'is', 'my message');
}).to.throw('This is my message');
}).to.throw(Hoek.AssertError, 'This is my message');
});

it('throws an Error when using assert in a test with multipart message (empty)', () => {

expect(() => {

Hoek.assert(false, 'This', 'is', '', 'my message');
}).to.throw('This is my message');
}).to.throw(Hoek.AssertError, 'This is my message');
});

it('throws an Error when using assert in a test with object message', () => {

expect(() => {

Hoek.assert(false, 'This', 'is', { spinal: 'tap' });
}).to.throw('This is {"spinal":"tap"}');
}).to.throw(Hoek.AssertError, 'This is {"spinal":"tap"}');
});

it('throws an Error when using assert in a test with multipart string and error messages', () => {

expect(() => {

Hoek.assert(false, new Error('This'), 'is', 'spinal', new Error('tap'));
}).to.throw('This is spinal tap');
}).to.throw(Hoek.AssertError, 'This is spinal tap');
});

it('throws an Error when using assert in a test with error object message', () => {

const err = new Error('This is spinal tap');
const got = expect(() => Hoek.assert(false, err)).to.throw('This is spinal tap');
const err = new TypeError('This is spinal tap');
const got = expect(() => Hoek.assert(false, err)).to.throw(TypeError, 'This is spinal tap');
expect(got).to.shallow.equal(err);
});

Expand All @@ -2172,6 +2172,34 @@ describe('assert()', () => {
});
});

describe('AssertError', () => {

it('takes an optional message', () => {

expect(new Hoek.AssertError().message).to.equal('Unknown error');
expect(new Hoek.AssertError(null).message).to.equal('Unknown error');
expect(new Hoek.AssertError('msg').message).to.equal('msg');
});

it('has AssertError name property', () => {

expect(new Hoek.AssertError().name).to.equal('AssertError');
expect(new Hoek.AssertError('msg').name).to.equal('AssertError');
});

it('uses ctor argument to hide stack', { skip: typeof Error.captureStackTrace !== 'function' }, () => {

const parentFn = () => {

throw new Hoek.AssertError('msg', parentFn);
};

const err = expect(parentFn).to.throw(Hoek.AssertError);

expect(err.stack).to.not.contain('parentFn');
});
});

describe('Bench', () => {

it('returns time elapsed', async () => {
Expand Down
10 changes: 10 additions & 0 deletions test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,13 @@ function xor(input: Hoek.ts.XOR<X, Y>): number {
xor({ a: 1 });
xor({ b: 2 });
expect.error(xor({ a: 1, b: 2 }));

// AssertError

expect.type<Hoek.AssertError>(new Hoek.AssertError());
expect.type<Hoek.AssertError>(new Hoek.AssertError('fail'));
expect.type<'AssertError'>(new Hoek.AssertError().name);
expect.type<string>(new Hoek.AssertError().message);

expect.error(new Hoek.AssertError(new Error()));
expect.error(new Hoek.AssertError('fail', 'again'));

0 comments on commit 35e613a

Please sign in to comment.