@khanacademy/wonder-blocks-testing 5.0.2 → 7.0.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.
Files changed (39) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/es/index.js +19 -191
  3. package/dist/index.js +87 -462
  4. package/package.json +2 -2
  5. package/src/__docs__/_overview_fixtures.stories.mdx +2 -6
  6. package/src/__docs__/exports.fixtures.stories.mdx +13 -27
  7. package/src/__docs__/types.get-props-options.stories.mdx +28 -1
  8. package/src/fixtures/__tests__/fixtures.test.js +75 -470
  9. package/src/fixtures/fixtures.basic.stories.js +34 -49
  10. package/src/fixtures/fixtures.defaultwrapper.stories.js +26 -40
  11. package/src/fixtures/fixtures.js +57 -100
  12. package/src/fixtures/types.js +7 -188
  13. package/src/index.js +1 -14
  14. package/src/__docs__/exports.fixture-adapters.stories.mdx +0 -49
  15. package/src/__docs__/exports.setup-fixtures.stories.mdx +0 -22
  16. package/src/__docs__/types.custom-mount-props.stories.mdx +0 -35
  17. package/src/__docs__/types.fixtures-adapter-factory.stories.mdx +0 -23
  18. package/src/__docs__/types.fixtures-adapter-fixture-options.stories.mdx +0 -35
  19. package/src/__docs__/types.fixtures-adapter-group-options.stories.mdx +0 -37
  20. package/src/__docs__/types.fixtures-adapter-group.stories.mdx +0 -43
  21. package/src/__docs__/types.fixtures-adapter-options.stories.mdx +0 -21
  22. package/src/__docs__/types.fixtures-adapter.stories.mdx +0 -35
  23. package/src/__docs__/types.fixtures-configuration.stories.mdx +0 -35
  24. package/src/__docs__/types.fixtures-options.stories.mdx +0 -51
  25. package/src/fixtures/__tests__/combine-options.test.js +0 -65
  26. package/src/fixtures/__tests__/combine-top-level.test.js +0 -100
  27. package/src/fixtures/__tests__/setup.test.js +0 -71
  28. package/src/fixtures/adapters/__tests__/__snapshots__/adapter-group.test.js.snap +0 -9
  29. package/src/fixtures/adapters/__tests__/__snapshots__/adapter.test.js.snap +0 -13
  30. package/src/fixtures/adapters/__tests__/adapter-group.test.js +0 -223
  31. package/src/fixtures/adapters/__tests__/adapter.test.js +0 -97
  32. package/src/fixtures/adapters/__tests__/storybook.test.js +0 -329
  33. package/src/fixtures/adapters/adapter-group.js +0 -88
  34. package/src/fixtures/adapters/adapter.js +0 -63
  35. package/src/fixtures/adapters/adapters.js +0 -2
  36. package/src/fixtures/adapters/storybook.js +0 -125
  37. package/src/fixtures/combine-options.js +0 -25
  38. package/src/fixtures/combine-top-level.js +0 -44
  39. package/src/fixtures/setup.js +0 -30
@@ -1,527 +1,132 @@
1
1
  // @flow
2
2
  import * as React from "react";
3
- import * as SetupModule from "../setup.js";
4
- import * as CombineOptionsModule from "../combine-options.js";
3
+ import {render, screen} from "@testing-library/react";
4
+ import * as AddonActionsModule from "@storybook/addon-actions";
5
5
  import {fixtures} from "../fixtures.js";
6
6
 
7
- jest.mock("../setup.js");
8
- jest.mock("../combine-options.js");
7
+ jest.mock("@storybook/addon-actions");
9
8
 
