Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

fetch-mock

Package Overview
Dependencies
Maintainers
1
Versions
226
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fetch-mock - npm Package Compare versions

Comparing version 5.5.0 to 5.6.0

560

es5/client-browserified.js
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.fetchMock = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';
var fetchMock = require('./fetch-mock');
var FetchMock = require('./fetch-mock');
var statusTextMap = require('./status-text');
var theGlobal = typeof window !== 'undefined' ? window : self;
module.exports = fetchMock({
FetchMock.setGlobals({
global: theGlobal,

@@ -15,2 +15,4 @@ Request: theGlobal.Request,

});
module.exports = new FetchMock();
},{"./fetch-mock":3,"./status-text":4}],2:[function(require,module,exports){

@@ -157,311 +159,309 @@ 'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var compileRoute = require('./compile-route');
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var FetchMock = function FetchMock() {
var compileRoute = require('./compile-route');
this.config = {
sendAsJson: true
};
var FetchMock = function () {
function FetchMock(opts) {
_classCallCheck(this, FetchMock);
// if (opts) {
// FetchMock.Headers = opts.Headers;
// FetchMock.Request = opts.Request;
// FetchMock.Response = opts.Response;
// FetchMock.stream = opts.stream;
// FetchMock.global = opts.global;
// FetchMock.statusTextMap = opts.statusTextMap;
// }
this.config = {
sendAsJson: true
this.routes = [];
this._calls = {};
this._matchedCalls = [];
this._unmatchedCalls = [];
this.bindMethods();
};
FetchMock.prototype.bindMethods = function () {
this.fetchMock = FetchMock.prototype.fetchMock.bind(this);
this.restore = FetchMock.prototype.restore.bind(this);
this.reset = FetchMock.prototype.reset.bind(this);
};
FetchMock.prototype.mock = function (matcher, response, options) {
var route = void 0;
// Handle the variety of parameters accepted by mock (see README)
// Old method matching signature
if (options && /^[A-Z]+$/.test(response)) {
throw new Error('The API for method matching has changed.\n\t\t\tNow use .get(), .post(), .put(), .delete() and .head() shorthand methods,\n\t\t\tor pass in, e.g. {method: \'PATCH\'} as a third paramter');
} else if (options) {
route = _extends({
matcher: matcher,
response: response
}, options);
} else if (matcher && response) {
route = {
matcher: matcher,
response: response
};
this.Headers = opts.Headers;
this.Request = opts.Request;
this.Response = opts.Response;
this.stream = opts.stream;
this.global = opts.global;
this.statusTextMap = opts.statusTextMap;
this.routes = [];
this._calls = {};
this._matchedCalls = [];
this._unmatchedCalls = [];
this.fetchMock = this.fetchMock.bind(this);
this.restore = this.restore.bind(this);
this.reset = this.reset.bind(this);
} else if (matcher && matcher.matcher) {
route = matcher;
} else {
throw new Error('Invalid parameters passed to fetch-mock');
}
_createClass(FetchMock, [{
key: 'mock',
value: function mock(matcher, response, options) {
this.addRoute(route);
var route = void 0;
return this._mock();
};
// Handle the variety of parameters accepted by mock (see README)
FetchMock.prototype.once = function (matcher, response, options) {
return this.mock(matcher, response, _extends({}, options, { times: 1 }));
};
// Old method matching signature
if (options && /^[A-Z]+$/.test(response)) {
throw new Error('The API for method matching has changed.\n\t\t\t\tNow use .get(), .post(), .put(), .delete() and .head() shorthand methods,\n\t\t\t\tor pass in, e.g. {method: \'PATCH\'} as a third paramter');
} else if (options) {
route = _extends({
matcher: matcher,
response: response
}, options);
} else if (matcher && response) {
route = {
matcher: matcher,
response: response
};
} else if (matcher && matcher.matcher) {
route = matcher;
} else {
throw new Error('Invalid parameters passed to fetch-mock');
}
FetchMock.prototype._mock = function () {
if (!this.isSandbox) {
// Do this here rather than in the constructor to ensure it's scoped to the test
this.realFetch = this.realFetch || FetchMock.global.fetch;
FetchMock.global.fetch = this.fetchMock;
}
return this;
};
this.addRoute(route);
FetchMock.prototype._unMock = function () {
if (this.realFetch) {
FetchMock.global.fetch = this.realFetch;
this.realFetch = null;
}
this.fallbackResponse = null;
return this;
};
return this._mock();
}
}, {
key: 'once',
value: function once(matcher, response, options) {
return this.mock(matcher, response, _extends({}, options, { times: 1 }));
}
}, {
key: '_mock',
value: function _mock() {
// Do this here rather than in the constructor to ensure it's scoped to the test
this.realFetch = this.realFetch || this.global.fetch;
this.global.fetch = this.fetchMock;
return this;
}
}, {
key: '_unMock',
value: function _unMock() {
if (this.realFetch) {
this.global.fetch = this.realFetch;
this.realFetch = null;
}
this.fallbackResponse = null;
return this;
}
}, {
key: 'catch',
value: function _catch(response) {
if (this.fallbackResponse) {
console.warn('calling fetchMock.catch() twice - are you sure you want to overwrite the previous fallback response');
}
this.fallbackResponse = response || 'ok';
return this._mock();
}
}, {
key: 'spy',
value: function spy() {
this._mock();
return this.catch(this.realFetch);
}
}, {
key: 'fetchMock',
value: function fetchMock(url, opts) {
var _this = this;
FetchMock.prototype.catch = function (response) {
if (this.fallbackResponse) {
console.warn('calling fetchMock.catch() twice - are you sure you want to overwrite the previous fallback response');
}
this.fallbackResponse = response || 'ok';
return this._mock();
};
var response = this.router(url, opts);
FetchMock.prototype.spy = function () {
this._mock();
return this.catch(this.realFetch);
};
if (!response) {
console.warn('unmatched call to ' + url);
this.push(null, [url, opts]);
FetchMock.prototype.fetchMock = function (url, opts) {
var _this = this;
if (this.fallbackResponse) {
response = this.fallbackResponse;
} else {
throw new Error('unmatched call to ' + url);
}
}
var response = this.router(url, opts);
if (typeof response === 'function') {
response = response(url, opts);
}
if (!response) {
console.warn('unmatched call to ' + url);
this.push(null, [url, opts]);
if (typeof response.then === 'function') {
return response.then(function (response) {
return _this.mockResponse(url, response, opts);
});
} else {
return this.mockResponse(url, response, opts);
}
if (this.fallbackResponse) {
response = this.fallbackResponse;
} else {
throw new Error('unmatched call to ' + url);
}
}, {
key: 'router',
value: function router(url, opts) {
var route = void 0;
for (var i = 0, il = this.routes.length; i < il; i++) {
route = this.routes[i];
if (route.matcher(url, opts)) {
this.push(route.name, [url, opts]);
return route.response;
}
}
}
}, {
key: 'addRoute',
value: function addRoute(route) {
}
if (!route) {
throw new Error('.mock() must be passed configuration for a route');
}
if (typeof response === 'function') {
response = response(url, opts);
}
// Allows selective application of some of the preregistered routes
this.routes.push(compileRoute(route, this.Request));
if (typeof response.then === 'function') {
return response.then(function (response) {
return _this.mockResponse(url, response, opts);
});
} else {
return this.mockResponse(url, response, opts);
}
};
FetchMock.prototype.router = function (url, opts) {
var route = void 0;
for (var i = 0, il = this.routes.length; i < il; i++) {
route = this.routes[i];
if (route.matcher(url, opts)) {
this.push(route.name, [url, opts]);
return route.response;
}
}, {
key: 'mockResponse',
value: function mockResponse(url, responseConfig, fetchOpts) {
// It seems odd to call this in here even though it's already called within fetchMock
// It's to handle the fact that because we want to support making it very easy to add a
// delay to any sort of response (including responses which are defined with a function)
// while also allowing function responses to return a Promise for a response config.
if (typeof responseConfig === 'function') {
responseConfig = responseConfig(url, fetchOpts);
}
}
};
if (this.Response.prototype.isPrototypeOf(responseConfig)) {
return Promise.resolve(responseConfig);
}
FetchMock.prototype.addRoute = function (route) {
if (responseConfig.throws) {
return Promise.reject(responseConfig.throws);
}
if (!route) {
throw new Error('.mock() must be passed configuration for a route');
}
if (typeof responseConfig === 'number') {
responseConfig = {
status: responseConfig
};
} else if (typeof responseConfig === 'string' || !(responseConfig.body || responseConfig.headers || responseConfig.throws || responseConfig.status)) {
responseConfig = {
body: responseConfig
};
}
// Allows selective application of some of the preregistered routes
this.routes.push(compileRoute(route, FetchMock.Request));
};
var opts = responseConfig.opts || {};
opts.url = url;
opts.sendAsJson = responseConfig.sendAsJson === undefined ? this.config.sendAsJson : responseConfig.sendAsJson;
if (responseConfig.status && (typeof responseConfig.status !== 'number' || parseInt(responseConfig.status, 10) !== responseConfig.status || responseConfig.status < 200 || responseConfig.status > 599)) {
throw new TypeError('Invalid status ' + responseConfig.status + ' passed on response object.\nTo respond with a JSON object that has status as a property assign the object to body\ne.g. {"body": {"status: "registered"}}');
}
opts.status = responseConfig.status || 200;
opts.statusText = this.statusTextMap['' + opts.status];
// The ternary operator is to cope with new Headers(undefined) throwing in Chrome
// https://code.google.com/p/chromium/issues/detail?id=335871
opts.headers = responseConfig.headers ? new this.Headers(responseConfig.headers) : new this.Headers();
FetchMock.prototype.mockResponse = function (url, responseConfig, fetchOpts) {
// It seems odd to call this in here even though it's already called within fetchMock
// It's to handle the fact that because we want to support making it very easy to add a
// delay to any sort of response (including responses which are defined with a function)
// while also allowing function responses to return a Promise for a response config.
if (typeof responseConfig === 'function') {
responseConfig = responseConfig(url, fetchOpts);
}
var body = responseConfig.body;
if (opts.sendAsJson && responseConfig.body != null && (typeof body === 'undefined' ? 'undefined' : _typeof(body)) === 'object') {
//eslint-disable-line
body = JSON.stringify(body);
}
if (FetchMock.Response.prototype.isPrototypeOf(responseConfig)) {
return Promise.resolve(responseConfig);
}
if (this.stream) {
var s = new this.stream.Readable();
if (body != null) {
//eslint-disable-line
s.push(body, 'utf-8');
}
s.push(null);
body = s;
}
if (responseConfig.throws) {
return Promise.reject(responseConfig.throws);
}
return Promise.resolve(new this.Response(body, opts));
if (typeof responseConfig === 'number') {
responseConfig = {
status: responseConfig
};
} else if (typeof responseConfig === 'string' || !(responseConfig.body || responseConfig.headers || responseConfig.throws || responseConfig.status)) {
responseConfig = {
body: responseConfig
};
}
var opts = responseConfig.opts || {};
opts.url = url;
opts.sendAsJson = responseConfig.sendAsJson === undefined ? this.config.sendAsJson : responseConfig.sendAsJson;
if (responseConfig.status && (typeof responseConfig.status !== 'number' || parseInt(responseConfig.status, 10) !== responseConfig.status || responseConfig.status < 200 || responseConfig.status > 599)) {
throw new TypeError('Invalid status ' + responseConfig.status + ' passed on response object.\nTo respond with a JSON object that has status as a property assign the object to body\ne.g. {"body": {"status: "registered"}}');
}
opts.status = responseConfig.status || 200;
opts.statusText = FetchMock.statusTextMap['' + opts.status];
// The ternary operator is to cope with new Headers(undefined) throwing in Chrome
// https://code.google.com/p/chromium/issues/detail?id=335871
opts.headers = responseConfig.headers ? new FetchMock.Headers(responseConfig.headers) : new FetchMock.Headers();
var body = responseConfig.body;
if (opts.sendAsJson && responseConfig.body != null && (typeof body === 'undefined' ? 'undefined' : _typeof(body)) === 'object') {
//eslint-disable-line
body = JSON.stringify(body);
}
if (FetchMock.stream) {
var s = new FetchMock.stream.Readable();
if (body != null) {
//eslint-disable-line
s.push(body, 'utf-8');
}
}, {
key: 'push',
value: function push(name, call) {
if (name) {
this._calls[name] = this._calls[name] || [];
this._calls[name].push(call);
this._matchedCalls.push(call);
} else {
this._unmatchedCalls.push(call);
}
}
}, {
key: 'restore',
value: function restore() {
this._unMock();
this.reset();
this.routes = [];
return this;
}
}, {
key: 'reset',
value: function reset() {
this._calls = {};
this._matchedCalls = [];
this._unmatchedCalls = [];
this.routes.forEach(function (route) {
return route.reset && route.reset();
});
return this;
}
}, {
key: 'calls',
value: function calls(name) {
return name ? this._calls[name] || [] : {
matched: this._matchedCalls,
unmatched: this._unmatchedCalls
};
}
}, {
key: 'lastCall',
value: function lastCall(name) {
var calls = name ? this.calls(name) : this.calls().matched;
if (calls && calls.length) {
return calls[calls.length - 1];
} else {
return undefined;
}
}
}, {
key: 'lastUrl',
value: function lastUrl(name) {
var call = this.lastCall(name);
return call && call[0];
}
}, {
key: 'lastOptions',
value: function lastOptions(name) {
var call = this.lastCall(name);
return call && call[1];
}
}, {
key: 'called',
value: function called(name) {
if (!name) {
return !!(this._matchedCalls.length || this._unmatchedCalls.length);
}
return !!(this._calls[name] && this._calls[name].length);
}
}, {
key: 'done',
value: function done(name) {
var _this2 = this;
s.push(null);
body = s;
}
var names = name ? [name] : this.routes.map(function (r) {
return r.name;
});
// Ideally would use array.every, but not widely supported
return names.map(function (name) {
if (!_this2.called(name)) {
return false;
}
// would use array.find... but again not so widely supported
var expectedTimes = (_this2.routes.filter(function (r) {
return r.name === name;
}) || [{}])[0].times;
return !expectedTimes || expectedTimes <= _this2.calls(name).length;
}).filter(function (bool) {
return !bool;
}).length === 0;
return Promise.resolve(new FetchMock.Response(body, opts));
};
FetchMock.prototype.push = function (name, call) {
if (name) {
this._calls[name] = this._calls[name] || [];
this._calls[name].push(call);
this._matchedCalls.push(call);
} else {
this._unmatchedCalls.push(call);
}
};
FetchMock.prototype.restore = function () {
this._unMock();
this.reset();
this.routes = [];
return this;
};
FetchMock.prototype.reset = function () {
this._calls = {};
this._matchedCalls = [];
this._unmatchedCalls = [];
this.routes.forEach(function (route) {
return route.reset && route.reset();
});
return this;
};
FetchMock.prototype.calls = function (name) {
return name ? this._calls[name] || [] : {
matched: this._matchedCalls,
unmatched: this._unmatchedCalls
};
};
FetchMock.prototype.lastCall = function (name) {
var calls = name ? this.calls(name) : this.calls().matched;
if (calls && calls.length) {
return calls[calls.length - 1];
} else {
return undefined;
}
};
FetchMock.prototype.lastUrl = function (name) {
var call = this.lastCall(name);
return call && call[0];
};
FetchMock.prototype.lastOptions = function (name) {
var call = this.lastCall(name);
return call && call[1];
};
FetchMock.prototype.called = function (name) {
if (!name) {
return !!(this._matchedCalls.length || this._unmatchedCalls.length);
}
return !!(this._calls[name] && this._calls[name].length);
};
FetchMock.prototype.done = function (name) {
var _this2 = this;
var names = name ? [name] : this.routes.map(function (r) {
return r.name;
});
// Ideally would use array.every, but not widely supported
return names.map(function (name) {
if (!_this2.called(name)) {
return false;
}
}, {
key: 'configure',
value: function configure(opts) {
_extends(this.config, opts);
}
}]);
// would use array.find... but again not so widely supported
var expectedTimes = (_this2.routes.filter(function (r) {
return r.name === name;
}) || [{}])[0].times;
return !expectedTimes || expectedTimes <= _this2.calls(name).length;
}).filter(function (bool) {
return !bool;
}).length === 0;
};
return FetchMock;
}();
FetchMock.prototype.configure = function (opts) {
_extends(this.config, opts);
};
FetchMock.prototype.sandbox = function () {
if (this.routes.length || this.fallbackResponse) {
throw new Error('.sandbox() can only be called on fetch-mock instances that don\'t have routes configured already');
}
var instance = new FetchMock();
_extends(instance.fetchMock, // the function
FetchMock.prototype, // all prototype methods
instance // instance data
);
instance.fetchMock.bindMethods();
instance.fetchMock.isSandbox = true;
this.restore();
return instance.fetchMock;
};
FetchMock.setGlobals = function (globals) {
_extends(FetchMock, globals);
};
['get', 'post', 'put', 'delete', 'head', 'patch'].forEach(function (method) {

@@ -476,5 +476,3 @@ FetchMock.prototype[method] = function (matcher, response, options) {

module.exports = function (opts) {
return new FetchMock(opts);
};
module.exports = FetchMock;
},{"./compile-route":2}],4:[function(require,module,exports){

@@ -481,0 +479,0 @@ 'use strict';

'use strict';
var fetchMock = require('./fetch-mock');
var FetchMock = require('./fetch-mock');
var statusTextMap = require('./status-text');
var theGlobal = typeof window !== 'undefined' ? window : self;
module.exports = fetchMock({
FetchMock.setGlobals({
global: theGlobal,

@@ -13,2 +13,4 @@ Request: theGlobal.Request,

statusTextMap: statusTextMap
});
});
module.exports = new FetchMock();

@@ -7,311 +7,309 @@ 'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var compileRoute = require('./compile-route');
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var FetchMock = function FetchMock() {
var compileRoute = require('./compile-route');
this.config = {
sendAsJson: true
};
var FetchMock = function () {
function FetchMock(opts) {
_classCallCheck(this, FetchMock);
// if (opts) {
// FetchMock.Headers = opts.Headers;
// FetchMock.Request = opts.Request;
// FetchMock.Response = opts.Response;
// FetchMock.stream = opts.stream;
// FetchMock.global = opts.global;
// FetchMock.statusTextMap = opts.statusTextMap;
// }
this.config = {
sendAsJson: true
this.routes = [];
this._calls = {};
this._matchedCalls = [];
this._unmatchedCalls = [];
this.bindMethods();
};
FetchMock.prototype.bindMethods = function () {
this.fetchMock = FetchMock.prototype.fetchMock.bind(this);
this.restore = FetchMock.prototype.restore.bind(this);
this.reset = FetchMock.prototype.reset.bind(this);
};
FetchMock.prototype.mock = function (matcher, response, options) {
var route = void 0;
// Handle the variety of parameters accepted by mock (see README)
// Old method matching signature
if (options && /^[A-Z]+$/.test(response)) {
throw new Error('The API for method matching has changed.\n\t\t\tNow use .get(), .post(), .put(), .delete() and .head() shorthand methods,\n\t\t\tor pass in, e.g. {method: \'PATCH\'} as a third paramter');
} else if (options) {
route = _extends({
matcher: matcher,
response: response
}, options);
} else if (matcher && response) {
route = {
matcher: matcher,
response: response
};
this.Headers = opts.Headers;
this.Request = opts.Request;
this.Response = opts.Response;
this.stream = opts.stream;
this.global = opts.global;
this.statusTextMap = opts.statusTextMap;
this.routes = [];
this._calls = {};
this._matchedCalls = [];
this._unmatchedCalls = [];
this.fetchMock = this.fetchMock.bind(this);
this.restore = this.restore.bind(this);
this.reset = this.reset.bind(this);
} else if (matcher && matcher.matcher) {
route = matcher;
} else {
throw new Error('Invalid parameters passed to fetch-mock');
}
_createClass(FetchMock, [{
key: 'mock',
value: function mock(matcher, response, options) {
this.addRoute(route);
var route = void 0;
return this._mock();
};
// Handle the variety of parameters accepted by mock (see README)
FetchMock.prototype.once = function (matcher, response, options) {
return this.mock(matcher, response, _extends({}, options, { times: 1 }));
};
// Old method matching signature
if (options && /^[A-Z]+$/.test(response)) {
throw new Error('The API for method matching has changed.\n\t\t\t\tNow use .get(), .post(), .put(), .delete() and .head() shorthand methods,\n\t\t\t\tor pass in, e.g. {method: \'PATCH\'} as a third paramter');
} else if (options) {
route = _extends({
matcher: matcher,
response: response
}, options);
} else if (matcher && response) {
route = {
matcher: matcher,
response: response
};
} else if (matcher && matcher.matcher) {
route = matcher;
} else {
throw new Error('Invalid parameters passed to fetch-mock');
}
FetchMock.prototype._mock = function () {
if (!this.isSandbox) {
// Do this here rather than in the constructor to ensure it's scoped to the test
this.realFetch = this.realFetch || FetchMock.global.fetch;
FetchMock.global.fetch = this.fetchMock;
}
return this;
};
this.addRoute(route);
FetchMock.prototype._unMock = function () {
if (this.realFetch) {
FetchMock.global.fetch = this.realFetch;
this.realFetch = null;
}
this.fallbackResponse = null;
return this;
};
return this._mock();
}
}, {
key: 'once',
value: function once(matcher, response, options) {
return this.mock(matcher, response, _extends({}, options, { times: 1 }));
}
}, {
key: '_mock',
value: function _mock() {
// Do this here rather than in the constructor to ensure it's scoped to the test
this.realFetch = this.realFetch || this.global.fetch;
this.global.fetch = this.fetchMock;
return this;
}
}, {
key: '_unMock',
value: function _unMock() {
if (this.realFetch) {
this.global.fetch = this.realFetch;
this.realFetch = null;
}
this.fallbackResponse = null;
return this;
}
}, {
key: 'catch',
value: function _catch(response) {
if (this.fallbackResponse) {
console.warn('calling fetchMock.catch() twice - are you sure you want to overwrite the previous fallback response');
}
this.fallbackResponse = response || 'ok';
return this._mock();
}
}, {
key: 'spy',
value: function spy() {
this._mock();
return this.catch(this.realFetch);
}
}, {
key: 'fetchMock',
value: function fetchMock(url, opts) {
var _this = this;
FetchMock.prototype.catch = function (response) {
if (this.fallbackResponse) {
console.warn('calling fetchMock.catch() twice - are you sure you want to overwrite the previous fallback response');
}
this.fallbackResponse = response || 'ok';
return this._mock();
};
var response = this.router(url, opts);
FetchMock.prototype.spy = function () {
this._mock();
return this.catch(this.realFetch);
};
if (!response) {
console.warn('unmatched call to ' + url);
this.push(null, [url, opts]);
FetchMock.prototype.fetchMock = function (url, opts) {
var _this = this;
if (this.fallbackResponse) {
response = this.fallbackResponse;
} else {
throw new Error('unmatched call to ' + url);
}
}
var response = this.router(url, opts);
if (typeof response === 'function') {
response = response(url, opts);
}
if (!response) {
console.warn('unmatched call to ' + url);
this.push(null, [url, opts]);
if (typeof response.then === 'function') {
return response.then(function (response) {
return _this.mockResponse(url, response, opts);
});
} else {
return this.mockResponse(url, response, opts);
}
if (this.fallbackResponse) {
response = this.fallbackResponse;
} else {
throw new Error('unmatched call to ' + url);
}
}, {
key: 'router',
value: function router(url, opts) {
var route = void 0;
for (var i = 0, il = this.routes.length; i < il; i++) {
route = this.routes[i];
if (route.matcher(url, opts)) {
this.push(route.name, [url, opts]);
return route.response;
}
}
}
}, {
key: 'addRoute',
value: function addRoute(route) {
}
if (!route) {
throw new Error('.mock() must be passed configuration for a route');
}
if (typeof response === 'function') {
response = response(url, opts);
}
// Allows selective application of some of the preregistered routes
this.routes.push(compileRoute(route, this.Request));
if (typeof response.then === 'function') {
return response.then(function (response) {
return _this.mockResponse(url, response, opts);
});
} else {
return this.mockResponse(url, response, opts);
}
};
FetchMock.prototype.router = function (url, opts) {
var route = void 0;
for (var i = 0, il = this.routes.length; i < il; i++) {
route = this.routes[i];
if (route.matcher(url, opts)) {
this.push(route.name, [url, opts]);
return route.response;
}
}, {
key: 'mockResponse',
value: function mockResponse(url, responseConfig, fetchOpts) {
// It seems odd to call this in here even though it's already called within fetchMock
// It's to handle the fact that because we want to support making it very easy to add a
// delay to any sort of response (including responses which are defined with a function)
// while also allowing function responses to return a Promise for a response config.
if (typeof responseConfig === 'function') {
responseConfig = responseConfig(url, fetchOpts);
}
}
};
if (this.Response.prototype.isPrototypeOf(responseConfig)) {
return Promise.resolve(responseConfig);
}
FetchMock.prototype.addRoute = function (route) {
if (responseConfig.throws) {
return Promise.reject(responseConfig.throws);
}
if (!route) {
throw new Error('.mock() must be passed configuration for a route');
}
if (typeof responseConfig === 'number') {
responseConfig = {
status: responseConfig
};
} else if (typeof responseConfig === 'string' || !(responseConfig.body || responseConfig.headers || responseConfig.throws || responseConfig.status)) {
responseConfig = {
body: responseConfig
};
}
// Allows selective application of some of the preregistered routes
this.routes.push(compileRoute(route, FetchMock.Request));
};
var opts = responseConfig.opts || {};
opts.url = url;
opts.sendAsJson = responseConfig.sendAsJson === undefined ? this.config.sendAsJson : responseConfig.sendAsJson;
if (responseConfig.status && (typeof responseConfig.status !== 'number' || parseInt(responseConfig.status, 10) !== responseConfig.status || responseConfig.status < 200 || responseConfig.status > 599)) {
throw new TypeError('Invalid status ' + responseConfig.status + ' passed on response object.\nTo respond with a JSON object that has status as a property assign the object to body\ne.g. {"body": {"status: "registered"}}');
}
opts.status = responseConfig.status || 200;
opts.statusText = this.statusTextMap['' + opts.status];
// The ternary operator is to cope with new Headers(undefined) throwing in Chrome
// https://code.google.com/p/chromium/issues/detail?id=335871
opts.headers = responseConfig.headers ? new this.Headers(responseConfig.headers) : new this.Headers();
FetchMock.prototype.mockResponse = function (url, responseConfig, fetchOpts) {
// It seems odd to call this in here even though it's already called within fetchMock
// It's to handle the fact that because we want to support making it very easy to add a
// delay to any sort of response (including responses which are defined with a function)
// while also allowing function responses to return a Promise for a response config.
if (typeof responseConfig === 'function') {
responseConfig = responseConfig(url, fetchOpts);
}
var body = responseConfig.body;
if (opts.sendAsJson && responseConfig.body != null && (typeof body === 'undefined' ? 'undefined' : _typeof(body)) === 'object') {
//eslint-disable-line
body = JSON.stringify(body);
}
if (FetchMock.Response.prototype.isPrototypeOf(responseConfig)) {
return Promise.resolve(responseConfig);
}
if (this.stream) {
var s = new this.stream.Readable();
if (body != null) {
//eslint-disable-line
s.push(body, 'utf-8');
}
s.push(null);
body = s;
}
if (responseConfig.throws) {
return Promise.reject(responseConfig.throws);
}
return Promise.resolve(new this.Response(body, opts));
if (typeof responseConfig === 'number') {
responseConfig = {
status: responseConfig
};
} else if (typeof responseConfig === 'string' || !(responseConfig.body || responseConfig.headers || responseConfig.throws || responseConfig.status)) {
responseConfig = {
body: responseConfig
};
}
var opts = responseConfig.opts || {};
opts.url = url;
opts.sendAsJson = responseConfig.sendAsJson === undefined ? this.config.sendAsJson : responseConfig.sendAsJson;
if (responseConfig.status && (typeof responseConfig.status !== 'number' || parseInt(responseConfig.status, 10) !== responseConfig.status || responseConfig.status < 200 || responseConfig.status > 599)) {
throw new TypeError('Invalid status ' + responseConfig.status + ' passed on response object.\nTo respond with a JSON object that has status as a property assign the object to body\ne.g. {"body": {"status: "registered"}}');
}
opts.status = responseConfig.status || 200;
opts.statusText = FetchMock.statusTextMap['' + opts.status];
// The ternary operator is to cope with new Headers(undefined) throwing in Chrome
// https://code.google.com/p/chromium/issues/detail?id=335871
opts.headers = responseConfig.headers ? new FetchMock.Headers(responseConfig.headers) : new FetchMock.Headers();
var body = responseConfig.body;
if (opts.sendAsJson && responseConfig.body != null && (typeof body === 'undefined' ? 'undefined' : _typeof(body)) === 'object') {
//eslint-disable-line
body = JSON.stringify(body);
}
if (FetchMock.stream) {
var s = new FetchMock.stream.Readable();
if (body != null) {
//eslint-disable-line
s.push(body, 'utf-8');
}
}, {
key: 'push',
value: function push(name, call) {
if (name) {
this._calls[name] = this._calls[name] || [];
this._calls[name].push(call);
this._matchedCalls.push(call);
} else {
this._unmatchedCalls.push(call);
}
}
}, {
key: 'restore',
value: function restore() {
this._unMock();
this.reset();
this.routes = [];
return this;
}
}, {
key: 'reset',
value: function reset() {
this._calls = {};
this._matchedCalls = [];
this._unmatchedCalls = [];
this.routes.forEach(function (route) {
return route.reset && route.reset();
});
return this;
}
}, {
key: 'calls',
value: function calls(name) {
return name ? this._calls[name] || [] : {
matched: this._matchedCalls,
unmatched: this._unmatchedCalls
};
}
}, {
key: 'lastCall',
value: function lastCall(name) {
var calls = name ? this.calls(name) : this.calls().matched;
if (calls && calls.length) {
return calls[calls.length - 1];
} else {
return undefined;
}
}
}, {
key: 'lastUrl',
value: function lastUrl(name) {
var call = this.lastCall(name);
return call && call[0];
}
}, {
key: 'lastOptions',
value: function lastOptions(name) {
var call = this.lastCall(name);
return call && call[1];
}
}, {
key: 'called',
value: function called(name) {
if (!name) {
return !!(this._matchedCalls.length || this._unmatchedCalls.length);
}
return !!(this._calls[name] && this._calls[name].length);
}
}, {
key: 'done',
value: function done(name) {
var _this2 = this;
s.push(null);
body = s;
}
var names = name ? [name] : this.routes.map(function (r) {
return r.name;
});
// Ideally would use array.every, but not widely supported
return names.map(function (name) {
if (!_this2.called(name)) {
return false;
}
// would use array.find... but again not so widely supported
var expectedTimes = (_this2.routes.filter(function (r) {
return r.name === name;
}) || [{}])[0].times;
return !expectedTimes || expectedTimes <= _this2.calls(name).length;
}).filter(function (bool) {
return !bool;
}).length === 0;
return Promise.resolve(new FetchMock.Response(body, opts));
};
FetchMock.prototype.push = function (name, call) {
if (name) {
this._calls[name] = this._calls[name] || [];
this._calls[name].push(call);
this._matchedCalls.push(call);
} else {
this._unmatchedCalls.push(call);
}
};
FetchMock.prototype.restore = function () {
this._unMock();
this.reset();
this.routes = [];
return this;
};
FetchMock.prototype.reset = function () {
this._calls = {};
this._matchedCalls = [];
this._unmatchedCalls = [];
this.routes.forEach(function (route) {
return route.reset && route.reset();
});
return this;
};
FetchMock.prototype.calls = function (name) {
return name ? this._calls[name] || [] : {
matched: this._matchedCalls,
unmatched: this._unmatchedCalls
};
};
FetchMock.prototype.lastCall = function (name) {
var calls = name ? this.calls(name) : this.calls().matched;
if (calls && calls.length) {
return calls[calls.length - 1];
} else {
return undefined;
}
};
FetchMock.prototype.lastUrl = function (name) {
var call = this.lastCall(name);
return call && call[0];
};
FetchMock.prototype.lastOptions = function (name) {
var call = this.lastCall(name);
return call && call[1];
};
FetchMock.prototype.called = function (name) {
if (!name) {
return !!(this._matchedCalls.length || this._unmatchedCalls.length);
}
return !!(this._calls[name] && this._calls[name].length);
};
FetchMock.prototype.done = function (name) {
var _this2 = this;
var names = name ? [name] : this.routes.map(function (r) {
return r.name;
});
// Ideally would use array.every, but not widely supported
return names.map(function (name) {
if (!_this2.called(name)) {
return false;
}
}, {
key: 'configure',
value: function configure(opts) {
_extends(this.config, opts);
}
}]);
// would use array.find... but again not so widely supported
var expectedTimes = (_this2.routes.filter(function (r) {
return r.name === name;
}) || [{}])[0].times;
return !expectedTimes || expectedTimes <= _this2.calls(name).length;
}).filter(function (bool) {
return !bool;
}).length === 0;
};
return FetchMock;
}();
FetchMock.prototype.configure = function (opts) {
_extends(this.config, opts);
};
FetchMock.prototype.sandbox = function () {
if (this.routes.length || this.fallbackResponse) {
throw new Error('.sandbox() can only be called on fetch-mock instances that don\'t have routes configured already');
}
var instance = new FetchMock();
_extends(instance.fetchMock, // the function
FetchMock.prototype, // all prototype methods
instance // instance data
);
instance.fetchMock.bindMethods();
instance.fetchMock.isSandbox = true;
this.restore();
return instance.fetchMock;
};
FetchMock.setGlobals = function (globals) {
_extends(FetchMock, globals);
};
['get', 'post', 'put', 'delete', 'head', 'patch'].forEach(function (method) {

@@ -326,4 +324,2 @@ FetchMock.prototype[method] = function (matcher, response, options) {

module.exports = function (opts) {
return new FetchMock(opts);
};
module.exports = FetchMock;

@@ -8,6 +8,6 @@ 'use strict';

var stream = require('stream');
var fetchMock = require('./fetch-mock');
var FetchMock = require('./fetch-mock');
var http = require('http');
module.exports = fetchMock({
FetchMock.setGlobals({
global: global,

@@ -19,2 +19,4 @@ Request: Request,

statusTextMap: http.STATUS_CODES
});
});
module.exports = new FetchMock();
{
"name": "fetch-mock",
"version": "5.5.0",
"version": "5.6.0",
"description": "Mock http requests made using fetch (or isomorphic-fetch)",

@@ -5,0 +5,0 @@ "main": "src/server.js",

@@ -100,8 +100,3 @@ # fetch-mock [![Build Status](https://travis-ci.org/wheresrhys/fetch-mock.svg?branch=master)](https://travis-ci.org/wheresrhys/fetch-mock)

##### `get()`
##### `post()`
##### `put()`
##### `delete()`
##### `head()`
##### `patch()`
##### `get()`, `post()`, `put()`, `delete()`, `head()`, `patch()`
Shorthands for `mock()` restricted to a particular method *Tip: if you use some other method a lot you can easily define your own shorthands e.g.:*

@@ -116,8 +111,3 @@

##### `getOnce()`
##### `postOnce()`
##### `putOnce()`
##### `deleteOnce()`
##### `headOnce()`
##### `patchOnce()`
##### `getOnce()`, `postOnce()`, `putOnce()`, `deleteOnce()`, `headOnce()`, `patchOnce()`
Shorthands for `mock()` restricted to a particular method and that can only be called one time only

@@ -128,5 +118,2 @@

##### `spy()`
Similar to `catch()`, this records the call history of unmatched calls, but instead of responding with a stubbed response, the request is passed through to native `fetch()` and is allowed to communicate over the network.
```

@@ -138,2 +125,12 @@ fetchMock

##### `spy()`
Similar to `catch()`, this records the call history of unmatched calls, but instead of responding with a stubbed response, the request is passed through to native `fetch()` and is allowed to communicate over the network.
##### `sandbox()` *experimental*
This returns a drop-in mock for fetch which can be passed to other mocking libraries. It implements the full fetch-mock api and maintains its own state independent of other instances, so tests can be run in parallel. e.g.
```
fetchMock.sandbox().mock('http://domain.com', 200)
```
##### `restore()`

@@ -149,3 +146,3 @@ Chainable method that restores `fetch()` to its unstubbed state and clears all data recorded for its calls.

**For the methods below `matcherName`, if given, should be either the name of a route (see advanced usage below) or equal to `matcher.toString()` for any unnamed route.**
**For the methods below `matcherName`, if given, should be either the name of a route (see advanced usage below) or equal to `matcher.toString()` for any unnamed route. You _can_ pass in the original regex or function used as a matcher, but they will be converted to strings and used to look up values in fetch-mock's internal maps of calls, rather than used as regexes or functions**

@@ -152,0 +149,0 @@ ##### `called(matcherName)`

'use strict';
const fetchMock = require('./fetch-mock');
const FetchMock = require('./fetch-mock');
const statusTextMap = require('./status-text');
const theGlobal = typeof window !== 'undefined' ? window : self;
module.exports = fetchMock({
FetchMock.setGlobals({
global: theGlobal,

@@ -14,1 +14,3 @@ Request: theGlobal.Request,

});
module.exports = new FetchMock()

@@ -5,272 +5,300 @@ 'use strict';

class FetchMock {
constructor (opts) {
this.config = {
sendAsJson: true
}
this.Headers = opts.Headers;
this.Request = opts.Request;
this.Response = opts.Response;
this.stream = opts.stream;
this.global = opts.global;
this.statusTextMap = opts.statusTextMap;
this.routes = [];
this._calls = {};
this._matchedCalls = [];
this._unmatchedCalls = [];
this.fetchMock = this.fetchMock.bind(this);
this.restore = this.restore.bind(this);
this.reset = this.reset.bind(this);
const FetchMock = function () {
this.config = {
sendAsJson: true
}
mock (matcher, response, options) {
// if (opts) {
// FetchMock.Headers = opts.Headers;
// FetchMock.Request = opts.Request;
// FetchMock.Response = opts.Response;
// FetchMock.stream = opts.stream;
// FetchMock.global = opts.global;
// FetchMock.statusTextMap = opts.statusTextMap;
// }
let route;
this.routes = [];
this._calls = {};
this._matchedCalls = [];
this._unmatchedCalls = [];
this.bindMethods();
}
// Handle the variety of parameters accepted by mock (see README)
FetchMock.prototype.bindMethods = function () {
this.fetchMock = FetchMock.prototype.fetchMock.bind(this);
this.restore = FetchMock.prototype.restore.bind(this);
this.reset = FetchMock.prototype.reset.bind(this);
}
// Old method matching signature
if (options && /^[A-Z]+$/.test(response)) {
throw new Error(`The API for method matching has changed.
Now use .get(), .post(), .put(), .delete() and .head() shorthand methods,
or pass in, e.g. {method: 'PATCH'} as a third paramter`);
} else if (options) {
route = Object.assign({
matcher,
response
}, options);
} else if (matcher && response) {
route = {
matcher,
response
}
} else if (matcher && matcher.matcher) {
route = matcher
} else {
throw new Error('Invalid parameters passed to fetch-mock')
}
FetchMock.prototype.mock = function (matcher, response, options) {
let route;
this.addRoute(route);
// Handle the variety of parameters accepted by mock (see README)
return this._mock();
// Old method matching signature
if (options && /^[A-Z]+$/.test(response)) {
throw new Error(`The API for method matching has changed.
Now use .get(), .post(), .put(), .delete() and .head() shorthand methods,
or pass in, e.g. {method: 'PATCH'} as a third paramter`);
} else if (options) {
route = Object.assign({
matcher,
response
}, options);
} else if (matcher && response) {
route = {
matcher,
response
}
} else if (matcher && matcher.matcher) {
route = matcher
} else {
throw new Error('Invalid parameters passed to fetch-mock')
}
once (matcher, response, options) {
return this.mock(matcher, response, Object.assign({}, options, {times: 1}));
}
_mock () {
this.addRoute(route);
return this._mock();
}
FetchMock.prototype.once = function (matcher, response, options) {
return this.mock(matcher, response, Object.assign({}, options, {times: 1}));
}
FetchMock.prototype._mock = function () {
if (!this.isSandbox) {
// Do this here rather than in the constructor to ensure it's scoped to the test
this.realFetch = this.realFetch || this.global.fetch;
this.global.fetch = this.fetchMock;
return this;
this.realFetch = this.realFetch || FetchMock.global.fetch;
FetchMock.global.fetch = this.fetchMock;
}
return this;
}
_unMock () {
if (this.realFetch) {
this.global.fetch = this.realFetch;
this.realFetch = null;
}
this.fallbackResponse = null;
return this;
FetchMock.prototype._unMock = function () {
if (this.realFetch) {
FetchMock.global.fetch = this.realFetch;
this.realFetch = null;
}
this.fallbackResponse = null;
return this;
}
catch (response) {
if (this.fallbackResponse) {
console.warn(`calling fetchMock.catch() twice - are you sure you want to overwrite the previous fallback response`);
}
this.fallbackResponse = response || 'ok';
return this._mock();
FetchMock.prototype.catch = function (response) {
if (this.fallbackResponse) {
console.warn(`calling fetchMock.catch() twice - are you sure you want to overwrite the previous fallback response`);
}
this.fallbackResponse = response || 'ok';
return this._mock();
}
spy () {
this._mock();
return this.catch(this.realFetch)
}
FetchMock.prototype.spy = function () {
this._mock();
return this.catch(this.realFetch)
}
fetchMock (url, opts) {
FetchMock.prototype.fetchMock = function (url, opts) {
let response = this.router(url, opts);
let response = this.router(url, opts);
if (!response) {
console.warn(`unmatched call to ${url}`);
this.push(null, [url, opts]);
if (!response) {
console.warn(`unmatched call to ${url}`);
this.push(null, [url, opts]);
if (this.fallbackResponse) {
response = this.fallbackResponse;
} else {
throw new Error(`unmatched call to ${url}`)
}
}
if (typeof response === 'function') {
response = response (url, opts);
}
if (typeof response.then === 'function') {
return response.then(response => this.mockResponse(url, response, opts))
if (this.fallbackResponse) {
response = this.fallbackResponse;
} else {
return this.mockResponse(url, response, opts)
throw new Error(`unmatched call to ${url}`)
}
}
if (typeof response === 'function') {
response = response (url, opts);
}
router (url, opts) {
let route;
for (let i = 0, il = this.routes.length; i < il ; i++) {
route = this.routes[i];
if (route.matcher(url, opts)) {
this.push(route.name, [url, opts]);
return route.response;
}
}
if (typeof response.then === 'function') {
return response.then(response => this.mockResponse(url, response, opts))
} else {
return this.mockResponse(url, response, opts)
}
addRoute (route) {
}
if (!route) {
throw new Error('.mock() must be passed configuration for a route')
FetchMock.prototype.router = function (url, opts) {
let route;
for (let i = 0, il = this.routes.length; i < il ; i++) {
route = this.routes[i];
if (route.matcher(url, opts)) {
this.push(route.name, [url, opts]);
return route.response;
}
}
}
// Allows selective application of some of the preregistered routes
this.routes.push(compileRoute(route, this.Request));
FetchMock.prototype.addRoute = function (route) {
if (!route) {
throw new Error('.mock() must be passed configuration for a route')
}
// Allows selective application of some of the preregistered routes
this.routes.push(compileRoute(route, FetchMock.Request));
}
mockResponse (url, responseConfig, fetchOpts) {
// It seems odd to call this in here even though it's already called within fetchMock
// It's to handle the fact that because we want to support making it very easy to add a
// delay to any sort of response (including responses which are defined with a function)
// while also allowing function responses to return a Promise for a response config.
if (typeof responseConfig === 'function') {
responseConfig = responseConfig(url, fetchOpts);
}
if (this.Response.prototype.isPrototypeOf(responseConfig)) {
return Promise.resolve(responseConfig);
}
FetchMock.prototype.mockResponse = function (url, responseConfig, fetchOpts) {
// It seems odd to call this in here even though it's already called within fetchMock
// It's to handle the fact that because we want to support making it very easy to add a
// delay to any sort of response (including responses which are defined with a function)
// while also allowing function responses to return a Promise for a response config.
if (typeof responseConfig === 'function') {
responseConfig = responseConfig(url, fetchOpts);
}
if (responseConfig.throws) {
return Promise.reject(responseConfig.throws);
}
if (FetchMock.Response.prototype.isPrototypeOf(responseConfig)) {
return Promise.resolve(responseConfig);
}
if (typeof responseConfig === 'number') {
responseConfig = {
status: responseConfig
};
} else if (typeof responseConfig === 'string' || !(responseConfig.body || responseConfig.headers || responseConfig.throws || responseConfig.status)) {
responseConfig = {
body: responseConfig
};
}
if (responseConfig.throws) {
return Promise.reject(responseConfig.throws);
}
const opts = responseConfig.opts || {};
opts.url = url;
opts.sendAsJson = responseConfig.sendAsJson === undefined ? this.config.sendAsJson : responseConfig.sendAsJson;
if (responseConfig.status && (typeof responseConfig.status !== 'number' || parseInt(responseConfig.status, 10) !== responseConfig.status || responseConfig.status < 200 || responseConfig.status > 599)) {
throw new TypeError(`Invalid status ${responseConfig.status} passed on response object.
if (typeof responseConfig === 'number') {
responseConfig = {
status: responseConfig
};
} else if (typeof responseConfig === 'string' || !(responseConfig.body || responseConfig.headers || responseConfig.throws || responseConfig.status)) {
responseConfig = {
body: responseConfig
};
}
const opts = responseConfig.opts || {};
opts.url = url;
opts.sendAsJson = responseConfig.sendAsJson === undefined ? this.config.sendAsJson : responseConfig.sendAsJson;
if (responseConfig.status && (typeof responseConfig.status !== 'number' || parseInt(responseConfig.status, 10) !== responseConfig.status || responseConfig.status < 200 || responseConfig.status > 599)) {
throw new TypeError(`Invalid status ${responseConfig.status} passed on response object.
To respond with a JSON object that has status as a property assign the object to body
e.g. {"body": {"status: "registered"}}`);
}
opts.status = responseConfig.status || 200;
opts.statusText = this.statusTextMap['' + opts.status];
// The ternary operator is to cope with new Headers(undefined) throwing in Chrome
// https://code.google.com/p/chromium/issues/detail?id=335871
opts.headers = responseConfig.headers ? new this.Headers(responseConfig.headers) : new this.Headers();
}
opts.status = responseConfig.status || 200;
opts.statusText = FetchMock.statusTextMap['' + opts.status];
// The ternary operator is to cope with new Headers(undefined) throwing in Chrome
// https://code.google.com/p/chromium/issues/detail?id=335871
opts.headers = responseConfig.headers ? new FetchMock.Headers(responseConfig.headers) : new FetchMock.Headers();
let body = responseConfig.body;
if (opts.sendAsJson && responseConfig.body != null && typeof body === 'object') { //eslint-disable-line
body = JSON.stringify(body);
}
if (this.stream) {
let s = new this.stream.Readable();
if (body != null) { //eslint-disable-line
s.push(body, 'utf-8');
}
s.push(null);
body = s;
}
return Promise.resolve(new this.Response(body, opts));
let body = responseConfig.body;
if (opts.sendAsJson && responseConfig.body != null && typeof body === 'object') { //eslint-disable-line
body = JSON.stringify(body);
}
push (name, call) {
if (name) {
this._calls[name] = this._calls[name] || [];
this._calls[name].push(call);
this._matchedCalls.push(call);
} else {
this._unmatchedCalls.push(call);
if (FetchMock.stream) {
let s = new FetchMock.stream.Readable();
if (body != null) { //eslint-disable-line
s.push(body, 'utf-8');
}
s.push(null);
body = s;
}
restore () {
this._unMock();
this.reset();
this.routes = [];
return this;
}
return Promise.resolve(new FetchMock.Response(body, opts));
}
reset () {
this._calls = {};
this._matchedCalls = [];
this._unmatchedCalls = [];
this.routes.forEach(route => route.reset && route.reset())
return this;
FetchMock.prototype.push = function (name, call) {
if (name) {
this._calls[name] = this._calls[name] || [];
this._calls[name].push(call);
this._matchedCalls.push(call);
} else {
this._unmatchedCalls.push(call);
}
}
calls (name) {
return name ? (this._calls[name] || []) : {
matched: this._matchedCalls,
unmatched: this._unmatchedCalls
};
}
FetchMock.prototype.restore = function () {
this._unMock();
this.reset();
this.routes = [];
return this;
}
lastCall (name) {
const calls = name ? this.calls(name) : this.calls().matched;
if (calls && calls.length) {
return calls[calls.length - 1];
} else {
return undefined;
}
}
FetchMock.prototype.reset = function () {
this._calls = {};
this._matchedCalls = [];
this._unmatchedCalls = [];
this.routes.forEach(route => route.reset && route.reset())
return this;
}
lastUrl (name) {
const call = this.lastCall(name);
return call && call[0];
FetchMock.prototype.calls = function (name) {
return name ? (this._calls[name] || []) : {
matched: this._matchedCalls,
unmatched: this._unmatchedCalls
};
}
FetchMock.prototype.lastCall = function (name) {
const calls = name ? this.calls(name) : this.calls().matched;
if (calls && calls.length) {
return calls[calls.length - 1];
} else {
return undefined;
}
}
lastOptions (name) {
const call = this.lastCall(name);
return call && call[1];
FetchMock.prototype.lastUrl = function (name) {
const call = this.lastCall(name);
return call && call[0];
}
FetchMock.prototype.lastOptions = function (name) {
const call = this.lastCall(name);
return call && call[1];
}
FetchMock.prototype.called = function (name) {
if (!name) {
return !!(this._matchedCalls.length || this._unmatchedCalls.length);
}
return !!(this._calls[name] && this._calls[name].length);
}
called (name) {
if (!name) {
return !!(this._matchedCalls.length || this._unmatchedCalls.length);
FetchMock.prototype.done = function (name) {
const names = name ? [name] : this.routes.map(r => r.name);
// Ideally would use array.every, but not widely supported
return names.map(name => {
if (!this.called(name)) {
return false
}
return !!(this._calls[name] && this._calls[name].length);
}
// would use array.find... but again not so widely supported
const expectedTimes = (this.routes.filter(r => r.name === name) || [{}])[0].times;
return !expectedTimes || (expectedTimes <= this.calls(name).length)
})
.filter(bool => !bool).length === 0
}
done (name) {
const names = name ? [name] : this.routes.map(r => r.name);
// Ideally would use array.every, but not widely supported
return names.map(name => {
if (!this.called(name)) {
return false
}
// would use array.find... but again not so widely supported
const expectedTimes = (this.routes.filter(r => r.name === name) || [{}])[0].times;
return !expectedTimes || (expectedTimes <= this.calls(name).length)
})
.filter(bool => !bool).length === 0
}
FetchMock.prototype.configure = function (opts) {
Object.assign(this.config, opts);
}
configure (opts) {
Object.assign(this.config, opts);
FetchMock.prototype.sandbox = function () {
if (this.routes.length || this.fallbackResponse) {
throw new Error('.sandbox() can only be called on fetch-mock instances that don\'t have routes configured already')
}
}
const instance = new FetchMock();
Object.assign(
instance.fetchMock, // the function
FetchMock.prototype, // all prototype methods
instance // instance data
);
instance.fetchMock.bindMethods();
instance.fetchMock.isSandbox = true;
this.restore();
return instance.fetchMock
};
FetchMock.setGlobals = function (globals) {
Object.assign(FetchMock, globals)
};
['get','post','put','delete','head', 'patch']

@@ -286,4 +314,2 @@ .forEach(method => {

module.exports = function (opts) {
return new FetchMock(opts);
}
module.exports = FetchMock;

@@ -7,6 +7,6 @@ 'use strict';

const stream = require('stream');
const fetchMock = require('./fetch-mock');
const FetchMock = require('./fetch-mock');
const http = require('http');
module.exports = fetchMock({
FetchMock.setGlobals({
global: global,

@@ -19,1 +19,3 @@ Request: Request,

});
module.exports = new FetchMock()
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc