@khanacademy/wonder-blocks-testing 3.0.0 → 3.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @khanacademy/wonder-blocks-testing
2
2
 
3
+ ## 3.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 6e4fbeed: Make sure simplified fixtures call copes with return values from React.forwardRef
8
+
3
9
  ## 3.0.0
4
10
 
5
11
  ### Major Changes
package/dist/es/index.js CHANGED
@@ -267,10 +267,8 @@ const combineOptions = (...toBeCombined) => {
267
267
 
268
268
  const normalizeOptions = componentOrOptions => {
269
269
  // To differentiate between a React component and a FixturesOptions object,
270
- // we have to do some type checking. Since all React components, whether
271
- // functional or class-based, are inherently functions in JavaScript
272
- // this should do the trick without relying on internal React details like
273
- // protoype.isReactComponent. This should be sufficient for our purposes.
270
+ // we have to do some type checking.
271
+ //
274
272
  // Alternatives I considered were:
275
273
  // - Use an additional parameter for the options and then do an arg number
276
274
  // check, but that always makes typing a function harder and often breaks
@@ -279,8 +277,17 @@ const normalizeOptions = componentOrOptions => {
279
277
  // being the component and the second being the options. However that
280
278
  // feels like an obscure API even though it's really easy to do the
281
279
  // typing.
282
- if (typeof componentOrOptions === "function") {
280
+ if ( // Most React components, whether functional or class-based, are
281
+ // inherently functions in JavaScript, so a check for functions is
282
+ // usually sufficient.
283
+ typeof componentOrOptions === "function" || // However, the return of React.forwardRef is not a function,
284
+ // so we also have to cope with that.
285
+ // A forwardRef has $$typeof = Symbol(react.forward_ref) and a
286
+ // render function.
287
+ // $FlowIgnore[prop-missing]
288
+ typeof componentOrOptions.render === "function") {
283
289
  return {
290
+ // $FlowIgnore[incompatible-return]
284
291
  component: componentOrOptions
285
292
  };
286
293
  } // We can't test for React.ComponentType at runtime.
package/dist/index.js CHANGED
@@ -328,10 +328,8 @@ const getAdapter = (MountingComponent = null) => new _adapter_js__WEBPACK_IMPORT
328
328
 
329
329
  const normalizeOptions = componentOrOptions => {
330
330
  // To differentiate between a React component and a FixturesOptions object,
331
- // we have to do some type checking. Since all React components, whether
332
- // functional or class-based, are inherently functions in JavaScript
333
- // this should do the trick without relying on internal React details like
334
- // protoype.isReactComponent. This should be sufficient for our purposes.
331
+ // we have to do some type checking.
332
+ //
335
333
  // Alternatives I considered were:
336
334
  // - Use an additional parameter for the options and then do an arg number
337
335
  // check, but that always makes typing a function harder and often breaks
@@ -340,8 +338,17 @@ const normalizeOptions = componentOrOptions => {
340
338
  // being the component and the second being the options. However that
341
339
  // feels like an obscure API even though it's really easy to do the
342
340
  // typing.
343
- if (typeof componentOrOptions === "function") {
341
+ if ( // Most React components, whether functional or class-based, are
342
+ // inherently functions in JavaScript, so a check for functions is
343
+ // usually sufficient.
344
+ typeof componentOrOptions === "function" || // However, the return of React.forwardRef is not a function,
345
+ // so we also have to cope with that.
346
+ // A forwardRef has $$typeof = Symbol(react.forward_ref) and a
347
+ // render function.
348
+ // $FlowIgnore[prop-missing]
349
+ typeof componentOrOptions.render === "function") {
344
350
  return {
351
+ // $FlowIgnore[incompatible-return]
345
352
  component: componentOrOptions
346
353
  };
347
354
  } // We can't test for React.ComponentType at runtime.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanacademy/wonder-blocks-testing",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "design": "v1",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -1,4 +1,5 @@
1
1
  // @flow
2
+ import * as React from "react";
2
3
  import * as SetupModule from "../setup.js";
3
4
  import * as CombineOptionsModule from "../combine-options.js";
4
5
  import {fixtures} from "../fixtures.js";
@@ -284,7 +285,7 @@ describe("#fixtures", () => {
284
285
  });
285
286
 
286
287
  describe("injected fixture fn", () => {
287
- it("should call group.declareFixture with description and props getter", () => {
288
+ it("should call group.declareFixture with description, props getter, and component", () => {
288
289
  // Arrange
289
290
  const fakeGroup = {
290
291
  declareFixture: jest.fn(),
@@ -319,6 +320,36 @@ describe("#fixtures", () => {
319
320
  });
320
321
  });
321
322
 
323
+ it("should call group.declareFixture with component if component is forward ref", () => {
324
+ // 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
+ ));
339
+
340
+ // Act
341
+ fixtures(component, (fixture) => {
342
+ fixture("FIXTURE_DESCRIPTION", {these: "areProps"});
343
+ });
344
+
345
+ // Assert
346
+ expect(fakeGroup.declareFixture).toHaveBeenCalledWith({
347
+ description: "FIXTURE_DESCRIPTION",
348
+ getProps: expect.any(Function),
349
+ component,
350
+ });
351
+ });
352
+
322
353
  it("should pass wrapper component to group.declareFixture", () => {
323
354
  // Arrange
324
355
  const fakeGroup = {
@@ -15,10 +15,8 @@ const normalizeOptions = <TProps: {...}>(
15
15
  | $ReadOnly<FixturesOptions<TProps>>,
16
16
  ): $ReadOnly<FixturesOptions<TProps>> => {
17
17
  // To differentiate between a React component and a FixturesOptions object,
18
- // we have to do some type checking. Since all React components, whether
19
- // functional or class-based, are inherently functions in JavaScript
20
- // this should do the trick without relying on internal React details like
21
- // protoype.isReactComponent. This should be sufficient for our purposes.
18
+ // we have to do some type checking.
19
+ //
22
20
  // Alternatives I considered were:
23
21
  // - Use an additional parameter for the options and then do an arg number
24
22
  // check, but that always makes typing a function harder and often breaks
@@ -27,8 +25,20 @@ const normalizeOptions = <TProps: {...}>(
27
25
  // being the component and the second being the options. However that
28
26
  // feels like an obscure API even though it's really easy to do the
29
27
  // typing.
30
- if (typeof componentOrOptions === "function") {
28
+ if (
29
+ // Most React components, whether functional or class-based, are
30
+ // inherently functions in JavaScript, so a check for functions is
31
+ // usually sufficient.
32
+ typeof componentOrOptions === "function" ||
33
+ // However, the return of React.forwardRef is not a function,
34
+ // so we also have to cope with that.
35
+ // A forwardRef has $$typeof = Symbol(react.forward_ref) and a
36
+ // render function.
37
+ // $FlowIgnore[prop-missing]
38
+ typeof componentOrOptions.render === "function"
39
+ ) {
31
40
  return {
41
+ // $FlowIgnore[incompatible-return]
32
42
  component: componentOrOptions,
33
43
  };
34
44
  }