Skip to content

Commit

Permalink
tcompare: include known non-enumerable Error properties
Browse files Browse the repository at this point in the history
Fix: #933
  • Loading branch information
isaacs committed Sep 30, 2023
1 parent d089e7e commit c433477
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 6 deletions.
14 changes: 11 additions & 3 deletions src/tcompare/src/format.ts
Expand Up @@ -822,8 +822,16 @@ export class Format {
}

getPojoKeys(obj: any = this.object): PropertyKey[] {
const keys: PropertyKey[] = []
// always include known non-enumerable properties of Error objects
if (obj instanceof Error) {
const known = ['errors', 'cause']
for (const prop of known) {
const desc = Object.getOwnPropertyDescriptor(obj, prop)
if (desc && !desc.enumerable) keys.push(prop)
}
}
if (this.options.includeEnumerable) {
const keys: PropertyKey[] = []
// optimized fast path, for/in over enumerable string keys only
for (const i in obj) {
keys.push(i)
Expand All @@ -835,9 +843,9 @@ export class Format {
return keys
}

const keys: PropertyKey[] = this.#getPojoKeys(obj).concat(
keys.push(...this.#getPojoKeys(obj).concat(
this.#getPojoKeys(obj, true)
)
))
if (!this.options.includeGetters) {
return keys
}
Expand Down
18 changes: 18 additions & 0 deletions src/tcompare/tap-snapshots/test/format.tsx.test.cjs
Expand Up @@ -33,6 +33,24 @@ exports[`test/format.tsx > TAP > error without name/message > {} > tight > must
new Object(undefined)
`

exports[`test/format.tsx > TAP > format aggregate errors and causes > must match snapshot 1`] = `
AggregateError: aggregated errors {
"errors": Array [
Error: xyz {
"cause": "something",
[Symbol.for(hsmusic.sugar.index)]: 1,
},
AggregateError: agg agg {
"errors": Array [
TypeError: blzhr {
[Symbol.for(hsmusic.sugar.index)]: "something",
},
],
},
],
}
`

exports[`test/format.tsx > TAP > format iterable > must match snapshot 1`] = `
And [
And [
Expand Down
33 changes: 30 additions & 3 deletions src/tcompare/test/format.tsx
Expand Up @@ -318,9 +318,12 @@ t.test('invalid iterator', t => {
// looks like an array
t.equal(f.isArray(), true)
// until you try to format it
t.equal(f.print(), `Object {
t.equal(
f.print(),
`Object {
[Symbol.iterator]: Function [Symbol.iterator](),
}`)
}`
)
// then it realizes it's actually not
t.equal(f.isArray(), false)
t.end()
Expand Down Expand Up @@ -455,9 +458,33 @@ t.test('formatting jsx', t => {
}
t.matchSnapshot(
format(lookAlike),
`children=${format(children).replace(/\n/g, ' ').replace(/ +/g, ' ').replace(/, ([}\]])/g, '$1').replace(/([\[{]) /g, '$1')}`
`children=${format(children)
.replace(/\n/g, ' ')
.replace(/ +/g, ' ')
.replace(/, ([}\]])/g, '$1')
.replace(/([\[{]) /g, '$1')}`
)
}

t.end()
})

t.test('format aggregate errors and causes', t => {
const sym = Symbol.for('hsmusic.sugar.index')
const errors = [
Object.assign(new Error('xyz', { cause: 'something' }), {
[sym]: 1,
}),
new AggregateError(
[
Object.assign(new TypeError('blzhr'), {
[sym]: 'something',
}),
],
'agg agg'
),
]
const er = new AggregateError(errors, 'aggregated errors')
t.matchSnapshot(format(er))
t.end()
})

0 comments on commit c433477

Please sign in to comment.