@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/dist/index.js
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var wonderBlocksTestingCore = require('@khanacademy/wonder-blocks-testing-core');
|
|
6
|
+
var _extends = require('@babel/runtime/helpers/extends');
|
|
5
7
|
var React = require('react');
|
|
6
|
-
var addonActions = require('@storybook/addon-actions');
|
|
7
8
|
var wonderBlocksData = require('@khanacademy/wonder-blocks-data');
|
|
8
|
-
var reactRouterDom = require('react-router-dom');
|
|
9
9
|
var wonderStuffCore = require('@khanacademy/wonder-stuff-core');
|
|
10
10
|
var wonderBlocksCore = require('@khanacademy/wonder-blocks-core');
|
|
11
11
|
|
|
12
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
13
|
+
|
|
12
14
|
function _interopNamespace(e) {
|
|
13
15
|
if (e && e.__esModule) return e;
|
|
14
16
|
var n = Object.create(null);
|
|
@@ -27,88 +29,9 @@ function _interopNamespace(e) {
|
|
|
27
29
|
return Object.freeze(n);
|
|
28
30
|
}
|
|
29
31
|
|
|
32
|
+
var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends);
|
|
30
33
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
31
34
|
|
|
32
|
-
const fixtures = Component => {
|
|
33
|
-
const templateMap = new WeakMap();
|
|
34
|
-
let storyNumber = 1;
|
|
35
|
-
const getPropsOptions = {
|
|
36
|
-
log: (message, ...args) => addonActions.action(message)(...args),
|
|
37
|
-
logHandler: addonActions.action
|
|
38
|
-
};
|
|
39
|
-
const makeStory = (description, props, wrapper = null) => {
|
|
40
|
-
const storyName = `${storyNumber++} ${description}`;
|
|
41
|
-
const getProps = options => typeof props === "function" ? props(options) : props;
|
|
42
|
-
const RealComponent = wrapper || Component;
|
|
43
|
-
let Template = templateMap.get(RealComponent);
|
|
44
|
-
if (Template == null) {
|
|
45
|
-
Template = args => React__namespace.createElement(RealComponent, args);
|
|
46
|
-
templateMap.set(RealComponent, Template);
|
|
47
|
-
}
|
|
48
|
-
const story = Template.bind({});
|
|
49
|
-
story.args = getProps(getPropsOptions);
|
|
50
|
-
story.storyName = storyName;
|
|
51
|
-
return story;
|
|
52
|
-
};
|
|
53
|
-
return makeStory;
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const getHref = input => {
|
|
57
|
-
if (typeof input === "string") {
|
|
58
|
-
return input;
|
|
59
|
-
} else if (typeof input.url === "string") {
|
|
60
|
-
return input.url;
|
|
61
|
-
} else if (typeof input.href === "string") {
|
|
62
|
-
return input.href;
|
|
63
|
-
} else {
|
|
64
|
-
throw new Error(`Unsupported input type`);
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
const fetchRequestMatchesMock = (mock, input, init) => {
|
|
68
|
-
const href = getHref(input);
|
|
69
|
-
if (typeof mock === "string") {
|
|
70
|
-
return href === mock;
|
|
71
|
-
} else if (mock instanceof RegExp) {
|
|
72
|
-
return mock.test(href);
|
|
73
|
-
} else {
|
|
74
|
-
throw new Error(`Unsupported mock operation: ${JSON.stringify(mock)}`);
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
const mockRequester = (operationMatcher, operationToString) => {
|
|
79
|
-
const mocks = [];
|
|
80
|
-
const mockFn = (...args) => {
|
|
81
|
-
for (const mock of mocks) {
|
|
82
|
-
if (mock.onceOnly && mock.used) {
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
if (operationMatcher(mock.operation, ...args)) {
|
|
86
|
-
mock.used = true;
|
|
87
|
-
return mock.response();
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
const operation = operationToString(...args);
|
|
91
|
-
return Promise.reject(new Error(`No matching mock response found for request:
|
|
92
|
-
${operation}`));
|
|
93
|
-
};
|
|
94
|
-
const addMockedOperation = (operation, response, onceOnly) => {
|
|
95
|
-
const mockResponse = () => response.toPromise();
|
|
96
|
-
mocks.push({
|
|
97
|
-
operation,
|
|
98
|
-
response: mockResponse,
|
|
99
|
-
onceOnly,
|
|
100
|
-
used: false
|
|
101
|
-
});
|
|
102
|
-
return mockFn;
|
|
103
|
-
};
|
|
104
|
-
mockFn.mockOperation = (operation, response) => addMockedOperation(operation, response, false);
|
|
105
|
-
mockFn.mockOperationOnce = (operation, response) => addMockedOperation(operation, response, true);
|
|
106
|
-
return mockFn;
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const mockFetch = () => mockRequester(fetchRequestMatchesMock, (input, init) => `Input: ${typeof input === "string" ? input : JSON.stringify(input, null, 2)}
|
|
110
|
-
Options: ${init == null ? "None" : JSON.stringify(init, null, 2)}`);
|
|
111
|
-
|
|
112
35
|
const safeHasOwnProperty = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
|
|
113
36
|
const areObjectsEqual = (a, b) => {
|
|
114
37
|
if (a === b) {
|
|
@@ -150,173 +73,12 @@ const gqlRequestMatchesMock = (mock, operation, variables, context) => {
|
|
|
150
73
|
return true;
|
|
151
74
|
};
|
|
152
75
|
|
|
153
|
-
const mockGqlFetch = () => mockRequester(gqlRequestMatchesMock, (operation, variables, context) => `Operation: ${operation.type} ${operation.id}
|
|
76
|
+
const mockGqlFetch = () => wonderBlocksTestingCore.mockRequester(gqlRequestMatchesMock, (operation, variables, context) => `Operation: ${operation.type} ${operation.id}
|
|
154
77
|
Variables: ${variables == null ? "None" : JSON.stringify(variables, null, 2)}
|
|
155
78
|
Context: ${JSON.stringify(context, null, 2)}`);
|
|
156
79
|
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
const textResponse = (text, statusCode, signal) => ({
|
|
160
|
-
toPromise: () => makeMockResponse({
|
|
161
|
-
type: "text",
|
|
162
|
-
text,
|
|
163
|
-
statusCode,
|
|
164
|
-
signal
|
|
165
|
-
})
|
|
166
|
-
});
|
|
167
|
-
const rejectResponse = (error, signal) => ({
|
|
168
|
-
toPromise: () => makeMockResponse({
|
|
169
|
-
type: "reject",
|
|
170
|
-
error,
|
|
171
|
-
signal
|
|
172
|
-
})
|
|
173
|
-
});
|
|
174
|
-
const RespondWith = Object.freeze({
|
|
175
|
-
text: (text, statusCode = 200, signal = null) => textResponse(text, statusCode, signal),
|
|
176
|
-
json: (json, signal = null) => textResponse(() => JSON.stringify(json), 200, signal),
|
|
177
|
-
graphQLData: (data, signal = null) => textResponse(() => JSON.stringify({
|
|
178
|
-
data
|
|
179
|
-
}), 200, signal),
|
|
180
|
-
unparseableBody: (signal = null) => textResponse("INVALID JSON", 200, signal),
|
|
181
|
-
abortedRequest: (signal = null) => rejectResponse(() => {
|
|
182
|
-
const abortError = new Error("Mock request aborted");
|
|
183
|
-
abortError.name = "AbortError";
|
|
184
|
-
return abortError;
|
|
185
|
-
}, signal),
|
|
186
|
-
reject: (error, signal = null) => rejectResponse(error, signal),
|
|
187
|
-
errorStatusCode: (statusCode, signal = null) => {
|
|
188
|
-
if (statusCode < 300) {
|
|
189
|
-
throw new Error(`${statusCode} is not a valid error status code`);
|
|
190
|
-
}
|
|
191
|
-
return textResponse("{}", statusCode, signal);
|
|
192
|
-
},
|
|
193
|
-
nonGraphQLBody: (signal = null) => textResponse(() => JSON.stringify({
|
|
194
|
-
valid: "json",
|
|
195
|
-
that: "is not a valid graphql response"
|
|
196
|
-
}), 200, signal),
|
|
197
|
-
graphQLErrors: (errorMessages, signal = null) => textResponse(() => JSON.stringify({
|
|
198
|
-
errors: errorMessages.map(e => ({
|
|
199
|
-
message: e
|
|
200
|
-
}))
|
|
201
|
-
}), 200, signal)
|
|
202
|
-
});
|
|
203
|
-
const callOnSettled = (signal, fn) => {
|
|
204
|
-
if (signal == null || signal.settled) {
|
|
205
|
-
fn();
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
const onSettled = () => {
|
|
209
|
-
signal.removeEventListener("settled", onSettled);
|
|
210
|
-
fn();
|
|
211
|
-
};
|
|
212
|
-
signal.addEventListener("settled", onSettled);
|
|
213
|
-
};
|
|
214
|
-
const makeMockResponse = response => {
|
|
215
|
-
const {
|
|
216
|
-
signal
|
|
217
|
-
} = response;
|
|
218
|
-
switch (response.type) {
|
|
219
|
-
case "text":
|
|
220
|
-
return new Promise((resolve, reject) => {
|
|
221
|
-
callOnSettled(signal, () => {
|
|
222
|
-
const text = typeof response.text === "function" ? response.text() : response.text;
|
|
223
|
-
resolve(new ResponseImpl(text, {
|
|
224
|
-
status: response.statusCode
|
|
225
|
-
}));
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
case "reject":
|
|
229
|
-
return new Promise((resolve, reject) => {
|
|
230
|
-
callOnSettled(signal, () => reject(response.error instanceof Error ? response.error : response.error()));
|
|
231
|
-
});
|
|
232
|
-
default:
|
|
233
|
-
if (process.env.NODE_ENV !== "production") {
|
|
234
|
-
throw new Error(`Unknown response type: ${response.type}`);
|
|
235
|
-
}
|
|
236
|
-
return makeMockResponse({
|
|
237
|
-
type: "reject",
|
|
238
|
-
error: new Error("Unknown response type"),
|
|
239
|
-
signal
|
|
240
|
-
});
|
|
241
|
-
}
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
class SettleSignal extends EventTarget {
|
|
245
|
-
constructor(setSettleFn = null) {
|
|
246
|
-
super();
|
|
247
|
-
this._settled = false;
|
|
248
|
-
setSettleFn == null ? void 0 : setSettleFn(() => {
|
|
249
|
-
if (this._settled) {
|
|
250
|
-
throw new Error("SettleSignal already settled");
|
|
251
|
-
}
|
|
252
|
-
this._settled = true;
|
|
253
|
-
this.dispatchEvent(new Event("settled"));
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
static settle() {
|
|
257
|
-
const signal = new SettleSignal();
|
|
258
|
-
signal._settled = true;
|
|
259
|
-
return signal;
|
|
260
|
-
}
|
|
261
|
-
get settled() {
|
|
262
|
-
return this._settled;
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
class SettleController {
|
|
267
|
-
constructor() {
|
|
268
|
-
this._settleFn = void 0;
|
|
269
|
-
this._signal = void 0;
|
|
270
|
-
this._signal = new SettleSignal(settleFn => this._settleFn = settleFn);
|
|
271
|
-
}
|
|
272
|
-
get signal() {
|
|
273
|
-
return this._signal;
|
|
274
|
-
}
|
|
275
|
-
settle() {
|
|
276
|
-
var _this$_settleFn;
|
|
277
|
-
(_this$_settleFn = this._settleFn) == null ? void 0 : _this$_settleFn.call(this);
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
const defaultConfig$4 = null;
|
|
282
|
-
const normalizeConfig = config => {
|
|
283
|
-
if (typeof config === "string") {
|
|
284
|
-
return {
|
|
285
|
-
classes: [config],
|
|
286
|
-
style: {}
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
if (Array.isArray(config)) {
|
|
290
|
-
return {
|
|
291
|
-
classes: config,
|
|
292
|
-
style: {}
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
if (typeof config === "object") {
|
|
296
|
-
if ("classes" in config && config.classes != null && "style" in config && config.style != null) {
|
|
297
|
-
return config;
|
|
298
|
-
}
|
|
299
|
-
return {
|
|
300
|
-
classes: [],
|
|
301
|
-
style: config
|
|
302
|
-
};
|
|
303
|
-
}
|
|
304
|
-
throw new Error(`Invalid config: ${config}`);
|
|
305
|
-
};
|
|
306
|
-
const adapter$4 = (children, config) => {
|
|
307
|
-
const {
|
|
308
|
-
classes,
|
|
309
|
-
style
|
|
310
|
-
} = normalizeConfig(config);
|
|
311
|
-
return React__namespace.createElement("div", {
|
|
312
|
-
"data-testid": "css-adapter-container",
|
|
313
|
-
className: classes.join(" "),
|
|
314
|
-
style: style
|
|
315
|
-
}, children);
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
const defaultConfig$3 = [];
|
|
319
|
-
const adapter$3 = (children, config) => {
|
|
80
|
+
const defaultConfig$1 = [];
|
|
81
|
+
const adapter$1 = (children, config) => {
|
|
320
82
|
let currentChildren = children;
|
|
321
83
|
const interceptors = Array.isArray(config) ? config : [config];
|
|
322
84
|
for (const interceptor of interceptors) {
|
|
@@ -327,63 +89,6 @@ const adapter$3 = (children, config) => {
|
|
|
327
89
|
return React__namespace.createElement(React__namespace.Fragment, null, currentChildren);
|
|
328
90
|
};
|
|
329
91
|
|
|
330
|
-
const defaultConfig$2 = null;
|
|
331
|
-
const adapter$2 = (children, config) => React__namespace.createElement(React__namespace.Fragment, null, React__namespace.createElement("div", {
|
|
332
|
-
id: config,
|
|
333
|
-
"data-testid": config
|
|
334
|
-
}), children);
|
|
335
|
-
|
|
336
|
-
const defaultConfig$1 = {
|
|
337
|
-
location: "/"
|
|
338
|
-
};
|
|
339
|
-
const maybeWithRoute = (children, path) => {
|
|
340
|
-
if (path == null) {
|
|
341
|
-
return React__namespace.createElement(React__namespace.Fragment, null, children);
|
|
342
|
-
}
|
|
343
|
-
return React__namespace.createElement(reactRouterDom.Switch, null, React__namespace.createElement(reactRouterDom.Route, {
|
|
344
|
-
exact: true,
|
|
345
|
-
path: path
|
|
346
|
-
}, children), React__namespace.createElement(reactRouterDom.Route, {
|
|
347
|
-
path: "*",
|
|
348
|
-
render: () => {
|
|
349
|
-
throw new Error("The configured path must match the configured location or your harnessed component will not render.");
|
|
350
|
-
}
|
|
351
|
-
}));
|
|
352
|
-
};
|
|
353
|
-
const adapter$1 = (children, config) => {
|
|
354
|
-
if (typeof config === "string") {
|
|
355
|
-
config = {
|
|
356
|
-
location: config
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
const wrappedWithRoute = maybeWithRoute(children, config.path);
|
|
360
|
-
if ("forceStatic" in config && config.forceStatic) {
|
|
361
|
-
return React__namespace.createElement(reactRouterDom.StaticRouter, {
|
|
362
|
-
location: config.location,
|
|
363
|
-
context: {}
|
|
364
|
-
}, wrappedWithRoute);
|
|
365
|
-
}
|
|
366
|
-
if ("location" in config && config.location !== undefined) {
|
|
367
|
-
return React__namespace.createElement(reactRouterDom.MemoryRouter, {
|
|
368
|
-
initialEntries: [config.location]
|
|
369
|
-
}, wrappedWithRoute);
|
|
370
|
-
}
|
|
371
|
-
if (!("initialEntries" in config) || config.initialEntries === undefined) {
|
|
372
|
-
throw new Error("A location or initial history entries must be provided.");
|
|
373
|
-
}
|
|
374
|
-
const entries = config.initialEntries.length === 0 ? [defaultConfig$1.location] : config.initialEntries;
|
|
375
|
-
const routerProps = {
|
|
376
|
-
initialEntries: entries
|
|
377
|
-
};
|
|
378
|
-
if (config.initialIndex != null) {
|
|
379
|
-
routerProps.initialIndex = config.initialIndex;
|
|
380
|
-
}
|
|
381
|
-
if (config.getUserConfirmation != null) {
|
|
382
|
-
routerProps.getUserConfirmation = config.getUserConfirmation;
|
|
383
|
-
}
|
|
384
|
-
return React__namespace.createElement(reactRouterDom.MemoryRouter, routerProps, wrappedWithRoute);
|
|
385
|
-
};
|
|
386
|
-
|
|
387
92
|
const defaultConfig = null;
|
|
388
93
|
const adapter = (children, config) => {
|
|
389
94
|
if (config !== true) {
|
|
@@ -399,109 +104,59 @@ const adapter = (children, config) => {
|
|
|
399
104
|
};
|
|
400
105
|
|
|
401
106
|
const DefaultAdapters = {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
107
|
+
boundary: wonderBlocksTestingCore.harnessAdapters.DefaultAdapters.boundary,
|
|
108
|
+
css: wonderBlocksTestingCore.harnessAdapters.DefaultAdapters.css,
|
|
109
|
+
data: adapter$1,
|
|
110
|
+
portal: wonderBlocksTestingCore.harnessAdapters.DefaultAdapters.portal,
|
|
111
|
+
router: wonderBlocksTestingCore.harnessAdapters.DefaultAdapters.router,
|
|
406
112
|
ssr: adapter
|
|
407
113
|
};
|
|
408
|
-
const DefaultConfigs = {
|
|
409
|
-
|
|
410
|
-
data: defaultConfig$3,
|
|
411
|
-
portal: defaultConfig$2,
|
|
412
|
-
router: defaultConfig$1,
|
|
114
|
+
const DefaultConfigs = _extends__default["default"]({}, wonderBlocksTestingCore.harnessAdapters.DefaultConfigs, {
|
|
115
|
+
data: defaultConfig$1,
|
|
413
116
|
ssr: defaultConfig
|
|
414
|
-
};
|
|
117
|
+
});
|
|
415
118
|
|
|
416
|
-
var
|
|
119
|
+
var index = /*#__PURE__*/Object.freeze({
|
|
417
120
|
__proto__: null,
|
|
418
121
|
DefaultAdapters: DefaultAdapters,
|
|
419
122
|
DefaultConfigs: DefaultConfigs
|
|
420
123
|
});
|
|
421
124
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
return
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
})
|
|
458
|
-
|
|
459
|
-
const theConfig = configs[name];
|
|
460
|
-
if (theConfig == null) {
|
|
461
|
-
return newChildren;
|
|
462
|
-
}
|
|
463
|
-
const Adapter = getNamedAdapterComponent(name);
|
|
464
|
-
return React__namespace.createElement(Adapter, {
|
|
465
|
-
key: name,
|
|
466
|
-
adapter: adapter,
|
|
467
|
-
config: theConfig
|
|
468
|
-
}, newChildren);
|
|
469
|
-
}, React__namespace.createElement(React__namespace.Fragment, null, children));
|
|
470
|
-
};
|
|
471
|
-
|
|
472
|
-
const makeTestHarness = (adapters, defaultConfigs) => {
|
|
473
|
-
return (Component, configs) => {
|
|
474
|
-
const fullConfig = _extends({}, defaultConfigs, configs);
|
|
475
|
-
const harnessedComponent = React__namespace.forwardRef((props, ref) => React__namespace.createElement(Adapt, {
|
|
476
|
-
adapters: adapters,
|
|
477
|
-
configs: fullConfig
|
|
478
|
-
}, React__namespace.createElement(Component, _extends({}, props, {
|
|
479
|
-
ref: ref
|
|
480
|
-
}))));
|
|
481
|
-
harnessedComponent.displayName = `testHarness(${Component.displayName || Component.name || "Component"})`;
|
|
482
|
-
return harnessedComponent;
|
|
483
|
-
};
|
|
484
|
-
};
|
|
485
|
-
|
|
486
|
-
const HookHarness = ({
|
|
487
|
-
children
|
|
488
|
-
}) => React__namespace.createElement(React__namespace.Fragment, null, children);
|
|
489
|
-
const makeHookHarness = (adapters, defaultConfigs) => {
|
|
490
|
-
const testHarness = makeTestHarness(adapters, defaultConfigs);
|
|
491
|
-
return configs => testHarness(HookHarness, configs);
|
|
492
|
-
};
|
|
493
|
-
|
|
494
|
-
const hookHarness = makeHookHarness(DefaultAdapters, DefaultConfigs);
|
|
495
|
-
|
|
496
|
-
const testHarness = makeTestHarness(DefaultAdapters, DefaultConfigs);
|
|
497
|
-
|
|
498
|
-
exports.RespondWith = RespondWith;
|
|
499
|
-
exports.SettleController = SettleController;
|
|
500
|
-
exports.fixtures = fixtures;
|
|
501
|
-
exports.harnessAdapters = adapters;
|
|
502
|
-
exports.hookHarness = hookHarness;
|
|
503
|
-
exports.makeHookHarness = makeHookHarness;
|
|
504
|
-
exports.makeTestHarness = makeTestHarness;
|
|
505
|
-
exports.mockFetch = mockFetch;
|
|
125
|
+
Object.defineProperty(exports, 'RespondWith', {
|
|
126
|
+
enumerable: true,
|
|
127
|
+
get: function () { return wonderBlocksTestingCore.RespondWith; }
|
|
128
|
+
});
|
|
129
|
+
Object.defineProperty(exports, 'SettleController', {
|
|
130
|
+
enumerable: true,
|
|
131
|
+
get: function () { return wonderBlocksTestingCore.SettleController; }
|
|
132
|
+
});
|
|
133
|
+
Object.defineProperty(exports, 'fixtures', {
|
|
134
|
+
enumerable: true,
|
|
135
|
+
get: function () { return wonderBlocksTestingCore.fixtures; }
|
|
136
|
+
});
|
|
137
|
+
Object.defineProperty(exports, 'hookHarness', {
|
|
138
|
+
enumerable: true,
|
|
139
|
+
get: function () { return wonderBlocksTestingCore.hookHarness; }
|
|
140
|
+
});
|
|
141
|
+
Object.defineProperty(exports, 'makeHookHarness', {
|
|
142
|
+
enumerable: true,
|
|
143
|
+
get: function () { return wonderBlocksTestingCore.makeHookHarness; }
|
|
144
|
+
});
|
|
145
|
+
Object.defineProperty(exports, 'makeTestHarness', {
|
|
146
|
+
enumerable: true,
|
|
147
|
+
get: function () { return wonderBlocksTestingCore.makeTestHarness; }
|
|
148
|
+
});
|
|
149
|
+
Object.defineProperty(exports, 'mockFetch', {
|
|
150
|
+
enumerable: true,
|
|
151
|
+
get: function () { return wonderBlocksTestingCore.mockFetch; }
|
|
152
|
+
});
|
|
153
|
+
Object.defineProperty(exports, 'renderHookStatic', {
|
|
154
|
+
enumerable: true,
|
|
155
|
+
get: function () { return wonderBlocksTestingCore.renderHookStatic; }
|
|
156
|
+
});
|
|
157
|
+
Object.defineProperty(exports, 'testHarness', {
|
|
158
|
+
enumerable: true,
|
|
159
|
+
get: function () { return wonderBlocksTestingCore.testHarness; }
|
|
160
|
+
});
|
|
161
|
+
exports.harnessAdapters = index;
|
|
506
162
|
exports.mockGqlFetch = mockGqlFetch;
|
|
507
|
-
exports.testHarness = testHarness;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@khanacademy/wonder-blocks-testing",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.1",
|
|
4
4
|
"design": "v1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -14,21 +14,23 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@babel/runtime": "^7.18.6",
|
|
17
|
-
"@khanacademy/wonder-blocks-core": "^6.4.
|
|
18
|
-
"@khanacademy/wonder-blocks-data": "^13.0.
|
|
17
|
+
"@khanacademy/wonder-blocks-core": "^6.4.3",
|
|
18
|
+
"@khanacademy/wonder-blocks-data": "^13.0.10",
|
|
19
|
+
"@khanacademy/wonder-blocks-testing-core": "^1.0.1"
|
|
19
20
|
},
|
|
20
21
|
"peerDependencies": {
|
|
21
22
|
"@khanacademy/wonder-stuff-core": "^1.2.2",
|
|
22
|
-
"@storybook/addon-actions": "^
|
|
23
|
-
"node-fetch": "^2.6.7",
|
|
23
|
+
"@storybook/addon-actions": "^7.0.0",
|
|
24
24
|
"aphrodite": "^1.2.5",
|
|
25
|
+
"node-fetch": "^2.6.7",
|
|
25
26
|
"react": "16.14.0",
|
|
27
|
+
"react-dom": "16.14.0",
|
|
26
28
|
"react-router-dom": "5.3.0"
|
|
27
29
|
},
|
|
28
30
|
"devDependencies": {
|
|
29
|
-
"@khanacademy/wb-dev-build-settings": "^1.0.
|
|
31
|
+
"@khanacademy/wb-dev-build-settings": "^1.0.1",
|
|
30
32
|
"@khanacademy/wonder-stuff-testing": "^3.0.1"
|
|
31
33
|
},
|
|
32
34
|
"author": "",
|
|
33
35
|
"license": "MIT"
|
|
34
|
-
}
|
|
36
|
+
}
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import {render, screen, waitFor} from "@testing-library/react";
|
|
3
3
|
|
|
4
4
|
import {GqlRouter, useGql} from "@khanacademy/wonder-blocks-data";
|
|
5
|
-
import {RespondWith} from "
|
|
5
|
+
import {RespondWith} from "@khanacademy/wonder-blocks-testing-core";
|
|
6
6
|
import {mockGqlFetch} from "../mock-gql-fetch";
|
|
7
7
|
|
|
8
8
|
describe("#mockGqlFetch", () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {GqlOperation} from "@khanacademy/wonder-blocks-data";
|
|
2
|
+
import {RespondWith} from "@khanacademy/wonder-blocks-testing-core";
|
|
2
3
|
import type {GqlFetchMockFn} from "../types";
|
|
3
|
-
import {RespondWith} from "../../respond-with";
|
|
4
4
|
|
|
5
5
|
type SomeGqlData = {
|
|
6
6
|
a: string;
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import {render, screen, waitFor} from "@testing-library/react";
|
|
3
3
|
|
|
4
4
|
import {GqlRouter, useGql} from "@khanacademy/wonder-blocks-data";
|
|
5
|
-
import {RespondWith} from "
|
|
5
|
+
import {RespondWith} from "@khanacademy/wonder-blocks-testing-core";
|
|
6
6
|
import {mockGqlFetch} from "../mock-gql-fetch";
|
|
7
7
|
|
|
8
8
|
describe("integrating mockGqlFetch, RespondWith, GqlRouter and useGql", () => {
|
package/src/gql/types.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type {GqlOperation, GqlContext} from "@khanacademy/wonder-blocks-data";
|
|
2
|
-
import type {
|
|
3
|
-
|
|
2
|
+
import type {
|
|
3
|
+
GraphQLJson,
|
|
4
|
+
MockResponse,
|
|
5
|
+
} from "@khanacademy/wonder-blocks-testing-core";
|
|
4
6
|
|
|
5
7
|
export type GqlMockOperation<
|
|
6
8
|
TData extends Record<any, any>,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import {render, screen} from "@testing-library/react";
|
|
3
3
|
import * as WBCore from "@khanacademy/wonder-blocks-core";
|
|
4
|
-
import {makeTestHarness} from "
|
|
4
|
+
import {makeTestHarness} from "@khanacademy/wonder-blocks-testing-core";
|
|
5
5
|
|
|
6
6
|
import * as SSR from "../ssr";
|
|
7
7
|
|
|
@@ -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
|
|
|
5
5
|
type Interceptor = JSX.LibraryManagedAttributes<
|
|
6
6
|
typeof InterceptRequests,
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {harnessAdapters} from "@khanacademy/wonder-blocks-testing-core";
|
|
2
|
+
import type {TestHarnessConfigs} from "@khanacademy/wonder-blocks-testing-core";
|
|
2
3
|
import * as data from "./data";
|
|
3
|
-
import * as portal from "./portal";
|
|
4
|
-
import * as router from "./router";
|
|
5
4
|
import * as ssr from "./ssr";
|
|
6
5
|
|
|
7
|
-
import type {TestHarnessConfigs} from "../types";
|
|
8
|
-
|
|
9
6
|
/**
|
|
10
7
|
* NOTE: We do not type `DefaultAdapters` with `Adapters` here because we want
|
|
11
8
|
* the individual config types of each adapter to remain intact rather than
|
|
@@ -16,10 +13,14 @@ import type {TestHarnessConfigs} from "../types";
|
|
|
16
13
|
* The default adapters provided by Wonder Blocks.
|
|
17
14
|
*/
|
|
18
15
|
export const DefaultAdapters = {
|
|
19
|
-
|
|
16
|
+
// The error boundary is as close to the component under test as possible,
|
|
17
|
+
// so that other adapters don't soil it with their own errors, if that
|
|
18
|
+
// should happen.
|
|
19
|
+
boundary: harnessAdapters.DefaultAdapters.boundary,
|
|
20
|
+
css: harnessAdapters.DefaultAdapters.css,
|
|
20
21
|
data: data.adapter,
|
|
21
|
-
portal: portal
|
|
22
|
-
router: router
|
|
22
|
+
portal: harnessAdapters.DefaultAdapters.portal,
|
|
23
|
+
router: harnessAdapters.DefaultAdapters.router,
|
|
23
24
|
ssr: ssr.adapter,
|
|
24
25
|
} as const;
|
|
25
26
|
|
|
@@ -27,9 +28,7 @@ export const DefaultAdapters = {
|
|
|
27
28
|
* The default configurations to use with the `DefaultAdapters`.
|
|
28
29
|
*/
|
|
29
30
|
export const DefaultConfigs: TestHarnessConfigs<typeof DefaultAdapters> = {
|
|
30
|
-
|
|
31
|
+
...harnessAdapters.DefaultConfigs,
|
|
31
32
|
data: data.defaultConfig,
|
|
32
|
-
portal: portal.defaultConfig,
|
|
33
|
-
router: router.defaultConfig,
|
|
34
33
|
ssr: ssr.defaultConfig,
|
|
35
34
|
} as const;
|
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import {KindError, Errors} from "@khanacademy/wonder-stuff-core";
|
|
3
3
|
import {RenderStateRoot} from "@khanacademy/wonder-blocks-core";
|
|
4
4
|
|
|
5
|
-
import type {TestHarnessAdapter} from "
|
|
5
|
+
import type {TestHarnessAdapter} from "@khanacademy/wonder-blocks-testing-core";
|
|
6
6
|
|
|
7
7
|
//
|
|
8
8
|
type Config = true;
|