|
| 1 | +import test from 'ava' |
| 2 | +import { serialize } from 'error-serializer' |
| 3 | +import { each } from 'test-each' |
| 4 | + |
| 5 | +import { handleError } from '../helpers/main.test.js' |
| 6 | + |
| 7 | +const createDeepErrors = () => Array.from({ length: 5 }, createDeepError) |
| 8 | + |
| 9 | +const createDeepError = (_, depth) => { |
| 10 | + const error = new TypeError('test') |
| 11 | + setDeepError(error, depth) |
| 12 | + return error |
| 13 | +} |
| 14 | + |
| 15 | +const setDeepError = (error, depth) => { |
| 16 | + if (depth === 0) { |
| 17 | + return |
| 18 | + } |
| 19 | + |
| 20 | + // eslint-disable-next-line fp/no-mutating-methods |
| 21 | + Object.defineProperty(error, 'cause', { |
| 22 | + value: new TypeError('test'), |
| 23 | + enumerable: false, |
| 24 | + writable: true, |
| 25 | + configurable: true, |
| 26 | + }) |
| 27 | + // eslint-disable-next-line fp/no-delete |
| 28 | + delete error.stack |
| 29 | + setDeepError(error.cause, depth - 1) |
| 30 | +} |
| 31 | + |
| 32 | +const recursiveError = new TypeError('test') |
| 33 | +// eslint-disable-next-line fp/no-mutation |
| 34 | +recursiveError.self = recursiveError |
| 35 | +const deepErrors = createDeepErrors() |
| 36 | +const ownNameError = new Error('test') |
| 37 | +// eslint-disable-next-line fp/no-mutation |
| 38 | +ownNameError.name = 'TypeError' |
| 39 | +const noStackError = new Error('test') |
| 40 | +// eslint-disable-next-line fp/no-mutating-methods |
| 41 | +Object.defineProperty(noStackError, 'stack', { value: noStackError.toString() }) |
| 42 | + |
| 43 | +each( |
| 44 | + [recursiveError, noStackError, ...deepErrors], |
| 45 | + [true, false, undefined], |
| 46 | + [true, false, undefined], |
| 47 | + // eslint-disable-next-line max-params |
| 48 | + ({ title }, error, stack, props) => { |
| 49 | + test.serial(`Prints stack unless "stack" is false | ${title}`, (t) => { |
| 50 | + const { consoleArg } = handleError(error, { stack, props }) |
| 51 | + t.is( |
| 52 | + consoleArg.includes('at '), |
| 53 | + stack !== false && error.stack.includes('at '), |
| 54 | + ) |
| 55 | + }) |
| 56 | + |
| 57 | + test.serial(`Does not put the error in brackets | ${title}`, (t) => { |
| 58 | + const { consoleArg } = handleError(error, { stack, props, icon: '' }) |
| 59 | + t.false(consoleArg.startsWith('[')) |
| 60 | + }) |
| 61 | + |
| 62 | + test.serial(`Does not modify the error | ${title}`, (t) => { |
| 63 | + const errorCopy = serialize(error) |
| 64 | + handleError(error, { stack, props }) |
| 65 | + t.deepEqual(serialize(error), errorCopy) |
| 66 | + }) |
| 67 | + |
| 68 | + test.serial(`Prints error name and message | ${title}`, (t) => { |
| 69 | + const { consoleArg } = handleError(error, { stack, props }) |
| 70 | + t.true(consoleArg.includes(`${error.name}: ${error.message}`)) |
| 71 | + }) |
| 72 | + }, |
| 73 | +) |
| 74 | + |
| 75 | +each([true, false], ({ title }, stack, props) => { |
| 76 | + test.serial(`Prints error name consistently | ${title}`, (t) => { |
| 77 | + const { consoleArg } = handleError(ownNameError, { stack: false, props }) |
| 78 | + t.true(consoleArg.includes(`Error [${ownNameError.name}`)) |
| 79 | + }) |
| 80 | +}) |
| 81 | + |
| 82 | +test.serial('Does not remove stacks from non-errors', (t) => { |
| 83 | + const error = new Error('test') |
| 84 | + error.prop = { stack: 'propStack' } |
| 85 | + const { consoleArg } = handleError(error, { stack: false, props: true }) |
| 86 | + t.true(consoleArg.includes(error.prop.stack)) |
| 87 | +}) |
0 commit comments