Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wraps assert functions, updating stack trace of generated errors #690

Merged
merged 1 commit into from
Jan 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 27 additions & 5 deletions lib/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,28 @@ Test.prototype.serverAddress = function(app, path) {
return protocol + '://127.0.0.1:' + port + path;
};

/**
* Wraps an assert function into another.
* The wrapper function edit the stack trace of any assertion error, prepending a more useful stack to it.
*
* @param {Function} assertFn
* @returns {Function} wrapped assert function
*/

function wrapAssertFn(assertFn) {
var savedStack = new Error().stack.split('\n').slice(3);

return function(res) {
var badStack;
var err = assertFn(res);
if (err && err.stack) {
badStack = err.stack.replace(err.message, '').split('\n').slice(1);
err.stack = [err.message, savedStack, '----', badStack].flat().join('\n');
}
return err;
};
}

/**
* Expectations:
*
Expand All @@ -83,30 +105,30 @@ Test.prototype.serverAddress = function(app, path) {
Test.prototype.expect = function(a, b, c) {
// callback
if (typeof a === 'function') {
this._asserts.push(a);
this._asserts.push(wrapAssertFn(a));
return this;
}
if (typeof b === 'function') this.end(b);
if (typeof c === 'function') this.end(c);

// status
if (typeof a === 'number') {
this._asserts.push(this._assertStatus.bind(this, a));
this._asserts.push(wrapAssertFn(this._assertStatus.bind(this, a)));
// body
if (typeof b !== 'function' && arguments.length > 1) {
this._asserts.push(this._assertBody.bind(this, b));
this._asserts.push(wrapAssertFn(this._assertBody.bind(this, b)));
}
return this;
}

// header field
if (typeof b === 'string' || typeof b === 'number' || b instanceof RegExp) {
this._asserts.push(this._assertHeader.bind(this, { name: '' + a, value: b }));
this._asserts.push(wrapAssertFn(this._assertHeader.bind(this, { name: '' + a, value: b })));
return this;
}

// body
this._asserts.push(this._assertBody.bind(this, a));
this._asserts.push(wrapAssertFn(this._assertBody.bind(this, a)));

return this;
};
Expand Down
22 changes: 22 additions & 0 deletions test/supertest.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ describe('request(app)', function () {
.expect(404)
.end(function (err, res) {
err.message.should.equal('expected 404 "Not Found", got 200 "OK"');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand Down Expand Up @@ -419,6 +420,7 @@ describe('request(app)', function () {
.expect(200, '')
.end(function (err, res) {
err.message.should.equal('expected \'\' response body, got \'foo\'');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand All @@ -440,6 +442,7 @@ describe('request(app)', function () {
.expect('hey')
.end(function (err, res) {
err.message.should.equal('expected \'hey\' response body, got \'{"foo":"bar"}\'');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand All @@ -459,6 +462,7 @@ describe('request(app)', function () {
.expect('hey')
.end(function (err, res) {
err.message.should.equal('expected 200 "OK", got 500 "Internal Server Error"');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand Down Expand Up @@ -491,6 +495,7 @@ describe('request(app)', function () {
.expect({ foo: 'baz' })
.end(function (err, res) {
err.message.should.equal('expected { foo: \'baz\' } response body, got { foo: \'bar\' }');
err.stack.should.match(/test\/supertest.js:/);

request(app)
.get('/')
Expand Down Expand Up @@ -522,6 +527,7 @@ describe('request(app)', function () {
.expect({ stringValue: 'foo', numberValue: 3, nestedObject: { innerString: 5 } })
.end(function (err, res) {
err.message.should.equal('expected {\n stringValue: \'foo\',\n numberValue: 3,\n nestedObject: { innerString: 5 }\n} response body, got {\n stringValue: \'foo\',\n numberValue: 3,\n nestedObject: { innerString: \'5\' }\n}'); // eslint-disable-line max-len
err.stack.should.match(/test\/supertest.js:/);

request(app)
.get('/')
Expand All @@ -542,6 +548,7 @@ describe('request(app)', function () {
.expect(/^bar/)
.end(function (err, res) {
err.message.should.equal('expected body \'foobar\' to match /^bar/');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand All @@ -560,6 +567,7 @@ describe('request(app)', function () {
.expect('hey tj')
.end(function (err, res) {
err.message.should.equal("expected 'hey' response body, got 'hey tj'");
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand Down Expand Up @@ -592,6 +600,7 @@ describe('request(app)', function () {
.expect('Content-Foo', 'bar')
.end(function (err, res) {
err.message.should.equal('expected "Content-Foo" header field');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand All @@ -609,6 +618,7 @@ describe('request(app)', function () {
.end(function (err, res) {
err.message.should.equal('expected "Content-Type" of "text/html", '
+ 'got "application/json; charset=utf-8"');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand Down Expand Up @@ -640,6 +650,7 @@ describe('request(app)', function () {
.end(function (err) {
err.message.should.equal('expected "Content-Type" matching /^application/, '
+ 'got "text/html; charset=utf-8"');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand All @@ -656,6 +667,7 @@ describe('request(app)', function () {
.expect('Content-Length', 4)
.end(function (err) {
err.message.should.equal('expected "Content-Length" of "4", got "3"');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand All @@ -682,6 +694,7 @@ describe('request(app)', function () {
})
.end(function (err) {
err.message.should.equal('failed');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand All @@ -707,6 +720,7 @@ describe('request(app)', function () {
})
.end(function (err) {
err.message.should.equal('some descriptive error');
err.stack.should.match(/test\/supertest.js:/);
(err instanceof Error).should.be.true;
done();
});
Expand Down Expand Up @@ -747,6 +761,7 @@ describe('request(app)', function () {
.expect('Content-Type', /json/)
.end(function (err) {
err.message.should.match(/Content-Type/);
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand Down Expand Up @@ -790,6 +805,7 @@ describe('request(app)', function () {
.end(function (err) {
err.message.should.equal('expected "Content-Type" matching /bloop/, '
+ 'got "text/html; charset=utf-8"');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand All @@ -808,6 +824,7 @@ describe('request(app)', function () {
.end(function (err) {
err.message.should.equal('expected "Content-Type" matching /bloop/, '
+ 'got "text/html; charset=utf-8"');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand All @@ -826,6 +843,7 @@ describe('request(app)', function () {
.end(function (err) {
err.message.should.equal('expected "Content-Type" matching /bloop/, '
+ 'got "text/html; charset=utf-8"');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand Down Expand Up @@ -984,6 +1002,7 @@ describe('assert ordering by call order', function () {
.end(function (err, res) {
err.message.should.equal('expected \'hey\' response body, '
+ 'got \'{"message":"something went wrong"}\'');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand All @@ -1003,6 +1022,7 @@ describe('assert ordering by call order', function () {
.expect('hey')
.end(function (err, res) {
err.message.should.equal('expected 200 "OK", got 500 "Internal Server Error"');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand All @@ -1023,6 +1043,7 @@ describe('assert ordering by call order', function () {
.end(function (err, res) {
err.message.should.equal('expected "content-type" matching /html/, '
+ 'got "application/json; charset=utf-8"');
err.stack.should.match(/test\/supertest.js:/);
done();
});
});
Expand Down Expand Up @@ -1195,6 +1216,7 @@ describe('request.get(url).query(vals) works as expected', function () {
.end(function (err, res) {
err.should.be.an.instanceof(Error);
err.message.should.match(/Nock: Disallowed net connect/);
err.stack.should.match(/test\/supertest.js:/);
done();
});

Expand Down