Skip to content

Commit

Permalink
Merge pull request #875 from wheresrhys/rhys/hardReset
Browse files Browse the repository at this point in the history
Rhys/hard reset
  • Loading branch information
wheresrhys authored Nov 15, 2024
2 parents a84cf47 + 757d480 commit edf15aa
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 25 deletions.
4 changes: 4 additions & 0 deletions docs/docs/API/resetting.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ sidebar_position: 5

The methods below can be used to restore some or all of fetchMock's behaviour toits default state.

## .hardReset(options)

Removes all the behaviour and state that's been added so far. It runs `.removeRoutes()`, `.clearHistory()` and `.unmockGlobal()`. Pass `{includeSticky: true}` to force even sticky routes to be removed.

## .removeRoutes(options)

This method removes some or all of the routes that have been added to fetch mock. It accepts the following options.
Expand Down
1 change: 1 addition & 0 deletions docs/docs/Usage/upgrade-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,5 @@ The same is true for `postOnce()`, `deleteOnce()` etc.
This was principally used when mocking node-fetch referenced as a local variable. Given that `fetch` is now available as a native global it's less useful and has been removed. If necessary to mock a local instance of node-fetch use [`.fetchHandler`](/fetch-mock/docs/API/mocking-and-spying#fetchhandler)

### Types completely written

There are many changes, both in the naming and structuring of types. Refer to the errors generated by your toolchain to update these.
4 changes: 2 additions & 2 deletions docs/src/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ export default function Home() {
const { siteConfig } = useDocusaurusContext();
return (
<Layout
title={`Hello from ${siteConfig.title}`}
description="Description will go into a meta tag in <head />"
description={`${siteConfig.tagline} Runs in a wide range of environments, from node.js to service workers,
and compatible with most testing frameworks.`}
>
<HomepageHeader />
<main>
Expand Down
22 changes: 4 additions & 18 deletions packages/codemods/src/__tests__/method-codemods.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,35 +66,21 @@ describe('codemods operating on methods', () => {

describe('converting resetting methods', () => {
it('rewrites restore()', () => {
expectCodemodResult(
'fetchMock.restore()',
`fetchMock.clearHistory();
fetchMock.removeRoutes();
fetchMock.unmockGlobal();`,
);
expectCodemodResult('fetchMock.restore()', `fetchMock.hardReset();`);
});
it('rewrites restore() with {sticky: true}', () => {
expectCodemodResult(
'fetchMock.restore({sticky: true})',
`fetchMock.clearHistory();
fetchMock.removeRoutes({includeSticky: true});
fetchMock.unmockGlobal();`,
`fetchMock.hardReset({includeSticky: true});`,
);
});
it('rewrites reset()', () => {
expectCodemodResult(
'fetchMock.reset()',
`fetchMock.clearHistory();
fetchMock.removeRoutes();
fetchMock.unmockGlobal();`,
);
expectCodemodResult('fetchMock.reset()', `fetchMock.hardReset();`);
});
it('rewrites reset() with {sticky: true}', () => {
expectCodemodResult(
'fetchMock.reset({sticky: true})',
`fetchMock.clearHistory();
fetchMock.removeRoutes({includeSticky: true});
fetchMock.unmockGlobal();`,
`fetchMock.hardReset({includeSticky: true});`,
);
});

Expand Down
13 changes: 9 additions & 4 deletions packages/codemods/src/codemods/methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,16 @@ module.exports.simpleMethods = function (fetchMockVariableName, root) {
const sticky = path?.value?.arguments[0]?.properties?.find(
(prop) => prop.key.name === 'sticky',
)?.value?.value;
const newExpressions = j(`
${methodName !== 'resetBehavior' ? 'fetchMock.clearHistory()' : ''};
let expressionsString;
if (methodName === 'resetBehavior') {
expressionsString = `
fetchMock.removeRoutes(${sticky ? '{includeSticky: true}' : ''});
fetchMock.unmockGlobal();
`)
fetchMock.unmockGlobal();`;
} else {
expressionsString = `
fetchMock.hardReset(${sticky ? '{includeSticky: true}' : ''});`;
}
const newExpressions = j(expressionsString)
.find(j.ExpressionStatement)
.paths();
const insertLocation = j(path)
Expand Down
11 changes: 11 additions & 0 deletions packages/fetch-mock/src/FetchMock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import { MatcherDefinition, RouteMatcher } from './Matchers.js';
import CallHistory from './CallHistory.js';
import * as requestUtils from './RequestUtils.js';

export type HardResetOptions = {
includeSticky?: boolean;
};

export type FetchMockGlobalConfig = {
includeContentLength?: boolean;
matchPartialBody?: boolean;
Expand Down Expand Up @@ -146,6 +150,13 @@ export class FetchMock {
return this;
}

hardReset(options?: HardResetOptions): FetchMock {
this.clearHistory();
this.removeRoutes(options as RemoveRouteOptions);
this.unmockGlobal();
return this;
}

spy(
this: FetchMock,
matcher?: RouteMatcher | UserRouteConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,27 @@ describe('instance management', () => {
expect(fm.router.routes.length).toEqual(0);
});
});

describe('hardReset', () => {
it('can hardReset and leave just sticky routes', () => {
const fm = fetchMock.createInstance();
fm.route('*', 200, { sticky: true, name: 'sticky' }).route('*', 200);
fm.mockGlobal();
fm.fetchHandler('http://a.com');
fm.hardReset();
expect(fm.callHistory.callLogs.length).toBe(0);
expect(globalThis.fetch).not.toEqual(fm.fetchHandler);
expect(fm.router.routes[0].config.name).toBe('sticky');
});
it('can hardReset including sticky routes', () => {
const fm = fetchMock.createInstance();
fm.route('*', 200, { sticky: true, name: 'sticky' }).route('*', 200);
fm.mockGlobal();
fm.fetchHandler('http://a.com');
fm.hardReset({ includeSticky: true });
expect(fm.callHistory.callLogs.length).toBe(0);
expect(globalThis.fetch).not.toEqual(fm.fetchHandler);
expect(fm.router.routes.length).toBe(0);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ describe('mock and spy', () => {
fm.mockGlobal().unmockGlobal();
expect(globalThis.fetch).toEqual(nativeFetch);
});

it('does not error when called on unmocked fetch', () => {
expect(() => fm.unmockGlobal()).not.toThrow();
});
});
describe('.spy()', () => {
testChainableMethod('spy');
Expand Down
1 change: 0 additions & 1 deletion packages/jest/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export function manageFetchMockGlobally(jest: Jest) {
const { clearAllMocks, resetAllMocks, restoreAllMocks } = jest;

jest.clearAllMocks = () => {
console.log('yeah');
clearAllMocks.apply(jest);
fetchMockJest.mockClear();
return jest;
Expand Down

0 comments on commit edf15aa

Please sign in to comment.