Skip to content

Commit

Permalink
feat: remove debug mode from fetch-mock
Browse files Browse the repository at this point in the history
  • Loading branch information
wheresrhys committed Aug 10, 2024
1 parent 0fb5c9f commit 89890b6
Show file tree
Hide file tree
Showing 10 changed files with 479 additions and 969 deletions.
1,208 changes: 476 additions & 732 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion packages/fetch-mock/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
},
"homepage": "http://www.wheresrhys.co.uk/fetch-mock",
"dependencies": {
"debug": "^4.1.1",
"dequal": "^2.0.3",
"globrex": "^0.1.2",
"is-subset": "^0.1.1",
Expand Down
30 changes: 0 additions & 30 deletions packages/fetch-mock/src/Route/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import builtInMatchers from './matchers.js';
import { debug, setDebugNamespace, getDebug } from '../lib/debug.js';

const isUrlMatcher = (matcher) =>
matcher instanceof RegExp ||
Expand All @@ -14,8 +13,6 @@ const nameToOptions = (options) =>
class Route {
constructor(args, fetchMock) {
this.fetchMock = fetchMock;
const debug = getDebug('compileRoute()');
debug('Compiling route');
this.init(args);
this.sanitize();
this.validate();
Expand Down Expand Up @@ -63,32 +60,21 @@ class Route {
}

sanitize() {
const debug = getDebug('sanitize()');
debug('Sanitizing route properties');

if (this.method) {
debug(`Converting method ${this.method} to lower case`);
this.method = this.method.toLowerCase();
}
if (isUrlMatcher(this.matcher)) {
debug('Mock uses a url matcher', this.matcher);
this.url = this.matcher;
delete this.matcher;
}

this.functionMatcher = this.matcher || this.functionMatcher;

debug('Setting route.identifier...');
debug(` route.name is ${this.name}`);
debug(` route.url is ${this.url}`);
debug(` route.functionMatcher is ${this.functionMatcher}`);
this.identifier = this.name || this.url || this.functionMatcher;
debug(` -> route.identifier set to ${this.identifier}`);
}

generateMatcher() {
setDebugNamespace('generateMatcher()');
debug('Compiling matcher for route');

const activeMatchers = Route.registeredMatchers
.map(
Expand All @@ -99,23 +85,15 @@ class Route {

this.usesBody = activeMatchers.some(({ usesBody }) => usesBody);

debug('Compiled matcher for route');
setDebugNamespace();
this.matcher = (url, options = {}, request) =>
activeMatchers.every(({ matcher }) => matcher(url, options, request));
}

limit() {
const debug = getDebug('limit()');
debug('Limiting number of requests to handle by route');
if (!this.repeat) {
debug(
' No `repeat` value set on route. Will match any number of requests',
);
return;
}

debug(` Route set to repeat ${this.repeat} times`);
const { matcher } = this;
let timesLeft = this.repeat;
this.matcher = (url, options) => {
Expand All @@ -131,21 +109,13 @@ class Route {
}

delayResponse() {
const debug = getDebug('delayResponse()');
debug('Applying response delay settings');
if (this.delay) {
debug(` Wrapping response in delay of ${this.delay} miliseconds`);
const { response } = this;
this.response = () => {
debug(`Delaying response by ${this.delay} miliseconds`);
return new Promise((res) =>
setTimeout(() => res(response), this.delay),
);
};
} else {
debug(
" No delay set on route. Will respond 'immediately' (but asynchronously)",
);
}
}

Expand Down
54 changes: 1 addition & 53 deletions packages/fetch-mock/src/Route/matchers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ import {
getQuery,
normalizeUrl,
} from '../lib/request-utils.js';
import { debug } from '../lib/debug.js';

const debuggableUrlFunc = (func) => (url) => {
debug('Actual url:', url);
return func(url);
};

Expand All @@ -35,46 +33,32 @@ const stringMatchers = {
};

const getHeaderMatcher = ({ headers: expectedHeaders }) => {
debug('Generating header matcher');
if (!expectedHeaders) {
debug(' No header expectations defined - skipping');
return;
}
const expectation = headerUtils.toLowerCase(expectedHeaders);
debug(' Expected headers:', expectation);
return (url, { headers = {} }) => {
debug('Attempting to match headers');
const lowerCaseHeaders = headerUtils.toLowerCase(
headerUtils.normalize(headers),
);
debug(' Expected headers:', expectation);
debug(' Actual headers:', lowerCaseHeaders);
return Object.keys(expectation).every((headerName) =>
headerUtils.equal(lowerCaseHeaders[headerName], expectation[headerName]),
);
};
};

const getMethodMatcher = ({ method: expectedMethod }) => {
debug('Generating method matcher');
if (!expectedMethod) {
debug(' No method expectations defined - skipping');
return;
}
debug(' Expected method:', expectedMethod);
return (url, { method }) => {
debug('Attempting to match method');
const actualMethod = method ? method.toLowerCase() : 'get';
debug(' Expected method:', expectedMethod);
debug(' Actual method:', actualMethod);
return expectedMethod === actualMethod;
};
};

const getQueryStringMatcher = ({ query: passedQuery }) => {
debug('Generating query parameters matcher');
if (!passedQuery) {
debug(' No query parameters expectations defined - skipping');
return;
}

Expand All @@ -101,14 +85,8 @@ const getQueryStringMatcher = ({ query: passedQuery }) => {

const keys = Array.from(expectedQuery.keys());
return (url) => {
debug('Attempting to match query parameters');
const queryString = getQuery(url);
const query = new URLSearchParams(queryString);
debug(
' Expected query parameters:',
Object.fromEntries(expectedQuery.entries()),
);
debug(' Actual query parameters:', Object.fromEntries(query.entries()));

return keys.every((key) => {
const expectedValues = expectedQuery.getAll(key).sort();
Expand All @@ -130,30 +108,24 @@ const getQueryStringMatcher = ({ query: passedQuery }) => {
};

const getParamsMatcher = ({ params: expectedParams, url: matcherUrl }) => {
debug('Generating path parameters matcher');
if (!expectedParams) {
debug(' No path parameters expectations defined - skipping');
return;
}
if (!/express:/.test(matcherUrl)) {
throw new Error(
'fetch-mock: matching on params is only possible when using an express: matcher',
);
}
debug(' Expected path parameters:', expectedParams);
const expectedKeys = Object.keys(expectedParams);
const re = regexparam.parse(matcherUrl.replace(/^express:/, ''));
return (url) => {
debug('Attempting to match path parameters');
const vals = re.pattern.exec(getPath(url)) || [];
vals.shift();
const params = re.keys.reduce(
(map, paramName, i) =>
vals[i] ? Object.assign(map, { [paramName]: vals[i] }) : map,
{},
);
debug(' Expected path parameters:', expectedParams);
debug(' Actual path parameters:', params);
return expectedKeys.every((key) => params[key] === expectedParams[key]);
};
};
Expand All @@ -162,28 +134,17 @@ const getBodyMatcher = (route, fetchMock) => {
const matchPartialBody = fetchMock.getOption('matchPartialBody', route);
const { body: expectedBody } = route;

debug('Generating body matcher');
return (url, { body, method = 'get' }) => {
debug('Attempting to match body');
if (method.toLowerCase() === 'get') {
debug(' GET request - skip matching body');
// GET requests don’t send a body so the body matcher should be ignored for them
return true;
}

let sentBody;

try {
debug(' Parsing request body as JSON');
sentBody = JSON.parse(body);
} catch (err) {
debug(' Failed to parse request body as JSON', err);
}
debug('Expected body:', expectedBody);
debug('Actual body:', sentBody);
if (matchPartialBody) {
debug('matchPartialBody is true - checking for partial match only');
}
} catch {} // eslint-disable-line no-empty

return (
sentBody &&
Expand All @@ -199,55 +160,42 @@ const getFullUrlMatcher = (route, matcherUrl, query) => {
// but we have to be careful to normalize the url we check and the name
// of the route to allow for e.g. http://it.at.there being indistinguishable
// from http://it.at.there/ once we start generating Request/Url objects
debug(' Matching using full url', matcherUrl);
const expectedUrl = normalizeUrl(matcherUrl);
debug(' Normalised url to:', matcherUrl);
if (route.identifier === matcherUrl) {
debug(' Updating route identifier to match normalized url:', matcherUrl);
route.identifier = expectedUrl;
}

return (matcherUrl) => {
debug('Expected url:', expectedUrl);
debug('Actual url:', matcherUrl);
if (query && expectedUrl.indexOf('?')) {
debug('Ignoring query string when matching url');
return matcherUrl.indexOf(expectedUrl) === 0;
}
return normalizeUrl(matcherUrl) === expectedUrl;
};
};

const getFunctionMatcher = ({ functionMatcher }) => {
debug('Detected user defined function matcher', functionMatcher);
return (...args) => {
debug('Calling function matcher with arguments', args);
return functionMatcher(...args);
};
};

const getUrlMatcher = (route) => {
debug('Generating url matcher');
const { url: matcherUrl, query } = route;

if (matcherUrl === '*') {
debug(' Using universal * rule to match any url');
return () => true;
}

if (matcherUrl instanceof RegExp) {
debug(' Using regular expression to match url:', matcherUrl);
return (url) => matcherUrl.test(url);
}

if (matcherUrl.href) {
debug(' Using URL object to match url', matcherUrl);
return getFullUrlMatcher(route, matcherUrl.href, query);
}

for (const shorthand in stringMatchers) {
if (matcherUrl.indexOf(`${shorthand}:`) === 0) {
debug(` Using ${shorthand}: pattern to match url`, matcherUrl);
const urlFragment = matcherUrl.replace(new RegExp(`^${shorthand}:`), '');
return stringMatchers[shorthand](urlFragment);
}
Expand Down
27 changes: 0 additions & 27 deletions packages/fetch-mock/src/lib/debug.js

This file was deleted.

Loading

0 comments on commit 89890b6

Please sign in to comment.