-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'cleanup/exchangeContainingNamedErrors'
- Loading branch information
Showing
11 changed files
with
811 additions
and
607 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
/*global Promise:false*/ | ||
module.exports = function consumeReadableStream(readableStream, options) { | ||
options = options || {}; | ||
var skipConcat = !!options.skipConcat; | ||
|
||
return new Promise(function (resolve, reject) { | ||
var chunks = []; | ||
readableStream.on('data', function (chunk) { | ||
chunks.push(chunk); | ||
}).on('end', function (chunk) { | ||
resolve({ body: skipConcat ? chunks : Buffer.concat(chunks) }); | ||
}).on('error', function (err) { | ||
resolve({ body: skipConcat ? chunks : Buffer.concat(chunks), error: err }); | ||
}); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
module.exports = function createSerializedRequestHandler(onRequest) { | ||
var activeRequest = false, | ||
requestQueue = []; | ||
|
||
function processNextRequest() { | ||
function cleanUpAndProceed() { | ||
if (activeRequest) { | ||
activeRequest = false; | ||
setImmediate(processNextRequest); | ||
} | ||
} | ||
while (requestQueue.length > 0 && !activeRequest) { | ||
activeRequest = true; | ||
var reqAndRes = requestQueue.shift(), | ||
req = reqAndRes[0], | ||
res = reqAndRes[1], | ||
resEnd = res.end; | ||
res.end = function () { | ||
resEnd.apply(this, arguments); | ||
cleanUpAndProceed(); | ||
}; | ||
// This happens upon an error, so we need to make sure that we catch that case also: | ||
res.on('close', cleanUpAndProceed); | ||
onRequest(req, res); | ||
} | ||
} | ||
|
||
return function (req, res) { | ||
requestQueue.push([req, res]); | ||
processNextRequest(); | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
var createError = require('createerror'); | ||
|
||
// base error | ||
var UnexpectedMitmError = createError({ name: 'UnexpectedMitmError' }); | ||
// marker errors | ||
var EarlyExitError = createError({ name: 'EarlyExitError' }, UnexpectedMitmError); | ||
var SawUnexpectedRequestsError = createError({ name: 'SawUnexpectedRequestsError' }, UnexpectedMitmError); | ||
var UnexercisedMocksError = createError({ name: 'UnexercisedMocksError' }, UnexpectedMitmError); | ||
|
||
|
||
exports.UnexpectedMitmError = UnexpectedMitmError; | ||
exports.EarlyExitError = EarlyExitError; | ||
exports.SawUnexpectedRequestsError = SawUnexpectedRequestsError; | ||
exports.UnexercisedMocksError = UnexercisedMocksError; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
var messy = require('messy'); | ||
|
||
module.exports = function formatHeaderObj(headerObj) { | ||
var result = {}; | ||
Object.keys(headerObj).forEach(function (headerName) { | ||
result[messy.formatHeaderName(headerName)] = headerObj[headerName]; | ||
}); | ||
return result; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
var messy = require('messy'); | ||
var trimHeadersLower = require('./trimHeadersLower'); | ||
var UnexpectedMitmMocker = require('./UnexpectedMitmMocker'); | ||
|
||
module.exports = { | ||
name: 'unexpected-mitm-mocker', | ||
version: require('../package.json').version, | ||
installInto: function (expect) { | ||
expect = expect.child() | ||
.use(require('unexpected-messy')) | ||
.exportType({ | ||
name: 'UnexpectedMitmMocker', | ||
base: 'object', | ||
identify: function (obj) { | ||
return obj instanceof UnexpectedMitmMocker; | ||
} | ||
}) | ||
.exportAssertion('<UnexpectedMitmMocker> to be complete [with extra info]', function (expect, subject) { | ||
var shouldReturnExtraInfo = expect.flags['with extra info']; | ||
|
||
return expect.promise(function () { | ||
return subject; | ||
}).then(function (result) { | ||
return [result.timeline, result.fulfilmentValue]; | ||
}).spread(function (timeline, fulfilmentValue) { | ||
var lastEventOrError = null; | ||
|
||
// pull out the last event if it exists | ||
if (timeline.length > 0) { | ||
lastEventOrError = timeline[timeline.length - 1]; | ||
} | ||
|
||
if (lastEventOrError instanceof Error) { | ||
var name = lastEventOrError.name; | ||
if (name === 'Error' || name === 'UnexpectedError') { | ||
throw lastEventOrError; | ||
} else if (name === 'EarlyExitError') { | ||
// in the case of an early exirt error we need | ||
// to generate a diff from the last recorded | ||
// event & spec | ||
var failedEvent = timeline[timeline.length - 2]; | ||
var failedExchange = failedEvent.exchange; | ||
trimHeadersLower(failedExchange.request); | ||
|
||
expect.errorMode = 'default'; | ||
return expect(failedExchange, 'to satisfy', failedEvent.spec); | ||
} else { | ||
// ignore to cause generation of a diff | ||
} | ||
} else if (lastEventOrError === null && fulfilmentValue) { | ||
return [null, fulfilmentValue]; | ||
} | ||
|
||
return [timeline, fulfilmentValue]; | ||
}).spread(function (timeline, fulfilmentValue) { | ||
// in the absence of a timeline immedistely resolve with fulfilmentValue | ||
if (timeline === null) { | ||
return fulfilmentValue; | ||
} | ||
|
||
var httpConversation = new messy.HttpConversation(); | ||
var httpConversationSatisfySpec = { exchanges: [] }; | ||
|
||
function recordEventForAssertion(event) { | ||
if (event.exchange) { | ||
httpConversation.exchanges.push(event.exchange); | ||
} | ||
if (event.spec) { | ||
httpConversationSatisfySpec.exchanges.push(event.spec); | ||
} | ||
} | ||
|
||
timeline.forEach(recordEventForAssertion); | ||
|
||
expect.errorMode = 'default'; | ||
return expect(httpConversation, 'to satisfy', httpConversationSatisfySpec).then(function () { | ||
if (shouldReturnExtraInfo) { | ||
return [fulfilmentValue, httpConversation, httpConversationSatisfySpec]; | ||
} else { | ||
return fulfilmentValue; | ||
} | ||
}); | ||
}); | ||
}); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
var _ = require('underscore'); | ||
var urlModule = require('url'); | ||
|
||
function isRegExp(obj) { | ||
return Object.prototype.toString.call(obj) === '[object RegExp]'; | ||
} | ||
|
||
module.exports = function resolveExpectedRequestProperties(expectedRequestProperties) { | ||
if (typeof expectedRequestProperties === 'string') { | ||
expectedRequestProperties = { url: expectedRequestProperties }; | ||
} else if (expectedRequestProperties && typeof expectedRequestProperties === 'object') { | ||
expectedRequestProperties = _.extend({}, expectedRequestProperties); | ||
} | ||
if (expectedRequestProperties) { | ||
if (typeof expectedRequestProperties.url === 'string') { | ||
var matchMethod = expectedRequestProperties.url.match(/^([A-Z]+) ([\s\S]*)$/); | ||
if (matchMethod) { | ||
expectedRequestProperties.method = expectedRequestProperties.method || matchMethod[1]; | ||
expectedRequestProperties.url = matchMethod[2]; | ||
} | ||
} | ||
} else { | ||
expectedRequestProperties = {}; | ||
} | ||
if (/^https?:\/\//.test(expectedRequestProperties.url)) { | ||
var urlObj = urlModule.parse(expectedRequestProperties.url); | ||
expectedRequestProperties.headers = expectedRequestProperties.headers || {}; | ||
if (Object.keys(expectedRequestProperties.headers).every(function (key) { | ||
return key.toLowerCase() !== 'host'; | ||
})) { | ||
expectedRequestProperties.headers.host = urlObj.host; | ||
} | ||
expectedRequestProperties.host = expectedRequestProperties.host || urlObj.hostname; | ||
if (urlObj.port && typeof expectedRequestProperties.port === 'undefined') { | ||
expectedRequestProperties.port = parseInt(urlObj.port, 10); | ||
} | ||
|
||
if (urlObj.protocol === 'https:' && typeof expectedRequestProperties.encrypted === 'undefined') { | ||
expectedRequestProperties.encrypted = true; | ||
} | ||
expectedRequestProperties.url = urlObj.path; | ||
} | ||
|
||
var expectedRequestBody = expectedRequestProperties.body; | ||
if (Array.isArray(expectedRequestBody) || (expectedRequestBody && typeof expectedRequestBody === 'object' && !isRegExp(expectedRequestBody) && (typeof Buffer === 'undefined' || !Buffer.isBuffer(expectedRequestBody)))) { | ||
// in the case of a streamed request body and skip asserting the body | ||
if (typeof expectedRequestBody.pipe === 'function') { | ||
throw new Error('unexpected-mitm: a stream cannot be used to verify the request body, please specify the buffer instead.'); | ||
} | ||
expectedRequestProperties.headers = expectedRequestProperties.headers || {}; | ||
if (Object.keys(expectedRequestProperties.headers).every(function (key) { | ||
return key.toLowerCase() !== 'content-type'; | ||
})) { | ||
expectedRequestProperties.headers['Content-Type'] = 'application/json'; | ||
} | ||
} | ||
return expectedRequestProperties; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
module.exports = function trimHeadersLower(message) { | ||
delete message.headers.valuesByName['content-length']; | ||
delete message.headers.valuesByName['transfer-encoding']; | ||
delete message.headers.valuesByName.connection; | ||
delete message.headers.valuesByName.date; | ||
|
||
return message; | ||
}; |
Oops, something went wrong.