@khanacademy/wonder-blocks-testing 6.1.0 → 7.0.2

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.
Files changed (40) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/es/index.js +17 -187
  3. package/dist/index.js +90 -463
  4. package/package.json +2 -2
  5. package/src/__docs__/_overview_fixtures.stories.mdx +2 -6
  6. package/src/__docs__/exports.fixtures.stories.mdx +9 -31
  7. package/src/__docs__/types.fixture-fn.stories.mdx +46 -0
  8. package/src/__docs__/types.fixture-props.stories.mdx +20 -0
  9. package/src/fixtures/__tests__/fixtures.test.js +89 -466
  10. package/src/fixtures/fixtures.basic.stories.js +30 -50
  11. package/src/fixtures/fixtures.defaultwrapper.stories.js +26 -40
  12. package/src/fixtures/fixtures.js +50 -103
  13. package/src/fixtures/types.js +15 -181
  14. package/src/index.js +2 -11
  15. package/src/__docs__/exports.fixture-adapters.stories.mdx +0 -49
  16. package/src/__docs__/exports.setup-fixtures.stories.mdx +0 -22
  17. package/src/__docs__/types.custom-mount-props.stories.mdx +0 -35
  18. package/src/__docs__/types.fixtures-adapter-factory.stories.mdx +0 -23
  19. package/src/__docs__/types.fixtures-adapter-fixture-options.stories.mdx +0 -35
  20. package/src/__docs__/types.fixtures-adapter-group-options.stories.mdx +0 -37
  21. package/src/__docs__/types.fixtures-adapter-group.stories.mdx +0 -43
  22. package/src/__docs__/types.fixtures-adapter-options.stories.mdx +0 -21
  23. package/src/__docs__/types.fixtures-adapter.stories.mdx +0 -35
  24. package/src/__docs__/types.fixtures-configuration.stories.mdx +0 -35
  25. package/src/__docs__/types.fixtures-options.stories.mdx +0 -51
  26. package/src/fixtures/__tests__/combine-options.test.js +0 -65
  27. package/src/fixtures/__tests__/combine-top-level.test.js +0 -100
  28. package/src/fixtures/__tests__/setup.test.js +0 -71
  29. package/src/fixtures/adapters/__tests__/__snapshots__/adapter-group.test.js.snap +0 -9
  30. package/src/fixtures/adapters/__tests__/__snapshots__/adapter.test.js.snap +0 -13
  31. package/src/fixtures/adapters/__tests__/adapter-group.test.js +0 -223
  32. package/src/fixtures/adapters/__tests__/adapter.test.js +0 -97
  33. package/src/fixtures/adapters/__tests__/storybook.test.js +0 -369
  34. package/src/fixtures/adapters/adapter-group.js +0 -88
  35. package/src/fixtures/adapters/adapter.js +0 -63
  36. package/src/fixtures/adapters/adapters.js +0 -2
  37. package/src/fixtures/adapters/storybook.js +0 -128
  38. package/src/fixtures/combine-options.js +0 -25
  39. package/src/fixtures/combine-top-level.js +0 -44
  40. package/src/fixtures/setup.js +0 -30