10
- describe("#fixtures", () => {
9
+ describe("fixtures", () => {
11
10
  beforeEach(() => {
12
- jest.clearAllMocks();
11
+ jest.resetAllMocks();
13
12
  });
14
13
 
15
- it("should declare a group on the configured adapter based off the given component", () => {
14
+ it("should create return a function", () => {
16
15
  // Arrange
17
- const fakeGroup = {
18
- closeGroup: jest.fn(),
19
- };
20
- const adapter = {
21
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
22
- name: "testadapter",
23
- };
24
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
25
- adapter,
26
- });
27
-
28
- // Act
29
- fixtures(() => "COMPONENT", jest.fn());
30
-
31
- // Assert
32
- expect(adapter.declareGroup).toHaveBeenCalledWith({
33
- getDefaultTitle: expect.any(Function),
34
- });
35
- });
36
-
37
- it("should declare a group on the configured adapter with the given title and description", () => {
38
- // Arrange
39
- const fakeGroup = {
40
- closeGroup: jest.fn(),
41
- };
42
- const adapter = {
43
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
44
- name: "testadapter",
45
- };
46
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
47
- adapter,
48
- });
49
-
50
- // Act
51
- fixtures(
52
- {
53
- title: "TITLE",
54
- description: "DESCRIPTION",
55
- component: () => "COMPONENT",
56
- },
57
- jest.fn(),
58
- );
59
-
60
- // Assert
61
- expect(adapter.declareGroup).toHaveBeenCalledWith({
62
- title: "TITLE",
63
- description: "DESCRIPTION",
64
- getDefaultTitle: expect.any(Function),
65
- });
66
- });
67
-
68
- it("should default the title to the component.displayName in the absence of title", () => {
69
- // Arrange
70
- const fakeGroup = {
71
- closeGroup: jest.fn(),
72
- };
73
- const adapter = {
74
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
75
- name: "testadapter",
76
- };
77
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
78
- adapter,
79
- });
80
- const component = () => "COMPONENT";
81
- component.displayName = "DISPLAYNAME";
82
-
83
- // Act
84
- fixtures(
85
- {
86
- component,
87
- },
88
- jest.fn(),
89
- );
90
- const {getDefaultTitle} = adapter.declareGroup.mock.calls[0][0];
91
- const result = getDefaultTitle();
92
-
93
- // Assert
94
- expect(result).toBe("DISPLAYNAME");
95
- });
96
-
97
- it("should default the title to the component.name in the absence of component.displayName", () => {
98
- // Arrange
99
- const fakeGroup = {
100
- closeGroup: jest.fn(),
101
- };
102
- const adapter = {
103
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
104
- name: "testadapter",
105
- };
106
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
107
- adapter,
108
- });
109
- const component = function FUNCTIONNAME() {
110
- return "COMPONENT";
111
- };
112
-
113
- // Act
114
- fixtures(component, jest.fn());
115
- const {getDefaultTitle} = adapter.declareGroup.mock.calls[0][0];
116
- const result = getDefaultTitle();
117
-
118
- // Assert
119
- expect(result).toBe("FUNCTIONNAME");
120
- });
121
-
122
- it("should default the title to 'Component' in the absence of component.name", () => {
123
- // Arrange
124
- const fakeGroup = {
125
- closeGroup: jest.fn(),
126
- };
127
- const adapter = {
128
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
129
- name: "testadapter",
130
- };
131
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
132
- adapter,
133
- });
134
-
135
- // Act
136
- fixtures(() => "test", jest.fn());
137
- const {getDefaultTitle} = adapter.declareGroup.mock.calls[0][0];
138
- const result = getDefaultTitle();
139
-
140
- // Assert
141
- expect(result).toBe("Component");
142
- });
143
-
144
- it("should invoke the passed fn with function argument", () => {
145
- // Arrange
146
- const fakeGroup = {
147
- declareFixture: jest.fn(),
148
- closeGroup: jest.fn(),
149
- };
150
- const adapter = {
151
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
152
- name: "testadapter",
153
- };
154
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
155
- adapter,
156
- });
157
- const fn = jest.fn();
158
-
159
- // Act
160
- fixtures(
161
- {
162
- title: "GROUP_TITLE",
163
- description: "GROUP_DESCRIPTION",
164
- component: () => "COMPONENT",
165
- },
166
- fn,
167
- );
168
-
169
- // Assert
170
- expect(fn).toHaveBeenCalledWith(expect.any(Function));
171
- });
172
-
173
- it("should combine additionalAdapterOptions for the appropriate adapter with defaultAdapterOptions", () => {
174
- // Arrange
175
- const combineOptionsSpy = jest.spyOn(
176
- CombineOptionsModule,
177
- "combineOptions",
178
- );
179
- const fakeGroup = {
180
- declareFixture: jest.fn(),
181
- closeGroup: jest.fn(),
182
- };
183
- const adapter = {
184
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
185
- name: "testadapter",
186
- };
187
- const defaultAdapterOptions = {
188
- foo: "bar",
189
- };
190
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
191
- adapter,
192
- defaultAdapterOptions,
193
- });
194
- const additionalTestAdapterOptions = {
195
- bim: "bop",
196
- };
197
16
 
