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

mockResponse.end(): added callback triggering once end() logic has run. #248

Merged
merged 6 commits into from
Aug 30, 2021
69 changes: 55 additions & 14 deletions lib/mockResponse.js
Original file line number Diff line number Diff line change
Expand Up @@ -376,20 +376,55 @@ function createResponse(options) {
}

};

/**
* Function: getEndArguments
*
* Utility function that parses and names parameters for the various
* mockResponse.end() signatures. Reference:
* https://nodejs.org/api/http.html#http_response_end_data_encoding_callback
*
*/
function getEndArguments(args) {
var data, encoding, callback;
if (args[0]) {
if (typeof args[0] === 'function') {
callback = args[0];
} else {
data = args[0];
}
}
if (args[1]) {
var type = typeof args[1];
if (type === 'function') {
callback = args[1];
} else if (type === 'string' || args[1] instanceof String){
encoding = args[1];
}
}
if (args[2] && typeof args[2] === 'function') {
callback = args[2];
}
return { data: data, encoding: encoding, callback: callback };
}

/**
* Function: end
*
* The 'end' function from node's HTTP API that finishes
* the connection request. This must be called.
*
* Signature: response.end([data[, encoding]][, callback])
*
* Parameters:
* Parameters:
*
* data - Optional data to return. Must be a string. Appended
* to previous calls to <send>.
* data - Optional data to return. Must be a string or Buffer instance.
* Appended to previous calls to <send>.
* encoding - Optional encoding value.
* callback - Optional callback function, called once the logic has run
*
*/
mockResponse.end = function(data, encoding) {
mockResponse.end = function() {
if (_endCalled) {
// Do not emit this event twice.
return;
Expand All @@ -400,13 +435,15 @@ function createResponse(options) {
mockResponse.headersSent = true;

_endCalled = true;

if (data) {
if (data instanceof Buffer) {
_chunks.push(data);
_size += data.length;

var args = getEndArguments(arguments);

if (args.data) {
if (args.data instanceof Buffer) {
_chunks.push(args.data);
_size += args.data.length;
} else {
_data += data;
_data += args.data;
}
}

Expand All @@ -426,15 +463,19 @@ function createResponse(options) {
}
}

if (encoding) {
_encoding = encoding;
if (args.encoding) {
_encoding = args.encoding;
}

mockResponse.emit('end');
mockResponse.writableFinished = true; //Reference: https://nodejs.org/docs/latest-v12.x/api/http.html#http_request_writablefinished
mockResponse.emit('finish');


if (args.callback) {
args.callback();
}
};


/**
* Function: vary
Expand Down
25 changes: 25 additions & 0 deletions test/lib/mockResponse.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,31 @@ describe('mockResponse', function () {

it('should inherit from Node OutogingMessage.end()');

it('triggers callback provided as 1st argument', function() {
var callback = sinon.spy();
response.end(callback);

expect(callback).to.have.been.called;
});

it('triggers callback provided as 2nd argument', function() {
var payload = 'random-text';
var callback = sinon.spy();
response.end(Buffer.from(payload), callback);

expect(callback).to.have.been.called;
expect(response._getBuffer().toString()).to.equal(payload);
});

it('triggers callback provided as 3rd argument', function() {
var payload = 'random-text';
var callback = sinon.spy();
response.end(Buffer.from(payload), 'utf8', callback);

expect(callback).to.have.been.called;
expect(response._getBuffer().toString()).to.equal(payload);
});

});

});
Expand Down