Skip to content

Commit

Permalink
Support for range function (#175)
Browse files Browse the repository at this point in the history
* Support .range on mock request

* Corrected version in package-lock (should have been updated on a npm install)

* Fixed lint warnings

* Updated release notes for next release noting new .range() function

* Added note in README about Express methods
  • Loading branch information
rhodgkins authored and howardabrams committed Oct 10, 2018
1 parent d99b008 commit 52568ee
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 9 deletions.
7 changes: 7 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
NEXT RELEASE
-------

- Added `.range()` on a mocked request mimicking the [same function](http://expressjs.com/en/4x/api.html#req.range) on Express' request. [#175][175]

[175]: https://github.com/howardabrams/node-mocks-http/pull/175

v 1.7.2
-------

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ option | description | default value
`query` | object hash with query values | {}
`files` | object hash with values | {}

The object returned from this function also supports the [Express request](http://expressjs.com/en/4x/api.html#req) functions ([`.accepts()`](http://expressjs.com/en/4x/api.html#req.accepts), [`.is()`](http://expressjs.com/en/4x/api.html#req.is), [`.get()`](http://expressjs.com/en/4x/api.html#req.get), [`.range()`](http://expressjs.com/en/4x/api.html#req.range), etc.). Please send a PR for any missing functions.

### .createResponse()

```js
Expand Down
14 changes: 7 additions & 7 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ gulp.task('coverage', function (done) {
.pipe(istanbul.hookRequire())
.on('finish', function () {
gulp.src(files.test)
.pipe(mocha({reporter: 'dot'}))
.pipe(istanbul.writeReports({
dir: './coverage',
reporters: ['lcov', 'json', 'html'],
reportOpts: { dir: './coverage' }
}))
.on('end', done);
.pipe(mocha({reporter: 'dot'}))
.pipe(istanbul.writeReports({
dir: './coverage',
reporters: ['lcov', 'json', 'html'],
reportOpts: { dir: './coverage' }
}))
.on('end', done);
});
});
35 changes: 35 additions & 0 deletions lib/mockRequest.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
var url = require('url');
var typeis = require('type-is');
var accepts = require('accepts');
var parseRange = require('range-parser');
var EventEmitter = require('events').EventEmitter;
var utils = require('./utils');

Expand Down Expand Up @@ -190,6 +191,40 @@ function createRequest(options) {
return Accepts.type(types);
};

/**
* Function: range
*
* Parse Range header field, capping to the given `size`.
*
* Unspecified ranges such as "0-" require knowledge of your resource length. In
* the case of a byte range this is of course the total number of bytes. If the
* Range header field is not given `undefined` is returned, `-1` when unsatisfiable,
* and `-2` when syntactically invalid.
*
* When ranges are returned, the array has a "type" property which is the type of
* range that is required (most commonly, "bytes"). Each array element is an object
* with a "start" and "end" property for the portion of the range.
*
* The "combine" option can be set to `true` and overlapping & adjacent ranges
* will be combined into a single range.
*
* NOTE: remember that ranges are inclusive, so for example "Range: users=0-3"
* should respond with 4 users when available, not 3.
*
* @param {number} size
* @param {object} [opts]
* @param {boolean} [opts.combine=false]
* @return {false|number|array}
* @public
*/
mockRequest.range = function(size, opts) {
var range = mockRequest.get('Range');
if (!range) {
return;
}
return parseRange(size, range, opts);
};

/**
* Function: param
*
Expand Down
2 changes: 1 addition & 1 deletion lib/mockResponse.js
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ function createResponse(options) {
// concat the new and prev vals
value = Array.isArray(prev) ? prev.concat(val)
: Array.isArray(val) ? [prev].concat(val)
: [prev, val];
: [prev, val];
}

return mockResponse.set(field, value);
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions test/lib/mockRequest.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ var chai = require('chai');
var expect = chai.expect;
var url = require('url');
var querystring = require('querystring');
var parseRange = require('range-parser');

var mockRequest = require('../../lib/mockRequest');

Expand Down Expand Up @@ -388,6 +389,57 @@ describe('mockRequest', function() {
});
});

describe('.range()', function() {
var request;

afterEach(function() {
request = null;
});

it('returns undefined if there is no Range header', function() {
request = mockRequest.createRequest();
expect(request.range()).to.be.undefined;
});

var tests = [
{
// Unsatisfiable
header: 'bytes=90-100',
size: 10
},
{
// Malformed
header: 'by90-100',
size: 10
},
{
// Basic range
header: 'bytes=50-55',
size: 100
},
{
// Complex, without options
header: 'bytes=50-55,0-10,5-10,56-60',
size: 100
},
{
// With options
header: 'bytes=50-55,0-10,5-10,56-60',
size: 100,
options: {
combine: true
}
}
];

tests.forEach(function(t) {
it('returns the result of range-parser if there is a Range header of ' + t.header + ' using size: ' + t.size, function() {
request = mockRequest.createRequest({ headers: { range: t.header }});
expect(request.range(t.size, t.options)).to.deep.equal(parseRange(t.size, t.header, t.options));
});
});
});

describe('.param()', function() {
var request;

Expand Down

0 comments on commit 52568ee

Please sign in to comment.