@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,527 +1,150 @@
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<any, _>(
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<any, _>(
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
16
 
113
17
  // Act
114
- fixtures(component, jest.fn());
115
- const {getDefaultTitle} = adapter.declareGroup.mock.calls[0][0];
116
- const result = getDefaultTitle();
18
+ const result = fixtures(() => <div />);
117
19
 
118
20
  // Assert
119
- expect(result).toBe("FUNCTIONNAME");
21
+ expect(result).toBeFunction();
120
22
  });
121
23
 
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<any, _>(
161
- {
162
- title: "GROUP_TITLE",
163
- description: "GROUP_DESCRIPTION",
164
- component: () => "COMPONENT",
165
- },
166
- fn,
167
- );
24
+ describe("returned function", () => {
25
+ it("should return a story component function", () => {
26
+ // Arrange
27
+ const fixture = fixtures(() => <div />);
168
28
 
169
- // Assert
170
- expect(fn).toHaveBeenCalledWith(expect.any(Function));
171
- });
29
+ // Act
30
+ const result = fixture("My fixture", {});
172
31
 
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,
32
+ // Assert
33
+ expect(result).toBeFunction();
193
34
  });
194
- const additionalTestAdapterOptions = {
195
- bim: "bop",
196
- };
197
35
 
198
- // Act
199
- fixtures<any, _>(
200
- {
201
- component: () => "COMPONENT",
202
- additionalAdapterOptions: {
203
- testadapter: additionalTestAdapterOptions,
204
- otheradapterwedontcareabout: {
205
- fig: "fug",
206
- },
207
- },
208
- },
209
- jest.fn(),
210
- );
36
+ it("should inject API into getProps generator", () => {
37
+ // Arrange
38
+ const fixture = fixtures(() => <div />);
39
+ const getPropsFn = jest.fn();
211
40
 
212
- // Assert
213
- expect(combineOptionsSpy).toHaveBeenCalledWith(
214
- defaultAdapterOptions,
215
- additionalTestAdapterOptions,
216
- );
217
- });
41
+ // Act
42
+ fixture("My fixture", getPropsFn);
218
43
 
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,
44
+ // Assert
45
+ expect(getPropsFn).toHaveBeenCalledWith({
46
+ log: expect.any(Function),
47
+ logHandler: expect.any(Function),
48
+ });
238
49
  });
239
- const additionalTestAdapterOptions = {
240
- bim: "bop",
241
- };
242
50
 
243
- // Act
244
- fixtures<any, _>(
245
- {
246
- component: () => "COMPONENT",
247
- additionalAdapterOptions: {
248
- testadapter: additionalTestAdapterOptions,
249
- otheradapterwedontcareabout: {
250
- fig: "fug",
251
- },
252
- },
253
- },
254
- jest.fn(),
255
- );
51
+ it("should inject log function that logs to storybook actions", () => {
52
+ // Arrange
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];
256
61
 
257
- // Assert
258
- expect(fakeGroup.closeGroup).toHaveBeenCalledWith("COMBINED_OPTIONS");
259
- });
62
+ // Act
63
+ logFn("MESSAGE", "ARG1", "ARG2");
260
64
 
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,
65
+ // Assert
66
+ expect(actionSpy).toHaveBeenCalledWith("MESSAGE");
67
+ expect(actionReturnFn).toHaveBeenCalledWith("ARG1", "ARG2");
273
68
  });
274
69
 
275
- // Act
276
- const result = fixtures<any, _>(
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", () => {
70
+ it("should inject logHandler function that logs to storybook actions", () => {
289
71
  // 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";
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];
302
80
 
303
81
  // Act
304
- fixtures<any, _>(
305
- {
306
- title: "GROUP_TITLE",
307
- description: "GROUP_DESCRIPTION",
308
- component,
309
- },
310
- (fixture) => {
311
- fixture("FIXTURE_DESCRIPTION", {these: "areProps"});
312
- },
313
- );
82
+ const logFn = logHandlerFn("MESSAGE");
83
+ logFn("ARG1", "ARG2");
314
84
 
315
85
  // Assert
316
- expect(fakeGroup.declareFixture).toHaveBeenCalledWith({
317
- description: "FIXTURE_DESCRIPTION",
318
- getProps: expect.any(Function),
319
- component,
320
- });
86
+ expect(actionSpy).toHaveBeenCalledWith("MESSAGE");
87
+ expect(actionReturnFn).toHaveBeenCalledWith("ARG1", "ARG2");
321
88
  });