198
17
  // Act
199
- fixtures(
200
- {
201
- component: () => "COMPONENT",
202
- additionalAdapterOptions: {
203
- testadapter: additionalTestAdapterOptions,
204
- otheradapterwedontcareabout: {
205
- fig: "fug",
206
- },
207
- },
208
- },
209
- jest.fn(),
210
- );
18
+ const result = fixtures(() => <div />);
211
19
 
212
20
  // Assert
213
- expect(combineOptionsSpy).toHaveBeenCalledWith(
214
- defaultAdapterOptions,
215
- additionalTestAdapterOptions,
216
- );
21
+ expect(result).toBeFunction();
217
22
  });
218
23
 
219
- it("should call group.closeGroup with the combined adapter options", () => {
220
- // Arrange
221
- jest.spyOn(CombineOptionsModule, "combineOptions").mockReturnValue(
222
- "COMBINED_OPTIONS",
223
- );
224
- const fakeGroup = {
225
- declareFixture: jest.fn(),
226
- closeGroup: jest.fn(),
227
- };
228
- const adapter = {
229
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
230
- name: "testadapter",
231
- };
232
- const defaultAdapterOptions = {
233
- foo: "bar",
234
- };
235
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
236
- adapter,
237
- defaultAdapterOptions,
238
- });
239
- const additionalTestAdapterOptions = {
240
- bim: "bop",
241
- };
242
-
243
- // Act
244
- fixtures(
245
- {
246
- component: () => "COMPONENT",
247
- additionalAdapterOptions: {
248
- testadapter: additionalTestAdapterOptions,
249
- otheradapterwedontcareabout: {
250
- fig: "fug",
251
- },
252
- },
253
- },
254
- jest.fn(),
255
- );
24
+ describe("returned function", () => {
25
+ it("should return a story component function", () => {
26
+ // Arrange
27
+ const fixture = fixtures(() => <div />);
256
28
 
257
- // Assert
258
- expect(fakeGroup.closeGroup).toHaveBeenCalledWith("COMBINED_OPTIONS");
259
- });
29
+ // Act
30
+ const result = fixture("My fixture", {});
260
31
 
261
- it("should return the result of group.closeGroup", () => {
262
- // Arrange
263
- const fakeGroup = {
264
- declareFixture: jest.fn(),
265
- closeGroup: jest.fn().mockReturnValue("RESULT"),
266
- };
267
- const adapter = {
268
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
269
- name: "testadapter",
270
- };
271
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
272
- adapter,
32
+ // Assert
33
+ expect(result).toBeFunction();
273
34
  });
274
35
 
275
- // Act
276
- const result = fixtures(
277
- {
278
- component: () => "COMPONENT",
279
- },
280
- jest.fn(),
281
- );
282
-
283
- // Assert
284
- expect(result).toEqual("RESULT");
285
- });
286
-
287
- describe("injected fixture fn", () => {
288
- it("should call group.declareFixture with description, props getter, and component", () => {
36
+ it("should inject API into getProps generator", () => {
289
37
  // Arrange
290
- const fakeGroup = {
291
- declareFixture: jest.fn(),
292
- closeGroup: jest.fn(),
293
- };
294
- const adapter = {
295
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
296
- name: "testadapter",
297
- };
298
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
299
- adapter,
300
- });
301
- const component = () => "COMPONENT";
38
+ const fixture = fixtures(() => <div />);
39
+ const getPropsFn = jest.fn();
302
40
 
303
41
  // Act
304
- fixtures(
305
- {
306
- title: "GROUP_TITLE",
307
- description: "GROUP_DESCRIPTION",
308
- component,
309
- },
310
- (fixture) => {
311
- fixture("FIXTURE_DESCRIPTION", {these: "areProps"});
312
- },
313
- );
42
+ fixture("My fixture", getPropsFn);
314
43
 
315
44
  // Assert
316
- expect(fakeGroup.declareFixture).toHaveBeenCalledWith({
317
- description: "FIXTURE_DESCRIPTION",
318
- getProps: expect.any(Function),
319
- component,
45
+ expect(getPropsFn).toHaveBeenCalledWith({
46
+ log: expect.any(Function),
47
+ logHandler: expect.any(Function),
320
48
  });
321
49
  });
322
50
 
323
- it("should call group.declareFixture with component if component is forward ref", () => {
51
+ it("should inject log function that logs to storybook actions", () => {
324
52
  // Arrange
325
- const fakeGroup = {
326
- declareFixture: jest.fn(),
327
- closeGroup: jest.fn(),
328
- };
329
- const adapter = {
330
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
331
- name: "testadapter",
332
- };
333
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
334
- adapter,
335
- });
336
- const component = React.forwardRef((props, ref) => (
337
- <div {...props} ref={ref} />
338
- ));
53
+ const fixture = fixtures(() => <div />);
54
+ const getPropsFn = jest.fn();
55
+ const actionReturnFn = jest.fn();
56
+ const actionSpy = jest
57
+ .spyOn(AddonActionsModule, "action")
58
+ .mockReturnValue(actionReturnFn);
59
+ fixture("My fixture", getPropsFn);
60
+ const {log: logFn} = getPropsFn.mock.calls[0][0];
339
61
 
340
62
  // Act
341
- fixtures(component, (fixture) => {
342
- fixture("FIXTURE_DESCRIPTION", {these: "areProps"});
343
- });
63
+ logFn("MESSAGE", "ARG1", "ARG2");
344
64
 
345
65
  // Assert
346
- expect(fakeGroup.declareFixture).toHaveBeenCalledWith({
347
- description: "FIXTURE_DESCRIPTION",
348
- getProps: expect.any(Function),
349
- component,
350
- });
66
+ expect(actionSpy).toHaveBeenCalledWith("MESSAGE");
67
+ expect(actionReturnFn).toHaveBeenCalledWith("ARG1", "ARG2");
351
68
  });
352
69
 
353
- it("should pass wrapper component to group.declareFixture", () => {
70
+ it("should inject logHandler function that logs to storybook actions", () => {
354
71
  // Arrange
355
- const fakeGroup = {
356
- declareFixture: jest.fn(),
357
- closeGroup: jest.fn(),
358
- };
359
- const adapter = {
360
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
361
- name: "testadapter",
362
- };
363
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
364
- adapter,
365
- });
366
- const defaultWrapper = () => "DEFAULT_WRAPPER";
367
- const wrapper = () => "WRAPPER";
72
+ const fixture = fixtures(() => <div />);
73
+ const getPropsFn = jest.fn();
74
+ const actionReturnFn = jest.fn();
75
+ const actionSpy = jest
76
+ .spyOn(AddonActionsModule, "action")
77
+ .mockReturnValue(actionReturnFn);
78
+ fixture("My fixture", getPropsFn);
79
+ const {logHandler: logHandlerFn} = getPropsFn.mock.calls[0][0];
368
80
 
369
81
  // Act
370
- fixtures(
371
- {
372
- title: "GROUP_TITLE",
373
- description: "GROUP_DESCRIPTION",
374
- component: () => "COMPONENT",
375
- defaultWrapper,
376
- },
377
- (fixture) => {
378
- fixture(
379
- "FIXTURE_DESCRIPTION",
380
- {these: "areProps"},
381
- wrapper,
382
- );
383
- },
384
- );
82
+ const logFn = logHandlerFn("MESSAGE");
83
+ logFn("ARG1", "ARG2");
385
84
 
386
85
  // Assert
387
- expect(fakeGroup.declareFixture).toHaveBeenCalledWith({
388
- description: "FIXTURE_DESCRIPTION",
389
- getProps: expect.any(Function),
390
- component: wrapper,
391
- });
86
+ expect(actionSpy).toHaveBeenCalledWith("MESSAGE");
87
+ expect(actionReturnFn).toHaveBeenCalledWith("ARG1", "ARG2");
392
88
  });
393
89
 
394
- it("should pass defaultWrapper component to group.declareFixture if no wrapper", () => {
90
+ it("should have args attached", () => {
395
91
  // Arrange
396
- const fakeGroup = {
397
- declareFixture: jest.fn(),
398
- closeGroup: jest.fn(),
92
+ const fixture = fixtures(() => <div />);
93
+ const props = {
94
+ this: "isAProp",
95
+ andSo: "isThis",
399
96
  };
400
- const adapter = {
401
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
402
- name: "testadapter",
403
- };
404
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
405
- adapter,
406
- });
407
- const defaultWrapper = () => "DEFAULT_WRAPPER";
408
97
 
409
98
  // Act
410
- fixtures(
411
- {
412
- title: "GROUP_TITLE",
413
- description: "GROUP_DESCRIPTION",
414
- component: () => "COMPONENT",
415
- defaultWrapper,
416
- },
417
- (fixture) => {
418
- fixture("FIXTURE_DESCRIPTION", {these: "areProps"});
419
- },
420
- );
99
+ const result = fixture("A simple story", props);
421
100
 
422
101
  // Assert
423
- expect(fakeGroup.declareFixture).toHaveBeenCalledWith({
424
- description: "FIXTURE_DESCRIPTION",
425
- getProps: expect.any(Function),
426
- component: defaultWrapper,
427
- });
102
+ expect(result).toHaveProperty("args", props);
428
103
  });
429
104
 
430
- describe("getProps fn passed to group.declareFixture", () => {
431
- it("should return the props when props is an object", () => {
432
- // Arrange
433
- const fakeGroup = {
434
- declareFixture: jest.fn(),
435
- closeGroup: jest.fn(),
436
- };
437
- const adapter = {
438
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
439
- name: "testadapter",
440
- };
441
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
442
- adapter,
443
- });
444
-
445
- // Act
446
- fixtures(
447
- {
448
- component: () => "COMPONENT",
449
- },
450
- (fixture) => {
451
- fixture("FIXTURE_DESCRIPTION", {these: "areProps"});
452
- },
453
- );
454
- const getPropsFn =
455
- fakeGroup.declareFixture.mock.calls[0][0].getProps;
456
- const result = getPropsFn("OPTIONS");
457
-
458
- // Assert
459
- expect(result).toEqual({these: "areProps"});
460
- });
461
-
462
- it("should invoke the props function with given options when props is a function", () => {
463
- // Arrange
464
- const fakeGroup = {
465
- declareFixture: jest.fn(),
466
- closeGroup: jest.fn(),
467
- };
468
- const adapter = {
469
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
470
- name: "testadapter",
471
- };
472
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
473
- adapter,
474
- });
475
- const props = jest.fn().mockReturnValue({these: "areProps"});
105
+ it("should have story name attached", () => {
106
+ // Arrange
107
+ const fixture = fixtures(() => <div />);
476
108
 
477
- // Act
478
- fixtures(
479
- {
480
- component: () => "COMPONENT",
481
- },
482
- (fixture) => {
483
- fixture("FIXTURE_DESCRIPTION", props);
484
- },
485
- );
486
- const getPropsFn =
487
- fakeGroup.declareFixture.mock.calls[0][0].getProps;
488
- getPropsFn("OPTIONS");
109
+ // Act
110
+ const result = fixture("A simple story", {});
489
111
 
490
- // Assert
491
- expect(props).toHaveBeenCalledWith("OPTIONS");
492
- });
112
+ // Assert
113
+ expect(result).toHaveProperty("storyName", "1 A simple story");
114
+ });
493
115
 
494
- it("should return the result of the props function when props is a function", () => {
495
- // Arrange
496
- const fakeGroup = {
497
- declareFixture: jest.fn(),
498
- closeGroup: jest.fn(),
499
- };
500
- const adapter = {
501
- declareGroup: jest.fn().mockReturnValue(fakeGroup),
502
- name: "testadapter",
503
- };
504
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
505
- adapter,
506
- });
507
- const props = jest.fn().mockReturnValue({these: "areProps"});
116
+ it("should render the component", () => {
117
+ // Arrange
118
+ const fixture = fixtures(
119
+ (props) => `I rendered ${JSON.stringify(props)}`,
120
+ );
121
+ const Fixture: any = fixture("A simple story", {});
508
122
 
509
- // Act
510
- fixtures(
511
- {
512
- component: () => "COMPONENT",
513
- },
514
- (fixture) => {
515
- fixture("FIXTURE_DESCRIPTION", props);
516
- },
517
- );
518
- const getPropsFn =
519
- fakeGroup.declareFixture.mock.calls[0][0].getProps;
520
- const result = getPropsFn("OPTIONS");
123
+ // Act
124
+ render(<Fixture aProp="aValue" />);
521
125
 
522
- // Assert
523
- expect(result).toEqual({these: "areProps"});
524
- });
126
+ // Assert
127
+ expect(
128
+ screen.getByText('I rendered {"aProp":"aValue"}'),
129
+ ).toBeInTheDocument();
525
130
  });
526
131
  });
527
132
  });