Skip to content

Commit ad087f2

Browse files
dflupunovemberborn
authored andcommitted
Fix stack traces in throw assertions
Fixes #1372.
1 parent 8ad5efd commit ad087f2

File tree

6 files changed

+404
-40
lines changed

6 files changed

+404
-40
lines changed

lib/assert.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class AssertionError extends Error {
3636
this.assertion = opts.assertion;
3737
this.fixedSource = opts.fixedSource;
3838
this.improperUsage = opts.improperUsage || false;
39+
this.actualStack = opts.actualStack;
3940
this.operator = opts.operator;
4041
this.values = opts.values || [];
4142

@@ -147,11 +148,14 @@ function assertExpectations({assertion, actual, expectations, message, prefix, s
147148
});
148149
}
149150

151+
const actualStack = actual.stack;
152+
150153
if (hasOwnProperty(expectations, 'is') && actual !== expectations.is) {
151154
throw new AssertionError({
152155
assertion,
153156
message,
154157
stack,
158+
actualStack,
155159
values: [
156160
formatWithLabel(`${prefix} unexpected exception:`, actual),
157161
formatWithLabel('Expected to be strictly equal to:', expectations.is)
@@ -164,6 +168,7 @@ function assertExpectations({assertion, actual, expectations, message, prefix, s
164168
assertion,
165169
message,
166170
stack,
171+
actualStack,
167172
values: [
168173
formatWithLabel(`${prefix} unexpected exception:`, actual),
169174
formatWithLabel('Expected instance of:', expectations.instanceOf)
@@ -176,6 +181,7 @@ function assertExpectations({assertion, actual, expectations, message, prefix, s
176181
assertion,
177182
message,
178183
stack,
184+
actualStack,
179185
values: [
180186
formatWithLabel(`${prefix} unexpected exception:`, actual),
181187
formatWithLabel('Expected name to equal:', expectations.name)
@@ -188,6 +194,7 @@ function assertExpectations({assertion, actual, expectations, message, prefix, s
188194
assertion,
189195
message,
190196
stack,
197+
actualStack,
191198
values: [
192199
formatWithLabel(`${prefix} unexpected exception:`, actual),
193200
formatWithLabel('Expected message to equal:', expectations.message)
@@ -200,6 +207,7 @@ function assertExpectations({assertion, actual, expectations, message, prefix, s
200207
assertion,
201208
message,
202209
stack,
210+
actualStack,
203211
values: [
204212
formatWithLabel(`${prefix} unexpected exception:`, actual),
205213
formatWithLabel('Expected message to match:', expectations.message)
@@ -212,6 +220,7 @@ function assertExpectations({assertion, actual, expectations, message, prefix, s
212220
assertion,
213221
message,
214222
stack,
223+
actualStack,
215224
values: [
216225
formatWithLabel(`${prefix} unexpected exception:`, actual),
217226
formatWithLabel('Expected code to equal:', expectations.code)
@@ -433,6 +442,7 @@ function wrapAssertions(callbacks) {
433442
fail(this, new AssertionError({
434443
assertion: 'throwsAsync',
435444
message,
445+
actualStack: actual.stack,
436446
values: [formatWithLabel('Function threw synchronously. Use `t.throws()` instead:', actual)]
437447
}));
438448
return Promise.resolve();
@@ -467,6 +477,7 @@ function wrapAssertions(callbacks) {
467477
fail(this, new AssertionError({
468478
assertion: 'notThrows',
469479
message,
480+
actualStack: error.stack,
470481
values: [formatWithLabel('Function threw:', error)]
471482
}));
472483
return;
@@ -493,7 +504,7 @@ function wrapAssertions(callbacks) {
493504
throw new AssertionError({
494505
assertion: 'notThrowsAsync',
495506
message,
496-
stack,
507+
actualStack: stack,
497508
values: [formatWithLabel(`${wasReturned ? 'Returned promise' : 'Promise'} rejected with:`, reason)]
498509
});
499510
});
@@ -513,6 +524,7 @@ function wrapAssertions(callbacks) {
513524
fail(this, new AssertionError({
514525
assertion: 'notThrowsAsync',
515526
message,
527+
actualStack: error.stack,
516528
values: [formatWithLabel('Function threw:', error)]
517529
}));
518530
return Promise.resolve();

lib/serialize-error.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ function trySerializeError(err, shouldBeautifyStack) {
6060
stack
6161
};
6262

63+
if (err.actualStack) {
64+
retval.stack = shouldBeautifyStack ? beautifyStack(err.actualStack) : err.actualStack;
65+
}
66+
6367
if (retval.avaAssertionError) {
6468
retval.improperUsage = err.improperUsage;
6569
retval.message = err.message;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import test from '../../../..';
2+
3+
function throwError() {
4+
throw new Error('uh-oh');
5+
}
6+
7+
function returnRejectedPromise() {
8+
return Promise.reject(new Error('uh-oh'));
9+
}
10+
11+
test('throws', t => {
12+
t.throws(() => throwError(), TypeError);
13+
});
14+
15+
test('notThrows', t => {
16+
t.notThrows(() => throwError());
17+
});
18+
19+
test('notThrowsAsync', t => {
20+
t.notThrowsAsync(() => throwError());
21+
});
22+
23+
test('throwsAsync', t => {
24+
t.throwsAsync(() => throwError(), TypeError);
25+
});
26+
27+
test('throwsAsync different error', t => {
28+
return t.throwsAsync(returnRejectedPromise, TypeError);
29+
});

0 commit comments

Comments
 (0)