Permalink
Browse files

Added a delay function which causes the request to halt for N ms befo…

…re replying.
  • Loading branch information...
1 parent e6b8832 commit f28dc3c973651830b930793932b4006577260dc1 @spalger spalger committed Dec 11, 2013
Showing with 277 additions and 51 deletions.
  1. +39 −15 README.md
  2. +83 −0 lib/delayed_body.js
  3. +13 −6 lib/request_overrider.js
  4. +42 −29 lib/scope.js
  5. +100 −1 tests/test_intercept.js
View
@@ -22,9 +22,9 @@ var nock = require('nock');
var couchdb = nock('http://myapp.iriscouch.com')
.get('/users/1')
.reply(200, {
- _id: '123ABC',
- _rev: '946B7D1C',
- username: 'pgte',
+ _id: '123ABC',
+ _rev: '946B7D1C',
+ username: 'pgte',
email: 'pedro.teixeira@gmail.com'
});
```
@@ -48,12 +48,12 @@ You can specify the request body to be matched as the second argument to the `ge
```js
var scope = nock('http://myapp.iriscouch.com')
.post('/users', {
- username: 'pgte',
+ username: 'pgte',
email: 'pedro.teixeira@gmail.com'
})
.reply(201, {
- ok: true,
- id: '123ABC',
+ ok: true,
+ id: '123ABC',
rev: '946B7D1C'
});
```
@@ -84,8 +84,8 @@ or as a JSON-encoded object:
var scope = nock('http://myapp.iriscouch.com')
.get('/')
.reply(200, {
- username: 'pgte',
- email: 'pedro.teixeira@gmail.com',
+ username: 'pgte',
+ email: 'pedro.teixeira@gmail.com',
_id: '4324243fsd'
});
```
@@ -109,6 +109,17 @@ var scope = nock('http://www.google.com')
});
```
+
+A Stream works too:
+```js
+var scope = nock('http://www.google.com')
+ .get('/cat-poems')
+ .reply(200, function(uri, requestBody) {
+ return fs.createReadStream('cat-poems.txt');
+ });
+```
+
+
### Specifying Reply Headers
You can specify the reply headers like this:
@@ -128,7 +139,7 @@ You can also specify default reply headers for all responses like this:
```js
var scope = nock('http://www.headdy.com')
.defaultReplyHeaders({
- 'X-Powered-By': 'Rails',
+ 'X-Powered-By': 'Rails',
'Content-Type': 'application/json'
})
.get('/')
@@ -187,6 +198,19 @@ nock('http://zombo.com').get('/').twice().reply(200, 'Ok');
nock('http://zombo.com').get('/').thrice().reply(200, 'Ok');
```
+## Delay the response
+
+You are able to specify the number of milliseconds that your reply should be delayed.
+
+```js
+nock('http://my.server.com')
+ .get('/')
+ .delay(2000) // 2 seconds
+ .reply(200, '<html></html>')
+```
+
+NOTE: the [`'response'`](http://nodejs.org/api/http.html#http_event_response) event will occur immediately, but the [IncomingMessage](http://nodejs.org/api/http.html#http_http_incomingmessage) not emit it's `'end'` event until after the delay.
+
## Chaining
You can chain behaviour like this:
@@ -196,19 +220,19 @@ var scope = nock('http://myapp.iriscouch.com')
.get('/users/1')
.reply(404)
.post('/users', {
- username: 'pgte',
+ username: 'pgte',
email: 'pedro.teixeira@gmail.com'
})
.reply(201, {
- ok: true,
- id: '123ABC',
+ ok: true,
+ id: '123ABC',
rev: '946B7D1C'
})
.get('/users/123ABC')
.reply(200, {
- _id: '123ABC',
- _rev: '946B7D1C',
- username: 'pgte',
+ _id: '123ABC',
+ _rev: '946B7D1C',
+ username: 'pgte',
email: 'pedro.teixeira@gmail.com'
});
```
View
@@ -0,0 +1,83 @@
+/**
+ * Creates a stream which becomes the response body of the interceptor when a
+ * delay is set. The stream outputs the intended body and EOF after the delay.
+ *
+ * @param {String|Buffer|Stream} body - the body to write/pipe out
+ * @param {Integer} ms - The delay in milliseconds
+ * @constructor
+ */
+module.exports = DelayedBody;
+
+var Transform = require('stream').Transform;
+var EventEmitter = require('events').EventEmitter;
+var noop = function () {};
+var util = require('util');
+
+function isStream(obj) {
+ var is = obj && (typeof a !== 'string') && (! Buffer.isBuffer(obj)) && (typeof obj.setEncoding == 'function');
+ return is;
+}
+
+if (!Transform) {
+ // for barebones compatibility for node < 0.10
+ var FakeTransformStream = function () {
+ EventEmitter.call(this);
+ };
+ util.inherits(FakeTransformStream, EventEmitter);
+ FakeTransformStream.prototype.pause = noop;
+ FakeTransformStream.prototype.resume = noop;
+ FakeTransformStream.prototype.setEncoding = noop;
+ FakeTransformStream.prototype.write = function (chunk, encoding) {
+ var self = this;
+ process.nextTick(function () {
+ self.emit('data', chunk, encoding);
+ });
+ };
+ FakeTransformStream.prototype.end = function (chunk) {
+ var self = this;
+ if (chunk) {
+ self.write(chunk);
+ }
+ process.nextTick(function () {
+ self.emit('end');
+ });
+ };
+
+ Transform = FakeTransformStream;
+}
+
+function DelayedBody(ms, body) {
+ Transform.call(this);
+
+ var self = this;
+ var data = '';
+ var ended = false;
+
+ if (isStream(body)) {
+ body.on('data', function (chunk) {
+ data += Buffer.isBuffer(chunk) ? chunk.toString() : chunk;
+ });
+
+ body.once('end', function () {
+ ended = true;
+ });
+
+ body.resume();
+ }
+
+ setTimeout(function () {
+ if (isStream(body) && !ended) {
+ body.once('end', function () {
+ self.end(data);
+ });
+ } else {
+ self.end(data || body);
+ }
+ }, ms);
+}
+util.inherits(DelayedBody, Transform);
+
+DelayedBody.prototype._transform = function (chunk, encoding, cb) {
+ this.push(chunk);
+ process.nextTick(cb);
+};
View
@@ -1,6 +1,7 @@
var EventEmitter = require('events').EventEmitter,
http = require('http'),
propagate = require('propagate'),
+ DelayedBody = require('./delayed_body'),
OutgoingMessage = http.OutgoingMessage,
ClientRequest = http.ClientRequest;
;
@@ -176,6 +177,18 @@ function RequestOverrider(req, options, interceptors, remove, cb) {
responseBody = interceptor.body;
}
+ if (responseBody && !Buffer.isBuffer(responseBody) && !isStream(responseBody)) {
+ if (typeof responseBody === 'string') {
+ responseBody = new Buffer(responseBody);
+ } else {
+ responseBody = JSON.stringify(responseBody);
+ }
+ }
+
+ if (interceptor.delayInMs) {
+ responseBody = new DelayedBody(interceptor.delayInMs, responseBody);
+ }
+
if (isStream(responseBody)) {
responseBody.on('data', function(d) {
response.emit('data', d);
@@ -186,12 +199,6 @@ function RequestOverrider(req, options, interceptors, remove, cb) {
process.nextTick(function() {
responseBody.resume();
});
- } else if (responseBody && !Buffer.isBuffer(responseBody)) {
- if (typeof responseBody === 'string') {
- responseBody = new Buffer(responseBody);
- } else {
- responseBody = JSON.stringify(responseBody);
- }
}
response.setEncoding = function(newEncoding) {
Oops, something went wrong.

0 comments on commit f28dc3c

Please sign in to comment.