322
89
 
323
- it("should call group.declareFixture with component if component is forward ref", () => {
90
+ it("should have args attached", () => {
324
91
  // 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",
92
+ const fixture = fixtures(() => <div />);
93
+ const props = {
94
+ this: "isAProp",
95
+ andSo: "isThis",
332
96
  };
333
- jest.spyOn(SetupModule, "getConfiguration").mockReturnValue({
334
- adapter,
335
- });
336
- const component = React.forwardRef((props, ref) => (
337
- <div {...props} ref={ref} />
338
- ));
339
97
 
340
98
  // Act
341
- fixtures(component, (fixture) => {
342
- fixture("FIXTURE_DESCRIPTION", {these: "areProps"});
343
- });
99
+ const result = fixture("A simple story", props);
344
100
 
345
101
  // Assert
346
- expect(fakeGroup.declareFixture).toHaveBeenCalledWith({
347
- description: "FIXTURE_DESCRIPTION",
348
- getProps: expect.any(Function),
349
- component,
350
- });
102
+ expect(result).toHaveProperty("args", props);
351
103
  });
352
104
 
353
- it("should pass wrapper component to group.declareFixture", () => {
105
+ it("should have story name attached", () => {
354
106
  // 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";
107
+ const fixture = fixtures(() => <div />);
368
108
 
369
109
  // Act
370
- fixtures<any, _>(
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
- );
110
+ const result = fixture("A simple story", {});
385
111
 
386
112
  // Assert
387
- expect(fakeGroup.declareFixture).toHaveBeenCalledWith({
388
- description: "FIXTURE_DESCRIPTION",
389
- getProps: expect.any(Function),
390
- component: wrapper,
391
- });
113
+ expect(result).toHaveProperty("storyName", "1 A simple story");
392
114
  });
393
115
 
394
- it("should pass defaultWrapper component to group.declareFixture if no wrapper", () => {
116
+ it("should render the component", () => {
395
117
  // Arrange
396
- const fakeGroup = {
397
- declareFixture: jest.fn(),
398
- closeGroup: jest.fn(),
399
- };
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";
118
+ const fixture = fixtures(
119
+ (props) => `I rendered ${JSON.stringify(props)}`,
120
+ );
121
+ const Fixture: any = fixture("A simple story", {});
408
122
 
409
123
  // Act
410
- fixtures<any, _>(
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
- );
124
+ render(<Fixture aProp="aValue" />);
421
125
 
422
126
  // Assert
423
- expect(fakeGroup.declareFixture).toHaveBeenCalledWith({
424
- description: "FIXTURE_DESCRIPTION",
425
- getProps: expect.any(Function),
426
- component: defaultWrapper,
427
- });
127
+ expect(
128
+ screen.getByText('I rendered {"aProp":"aValue"}'),
129
+ ).toBeInTheDocument();
428
130
  });
429
131
 
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<any, _>(
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"});
476
-
477
- // Act
478
- fixtures<any, _>(
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");
489
-
490
- // Assert
491
- expect(props).toHaveBeenCalledWith("OPTIONS");
492
- });
493
-
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"});
132
+ it("should render the wrapper", () => {
133
+ // Arrange
134
+ const fixture = fixtures(
135
+ (props) => `I rendered ${JSON.stringify(props)}`,
136
+ );
137
+ const Fixture: any = fixture(
138
+ "A simple story",
139
+ {},
140
+ () => "I am a wrapper",
141
+ );
508
142
 
509
- // Act
510
- fixtures<any, _>(
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");
143
+ // Act
144
+ render(<Fixture aProp="aValue" />);
521
145
 
522
- // Assert
523
- expect(result).toEqual({these: "areProps"});
524
- });
146
+ // Assert
147
+ expect(screen.getByText("I am a wrapper")).toBeInTheDocument();
525
148
  });
526
149
  });
527
150
  });