@khanacademy/wonder-blocks-testing-core 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/es/index.js +22 -4
- package/dist/fetch/types.d.ts +50 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +22 -4
- package/dist/mock-requester.d.ts +1 -1
- package/dist/types.d.ts +67 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dist/es/index.js
CHANGED
|
@@ -52,19 +52,33 @@ const fetchRequestMatchesMock = (mock, input, init) => {
|
|
|
52
52
|
|
|
53
53
|
const mockRequester = (operationMatcher, operationToString) => {
|
|
54
54
|
const mocks = [];
|
|
55
|
-
const
|
|
55
|
+
const configuration = {
|
|
56
|
+
hardFailOnUnmockedRequests: false
|
|
57
|
+
};
|
|
58
|
+
const getMatchingMock = (...args) => {
|
|
56
59
|
for (const mock of mocks) {
|
|
57
60
|
if (mock.onceOnly && mock.used) {
|
|
58
61
|
continue;
|
|
59
62
|
}
|
|
60
63
|
if (operationMatcher(mock.operation, ...args)) {
|
|
61
64
|
mock.used = true;
|
|
62
|
-
return mock
|
|
65
|
+
return mock;
|
|
63
66
|
}
|
|
64
67
|
}
|
|
68
|
+
return null;
|
|
69
|
+
};
|
|
70
|
+
const mockFn = (...args) => {
|
|
71
|
+
const matchingMock = getMatchingMock(...args);
|
|
72
|
+
if (matchingMock) {
|
|
73
|
+
return matchingMock.response();
|
|
74
|
+
}
|
|
65
75
|
const operation = operationToString(...args);
|
|
66
|
-
|
|
67
|
-
${operation}`)
|
|
76
|
+
const noMatchError = new Error(`No matching mock response found for request:
|
|
77
|
+
${operation}`);
|
|
78
|
+
if (configuration.hardFailOnUnmockedRequests) {
|
|
79
|
+
throw noMatchError;
|
|
80
|
+
}
|
|
81
|
+
return Promise.reject(noMatchError);
|
|
68
82
|
};
|
|
69
83
|
const addMockedOperation = (operation, response, onceOnly) => {
|
|
70
84
|
const mockResponse = () => response.toPromise();
|
|
@@ -78,6 +92,10 @@ const mockRequester = (operationMatcher, operationToString) => {
|
|
|
78
92
|
};
|
|
79
93
|
mockFn.mockOperation = (operation, response) => addMockedOperation(operation, response, false);
|
|
80
94
|
mockFn.mockOperationOnce = (operation, response) => addMockedOperation(operation, response, true);
|
|
95
|
+
mockFn.configure = config => {
|
|
96
|
+
Object.assign(configuration, config);
|
|
97
|
+
return mockFn;
|
|
98
|
+
};
|
|
81
99
|
return mockFn;
|
|
82
100
|
};
|
|
83
101
|
|
package/dist/fetch/types.d.ts
CHANGED
|
@@ -1,9 +1,58 @@
|
|
|
1
1
|
import type { MockResponse } from "../respond-with";
|
|
2
|
+
import { ConfigureFn } from "../types";
|
|
2
3
|
export type FetchMockOperation = RegExp | string;
|
|
3
|
-
|
|
4
|
+
interface FetchMockOperationFn {
|
|
5
|
+
(
|
|
6
|
+
/**
|
|
7
|
+
* The operation to match.
|
|
8
|
+
*
|
|
9
|
+
* This is a string for an exact match, or a regex. This is compared to
|
|
10
|
+
* to the URL of the fetch request to determine if it is a matching
|
|
11
|
+
* request.
|
|
12
|
+
*/
|
|
13
|
+
operation: FetchMockOperation,
|
|
14
|
+
/**
|
|
15
|
+
* The response to return when the operation is matched.
|
|
16
|
+
*/
|
|
17
|
+
response: MockResponse<any>): FetchMockFn;
|
|
18
|
+
}
|
|
4
19
|
export type FetchMockFn = {
|
|
20
|
+
/**
|
|
21
|
+
* The mock fetch function.
|
|
22
|
+
*
|
|
23
|
+
* This function is a drop-in replacement for the fetch function. You should
|
|
24
|
+
* not need to call this function directly. Just replace the normal fetch
|
|
25
|
+
* function implementation with this.
|
|
26
|
+
*/
|
|
5
27
|
(input: RequestInfo, init?: RequestInit): Promise<Response>;
|
|
28
|
+
/**
|
|
29
|
+
* Mock a fetch operation.
|
|
30
|
+
*
|
|
31
|
+
* This adds a response for a given mocked operation. Regardless of how
|
|
32
|
+
* many times this mock is matched, it will be used.
|
|
33
|
+
*
|
|
34
|
+
* @returns The mock fetch function for chaining.
|
|
35
|
+
*/
|
|
6
36
|
mockOperation: FetchMockOperationFn;
|
|
37
|
+
/**
|
|
38
|
+
* Mock a fetch operation once.
|
|
39
|
+
*
|
|
40
|
+
* This adds a response for a given mocked operation that will only be used
|
|
41
|
+
* once and discarded.
|
|
42
|
+
*
|
|
43
|
+
* @returns The mock fetch function for chaining.
|
|
44
|
+
*/
|
|
7
45
|
mockOperationOnce: FetchMockOperationFn;
|
|
46
|
+
/**
|
|
47
|
+
* Configure the mock fetch function with the given configuration.
|
|
48
|
+
*
|
|
49
|
+
* This function is provided as a convenience to allow for configuring the
|
|
50
|
+
* mock fetch function in a fluent manner. The configuration is applied
|
|
51
|
+
* to all mocks for a given fetch function; the last configuration applied
|
|
52
|
+
* will be the one that is used for all mocked operations.
|
|
53
|
+
*
|
|
54
|
+
* @returns The mock fetch function for chaining.
|
|
55
|
+
*/
|
|
56
|
+
configure: ConfigureFn<FetchMockOperation, any>;
|
|
8
57
|
};
|
|
9
58
|
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export { RespondWith } from "./respond-with";
|
|
|
6
6
|
export { SettleController } from "./settle-controller";
|
|
7
7
|
export type { MockResponse } from "./respond-with";
|
|
8
8
|
export type { FetchMockFn, FetchMockOperation } from "./fetch/types";
|
|
9
|
-
export type { GraphQLJson, MockFn, OperationMock, OperationMatcher, MockOperationFn, } from "./types";
|
|
9
|
+
export type { GraphQLJson, MockFn, OperationMock, OperationMatcher, MockOperationFn, MockConfiguration, ConfigureFn, } from "./types";
|
|
10
10
|
export * from "./harness/types";
|
|
11
11
|
export * as harnessAdapters from "./harness/adapters/adapters";
|
|
12
12
|
export { makeHookHarness } from "./harness/make-hook-harness";
|
package/dist/index.js
CHANGED
|
@@ -80,19 +80,33 @@ const fetchRequestMatchesMock = (mock, input, init) => {
|
|
|
80
80
|
|
|
81
81
|
const mockRequester = (operationMatcher, operationToString) => {
|
|
82
82
|
const mocks = [];
|
|
83
|
-
const
|
|
83
|
+
const configuration = {
|
|
84
|
+
hardFailOnUnmockedRequests: false
|
|
85
|
+
};
|
|
86
|
+
const getMatchingMock = (...args) => {
|
|
84
87
|
for (const mock of mocks) {
|
|
85
88
|
if (mock.onceOnly && mock.used) {
|
|
86
89
|
continue;
|
|
87
90
|
}
|
|
88
91
|
if (operationMatcher(mock.operation, ...args)) {
|
|
89
92
|
mock.used = true;
|
|
90
|
-
return mock
|
|
93
|
+
return mock;
|
|
91
94
|
}
|
|
92
95
|
}
|
|
96
|
+
return null;
|
|
97
|
+
};
|
|
98
|
+
const mockFn = (...args) => {
|
|
99
|
+
const matchingMock = getMatchingMock(...args);
|
|
100
|
+
if (matchingMock) {
|
|
101
|
+
return matchingMock.response();
|
|
102
|
+
}
|
|
93
103
|
const operation = operationToString(...args);
|
|
94
|
-
|
|
95
|
-
${operation}`)
|
|
104
|
+
const noMatchError = new Error(`No matching mock response found for request:
|
|
105
|
+
${operation}`);
|
|
106
|
+
if (configuration.hardFailOnUnmockedRequests) {
|
|
107
|
+
throw noMatchError;
|
|
108
|
+
}
|
|
109
|
+
return Promise.reject(noMatchError);
|
|
96
110
|
};
|
|
97
111
|
const addMockedOperation = (operation, response, onceOnly) => {
|
|
98
112
|
const mockResponse = () => response.toPromise();
|
|
@@ -106,6 +120,10 @@ const mockRequester = (operationMatcher, operationToString) => {
|
|
|
106
120
|
};
|
|
107
121
|
mockFn.mockOperation = (operation, response) => addMockedOperation(operation, response, false);
|
|
108
122
|
mockFn.mockOperationOnce = (operation, response) => addMockedOperation(operation, response, true);
|
|
123
|
+
mockFn.configure = config => {
|
|
124
|
+
Object.assign(configuration, config);
|
|
125
|
+
return mockFn;
|
|
126
|
+
};
|
|
109
127
|
return mockFn;
|
|
110
128
|
};
|
|
111
129
|
|
package/dist/mock-requester.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ import type { OperationMatcher, MockFn } from "./types";
|
|
|
2
2
|
/**
|
|
3
3
|
* A generic mock request function for using when mocking fetch or gqlFetch.
|
|
4
4
|
*/
|
|
5
|
-
export declare const mockRequester: <TOperationType>(operationMatcher: OperationMatcher<any>, operationToString: (...args: Array<any>) => string) => MockFn<TOperationType>;
|
|
5
|
+
export declare const mockRequester: <TOperationType, TResponseData>(operationMatcher: OperationMatcher<any>, operationToString: (...args: Array<any>) => string) => MockFn<TOperationType, TResponseData>;
|
package/dist/types.d.ts
CHANGED
|
@@ -10,11 +10,43 @@ export type GraphQLJson<TData extends Record<any, any>> = {
|
|
|
10
10
|
message: string;
|
|
11
11
|
}>;
|
|
12
12
|
};
|
|
13
|
-
export
|
|
13
|
+
export interface MockFn<TOperationType, TResponseData> {
|
|
14
|
+
/**
|
|
15
|
+
* The mock fetch function.
|
|
16
|
+
*
|
|
17
|
+
* This function is a drop-in replacement for the fetch function being
|
|
18
|
+
* mocked. It is recommended that a more strongly-typed definition is
|
|
19
|
+
* provided in the consuming codebase, as this definition is intentionally
|
|
20
|
+
* loose to allow for mocking any fetch operation.
|
|
21
|
+
*/
|
|
14
22
|
(...args: Array<any>): Promise<Response>;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Mock a fetch operation.
|
|
25
|
+
*
|
|
26
|
+
* This adds a response for a given mocked operation of the given type.
|
|
27
|
+
* Matches are determined by the operation matcher provided to the
|
|
28
|
+
* mockRequester function that creates the mock fetch function.
|
|
29
|
+
*/
|
|
30
|
+
mockOperation: MockOperationFn<TOperationType, TResponseData>;
|
|
31
|
+
/**
|
|
32
|
+
* Mock a fetch operation once.
|
|
33
|
+
*
|
|
34
|
+
* This adds a response for a given mocked operation of the given type that
|
|
35
|
+
* will only be used once and discarded. Matches are determined by the
|
|
36
|
+
* operation matcher provided to the mockRequester function that creates the
|
|
37
|
+
* mock fetch function.
|
|
38
|
+
*/
|
|
39
|
+
mockOperationOnce: MockOperationFn<TOperationType, TResponseData>;
|
|
40
|
+
/**
|
|
41
|
+
* Configure the mock fetch function with the given configuration.
|
|
42
|
+
*
|
|
43
|
+
* This function is provided as a convenience to allow for configuring the
|
|
44
|
+
* mock fetch function in a fluent manner. The configuration is applied
|
|
45
|
+
* to all mocks for a given fetch function; the last configuration applied
|
|
46
|
+
* will be the one that is used for all mocked operations.
|
|
47
|
+
*/
|
|
48
|
+
configure: ConfigureFn<TOperationType, TResponseData>;
|
|
49
|
+
}
|
|
18
50
|
export type OperationMock<TOperation> = {
|
|
19
51
|
operation: TOperation;
|
|
20
52
|
onceOnly: boolean;
|
|
@@ -22,4 +54,34 @@ export type OperationMock<TOperation> = {
|
|
|
22
54
|
response: () => Promise<Response>;
|
|
23
55
|
};
|
|
24
56
|
export type OperationMatcher<TOperation> = (operation: TOperation, ...args: Array<any>) => boolean;
|
|
25
|
-
export type MockOperationFn<TOperationType> = <TOperation extends TOperationType>(operation: TOperation, response: MockResponse<
|
|
57
|
+
export type MockOperationFn<TOperationType, TResponseData> = <TOperation extends TOperationType>(operation: TOperation, response: MockResponse<TResponseData>) => MockFn<TOperationType, TResponseData>;
|
|
58
|
+
/**
|
|
59
|
+
* Configuration options for mocked fetches.
|
|
60
|
+
*/
|
|
61
|
+
export type MockConfiguration = {
|
|
62
|
+
/**
|
|
63
|
+
* If true, any requests that don't match a mock will throw an error
|
|
64
|
+
* immediately on the request being made; otherwise, if false, unmatched
|
|
65
|
+
* requests will return a rejected promise.
|
|
66
|
+
*
|
|
67
|
+
* Defaults to false. When true, this is akin to the Apollo MockLink
|
|
68
|
+
* behavior that throws upon the request being. This is useful as it will
|
|
69
|
+
* clearly fail a test early, indicating that a request was not mocked.
|
|
70
|
+
* However, that mode requires all requests to be mocked, which can be
|
|
71
|
+
* cumbersome and unncessary. Having unmocked requests return a rejected
|
|
72
|
+
* promise is more flexible and allows for more granular control over
|
|
73
|
+
* mocking, allowing developers to mock only the requests they care about
|
|
74
|
+
* and let the error handling of their code deal with the rejected promises.
|
|
75
|
+
*/
|
|
76
|
+
hardFailOnUnmockedRequests: boolean;
|
|
77
|
+
};
|
|
78
|
+
export interface ConfigureFn<TOperationType, TResponseData> {
|
|
79
|
+
/**
|
|
80
|
+
* Configure the mock fetch function with the given configuration.
|
|
81
|
+
*
|
|
82
|
+
* @param config The configuration changes to apply to the mock fetch
|
|
83
|
+
* function.
|
|
84
|
+
* @returns The mock fetch function .
|
|
85
|
+
*/
|
|
86
|
+
(config: Partial<MockConfiguration>): MockFn<TOperationType, TResponseData>;
|
|
87
|
+
}
|