@khanacademy/wonder-blocks-testing 7.0.0 → 7.0.3

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,24 @@
1
1
  # @khanacademy/wonder-blocks-testing
2
2
 
3
+ ## 7.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [dc2e00f4]
8
+ - @khanacademy/wonder-blocks-data@8.0.4
9
+
10
+ ## 7.0.2
11
+
12
+ ### Patch Changes
13
+
14
+ - aa7993a8: Make sure wrapper component is used when provided
15
+
16
+ ## 7.0.1
17
+
18
+ ### Patch Changes
19
+
20
+ - 79a3bc8e: Export more types for the fixtures framework
21
+
3
22
  ## 7.0.0
4
23
 
5
24
  ### Major Changes
package/dist/es/index.js CHANGED
@@ -17,12 +17,13 @@ const fixtures = Component => {
17
17
 
18
18
  const getProps = options => typeof props === "function" ? props(options) : props;
19
19
 
20
- let Template = templateMap.get(Component);
20
+ const RealComponent = wrapper || Component;
21
+ let Template = templateMap.get(RealComponent);
21
22
 
22
23
  if (Template == null) {
23
- Template = args => React.createElement(Component, args);
24
+ Template = args => React.createElement(RealComponent, args);
24
25
 
25
- templateMap.set(Component, Template);
26
+ templateMap.set(RealComponent, Template);
26
27
  }
27
28
 
28
29
  const story = Template.bind({});
package/dist/index.js CHANGED
@@ -719,20 +719,21 @@ const fixtures = Component => {
719
719
  const makeStory = (description, props, wrapper = null) => {
720
720
  const storyName = `${storyNumber++} ${description}`;
721
721
 
722
- const getProps = options => typeof props === "function" ? props(options) : props; // We create a “template” of how args map to rendering
722
+ const getProps = options => typeof props === "function" ? props(options) : props;
723
+
724
+ const RealComponent = wrapper || Component; // We create a “template” of how args map to rendering
723
725
  // for each type of component as the component here could
724
726
  // be the component under test, or wrapped in a wrapper
725
727
  // component. We don't use decorators for the wrapper
726
728
  // because we may not be in a storybook context and it
727
729
  // keeps the framework API simpler this way.
728
730
 
729
-
730
- let Template = templateMap.get(Component);
731
+ let Template = templateMap.get(RealComponent);
731
732
 
732
733
  if (Template == null) {
733
- Template = args => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](Component, args);
734
+ Template = args => /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__["createElement"](RealComponent, args);
734
735
 
735
- templateMap.set(Component, Template);
736
+ templateMap.set(RealComponent, Template);
736
737
  } // Each story that shares that component then reuses that
737
738
  // template.
738
739
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@khanacademy/wonder-blocks-testing",
3
- "version": "7.0.0",
3
+ "version": "7.0.3",
4
4
  "design": "v1",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@babel/runtime": "^7.18.6",
17
- "@khanacademy/wonder-blocks-data": "^8.0.3"
17
+ "@khanacademy/wonder-blocks-data": "^8.0.4"
18
18
  },
19
19
  "peerDependencies": {
20
20
  "@khanacademy/wonder-stuff-core": "^0.1.2",
@@ -21,19 +21,11 @@ fixtures<
21
21
  TProps: React.ElementConfig<TComponent>,
22
22
  >(
23
23
  Component: TComponent,
24
- ): (
25
- description: string,
26
- props: FixtureProps<TProps>,
27
- wrapper?: React.ComponentType<TProps>,
28
- ) => void;
24
+ ): FixtureFn<TProps>;
29
25
  ```
30
26
 
31
27
  The `fixtures()` method is used to define a set of fixtures for a component. Each fixture is a story compatible with the CSF format used by Storybook.
32
28
 
33
29
  The method returned by `fixtures(Component)` is a strongly-typed call for generating a named story with the given args, and using the given wrapper component, if provided. See [our Fixtures Framework example stories](/docs/testing-fixtures-basic--f-1) for examples.
34
30
 
35
- The `fixture` function takes two or three arguments:
36
-
37
- - `description: string`: A string describing the fixture. This should be used to explain what the fixture is expected to show.
38
- - `props: FixtureProps<TProps>`: The props that the fixture should be rendered with. This can be either a plain object, or a function that returns a plain object. The function will be called with an API to assist in generating the props (see [`GetPropsOptions`](/docs/testing-fixtures-types-getpropsoptions--page)).
39
- - `wrapper?: React.ComponentType<TProps>`: An optional component that will be rendered around the fixture. This can be used to wrap the fixture in a component that adds additional functionality, such as a test harness (see [`makeTestHarness`](/docs/testing-test-harness-exports-maketestharness--page)).
31
+ The returned `fixture` function is of type [`FixtureFn<TProps>`](/docs/testing-fixtures-types-fixturefn--page).
@@ -0,0 +1,46 @@
1
+ import {Meta} from "@storybook/addon-docs";
2
+
3
+ <Meta
4
+ title="Testing / Fixtures / Types / FixtureFn"
5
+ parameters={{
6
+ chromatic: {
7
+ disableSnapshot: true,
8
+ },
9
+ }}
10
+ />
11
+
12
+ # FixtureFn
13
+
14
+ ```ts
15
+ /**
16
+ * A function for defining a fixture.
17
+ */
18
+ type FixtureFn<TProps: {...}> = (
19
+ /**
20
+ * The name of the fixture.
21
+ */
22
+ description: string,
23
+
24
+ /**
25
+ * The props for the fixture or a function that returns the props.
26
+ * The function is injected with an API to facilitate logging.
27
+ */
28
+ props: FixtureProps<TProps>,
29
+
30
+ /**
31
+ * An alternative component to render for the fixture.
32
+ * Useful if the fixture requires some additional setup for testing the
33
+ * component.
34
+ */
35
+ wrapper?: React.ComponentType<TProps>,
36
+ ) => mixed;
37
+
38
+ ```
39
+
40
+ The [`fixtures`](/docs/testing-fixtures-exports-fixtures--page) method returns a method of this type, specific to the component that was passed into `fixtures`.
41
+
42
+ This function takes two or three arguments:
43
+
44
+ - `description: string`: A string describing the fixture. This should be used to explain what the fixture is expected to show.
45
+ - `props: FixtureProps<TProps>`: The props that the fixture should be rendered with. See [`FixtureProps`](/docs/testing-fixtures-types-fixtureprops--page).
46
+ - `wrapper?: React.ComponentType<TProps>`: An optional component that will be rendered for the fixture. This can be used to wrap the fixture in a component that adds additional functionality, such as a test harness (see [`makeTestHarness`](/docs/testing-test-harness-exports-maketestharness--page)).
@@ -0,0 +1,20 @@
1
+ import {Meta} from "@storybook/addon-docs";
2
+
3
+ <Meta
4
+ title="Testing / Fixtures / Types / FixtureProps"
5
+ parameters={{
6
+ chromatic: {
7
+ disableSnapshot: true,
8
+ },
9
+ }}
10
+ />
11
+
12
+ # FixtureProps
13
+
14
+ ```ts
15
+ type FixtureProps<TProps: {...}> =
16
+ | $ReadOnly<TProps>
17
+ | ((options: $ReadOnly<GetPropsOptions>) => $ReadOnly<TProps>);
18
+ ```
19
+
20
+ This type describes how props can be provided to a fixture as either a plain object, or a function that returns a plain object. The function will be called with an API to assist in generating the props (see [`GetPropsOptions`](/docs/testing-fixtures-types-getpropsoptions--page)).
@@ -128,5 +128,23 @@ describe("fixtures", () => {
128
128
  screen.getByText('I rendered {"aProp":"aValue"}'),
129
129
  ).toBeInTheDocument();
130
130
  });
131
+
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
+ );
142
+
143
+ // Act
144
+ render(<Fixture aProp="aValue" />);
145
+
146
+ // Assert
147
+ expect(screen.getByText("I am a wrapper")).toBeInTheDocument();
148
+ });
131
149
  });
132
150
  });
@@ -2,13 +2,7 @@
2
2
  import * as React from "react";
3
3
  import {action} from "@storybook/addon-actions";
4
4
 
5
- import type {FixtureProps} from "./types.js";
6
-
7
- type FixtureFn<TProps: {...}> = (
8
- description: string,
9
- props: FixtureProps<TProps>,
10
- wrapper?: React.ComponentType<TProps>,
11
- ) => mixed;
5
+ import type {FixtureFn, FixtureProps} from "./types.js";
12
6
 
13
7
  /**
14
8
  * Describe a group of fixtures for a given component.
@@ -50,16 +44,18 @@ export const fixtures = <
50
44
  const getProps = (options) =>
51
45
  typeof props === "function" ? props(options) : props;
52
46
 
47
+ const RealComponent = wrapper || Component;
48
+
53
49
  // We create a “template” of how args map to rendering
54
50
  // for each type of component as the component here could
55
51
  // be the component under test, or wrapped in a wrapper
56
52
  // component. We don't use decorators for the wrapper
57
53
  // because we may not be in a storybook context and it
58
54
  // keeps the framework API simpler this way.
59
- let Template = templateMap.get((Component: any));
55
+ let Template = templateMap.get((RealComponent: any));
60
56
  if (Template == null) {
61
- Template = (args) => <Component {...args} />;
62
- templateMap.set((Component: any), Template);
57
+ Template = (args) => <RealComponent {...args} />;
58
+ templateMap.set((RealComponent: any), Template);
63
59
  }
64
60
 
65
61
  // Each story that shares that component then reuses that
@@ -1,4 +1,6 @@
1
1
  // @flow
2
+ import * as React from "react";
3
+
2
4
  /**
3
5
  * Options injected to the function that returns the fixture props.
4
6
  */
@@ -19,3 +21,26 @@ export type GetPropsOptions = {|
19
21
  export type FixtureProps<TProps: {...}> =
20
22
  | $ReadOnly<TProps>
21
23
  | ((options: $ReadOnly<GetPropsOptions>) => $ReadOnly<TProps>);
24
+
25
+ /**
26
+ * A function for defining a fixture.
27
+ */
28
+ export type FixtureFn<TProps: {...}> = (
29
+ /**
30
+ * The name of the fixture.
31
+ */
32
+ description: string,
33
+
34
+ /**
35
+ * The props for the fixture or a function that returns the props.
36
+ * The function is injected with an API to facilitate logging.
37
+ */
38
+ props: FixtureProps<TProps>,
39
+
40
+ /**
41
+ * An alternative component to render for the fixture.
42
+ * Useful if the fixture requires some additional setup for testing the
43
+ * component.
44
+ */
45
+ wrapper?: React.ComponentType<TProps>,
46
+ ) => mixed;
package/src/index.js CHANGED
@@ -2,7 +2,11 @@
2
2
 
3
3
  // Fixtures framework
4
4
  export {fixtures} from "./fixtures/fixtures.js";
5
- export type {GetPropsOptions} from "./fixtures/types.js";
5
+ export type {
6
+ FixtureFn,
7
+ FixtureProps,
8
+ GetPropsOptions,
9
+ } from "./fixtures/types.js";
6
10
 
7
11
  // Fetch mocking framework
8
12
  export {mockFetch} from "./fetch/mock-fetch.js";