Repository: wheresrhys/fetch-mock (js)

Issue:
Remove top level done and flush methods
In @fetch-mock/core just expose them on callHistory

Pull request:
Rhys/no top level done
fixes #715 

Patch:
diff --git a/docs/docs/@fetch-mock/core/CallHistory.md b/docs/docs/@fetch-mock/core/CallHistory.md
index 62a4678..2037bc0 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 21c2bcf..8a4fc33 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 045f818..0820823 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 76feff8..e893cc1 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;


Test patch:
diff --git a/packages/core/src/__tests__/CallHistory.test.js b/packages/core/src/__tests__/CallHistory.test.js
index 889e66d..47c7098 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 6c7b426..b5aa22b 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 8c6b250..78cc3db 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);
 		});
 	});
 });