diff --git a/docs/docs/@fetch-mock/core/CallHistory.md b/docs/docs/@fetch-mock/core/CallHistory.md index 62a46780..2037bc01 100644 --- a/docs/docs/@fetch-mock/core/CallHistory.md +++ b/docs/docs/@fetch-mock/core/CallHistory.md @@ -74,11 +74,7 @@ Returns a Boolean indicating whether any calls to `fetch` matched the given `fil Returns the `CallLog` for the last call to `fetch` matching the given `filter` and `options`. -### fetchMock.done(routeNames) - -_Note that this function is exposed on the `fetchMock` object, not on `fetchMock.callHistory`_ - -TODO, should callHistory just have access to `routes`... yes probably as these docs are horrible +### .done(routeNames) Returns a Boolean indicating whether `fetch` was called the expected number of times (or has been called at least once if `repeat` is not defined for the route). It does not take into account whether the `fetches` completed successfully. diff --git a/docs/docs/@fetch-mock/core/route/matcher.md b/docs/docs/@fetch-mock/core/route/matcher.md index 21c2bcfe..8a4fc331 100644 --- a/docs/docs/@fetch-mock/core/route/matcher.md +++ b/docs/docs/@fetch-mock/core/route/matcher.md @@ -116,7 +116,7 @@ Match only requests that have these query parameters set (in any order). Query p Match only requests that send a JSON body with the exact structure and properties as the one provided here. -Note that if matching on body _and_ using `Request` instances in your source code, this forces fetch-mock into an asynchronous flow _before_ it is able to route requests effectively. This means no [inspection methods](#api-inspectionfundamentals) can be used synchronously. You must first either await the fetches to resolve, or `await fetchMock.flush()`. The popular library [Ky](https://github.com/sindresorhus/ky) uses `Request` instances internally, and so also triggers this mode. +Note that if matching on body _and_ using `Request` instances in your source code, this forces fetch-mock into an asynchronous flow _before_ it is able to route requests effectively. This means no [inspection methods](#api-inspectionfundamentals) can be used synchronously. You must first either await the fetches to resolve, or `await fetchMock.callHistory.flush()`. The popular library [Ky](https://github.com/sindresorhus/ky) uses `Request` instances internally, and so also triggers this mode. e.g.`{body: { "key1": "value1", "key2": "value2" }}` diff --git a/packages/core/src/CallHistory.js b/packages/core/src/CallHistory.js index 045f818e..08208233 100644 --- a/packages/core/src/CallHistory.js +++ b/packages/core/src/CallHistory.js @@ -44,11 +44,13 @@ const isMatchedOrUnmatched = (filter) => class CallHistory { /** * @param {FetchMockConfig} globalConfig + * @param router */ - constructor(globalConfig) { + constructor(globalConfig, router) { /** @type {CallLog[]} */ this.callLogs = []; this.config = globalConfig; + this.router = router; } /** * @@ -163,17 +165,19 @@ class CallHistory { lastCall(filter, options) { return this.calls(filter, options).pop(); } + /** - * - * @param {RouteName[]} [routeNames] - * @param {Route[]} allRoutes + * @param {RouteName|RouteName[]} [routeNames] * @returns {boolean} */ - done(allRoutes, routeNames) { - const routesToCheck = routeNames - ? allRoutes.filter(({ config: { name } }) => routeNames.includes(name)) - : allRoutes; - + done(routeNames) { + let routesToCheck = this.router.routes; + if (routeNames) { + routeNames = Array.isArray(routeNames) ? routeNames : [routeNames]; + routesToCheck = this.router.routes.filter(({ config: { name } }) => + routeNames.includes(name), + ); + } // TODO when checking all routes needs to check against all calls // Can't use array.every because would exit after first failure, which would // break the logging diff --git a/packages/core/src/FetchMock.js b/packages/core/src/FetchMock.js index 76feff83..e893cc10 100644 --- a/packages/core/src/FetchMock.js +++ b/packages/core/src/FetchMock.js @@ -55,7 +55,7 @@ const defaultConfig = { const FetchMock = { config: defaultConfig, router: new Router(defaultConfig), - callHistory: new CallHistory(defaultConfig), + callHistory: new CallHistory(defaultConfig, this.router), createInstance() { const instance = Object.create(FetchMock); instance.config = { ...this.config }; @@ -63,7 +63,7 @@ const FetchMock = { routes: [...this.router.routes], fallbackRoute: this.router.fallbackRoute, }); - instance.callHistory = new CallHistory(this.config); + instance.callHistory = new CallHistory(instance.config, instance.router); return instance; }, /** @@ -122,23 +122,6 @@ const FetchMock = { defineMatcher(matcher) { Route.defineMatcher(matcher); }, - flush(waitForResponseBody) { - return this.callHistory.flush(waitForResponseBody); - }, - /** - * - * @param {RouteName|RouteName[]} routeNames - * @returns {boolean} - */ - done(routeNames) { - if (!routeNames) { - return this.callHistory.done(this.router.routes); - } - return this.callHistory.done( - this.router.routes, - Array.isArray(routeNames) ? routeNames : [routeNames], - ); - }, removeRoutes(options) { this.router.removeRoutes(options); return this; diff --git a/packages/core/src/__tests__/CallHistory.test.js b/packages/core/src/__tests__/CallHistory.test.js index 889e66dc..47c70989 100644 --- a/packages/core/src/__tests__/CallHistory.test.js +++ b/packages/core/src/__tests__/CallHistory.test.js @@ -362,11 +362,11 @@ describe('CallHistory', () => { it('clearHistory() resets count done-ness', async () => { fm = fetchMock.createInstance().route('http://a.com/', 200); await fm.fetchHandler('http://a.com/'); - expect(fm.done()).toBe(true); + expect(fm.callHistory.done()).toBe(true); fm.clearHistory(); - expect(fm.done()).toBe(false); + expect(fm.callHistory.done()).toBe(false); await fm.fetchHandler('http://a.com/'); - expect(fm.done()).toBe(true); + expect(fm.callHistory.done()).toBe(true); }); describe('where number of expected calls is not specified', () => { @@ -379,32 +379,32 @@ describe('CallHistory', () => { }); it('can expect at least one call to have been made to every defined route', () => { - expect(fm.done()).toBe(false); + expect(fm.callHistory.done()).toBe(false); fm.fetchHandler('http://a.com/'); - expect(fm.done()).toBe(false); + expect(fm.callHistory.done()).toBe(false); fm.fetchHandler('http://b.com/'); - expect(fm.done()).toBe(false); + expect(fm.callHistory.done()).toBe(false); fm.fetchHandler('http://c.com/'); - expect(fm.done()).toBe(true); + expect(fm.callHistory.done()).toBe(true); }); it('can expect a named route to be called at least once', () => { - expect(fm.done('a')).toBe(false); - expect(fm.done('b')).toBe(false); + expect(fm.callHistory.done('a')).toBe(false); + expect(fm.callHistory.done('b')).toBe(false); fm.fetchHandler('http://a.com/'); - expect(fm.done('a')).toBe(true); - expect(fm.done('b')).toBe(false); + expect(fm.callHistory.done('a')).toBe(true); + expect(fm.callHistory.done('b')).toBe(false); fm.fetchHandler('http://a.com/'); - expect(fm.done('a')).toBe(true); - expect(fm.done('b')).toBe(false); + expect(fm.callHistory.done('a')).toBe(true); + expect(fm.callHistory.done('b')).toBe(false); }); it('can expect multiple named routes to be called at least once each', () => { - expect(fm.done(['a', 'b'])).toBe(false); + expect(fm.callHistory.done(['a', 'b'])).toBe(false); fm.fetchHandler('http://a.com/'); - expect(fm.done(['a', 'b'])).toBe(false); + expect(fm.callHistory.done(['a', 'b'])).toBe(false); fm.fetchHandler('http://b.com/'); - expect(fm.done(['a', 'b'])).toBe(true); + expect(fm.callHistory.done(['a', 'b'])).toBe(true); }); }); describe('where number of expected calls is specified', () => { @@ -417,32 +417,32 @@ describe('CallHistory', () => { }); it('can expect a named route to be called specified number of times', () => { - expect(fm.done('a')).toBe(false); + expect(fm.callHistory.done('a')).toBe(false); fm.fetchHandler('http://a.com/'); - expect(fm.done('a')).toBe(false); + expect(fm.callHistory.done('a')).toBe(false); fm.fetchHandler('http://a.com/'); - expect(fm.done('a')).toBe(true); + expect(fm.callHistory.done('a')).toBe(true); }); it('can expect multiple named routes to be called specified number of times', () => { - expect(fm.done(['a', 'b'])).toBe(false); + expect(fm.callHistory.done(['a', 'b'])).toBe(false); fm.fetchHandler('http://a.com/'); fm.fetchHandler('http://b.com/'); - expect(fm.done(['a', 'b'])).toBe(false); + expect(fm.callHistory.done(['a', 'b'])).toBe(false); fm.fetchHandler('http://a.com/'); - expect(fm.done(['a', 'b'])).toBe(true); + expect(fm.callHistory.done(['a', 'b'])).toBe(true); }); it('can expect specific number of calls to have been made to every defined route', () => { - expect(fm.done()).toBe(false); + expect(fm.callHistory.done()).toBe(false); fm.fetchHandler('http://a.com/'); fm.fetchHandler('http://b.com/'); fm.fetchHandler('http://c.com/'); - expect(fm.done()).toBe(false); + expect(fm.callHistory.done()).toBe(false); fm.fetchHandler('http://a.com/'); - expect(fm.done()).toBe(false); + expect(fm.callHistory.done()).toBe(false); fm.fetchHandler('http://c.com/'); - expect(fm.done()).toBe(true); + expect(fm.callHistory.done()).toBe(true); }); it('can combine with routes where specific number of calls is unspecified', () => { @@ -452,15 +452,15 @@ describe('CallHistory', () => { .route('http://b.com/', 200, { name: 'b' }) .route('http://c.com/', 200); - expect(fm.done()).toBe(false); + expect(fm.callHistory.done()).toBe(false); fm.fetchHandler('http://a.com/'); fm.fetchHandler('http://b.com/'); fm.fetchHandler('http://c.com/'); - expect(fm.done()).toBe(false); - expect(fm.done(['a', 'b'])).toBe(false); + expect(fm.callHistory.done()).toBe(false); + expect(fm.callHistory.done(['a', 'b'])).toBe(false); fm.fetchHandler('http://a.com/'); - expect(fm.done()).toBe(true); - expect(fm.done(['a', 'b'])).toBe(true); + expect(fm.callHistory.done()).toBe(true); + expect(fm.callHistory.done(['a', 'b'])).toBe(true); }); }); }); diff --git a/packages/core/src/__tests__/FetchMock/flush.test.js b/packages/core/src/__tests__/FetchMock/flush.test.js index 6c7b426a..b5aa22b0 100644 --- a/packages/core/src/__tests__/FetchMock/flush.test.js +++ b/packages/core/src/__tests__/FetchMock/flush.test.js @@ -12,11 +12,11 @@ describe('FetchMockWrapper.js', () => { fm.route('http://one.com/', 200).route('http://two.com/', 200); // no expectation, but if it doesn't work then the promises will hang // or reject and the test will timeout - await fm.flush(); + await fm.callHistory.flush(); fm.fetchHandler('http://one.com'); - await fm.flush(); + await fm.callHistory.flush(); fm.fetchHandler('http://two.com'); - await fm.flush(); + await fm.callHistory.flush(); }); it('should resolve after fetches', async () => { @@ -25,7 +25,7 @@ describe('FetchMockWrapper.js', () => { fm.fetchHandler('http://example').then(() => { data = 'done'; }); - await fm.flush(); + await fm.callHistory.flush(); expect(data).toEqual('done'); }); @@ -38,7 +38,7 @@ describe('FetchMockWrapper.js', () => { data = 'done'; }); - await fm.flush(true); + await fm.callHistory.flush(true); expect(data).toEqual('done'); }); it('should resolve after .json() if waitForResponseMethods option passed', async () => { @@ -50,7 +50,7 @@ describe('FetchMockWrapper.js', () => { data = 'done'; }); - await fm.flush(true); + await fm.callHistory.flush(true); expect(data).toEqual('done'); }); @@ -63,7 +63,7 @@ describe('FetchMockWrapper.js', () => { data = 'done'; }); - await fm.flush(true); + await fm.callHistory.flush(true); expect(data).toEqual('done'); }); }); @@ -80,14 +80,14 @@ describe('FetchMockWrapper.js', () => { setTimeout(() => orderedResults.push('not flush'), 25); - await fm.flush(); + await fm.callHistory.flush(); orderedResults.push('flush'); expect(orderedResults).toEqual(['not flush', 'flush']); }); it('flush resolves on expected error', async () => { fm.route('http://one.com/', { throws: 'Problem in space' }); - await fm.flush(); + await fm.callHistory.flush(); }); }); }); diff --git a/packages/core/src/__tests__/FetchMock/response-negotiation.test.js b/packages/core/src/__tests__/FetchMock/response-negotiation.test.js index 8c6b2509..78cc3db0 100644 --- a/packages/core/src/__tests__/FetchMock/response-negotiation.test.js +++ b/packages/core/src/__tests__/FetchMock/response-negotiation.test.js @@ -209,7 +209,7 @@ describe('response negotiation', () => { await expectAbortError('http://a.com', { signal: getDelayedAbortController().signal, }); - expect(fm.done()).toBe(true); + expect(fm.callHistory.done()).toBe(true); }); it('will flush even when aborted', async () => { @@ -218,8 +218,8 @@ describe('response negotiation', () => { await expectAbortError('http://a.com', { signal: getDelayedAbortController().signal, }); - await fm.flush(); - expect(fm.done()).toBe(true); + await fm.callHistory.flush(); + expect(fm.callHistory.done()).toBe(true); }); }); });