@@ -1,223 +0,0 @@
1
- // @flow
2
- import {AdapterGroup} from "../adapter-group.js";
3
-
4
- describe("AdapterGroup", () => {
5
- describe("#constructor", () => {
6
- it("should throw if closeGroupFn is not valid", () => {
7
- // Arrange
8
- const badCloseGroupFn: any = null;
9
-
10
- // Act
11
- const act = () =>
12
- new AdapterGroup(badCloseGroupFn, {
13
- title: "TITLE",
14
- description: null,
15
- getDefaultTitle: () => {
16
- throw new Error("NOT IMPLEMENTED");
17
- },
18
- });
19
-
20
- expect(act).toThrowErrorMatchingInlineSnapshot(
21
- `"closeGroupFn must be a function"`,
22
- );
23
- });
24
-
25
- it.each([null, "a string"])(
26
- "should throw if options are not valid (%s)",
27
- (badOptions) => {
28
- // Arrange
29
-
30
- // Act
31
- const act = () => new AdapterGroup(() => {}, badOptions);
32
-
33
- // Assert
34
- expect(act).toThrowErrorMatchingSnapshot();
35
- },
36
- );
37
- });
38
-
39
- describe("#closeGroup", () => {
40
- it("should call closeGroupFn with group options and empty fixtures if there are none", () => {
41
- // Arrange
42
- const closeGroupFn = jest.fn();
43
- const groupOptions = {
44
- title: "TITLE",
45
- description: null,
46
- getDefaultTitle: () => {
47
- throw new Error("NOT IMPLEMENTED");
48
- },
49
- };
50
- const adapterGroup = new AdapterGroup(closeGroupFn, groupOptions);
51
-
52
- // Act
53
- adapterGroup.closeGroup();
54
-
55
- // Assert
56
- expect(closeGroupFn).toHaveBeenCalledWith(groupOptions, null, []);
57
- });
58
-
59
- it("should call closeGroupFn with group options, adapter options, and empty fixtures if there are none", () => {
60
- // Arrange
61
- const closeGroupFn = jest.fn();
62
- const groupOptions = {
63
- title: "TITLE",
64
- description: null,
65
- getDefaultTitle: () => {
66
- throw new Error("NOT IMPLEMENTED");
67
- },
68
- };
69
- const adapterSpecificOptions = {
70
- adapterSpecificOption: "adapterSpecificOption",
71
- };
72
- const adapterGroup = new AdapterGroup(closeGroupFn, groupOptions);
73
-
74
- // Act
75
- adapterGroup.closeGroup(adapterSpecificOptions);
76
-
77
- // Assert
78
- expect(closeGroupFn).toHaveBeenCalledWith(
79
- groupOptions,
80
- adapterSpecificOptions,
81
- [],
82
- );
83
- });
84
-
85
- it("should call closeGroupFn with fixtures if some were declared", () => {
86
- // Arrange
87
- const closeGroupFn = jest.fn();
88
- const groupOptions = {
89
- title: "TITLE",
90
- description: "DESCRIPTION",
91
- getDefaultTitle: () => {
92
- throw new Error("NOT IMPLEMENTED");
93
- },
94
- };
95
- const adapterGroup = new AdapterGroup(closeGroupFn, groupOptions);
96
- const fixture = {
97
- component: () => null,
98
- description: "FIXTURE_DESCRIPTION",
99
- getProps: jest.fn(),
100
- };
101
-
102
- // Act
103
- adapterGroup.declareFixture(fixture);
104
- adapterGroup.closeGroup();
105
-
106
- // Assert
107
- expect(closeGroupFn).toHaveBeenCalledWith(groupOptions, null, [
108
- fixture,
109
- ]);
110
- });
111
-
112
- it("should throw if called when group has already closed", () => {
113
- // Arrange
114
- const closeGroupFn = jest.fn();
115
- const groupOptions = {
116
- title: "TITLE",
117
- description: null,
118
- getDefaultTitle: () => {
119
- throw new Error("NOT IMPLEMENTED");
120
- },
121
- };
122
- const adapterGroup = new AdapterGroup(closeGroupFn, groupOptions);
123
- adapterGroup.closeGroup();
124
-
125
- // Act
126
- const act = () => adapterGroup.closeGroup();
127
-
128
- // Assert
129
- expect(act).toThrowErrorMatchingInlineSnapshot(
130
- `"Group already closed"`,
131
- );
132
- });
133
- });
134
-
135
- describe("#declareFixture", () => {
136
- it.each([null, "a string"])(
137
- "should throw if options are not valid (%s)",
138
- (badFixtureOptions) => {
139
- // Arrange
140
- const closeGroupFn = jest.fn();
141
- const groupOptions = {
142
- title: "TITLE",
143
- description: null,
144
- getDefaultTitle: () => {
145
- throw new Error("NOT IMPLEMENTED");
146
- },
147
- };
148
- const adapterGroup = new AdapterGroup(
149
- closeGroupFn,
150
- groupOptions,
151
- );
152
-
153
- // Act
154
- const act = () =>
155
- adapterGroup.declareFixture(badFixtureOptions);
156
-
157
- // Assert
158
- expect(act).toThrowErrorMatchingSnapshot();
159
- },
160
- );
161
-
162
- it("should add fixtures for inclusion in the closeGroup call", () => {
163
- // Arrange
164
- const closeGroupFn = jest.fn();
165
- const groupOptions = {
166
- title: "TITLE",
167
- description: "DESCRIPTION",
168
- getDefaultTitle: () => {
169
- throw new Error("NOT IMPLEMENTED");
170
- },
171
- };
172
- const adapterGroup = new AdapterGroup(closeGroupFn, groupOptions);
173
- const fixture1 = {
174
- component: () => null,
175
- description: "FIXTURE_DESCRIPTION1",
176
- getProps: jest.fn(),
177
- };
178
- const fixture2 = {
179
- component: () => null,
180
- description: "FIXTURE_DESCRIPTION2",
181
- getProps: jest.fn(),
182
- };
183
-
184
- // Act
185
- adapterGroup.declareFixture(fixture1);
186
- adapterGroup.declareFixture(fixture2);
187
- adapterGroup.closeGroup();
188
-
189
- // Assert
190
- expect(closeGroupFn).toHaveBeenCalledWith(groupOptions, null, [
191
- fixture1,
192
- fixture2,
193
- ]);
194
- });
195
-
196
- it("should throw if called when group has already closed", () => {
197
- // Arrange
198
- const closeGroupFn = jest.fn();
199
- const groupOptions = {
200
- title: "TITLE",
201
- description: null,
202
- getDefaultTitle: () => {
203
- throw new Error("NOT IMPLEMENTED");
204
- },
205
- };
206
- const adapterGroup = new AdapterGroup(closeGroupFn, groupOptions);
207
- adapterGroup.closeGroup();
208
-
209
- // Act
210
- const act = () =>
211
- adapterGroup.declareFixture({
212
- component: () => null,
213
- description: "FIXTURE_DESCRIPTION",
214
- getProps: jest.fn(),
215
- });
216
-
217
- // Assert
218
- expect(act).toThrowErrorMatchingInlineSnapshot(
219
- `"Cannot declare fixtures after closing the group"`,
220
- );
221
- });
222
- });
223
- });
@@ -1,97 +0,0 @@
1
- // @flow
2
- import {Adapter} from "../adapter.js";
3
-
4
- import * as AdapterGroupModule from "../adapter-group.js";
5
-
6
- jest.mock("../adapter-group.js");
7
-
8
- describe("Adapter", () => {
9
- describe("#constructor", () => {
10
- it.each([null, 8, "", " "])(
11
- "should throw if the name is invalid (%s)",
12
- (invalidName) => {
13
- // Arrange
14
-
15
- // Act
16
- const act = () => new Adapter(invalidName, () => {});
17
-
18
- // Assert
19
- expect(act).toThrowErrorMatchingSnapshot();
20
- },
21
- );
22
-
23
- it.each([null, 5])(
24
- "should throw if closeGroupFn is invalid",
25
- (invalidCloseGroupFn) => {
26
- // Arrange
27
-
28
- // Act
29
- const act = () => new Adapter("name", invalidCloseGroupFn);
30
-
31
- // Assert
32
- expect(act).toThrowErrorMatchingSnapshot();
33
- },
34
- );
35
- });
36
-
37
- describe("@name", () => {
38
- it("should match the value passed during construction", () => {
39
- // Arrange
40
- const name = "adapter_name";
41
- const adapter = new Adapter(name, () => {});
42
-
43
- // Act
44
- const result = adapter.name;
45
-
46
- // Assert
47
- expect(result).toBe(name);
48
- });
49
- });
50
-
51
- describe("#declareGroup", () => {
52
- it("should pass the closeGroupFn and options to the adapter group", () => {
53
- // Arrange
54
- const closeGroupFn = jest.fn();
55
- const adapter = new Adapter("adapter_name", closeGroupFn);
56
- const options = {
57
- title: "group_title",
58
- description: "group_description",
59
- getDefaultTitle: () => {
60
- throw new Error("NOT IMPLEMENTED");
61
- },
62
- };
63
- const adapterGroupSpy = jest
64
- .spyOn(AdapterGroupModule, "AdapterGroup")
65
- .mockImplementation(() => {});
66
-
67
- // Act
68
- adapter.declareGroup(options);
69
-
70
- // Assert
71
- expect(adapterGroupSpy).toHaveBeenCalledWith(closeGroupFn, options);
72
- });
73
-
74
- it("should return the created AdapterGroup", () => {
75
- // Arrange
76
- const adapter = new Adapter("adapter_name", () => {});
77
- const adapterGroup: any = {
78
- whatAmI: "ADAPTER_GROUP",
79
- };
80
- jest.spyOn(AdapterGroupModule, "AdapterGroup").mockImplementation(
81
- () => adapterGroup,
82
- );
83
-
84
- // Act
85
- const result = adapter.declareGroup({
86
- title: "group_title",
87
- description: "group_description",
88
- getDefaultTitle: () => {
89
- throw new Error("NOT IMPLEMENTED");
90
- },
91
- });
92
-
93
- // Assert
94
- expect(result).toBe(adapterGroup);
95
- });
96
- });
97
- });
@@ -1,369 +0,0 @@
1
- // @flow
2
- import * as React from "react";
3
- import {render, screen} from "@testing-library/react";
4
- import * as AddonActionsModule from "@storybook/addon-actions";
5
- import {getAdapter} from "../storybook.js";
6
-
7
- import * as AdapterModule from "../adapter.js";
8
-
9
- jest.mock("../adapter.js");
10
- jest.mock("@storybook/addon-actions");
11
-
12
- describe("Storybook Adapter", () => {
13
- beforeEach(() => {
14
- jest.resetAllMocks();
15
- });
16
-
17
- describe("#getAdapter", () => {
18
- it("should create an Adapter instance", () => {
19
- // Arrange
20
- const adapterSpy = jest
21
- .spyOn(AdapterModule, "Adapter")
22
- .mockImplementation(() => {});
23
-
24
- // Act
25
- getAdapter();
26
-
27
- // Assert
28
- expect(adapterSpy).toHaveBeenCalledWith(
29
- "storybook",
30
- expect.any(Function),
31
- );
32
- });
33
-
34
- it("should return the created Adapter instance", () => {
35
- // Arrangejest
36
- const fakeAdapter = {
37
- iAmA: "FAKE_ADAPTER",
38
- };
39
- jest.spyOn(AdapterModule, "Adapter").mockImplementation(
40
- () => fakeAdapter,
41
- );
42
-
43
- // Act
44
- const result = getAdapter();
45
-
46
- // Assert
47
- expect(result).toBe(fakeAdapter);
48
- });
49
-
50
- describe("closeGroupFn", () => {
51
- it("should return the storybook exports", () => {
52
- // Arrange
53
- const adapterSpy = jest
54
- .spyOn(AdapterModule, "Adapter")
55
- .mockImplementation(() => {});
56
- getAdapter();
57
- const closeGroupFn = adapterSpy.mock.calls[0][1];
58
-
59
- // Act
60
- const result = closeGroupFn(
61
- {
62
- title: "TITLE",
63
- description: "DESCRIPTION",
64
- },
65
- {
66
- adapterOption1: "adapterOption1",
67
- adapterOption2: "adapterOption2",
68
- },
69
- [
70
- {
71
- description:
72
- "🎉 This is a story with legal and illegal characters",
73
- component: () => "I AM A COMPONENT",
74
- getProps: () => ({
75
- these: "areProps",
76
- }),
77
- },
78
- ],
79
- );
80
-
81
- // Assert
82
- expect(result).toStrictEqual({
83
- default: {
84
- title: "TITLE",
85
- adapterOption1: "adapterOption1",
86
- adapterOption2: "adapterOption2",
87
- },
88
- "1ThisIsAStoryWithLegalAndIllegalCharacters":
89
- expect.any(Function),
90
- });
91
- });
92
- });
93
-
94
- describe("exported story", () => {
95
- it("should inject API into getProps generator", () => {
96
- // Arrange
97
- const adapterSpy = jest
98
- .spyOn(AdapterModule, "Adapter")
99
- .mockImplementation(() => {});
100
- getAdapter();
101
- const closeGroupFn = adapterSpy.mock.calls[0][1];
102
- const getPropsStub = jest.fn();
103
-
104
- // Act
105
- closeGroupFn(
106
- {
107
- title: "TITLE",
108
- description: "DESCRIPTION",
109
- },
110
- null,
111
- [
112
- {
113
- description:
114
- "🎉 This is a story with legal and illegal characters",
115
- component: () => "I AM A COMPONENT",
116
- getProps: getPropsStub,
117
- },
118
- ],
119
- );
120
-
121
- // Assert
122
- expect(getPropsStub).toHaveBeenCalledWith({
123
- log: expect.any(Function),
124
- logHandler: expect.any(Function),
125
- });
126
- });
127
-
128
- it("should inject log function that logs to storybook actions", () => {
129
- // Arrange
130
- const adapterSpy = jest
131
- .spyOn(AdapterModule, "Adapter")
132
- .mockImplementation(() => {});
133
- getAdapter();
134
- const actionReturnFn = jest.fn();
135
- const actionSpy = jest
136
- .spyOn(AddonActionsModule, "action")
137
- .mockReturnValue(actionReturnFn);
138
- const closeGroupFn = adapterSpy.mock.calls[0][1];
139
- const getPropsStub = jest.fn();
140
- closeGroupFn(
141
- {
142
- title: "TITLE",
143
- description: "DESCRIPTION",
144
- },
145
- null,
146
- [
147
- {
148
- description:
149
- "🎉 This is a story with legal and illegal characters",
150
- component: () => "I AM A COMPONENT",
151
- getProps: getPropsStub,
152
- },
153
- ],
154
- );
155
- const {log: logFn} = getPropsStub.mock.calls[0][0];
156
-
157
- // Act
158
- logFn("MESSAGE", "ARG1", "ARG2");
159
-
160
- // Assert
161
- expect(actionSpy).toHaveBeenCalledWith("MESSAGE");
162
- expect(actionReturnFn).toHaveBeenCalledWith("ARG1", "ARG2");
163
- });
164
-
165
- it("should inject logHandler function that logs to storybook actions", () => {
166
- // Arrange
167
- const adapterSpy = jest
168
- .spyOn(AdapterModule, "Adapter")
169
- .mockImplementation(() => {});
170
- getAdapter();
171
- const actionReturnFn = jest.fn();
172
- const actionSpy = jest
173
- .spyOn(AddonActionsModule, "action")
174
- .mockReturnValue(actionReturnFn);
175
- const closeGroupFn = adapterSpy.mock.calls[0][1];
176
- const getPropsStub = jest.fn();
177
- closeGroupFn(
178
- {
179
- title: "TITLE",
180
- description: "DESCRIPTION",
181
- },
182
- null,
183
- [
184
- {
185
- description:
186
- "🎉 This is a story with legal and illegal characters",
187
- component: () => "I AM A COMPONENT",
188
- getProps: getPropsStub,
189
- },
190
- ],
191
- );
192
- const {logHandler: logHandlerFn} =
193
- getPropsStub.mock.calls[0][0];
194
-
195
- // Act
196
- const logFn = logHandlerFn("MESSAGE");
197
- logFn("ARG1", "ARG2");
198
-
199
- // Assert
200
- expect(actionSpy).toHaveBeenCalledWith("MESSAGE");
201
- expect(actionReturnFn).toHaveBeenCalledWith("ARG1", "ARG2");
202
- });
203
-
204
- it("should have args attached", () => {
205
- // Arrange
206
- const adapterSpy = jest
207
- .spyOn(AdapterModule, "Adapter")
208
- .mockImplementation(() => {});
209
- getAdapter();
210
- const closeGroupFn = adapterSpy.mock.calls[0][1];
211
- const props = {
212
- this: "isAProp",
213
- andSo: "isThis",
214
- };
215
-
216
- // Act
217
- const {"1ASimpleStory": result} = closeGroupFn(
218
- {
219
- title: "TITLE",
220
- description: "DESCRIPTION",
221
- },
222
- null,
223
- [
224
- {
225
- description: "A simple story",
226
- component: () => "I AM A COMPONENT",
227
- getProps: () => props,
228
- },
229
- ],
230
- );
231
-
232
- // Assert
233
- expect(result).toHaveProperty("args", props);
234
- });
235
-
236
- it("should have story name attached", () => {
237
- // Arrange
238
- const adapterSpy = jest
239
- .spyOn(AdapterModule, "Adapter")
240
- .mockImplementation(() => {});
241
- getAdapter();
242
- const closeGroupFn = adapterSpy.mock.calls[0][1];
243
-
244
- // Act
245
- const {"1ASimpleStory": result} = closeGroupFn(
246
- {
247
- title: "TITLE",
248
- description: "DESCRIPTION",
249
- },
250
- null,
251
- [
252
- {
253
- description: "A simple story",
254
- component: () => "I AM A COMPONENT",
255
- getProps: () => ({}),
256
- },
257
- ],
258
- );
259
-
260
- // Assert
261
- expect(result).toHaveProperty("storyName", "1 A simple story");
262
- });
263
-
264
- it("should render the component", () => {
265
- // Arrange
266
- const adapterSpy = jest
267
- .spyOn(AdapterModule, "Adapter")
268
- .mockImplementation(() => {});
269
- getAdapter();
270
- const closeGroupFn = adapterSpy.mock.calls[0][1];
271
- const {"1ASimpleStory": Fixture} = closeGroupFn(
272
- {
273
- title: "TITLE",
274
- description: "DESCRIPTION",
275
- },
276
- null,
277
- [
278
- {
279
- description: "A simple story",
280
- component: (props) =>
281
- `I rendered ${JSON.stringify(props)}`,
282
- getProps: () => ({}),
283
- },
284
- ],
285
- );
286
-
287
- // Act
288
- render(<Fixture aProp="aValue" />);
289
-
290
- // Assert
291
- expect(
292
- screen.getByText('I rendered {"aProp":"aValue"}'),
293
- ).toBeInTheDocument();
294
- });
295
-
296
- it("should render the MountingComponent when provided", () => {
297
- // Arrange
298
- const adapterSpy = jest
299
- .spyOn(AdapterModule, "Adapter")
300
- .mockImplementation(() => {});
301
- const MountingComponent = (props) =>
302
- "I AM A MOUNTING COMPONENT";
303
- getAdapter(MountingComponent);
304
- const closeGroupFn = adapterSpy.mock.calls[0][1];
305
- const {"1ASimpleStory": Fixture} = closeGroupFn(
306
- {
307
- title: "TITLE",
308
- description: "DESCRIPTION",
309
- },
310
- null,
311
- [
312
- {
313
- description: "A simple story",
314
- component: (props) =>
315
- `I rendered ${JSON.stringify(props)}`,
316
- getProps: () => ({}),
317
- },
318
- ],
319
- );
320
-
321
- // Act
322
- render(<Fixture aProp="aValue" />);
323
-
324
- // Assert
325
- expect(
326
- screen.getByText("I AM A MOUNTING COMPONENT"),
327
- ).toBeInTheDocument();
328
- });
329
-
330
- it("should render the mounting component with the expected API", () => {
331
- // Arrange
332
- // Have to use the real Adapter here or the closure around
333
- // the MountingComponent doesn't work for this test.
334
- const adapterSpy = jest.spyOn(AdapterModule, "Adapter");
335
- const mountingComponentStub = jest.fn().mockReturnValue(null);
336
- const MountingComponent = (props) =>
337
- mountingComponentStub(props);
338
- getAdapter(MountingComponent);
339
- const closeGroupFn = adapterSpy.mock.calls[0][1];
340
- const Component = (props) =>
341
- `I rendered ${JSON.stringify(props)}`;
342
- const {"1ASimpleStory": Fixture} = closeGroupFn(
343
- {
344
- title: "TITLE",
345
- description: "DESCRIPTION",
346
- },
347
- null,
348
- [
349
- {
350
- description: "A simple story",
351
- component: Component,
352
- getProps: () => ({}),
353
- },
354
- ],
355
- );
356
-
357
- // Act
358
- render(<Fixture aProp="aValue" />);
359
-
360
- // Assert
361
- expect(mountingComponentStub).toHaveBeenCalledWith({
362
- component: Component,
363
- props: {aProp: "aValue"},
364
- log: expect.any(Function),
365
- });
366
- });
367
- });
368
- });
369
- });