@khanacademy/wonder-blocks-testing 10.1.1 → 11.0.1
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 +28 -0
- package/dist/es/index.js +15 -390
- package/dist/gql/types.d.ts +1 -2
- package/dist/harness/adapters/data.d.ts +1 -1
- package/dist/harness/adapters/index.d.ts +41 -0
- package/dist/harness/adapters/ssr.d.ts +1 -1
- package/dist/index.d.ts +8 -13
- package/dist/index.js +54 -399
- package/package.json +9 -7
- package/src/gql/__tests__/mock-gql-fetch.test.tsx +1 -1
- package/src/gql/__tests__/types.typestest.ts +1 -1
- package/src/gql/__tests__/wb-data-integration.test.tsx +1 -1
- package/src/gql/mock-gql-fetch.ts +1 -1
- package/src/gql/types.ts +4 -2
- package/src/harness/adapters/__tests__/ssr.test.tsx +1 -1
- package/src/harness/adapters/data.tsx +1 -1
- package/src/harness/adapters/{adapters.ts → index.ts} +10 -11
- package/src/harness/adapters/ssr.tsx +1 -1
- package/src/index.ts +32 -13
- package/tsconfig-build.json +1 -0
- package/tsconfig-build.tsbuildinfo +1 -1
- package/dist/fetch/fetch-request-matches-mock.d.ts +0 -5
- package/dist/fetch/mock-fetch.d.ts +0 -5
- package/dist/fetch/types.d.ts +0 -9
- package/dist/fixtures/fixtures.basic.stories.d.ts +0 -13
- package/dist/fixtures/fixtures.d.ts +0 -13
- package/dist/fixtures/fixtures.defaultwrapper.stories.d.ts +0 -9
- package/dist/fixtures/types.d.ts +0 -36
- package/dist/harness/adapt.d.ts +0 -17
- package/dist/harness/adapters/adapters.d.ts +0 -36
- package/dist/harness/adapters/css.d.ts +0 -12
- package/dist/harness/adapters/portal.d.ts +0 -12
- package/dist/harness/adapters/router.d.ts +0 -94
- package/dist/harness/get-named-adapter-component.d.ts +0 -16
- package/dist/harness/hook-harness.d.ts +0 -13
- package/dist/harness/make-hook-harness.d.ts +0 -17
- package/dist/harness/make-test-harness.d.ts +0 -15
- package/dist/harness/test-harness.d.ts +0 -33
- package/dist/harness/types.d.ts +0 -36
- package/dist/mock-requester.d.ts +0 -5
- package/dist/respond-with.d.ts +0 -75
- package/dist/response-impl.d.ts +0 -1
- package/dist/settle-controller.d.ts +0 -19
- package/dist/settle-signal.d.ts +0 -18
- package/dist/types.d.ts +0 -25
- package/src/__tests__/mock-requester.test.ts +0 -212
- package/src/__tests__/respond-with.test.ts +0 -524
- package/src/__tests__/response-impl.test.js +0 -47
- package/src/__tests__/settle-controller.test.ts +0 -28
- package/src/__tests__/settle-signal.test.ts +0 -104
- package/src/fetch/__tests__/__snapshots__/mock-fetch.test.ts.snap +0 -29
- package/src/fetch/__tests__/fetch-request-matches-mock.test.ts +0 -98
- package/src/fetch/__tests__/mock-fetch.test.ts +0 -83
- package/src/fetch/fetch-request-matches-mock.ts +0 -42
- package/src/fetch/mock-fetch.ts +0 -20
- package/src/fetch/types.ts +0 -14
- package/src/fixtures/__tests__/fixtures.test.tsx +0 -147
- package/src/fixtures/fixtures.basic.stories.tsx +0 -62
- package/src/fixtures/fixtures.defaultwrapper.stories.tsx +0 -49
- package/src/fixtures/fixtures.tsx +0 -72
- package/src/fixtures/types.ts +0 -42
- package/src/harness/__tests__/adapt.test.tsx +0 -248
- package/src/harness/__tests__/hook-harness.test.ts +0 -73
- package/src/harness/__tests__/make-hook-harness.test.tsx +0 -93
- package/src/harness/__tests__/make-test-harness.test.tsx +0 -195
- package/src/harness/__tests__/test-harness.test.ts +0 -75
- package/src/harness/__tests__/types.typestest.tsx +0 -103
- package/src/harness/adapt.tsx +0 -41
- package/src/harness/adapters/__tests__/__snapshots__/router.test.tsx.snap +0 -5
- package/src/harness/adapters/__tests__/css.test.tsx +0 -95
- package/src/harness/adapters/__tests__/portal.test.tsx +0 -30
- package/src/harness/adapters/__tests__/router.test.tsx +0 -252
- package/src/harness/adapters/css.tsx +0 -66
- package/src/harness/adapters/portal.tsx +0 -25
- package/src/harness/adapters/router.tsx +0 -205
- package/src/harness/get-named-adapter-component.tsx +0 -36
- package/src/harness/hook-harness.ts +0 -22
- package/src/harness/make-hook-harness.tsx +0 -40
- package/src/harness/make-test-harness.tsx +0 -60
- package/src/harness/test-harness.ts +0 -13
- package/src/harness/types.ts +0 -47
- package/src/mock-requester.ts +0 -68
- package/src/respond-with.ts +0 -263
- package/src/response-impl.ts +0 -8
- package/src/settle-controller.ts +0 -34
- package/src/settle-signal.ts +0 -42
- package/src/types.ts +0 -40
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @khanacademy/wonder-blocks-testing
|
|
2
2
|
|
|
3
|
+
## 11.0.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 559e82d5: Update to build tooling, generating smaller output
|
|
8
|
+
- Updated dependencies [c954464a]
|
|
9
|
+
- Updated dependencies [559e82d5]
|
|
10
|
+
- @khanacademy/wonder-blocks-testing-core@1.0.1
|
|
11
|
+
- @khanacademy/wonder-blocks-core@6.4.3
|
|
12
|
+
- @khanacademy/wonder-blocks-data@13.0.10
|
|
13
|
+
|
|
14
|
+
## 11.0.0
|
|
15
|
+
|
|
16
|
+
### Major Changes
|
|
17
|
+
|
|
18
|
+
- 2a6c85df: New package containing core Testing functionality without dependencies on other WB packages
|
|
19
|
+
- 2a6c85df: - Minimum version for Storybook actions addon increased to 7
|
|
20
|
+
- Added new `renderHookStatic` utility to replace deprecated `renderHookServer` from `@testing-library/react-hooks`; ready for React 18 updates
|
|
21
|
+
- Added new `boundary` error boundary adapter for the test harness to capture errors during tests; ready for React 18 updates
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- Updated dependencies [2a6c85df]
|
|
26
|
+
- Updated dependencies [eab37b8b]
|
|
27
|
+
- @khanacademy/wonder-blocks-testing-core@1.0.0
|
|
28
|
+
- @khanacademy/wonder-blocks-core@6.4.2
|
|
29
|
+
- @khanacademy/wonder-blocks-data@13.0.9
|
|
30
|
+
|
|
3
31
|
## 10.1.1
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
package/dist/es/index.js
CHANGED
|
@@ -1,90 +1,11 @@
|
|
|
1
|
+
import { mockRequester, harnessAdapters } from '@khanacademy/wonder-blocks-testing-core';
|
|
2
|
+
export { RespondWith, SettleController, fixtures, hookHarness, makeHookHarness, makeTestHarness, mockFetch, renderHookStatic, testHarness } from '@khanacademy/wonder-blocks-testing-core';
|
|
3
|
+
import _extends from '@babel/runtime/helpers/extends';
|
|
1
4
|
import * as React from 'react';
|
|
2
|
-
import { action } from '@storybook/addon-actions';
|
|
3
5
|
import { InterceptRequests } from '@khanacademy/wonder-blocks-data';
|
|
4
|
-
import { StaticRouter, MemoryRouter, Switch, Route } from 'react-router-dom';
|
|
5
6
|
import { KindError, Errors } from '@khanacademy/wonder-stuff-core';
|
|
6
7
|
import { RenderStateRoot } from '@khanacademy/wonder-blocks-core';
|
|
7
8
|
|
|
8
|
-
const fixtures = Component => {
|
|
9
|
-
const templateMap = new WeakMap();
|
|
10
|
-
let storyNumber = 1;
|
|
11
|
-
const getPropsOptions = {
|
|
12
|
-
log: (message, ...args) => action(message)(...args),
|
|
13
|
-
logHandler: action
|
|
14
|
-
};
|
|
15
|
-
const makeStory = (description, props, wrapper = null) => {
|
|
16
|
-
const storyName = `${storyNumber++} ${description}`;
|
|
17
|
-
const getProps = options => typeof props === "function" ? props(options) : props;
|
|
18
|
-
const RealComponent = wrapper || Component;
|
|
19
|
-
let Template = templateMap.get(RealComponent);
|
|
20
|
-
if (Template == null) {
|
|
21
|
-
Template = args => React.createElement(RealComponent, args);
|
|
22
|
-
templateMap.set(RealComponent, Template);
|
|
23
|
-
}
|
|
24
|
-
const story = Template.bind({});
|
|
25
|
-
story.args = getProps(getPropsOptions);
|
|
26
|
-
story.storyName = storyName;
|
|
27
|
-
return story;
|
|
28
|
-
};
|
|
29
|
-
return makeStory;
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const getHref = input => {
|
|
33
|
-
if (typeof input === "string") {
|
|
34
|
-
return input;
|
|
35
|
-
} else if (typeof input.url === "string") {
|
|
36
|
-
return input.url;
|
|
37
|
-
} else if (typeof input.href === "string") {
|
|
38
|
-
return input.href;
|
|
39
|
-
} else {
|
|
40
|
-
throw new Error(`Unsupported input type`);
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
const fetchRequestMatchesMock = (mock, input, init) => {
|
|
44
|
-
const href = getHref(input);
|
|
45
|
-
if (typeof mock === "string") {
|
|
46
|
-
return href === mock;
|
|
47
|
-
} else if (mock instanceof RegExp) {
|
|
48
|
-
return mock.test(href);
|
|
49
|
-
} else {
|
|
50
|
-
throw new Error(`Unsupported mock operation: ${JSON.stringify(mock)}`);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const mockRequester = (operationMatcher, operationToString) => {
|
|
55
|
-
const mocks = [];
|
|
56
|
-
const mockFn = (...args) => {
|
|
57
|
-
for (const mock of mocks) {
|
|
58
|
-
if (mock.onceOnly && mock.used) {
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
if (operationMatcher(mock.operation, ...args)) {
|
|
62
|
-
mock.used = true;
|
|
63
|
-
return mock.response();
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
const operation = operationToString(...args);
|
|
67
|
-
return Promise.reject(new Error(`No matching mock response found for request:
|
|
68
|
-
${operation}`));
|
|
69
|
-
};
|
|
70
|
-
const addMockedOperation = (operation, response, onceOnly) => {
|
|
71
|
-
const mockResponse = () => response.toPromise();
|
|
72
|
-
mocks.push({
|
|
73
|
-
operation,
|
|
74
|
-
response: mockResponse,
|
|
75
|
-
onceOnly,
|
|
76
|
-
used: false
|
|
77
|
-
});
|
|
78
|
-
return mockFn;
|
|
79
|
-
};
|
|
80
|
-
mockFn.mockOperation = (operation, response) => addMockedOperation(operation, response, false);
|
|
81
|
-
mockFn.mockOperationOnce = (operation, response) => addMockedOperation(operation, response, true);
|
|
82
|
-
return mockFn;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const mockFetch = () => mockRequester(fetchRequestMatchesMock, (input, init) => `Input: ${typeof input === "string" ? input : JSON.stringify(input, null, 2)}
|
|
86
|
-
Options: ${init == null ? "None" : JSON.stringify(init, null, 2)}`);
|
|
87
|
-
|
|
88
9
|
const safeHasOwnProperty = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
|
|
89
10
|
const areObjectsEqual = (a, b) => {
|
|
90
11
|
if (a === b) {
|
|
@@ -130,169 +51,8 @@ const mockGqlFetch = () => mockRequester(gqlRequestMatchesMock, (operation, vari
|
|
|
130
51
|
Variables: ${variables == null ? "None" : JSON.stringify(variables, null, 2)}
|
|
131
52
|
Context: ${JSON.stringify(context, null, 2)}`);
|
|
132
53
|
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
const textResponse = (text, statusCode, signal) => ({
|
|
136
|
-
toPromise: () => makeMockResponse({
|
|
137
|
-
type: "text",
|
|
138
|
-
text,
|
|
139
|
-
statusCode,
|
|
140
|
-
signal
|
|
141
|
-
})
|
|
142
|
-
});
|
|
143
|
-
const rejectResponse = (error, signal) => ({
|
|
144
|
-
toPromise: () => makeMockResponse({
|
|
145
|
-
type: "reject",
|
|
146
|
-
error,
|
|
147
|
-
signal
|
|
148
|
-
})
|
|
149
|
-
});
|
|
150
|
-
const RespondWith = Object.freeze({
|
|
151
|
-
text: (text, statusCode = 200, signal = null) => textResponse(text, statusCode, signal),
|
|
152
|
-
json: (json, signal = null) => textResponse(() => JSON.stringify(json), 200, signal),
|
|
153
|
-
graphQLData: (data, signal = null) => textResponse(() => JSON.stringify({
|
|
154
|
-
data
|
|
155
|
-
}), 200, signal),
|
|
156
|
-
unparseableBody: (signal = null) => textResponse("INVALID JSON", 200, signal),
|
|
157
|
-
abortedRequest: (signal = null) => rejectResponse(() => {
|
|
158
|
-
const abortError = new Error("Mock request aborted");
|
|
159
|
-
abortError.name = "AbortError";
|
|
160
|
-
return abortError;
|
|
161
|
-
}, signal),
|
|
162
|
-
reject: (error, signal = null) => rejectResponse(error, signal),
|
|
163
|
-
errorStatusCode: (statusCode, signal = null) => {
|
|
164
|
-
if (statusCode < 300) {
|
|
165
|
-
throw new Error(`${statusCode} is not a valid error status code`);
|
|
166
|
-
}
|
|
167
|
-
return textResponse("{}", statusCode, signal);
|
|
168
|
-
},
|
|
169
|
-
nonGraphQLBody: (signal = null) => textResponse(() => JSON.stringify({
|
|
170
|
-
valid: "json",
|
|
171
|
-
that: "is not a valid graphql response"
|
|
172
|
-
}), 200, signal),
|
|
173
|
-
graphQLErrors: (errorMessages, signal = null) => textResponse(() => JSON.stringify({
|
|
174
|
-
errors: errorMessages.map(e => ({
|
|
175
|
-
message: e
|
|
176
|
-
}))
|
|
177
|
-
}), 200, signal)
|
|
178
|
-
});
|
|
179
|
-
const callOnSettled = (signal, fn) => {
|
|
180
|
-
if (signal == null || signal.settled) {
|
|
181
|
-
fn();
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
const onSettled = () => {
|
|
185
|
-
signal.removeEventListener("settled", onSettled);
|
|
186
|
-
fn();
|
|
187
|
-
};
|
|
188
|
-
signal.addEventListener("settled", onSettled);
|
|
189
|
-
};
|
|
190
|
-
const makeMockResponse = response => {
|
|
191
|
-
const {
|
|
192
|
-
signal
|
|
193
|
-
} = response;
|
|
194
|
-
switch (response.type) {
|
|
195
|
-
case "text":
|
|
196
|
-
return new Promise((resolve, reject) => {
|
|
197
|
-
callOnSettled(signal, () => {
|
|
198
|
-
const text = typeof response.text === "function" ? response.text() : response.text;
|
|
199
|
-
resolve(new ResponseImpl(text, {
|
|
200
|
-
status: response.statusCode
|
|
201
|
-
}));
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
case "reject":
|
|
205
|
-
return new Promise((resolve, reject) => {
|
|
206
|
-
callOnSettled(signal, () => reject(response.error instanceof Error ? response.error : response.error()));
|
|
207
|
-
});
|
|
208
|
-
default:
|
|
209
|
-
if (process.env.NODE_ENV !== "production") {
|
|
210
|
-
throw new Error(`Unknown response type: ${response.type}`);
|
|
211
|
-
}
|
|
212
|
-
return makeMockResponse({
|
|
213
|
-
type: "reject",
|
|
214
|
-
error: new Error("Unknown response type"),
|
|
215
|
-
signal
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
class SettleSignal extends EventTarget {
|
|
221
|
-
constructor(setSettleFn = null) {
|
|
222
|
-
super();
|
|
223
|
-
this._settled = false;
|
|
224
|
-
setSettleFn == null ? void 0 : setSettleFn(() => {
|
|
225
|
-
if (this._settled) {
|
|
226
|
-
throw new Error("SettleSignal already settled");
|
|
227
|
-
}
|
|
228
|
-
this._settled = true;
|
|
229
|
-
this.dispatchEvent(new Event("settled"));
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
static settle() {
|
|
233
|
-
const signal = new SettleSignal();
|
|
234
|
-
signal._settled = true;
|
|
235
|
-
return signal;
|
|
236
|
-
}
|
|
237
|
-
get settled() {
|
|
238
|
-
return this._settled;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
class SettleController {
|
|
243
|
-
constructor() {
|
|
244
|
-
this._settleFn = void 0;
|
|
245
|
-
this._signal = void 0;
|
|
246
|
-
this._signal = new SettleSignal(settleFn => this._settleFn = settleFn);
|
|
247
|
-
}
|
|
248
|
-
get signal() {
|
|
249
|
-
return this._signal;
|
|
250
|
-
}
|
|
251
|
-
settle() {
|
|
252
|
-
var _this$_settleFn;
|
|
253
|
-
(_this$_settleFn = this._settleFn) == null ? void 0 : _this$_settleFn.call(this);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
const defaultConfig$4 = null;
|
|
258
|
-
const normalizeConfig = config => {
|
|
259
|
-
if (typeof config === "string") {
|
|
260
|
-
return {
|
|
261
|
-
classes: [config],
|
|
262
|
-
style: {}
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
if (Array.isArray(config)) {
|
|
266
|
-
return {
|
|
267
|
-
classes: config,
|
|
268
|
-
style: {}
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
if (typeof config === "object") {
|
|
272
|
-
if ("classes" in config && config.classes != null && "style" in config && config.style != null) {
|
|
273
|
-
return config;
|
|
274
|
-
}
|
|
275
|
-
return {
|
|
276
|
-
classes: [],
|
|
277
|
-
style: config
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
throw new Error(`Invalid config: ${config}`);
|
|
281
|
-
};
|
|
282
|
-
const adapter$4 = (children, config) => {
|
|
283
|
-
const {
|
|
284
|
-
classes,
|
|
285
|
-
style
|
|
286
|
-
} = normalizeConfig(config);
|
|
287
|
-
return React.createElement("div", {
|
|
288
|
-
"data-testid": "css-adapter-container",
|
|
289
|
-
className: classes.join(" "),
|
|
290
|
-
style: style
|
|
291
|
-
}, children);
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
const defaultConfig$3 = [];
|
|
295
|
-
const adapter$3 = (children, config) => {
|
|
54
|
+
const defaultConfig$1 = [];
|
|
55
|
+
const adapter$1 = (children, config) => {
|
|
296
56
|
let currentChildren = children;
|
|
297
57
|
const interceptors = Array.isArray(config) ? config : [config];
|
|
298
58
|
for (const interceptor of interceptors) {
|
|
@@ -303,63 +63,6 @@ const adapter$3 = (children, config) => {
|
|
|
303
63
|
return React.createElement(React.Fragment, null, currentChildren);
|
|
304
64
|
};
|
|
305
65
|
|
|
306
|
-
const defaultConfig$2 = null;
|
|
307
|
-
const adapter$2 = (children, config) => React.createElement(React.Fragment, null, React.createElement("div", {
|
|
308
|
-
id: config,
|
|
309
|
-
"data-testid": config
|
|
310
|
-
}), children);
|
|
311
|
-
|
|
312
|
-
const defaultConfig$1 = {
|
|
313
|
-
location: "/"
|
|
314
|
-
};
|
|
315
|
-
const maybeWithRoute = (children, path) => {
|
|
316
|
-
if (path == null) {
|
|
317
|
-
return React.createElement(React.Fragment, null, children);
|
|
318
|
-
}
|
|
319
|
-
return React.createElement(Switch, null, React.createElement(Route, {
|
|
320
|
-
exact: true,
|
|
321
|
-
path: path
|
|
322
|
-
}, children), React.createElement(Route, {
|
|
323
|
-
path: "*",
|
|
324
|
-
render: () => {
|
|
325
|
-
throw new Error("The configured path must match the configured location or your harnessed component will not render.");
|
|
326
|
-
}
|
|
327
|
-
}));
|
|
328
|
-
};
|
|
329
|
-
const adapter$1 = (children, config) => {
|
|
330
|
-
if (typeof config === "string") {
|
|
331
|
-
config = {
|
|
332
|
-
location: config
|
|
333
|
-
};
|
|
334
|
-
}
|
|
335
|
-
const wrappedWithRoute = maybeWithRoute(children, config.path);
|
|
336
|
-
if ("forceStatic" in config && config.forceStatic) {
|
|
337
|
-
return React.createElement(StaticRouter, {
|
|
338
|
-
location: config.location,
|
|
339
|
-
context: {}
|
|
340
|
-
}, wrappedWithRoute);
|
|
341
|
-
}
|
|
342
|
-
if ("location" in config && config.location !== undefined) {
|
|
343
|
-
return React.createElement(MemoryRouter, {
|
|
344
|
-
initialEntries: [config.location]
|
|
345
|
-
}, wrappedWithRoute);
|
|
346
|
-
}
|
|
347
|
-
if (!("initialEntries" in config) || config.initialEntries === undefined) {
|
|
348
|
-
throw new Error("A location or initial history entries must be provided.");
|
|
349
|
-
}
|
|
350
|
-
const entries = config.initialEntries.length === 0 ? [defaultConfig$1.location] : config.initialEntries;
|
|
351
|
-
const routerProps = {
|
|
352
|
-
initialEntries: entries
|
|
353
|
-
};
|
|
354
|
-
if (config.initialIndex != null) {
|
|
355
|
-
routerProps.initialIndex = config.initialIndex;
|
|
356
|
-
}
|
|
357
|
-
if (config.getUserConfirmation != null) {
|
|
358
|
-
routerProps.getUserConfirmation = config.getUserConfirmation;
|
|
359
|
-
}
|
|
360
|
-
return React.createElement(MemoryRouter, routerProps, wrappedWithRoute);
|
|
361
|
-
};
|
|
362
|
-
|
|
363
66
|
const defaultConfig = null;
|
|
364
67
|
const adapter = (children, config) => {
|
|
365
68
|
if (config !== true) {
|
|
@@ -375,100 +78,22 @@ const adapter = (children, config) => {
|
|
|
375
78
|
};
|
|
376
79
|
|
|
377
80
|
const DefaultAdapters = {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
81
|
+
boundary: harnessAdapters.DefaultAdapters.boundary,
|
|
82
|
+
css: harnessAdapters.DefaultAdapters.css,
|
|
83
|
+
data: adapter$1,
|
|
84
|
+
portal: harnessAdapters.DefaultAdapters.portal,
|
|
85
|
+
router: harnessAdapters.DefaultAdapters.router,
|
|
382
86
|
ssr: adapter
|
|
383
87
|
};
|
|
384
|
-
const DefaultConfigs = {
|
|
385
|
-
|
|
386
|
-
data: defaultConfig$3,
|
|
387
|
-
portal: defaultConfig$2,
|
|
388
|
-
router: defaultConfig$1,
|
|
88
|
+
const DefaultConfigs = _extends({}, harnessAdapters.DefaultConfigs, {
|
|
89
|
+
data: defaultConfig$1,
|
|
389
90
|
ssr: defaultConfig
|
|
390
|
-
};
|
|
91
|
+
});
|
|
391
92
|
|
|
392
|
-
var
|
|
93
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
393
94
|
__proto__: null,
|
|
394
95
|
DefaultAdapters: DefaultAdapters,
|
|
395
96
|
DefaultConfigs: DefaultConfigs
|
|
396
97
|
});
|
|
397
98
|
|
|
398
|
-
|
|
399
|
-
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
400
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
401
|
-
var source = arguments[i];
|
|
402
|
-
for (var key in source) {
|
|
403
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
404
|
-
target[key] = source[key];
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
return target;
|
|
409
|
-
};
|
|
410
|
-
return _extends.apply(this, arguments);
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
const componentCache = new Map();
|
|
414
|
-
const getNamedAdapterComponent = name => {
|
|
415
|
-
const existing = componentCache.get(name);
|
|
416
|
-
if (existing != null) {
|
|
417
|
-
return existing;
|
|
418
|
-
}
|
|
419
|
-
const newComponent = ({
|
|
420
|
-
children,
|
|
421
|
-
config,
|
|
422
|
-
adapter
|
|
423
|
-
}) => adapter(children, config);
|
|
424
|
-
newComponent.displayName = `Adapter(${name})`;
|
|
425
|
-
componentCache.set(name, newComponent);
|
|
426
|
-
return newComponent;
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
const Adapt = ({
|
|
430
|
-
children,
|
|
431
|
-
adapters,
|
|
432
|
-
configs
|
|
433
|
-
}) => {
|
|
434
|
-
return Object.entries(adapters).reduce((newChildren, [name, adapter]) => {
|
|
435
|
-
const theConfig = configs[name];
|
|
436
|
-
if (theConfig == null) {
|
|
437
|
-
return newChildren;
|
|
438
|
-
}
|
|
439
|
-
const Adapter = getNamedAdapterComponent(name);
|
|
440
|
-
return React.createElement(Adapter, {
|
|
441
|
-
key: name,
|
|
442
|
-
adapter: adapter,
|
|
443
|
-
config: theConfig
|
|
444
|
-
}, newChildren);
|
|
445
|
-
}, React.createElement(React.Fragment, null, children));
|
|
446
|
-
};
|
|
447
|
-
|
|
448
|
-
const makeTestHarness = (adapters, defaultConfigs) => {
|
|
449
|
-
return (Component, configs) => {
|
|
450
|
-
const fullConfig = _extends({}, defaultConfigs, configs);
|
|
451
|
-
const harnessedComponent = React.forwardRef((props, ref) => React.createElement(Adapt, {
|
|
452
|
-
adapters: adapters,
|
|
453
|
-
configs: fullConfig
|
|
454
|
-
}, React.createElement(Component, _extends({}, props, {
|
|
455
|
-
ref: ref
|
|
456
|
-
}))));
|
|
457
|
-
harnessedComponent.displayName = `testHarness(${Component.displayName || Component.name || "Component"})`;
|
|
458
|
-
return harnessedComponent;
|
|
459
|
-
};
|
|
460
|
-
};
|
|
461
|
-
|
|
462
|
-
const HookHarness = ({
|
|
463
|
-
children
|
|
464
|
-
}) => React.createElement(React.Fragment, null, children);
|
|
465
|
-
const makeHookHarness = (adapters, defaultConfigs) => {
|
|
466
|
-
const testHarness = makeTestHarness(adapters, defaultConfigs);
|
|
467
|
-
return configs => testHarness(HookHarness, configs);
|
|
468
|
-
};
|
|
469
|
-
|
|
470
|
-
const hookHarness = makeHookHarness(DefaultAdapters, DefaultConfigs);
|
|
471
|
-
|
|
472
|
-
const testHarness = makeTestHarness(DefaultAdapters, DefaultConfigs);
|
|
473
|
-
|
|
474
|
-
export { RespondWith, SettleController, fixtures, adapters as harnessAdapters, hookHarness, makeHookHarness, makeTestHarness, mockFetch, mockGqlFetch, testHarness };
|
|
99
|
+
export { index as harnessAdapters, mockGqlFetch };
|
package/dist/gql/types.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { GqlOperation, GqlContext } from "@khanacademy/wonder-blocks-data";
|
|
2
|
-
import type { GraphQLJson } from "
|
|
3
|
-
import type { MockResponse } from "../respond-with";
|
|
2
|
+
import type { GraphQLJson, MockResponse } from "@khanacademy/wonder-blocks-testing-core";
|
|
4
3
|
export type GqlMockOperation<TData extends Record<any, any>, TVariables extends Record<any, any>, TContext extends GqlContext> = {
|
|
5
4
|
operation: GqlOperation<TData, TVariables>;
|
|
6
5
|
variables?: TVariables;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { InterceptRequests } from "@khanacademy/wonder-blocks-data";
|
|
3
|
-
import type { TestHarnessAdapter } from "
|
|
3
|
+
import type { TestHarnessAdapter } from "@khanacademy/wonder-blocks-testing-core";
|
|
4
4
|
type Interceptor = JSX.LibraryManagedAttributes<typeof InterceptRequests, React.ComponentProps<typeof InterceptRequests>>["interceptor"];
|
|
5
5
|
type Config = Interceptor | Array<Interceptor>;
|
|
6
6
|
/**
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/// <reference path="../../../../wonder-blocks-testing-core/types/aphrodite.d.ts" />
|
|
2
|
+
/// <reference path="../../../types/aphrodite.d.ts" />
|
|
3
|
+
/// <reference types="react" />
|
|
4
|
+
import type { TestHarnessConfigs } from "@khanacademy/wonder-blocks-testing-core";
|
|
5
|
+
/**
|
|
6
|
+
* NOTE: We do not type `DefaultAdapters` with `Adapters` here because we want
|
|
7
|
+
* the individual config types of each adapter to remain intact rather than
|
|
8
|
+
* getting changed to `any`.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* The default adapters provided by Wonder Blocks.
|
|
12
|
+
*/
|
|
13
|
+
export declare const DefaultAdapters: {
|
|
14
|
+
readonly boundary: import("@khanacademy/wonder-blocks-testing-core").TestHarnessAdapter<(error: Error | null | undefined, errorInfo: {
|
|
15
|
+
componentStack: string;
|
|
16
|
+
}) => import("react").ReactNode>;
|
|
17
|
+
readonly css: import("@khanacademy/wonder-blocks-testing-core").TestHarnessAdapter<string | string[] | import("aphrodite").CSSProperties | {
|
|
18
|
+
classes: string[];
|
|
19
|
+
style: import("aphrodite").CSSProperties;
|
|
20
|
+
}>;
|
|
21
|
+
readonly data: import("@khanacademy/wonder-blocks-testing-core").TestHarnessAdapter<((requestId: string) => Promise<import("@khanacademy/wonder-blocks-data").ValidCacheData> | null | undefined) | ((requestId: string) => Promise<import("@khanacademy/wonder-blocks-data").ValidCacheData> | null | undefined)[]>;
|
|
22
|
+
readonly portal: import("@khanacademy/wonder-blocks-testing-core").TestHarnessAdapter<string>;
|
|
23
|
+
readonly router: import("@khanacademy/wonder-blocks-testing-core").TestHarnessAdapter<string | Readonly<{
|
|
24
|
+
initialEntries: import("history").LocationDescriptor<unknown>[] | undefined;
|
|
25
|
+
initialIndex?: number | undefined;
|
|
26
|
+
getUserConfirmation?: ((message: string, callback: (ok: boolean) => void) => void) | undefined;
|
|
27
|
+
path?: string | undefined;
|
|
28
|
+
} | {
|
|
29
|
+
location: import("history").LocationDescriptor<unknown>;
|
|
30
|
+
forceStatic: true;
|
|
31
|
+
path?: string | undefined;
|
|
32
|
+
} | {
|
|
33
|
+
location: import("history").LocationDescriptor<unknown>;
|
|
34
|
+
path?: string | undefined;
|
|
35
|
+
}>>;
|
|
36
|
+
readonly ssr: import("@khanacademy/wonder-blocks-testing-core").TestHarnessAdapter<true>;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* The default configurations to use with the `DefaultAdapters`.
|
|
40
|
+
*/
|
|
41
|
+
export declare const DefaultConfigs: TestHarnessConfigs<typeof DefaultAdapters>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
export { fixtures } from "
|
|
2
|
-
export type { FixtureFn, FixtureProps, GetPropsOptions } from "
|
|
3
|
-
export { mockFetch } from "
|
|
1
|
+
export { fixtures } from "@khanacademy/wonder-blocks-testing-core";
|
|
2
|
+
export type { FixtureFn, FixtureProps, GetPropsOptions, } from "@khanacademy/wonder-blocks-testing-core";
|
|
3
|
+
export { mockFetch, RespondWith, SettleController, } from "@khanacademy/wonder-blocks-testing-core";
|
|
4
4
|
export { mockGqlFetch } from "./gql/mock-gql-fetch";
|
|
5
|
-
export {
|
|
6
|
-
export { SettleController } from "./settle-controller";
|
|
7
|
-
export type { MockResponse } from "./respond-with";
|
|
8
|
-
export type { FetchMockFn, FetchMockOperation } from "./fetch/types";
|
|
5
|
+
export type { MockResponse, FetchMockFn, FetchMockOperation, } from "@khanacademy/wonder-blocks-testing-core";
|
|
9
6
|
export type { GqlFetchMockFn, GqlMockOperation } from "./gql/types";
|
|
10
|
-
export
|
|
11
|
-
export * as harnessAdapters from "./harness/adapters
|
|
12
|
-
export { makeHookHarness } from "
|
|
13
|
-
export {
|
|
14
|
-
export { hookHarness } from "./harness/hook-harness";
|
|
15
|
-
export { testHarness } from "./harness/test-harness";
|
|
7
|
+
export type { TestHarnessAdapter, TestHarnessAdapters, TestHarnessConfig, TestHarnessConfigs, } from "@khanacademy/wonder-blocks-testing-core";
|
|
8
|
+
export * as harnessAdapters from "./harness/adapters";
|
|
9
|
+
export { makeHookHarness, makeTestHarness, hookHarness, testHarness, } from "@khanacademy/wonder-blocks-testing-core";
|
|
10
|
+
export { renderHookStatic } from "@khanacademy/wonder-blocks-testing-core";
|