@khanacademy/wonder-blocks-testing 4.0.4 → 5.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 (70) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/es/index.js +212 -26
  3. package/dist/index.js +589 -62
  4. package/package.json +5 -3
  5. package/src/__docs__/_overview_.stories.mdx +3 -4
  6. package/src/__docs__/_overview_fixtures.stories.mdx +22 -0
  7. package/src/__docs__/_overview_mocking.stories.mdx +14 -0
  8. package/src/__docs__/_overview_test_harness.stories.mdx +18 -0
  9. package/src/__docs__/exports.fixture-adapters.stories.mdx +49 -0
  10. package/src/__docs__/exports.fixtures.stories.mdx +53 -0
  11. package/src/__docs__/exports.harness-adapters.stories.mdx +187 -0
  12. package/src/__docs__/exports.hook-harness.stories.mdx +22 -0
  13. package/src/__docs__/exports.make-hook-harness.stories.mdx +25 -0
  14. package/src/__docs__/exports.make-test-harness.stories.mdx +28 -0
  15. package/src/__docs__/exports.mock-fetch.stories.mdx +40 -0
  16. package/src/__docs__/exports.mock-gql-fetch.stories.mdx +13 -8
  17. package/src/__docs__/exports.respond-with.stories.mdx +54 -8
  18. package/src/__docs__/exports.setup-fixtures.stories.mdx +22 -0
  19. package/src/__docs__/exports.test-harness.stories.mdx +23 -0
  20. package/src/__docs__/types.custom-mount-props.stories.mdx +35 -0
  21. package/src/__docs__/types.fetch-mock-fn.stories.mdx +22 -0
  22. package/src/__docs__/types.fetch-mock-operation.stories.mdx +18 -0
  23. package/src/__docs__/types.fixtures-adapter-factory.stories.mdx +23 -0
  24. package/src/__docs__/types.fixtures-adapter-fixture-options.stories.mdx +35 -0
  25. package/src/__docs__/types.fixtures-adapter-group-options.stories.mdx +37 -0
  26. package/src/__docs__/types.fixtures-adapter-group.stories.mdx +43 -0
  27. package/src/__docs__/types.fixtures-adapter-options.stories.mdx +21 -0
  28. package/src/__docs__/types.fixtures-adapter.stories.mdx +35 -0
  29. package/src/__docs__/types.fixtures-configuration.stories.mdx +35 -0
  30. package/src/__docs__/types.fixtures-options.stories.mdx +51 -0
  31. package/src/__docs__/types.get-props-options.stories.mdx +25 -0
  32. package/src/__docs__/types.gql-fetch-mock-fn.stories.mdx +27 -0
  33. package/src/__docs__/types.gql-mock-operation.stories.mdx +26 -0
  34. package/src/__docs__/types.mock-response.stories.mdx +18 -0
  35. package/src/__docs__/types.test-harness-adapter.stories.mdx +21 -0
  36. package/src/__docs__/types.test-harness-adapters.stories.mdx +46 -0
  37. package/src/__docs__/types.test-harness-config.stories.mdx +18 -0
  38. package/src/__docs__/types.test-harness-configs.stories.mdx +59 -0
  39. package/src/fetch/types.js +0 -3
  40. package/src/fixtures/adapters/adapter-group.js +11 -11
  41. package/src/fixtures/adapters/adapter.js +8 -8
  42. package/src/fixtures/adapters/storybook.js +11 -8
  43. package/src/fixtures/fixtures.basic.stories.js +6 -2
  44. package/src/fixtures/fixtures.defaultwrapper.stories.js +6 -2
  45. package/src/fixtures/setup.js +8 -4
  46. package/src/fixtures/types.js +27 -16
  47. package/src/gql/types.js +1 -3
  48. package/src/harness/__tests__/hook-harness.test.js +72 -0
  49. package/src/harness/__tests__/make-hook-harness.test.js +94 -0
  50. package/src/harness/__tests__/make-test-harness.test.js +190 -0
  51. package/src/harness/__tests__/render-adapters.test.js +88 -0
  52. package/src/harness/__tests__/test-harness.test.js +74 -0
  53. package/src/harness/__tests__/types.flowtest.js +115 -0
  54. package/src/harness/adapters/__tests__/__snapshots__/router.test.js.snap +5 -0
  55. package/src/harness/adapters/__tests__/css.test.js +96 -0
  56. package/src/harness/adapters/__tests__/data.test.js +66 -0
  57. package/src/harness/adapters/__tests__/portal.test.js +31 -0
  58. package/src/harness/adapters/__tests__/router.test.js +233 -0
  59. package/src/harness/adapters/adapters.js +33 -0
  60. package/src/harness/adapters/css.js +65 -0
  61. package/src/harness/adapters/data.js +46 -0
  62. package/src/harness/adapters/portal.js +26 -0
  63. package/src/harness/adapters/router.js +206 -0
  64. package/src/harness/hook-harness.js +23 -0
  65. package/src/harness/make-hook-harness.js +39 -0
  66. package/src/harness/make-test-harness.js +68 -0
  67. package/src/harness/render-adapters.js +27 -0
  68. package/src/harness/test-harness.js +24 -0
  69. package/src/harness/types.js +57 -0
  70. package/src/index.js +22 -18
@@ -0,0 +1,190 @@
1
+ // @flow
2
+ import * as React from "react";
3
+ import {Route} from "react-router-dom";
4
+ import {render} from "@testing-library/react";
5
+
6
+ import * as RA from "../render-adapters.js";
7
+ import {makeTestHarness} from "../make-test-harness.js";
8
+ import {DefaultConfigs, DefaultAdapters} from "../adapters/adapters.js";
9
+
10
+ describe("#makeTestHarness", () => {
11
+ it("should return a function", () => {
12
+ // Arrange
13
+
14
+ // Act
15
+ const result = makeTestHarness(DefaultAdapters, DefaultConfigs);
16
+
17
+ // Assert
18
+ expect(result).toBeFunction();
19
+ });
20
+
21
+ describe("returned function", () => {
22
+ describe("returned component", () => {
23
+ it("should have displayName generated from component displayName", () => {
24
+ // Arrange
25
+ const testHarness = makeTestHarness(
26
+ DefaultAdapters,
27
+ DefaultConfigs,
28
+ );
29
+ const Component = () => <div>test</div>;
30
+ Component.displayName = "MyNamedComponent";
31
+
32
+ // Act
33
+ const {displayName: result} = testHarness(Component);
34
+
35
+ // Assert
36
+ expect(result).toBe("testHarness(MyNamedComponent)");
37
+ });
38
+
39
+ it("should have displayName generated from component name in absence of displayName", () => {
40
+ // Arrange
41
+ const testHarness = makeTestHarness(
42
+ DefaultAdapters,
43
+ DefaultConfigs,
44
+ );
45
+ const Component = function MyFunctionNamedComponent() {
46
+ return <div>test</div>;
47
+ };
48
+
49
+ // Act
50
+ const {displayName: result} = testHarness(Component);
51
+
52
+ // Assert
53
+ expect(result).toBe("testHarness(MyFunctionNamedComponent)");
54
+ });
55
+
56
+ it("should have default displayName in absence of displayName or name", () => {
57
+ // Arrange
58
+ const testHarness = makeTestHarness(
59
+ DefaultAdapters,
60
+ DefaultConfigs,
61
+ );
62
+ const Component = () => <div>test</div>;
63
+
64
+ // Act
65
+ const {displayName: result} = testHarness(Component);
66
+
67
+ // Assert
68
+ expect(result).toBe("testHarness(Component)");
69
+ });
70
+
71
+ describe("if config is omitted", () => {
72
+ it("should render with defaults", () => {
73
+ // Arrange
74
+ const testHarness = makeTestHarness(
75
+ DefaultAdapters,
76
+ DefaultConfigs,
77
+ );
78
+ const Component = () => <div>test</div>;
79
+ const renderSpy = jest.spyOn(RA, "renderAdapters");
80
+
81
+ // Act
82
+ const HarnessedComponent = testHarness(Component);
83
+ render(<HarnessedComponent />);
84
+
85
+ // Assert
86
+ expect(renderSpy).toHaveBeenCalledWith(
87
+ DefaultAdapters,
88
+ DefaultConfigs,
89
+ expect.anything(),
90
+ );
91
+ });
92
+
93
+ it("should render harnessed component", () => {
94
+ // Arrange
95
+ const testHarness = makeTestHarness(
96
+ DefaultAdapters,
97
+ DefaultConfigs,
98
+ );
99
+ const Component = (props: {|text: string|}) => (
100
+ <div>{props.text}</div>
101
+ );
102
+
103
+ // Act
104
+ const HarnessedComponent = testHarness(Component, {
105
+ // Need to provide a key as this a snapshot test that will
106
+ // break because of MemoryRouter using random keys
107
+ // otherwise. Could also use `forceStatic` to avoid this.
108
+ router: {location: {pathname: "/", key: "root"}},
109
+ });
110
+ const {container} = render(
111
+ <HarnessedComponent text="Test!" />,
112
+ );
113
+
114
+ // Assert
115
+ expect(container).toMatchInlineSnapshot(`
116
+ <div>
117
+ <div>
118
+ Test!
119
+ </div>
120
+ </div>
121
+ `);
122
+ });
123
+ });
124
+
125
+ describe("if config overrides a default", () => {
126
+ it("should render with updated config", () => {
127
+ // Arrange
128
+ const testHarness = makeTestHarness(
129
+ DefaultAdapters,
130
+ DefaultConfigs,
131
+ );
132
+ const configOverrides: $Shape<typeof DefaultConfigs> = {
133
+ router: "/mysecretplace",
134
+ };
135
+ const Component = () => <div>test</div>;
136
+ const renderSpy = jest.spyOn(RA, "renderAdapters");
137
+
138
+ // Act
139
+ const HarnessedComponent = testHarness(
140
+ Component,
141
+ configOverrides,
142
+ );
143
+ render(<HarnessedComponent />);
144
+
145
+ // Assert
146
+ expect(renderSpy).toHaveBeenCalledWith(
147
+ DefaultAdapters,
148
+ {
149
+ ...DefaultConfigs,
150
+ router: configOverrides.router,
151
+ },
152
+ expect.anything(),
153
+ );
154
+ });
155
+
156
+ it("should render harnessed component", () => {
157
+ // Arrange
158
+ const testHarness = makeTestHarness(
159
+ DefaultAdapters,
160
+ DefaultConfigs,
161
+ );
162
+ const configOverrides: $Shape<typeof DefaultConfigs> = {
163
+ router: "/mysecretplace/test",
164
+ };
165
+ // Render a route match that only works if we render our
166
+ // overridden location.
167
+ const Component = (props: {|text: string|}) => (
168
+ <Route path="/mysecretplace/*">{props.text}</Route>
169
+ );
170
+
171
+ // Act
172
+ const HarnessedComponent = testHarness(
173
+ Component,
174
+ configOverrides,
175
+ );
176
+ const {container} = render(
177
+ <HarnessedComponent text="Test!" />,
178
+ );
179
+
180
+ // Assert
181
+ expect(container).toMatchInlineSnapshot(`
182
+ <div>
183
+ Test!
184
+ </div>
185
+ `);
186
+ });
187
+ });
188
+ });
189
+ });
190
+ });
@@ -0,0 +1,88 @@
1
+ // @flow
2
+ import * as React from "react";
3
+ import {renderAdapters} from "../render-adapters.js";
4
+
5
+ import type {TestHarnessAdapter, TestHarnessConfigs} from "../types.js";
6
+
7
+ describe("#renderAdapters", () => {
8
+ it("should return children if no adapters", () => {
9
+ // Arrange
10
+ const children = <div>Adapt me!</div>;
11
+
12
+ // Act
13
+ const result = renderAdapters({}, {}, children);
14
+
15
+ // Assert
16
+ expect(result).toBe(children);
17
+ });
18
+
19
+ it("should invoke the adapter with its corresponding config", () => {
20
+ // Arrange
21
+ const children = <div>Adapt me!</div>;
22
+ const adapters = {
23
+ adapterA: ((jest.fn(): any): TestHarnessAdapter<string>),
24
+ };
25
+ const configs: TestHarnessConfigs<typeof adapters> = {
26
+ adapterA: "APPLY A CONFIG",
27
+ };
28
+
29
+ // Act
30
+ renderAdapters(adapters, configs, children);
31
+
32
+ // Assert
33
+ expect(adapters.adapterA).toHaveBeenCalledWith(
34
+ children,
35
+ "APPLY A CONFIG",
36
+ );
37
+ });
38
+
39
+ it("should render each adapter and the children", () => {
40
+ // Arrange
41
+ const children = "Adapt me!";
42
+ const adapter: TestHarnessAdapter<string> = (c, conf) => {
43
+ // $FlowIgnore[incompatible-type] We know, it's ok.
44
+ return `${conf}:${c}`;
45
+ };
46
+ const adapters = {
47
+ adapterA: adapter,
48
+ adapterB: adapter,
49
+ adapterC: adapter,
50
+ };
51
+ const configs: TestHarnessConfigs<typeof adapters> = {
52
+ adapterA: "A",
53
+ adapterB: "B",
54
+ adapterC: "C",
55
+ };
56
+
57
+ // Act
58
+ const result = renderAdapters(adapters, configs, children);
59
+
60
+ // Assert
61
+ expect(result).toMatchInlineSnapshot(`"C:B:A:Adapt me!"`);
62
+ });
63
+
64
+ it("should skip adapters where the corresponding config is null", () => {
65
+ // Arrange
66
+ const children = "Adapt me!";
67
+ const adapter: TestHarnessAdapter<string> = (c, conf) => {
68
+ // $FlowIgnore[incompatible-type] We know, it's ok.
69
+ return `${conf}:${c}`;
70
+ };
71
+ const adapters = {
72
+ adapterA: adapter,
73
+ adapterB: adapter,
74
+ adapterC: adapter,
75
+ };
76
+ const configs: TestHarnessConfigs<typeof adapters> = {
77
+ adapterA: "A",
78
+ adapterB: null,
79
+ adapterC: "C",
80
+ };
81
+
82
+ // Act
83
+ const result = renderAdapters(adapters, configs, children);
84
+
85
+ // Assert
86
+ expect(result).toMatchInlineSnapshot(`"C:A:Adapt me!"`);
87
+ });
88
+ });
@@ -0,0 +1,74 @@
1
+ // @flow
2
+ import {jest as ws} from "@khanacademy/wonder-stuff-testing";
3
+ import * as MTH from "../make-test-harness.js";
4
+ import {DefaultAdapters, DefaultConfigs} from "../adapters/adapters.js";
5
+
6
+ jest.mock("../make-test-harness.js", () => {
7
+ const returnValueFake = {
8
+ thisisa: "PRETEND REACT COMPONENT",
9
+ };
10
+ const harnessFake = jest.fn().mockReturnValue(returnValueFake);
11
+ return {
12
+ harnessFake,
13
+ returnValueFake,
14
+ makeTestHarness: jest.fn().mockReturnValue(harnessFake),
15
+ };
16
+ });
17
+
18
+ describe("#testHarness", () => {
19
+ it("should be created by calling makeTestHarness with the DefaultAdapters and DefaultConfigs", async () => {
20
+ // Arrange
21
+ const makeTestHarnessSpy = jest.spyOn(MTH, "makeTestHarness");
22
+
23
+ // Act
24
+ await ws.isolateModules(() => import("../hook-harness.js"));
25
+
26
+ // Assert
27
+ expect(makeTestHarnessSpy).toHaveBeenCalledWith(
28
+ DefaultAdapters,
29
+ DefaultConfigs,
30
+ );
31
+ });
32
+
33
+ it("should invoke the function made by makeTestHarness", async () => {
34
+ // Arrange
35
+ const Component = () => null;
36
+ const config = {
37
+ router: "/boo",
38
+ };
39
+ // $FlowIgnore[prop-missing] - we add this into our mock at the top.
40
+ const [{harnessFake}, {testHarness}] = await ws.isolateModules(() =>
41
+ Promise.all([
42
+ import("../make-test-harness.js"),
43
+ import("../test-harness.js"),
44
+ ]),
45
+ );
46
+
47
+ // Act
48
+ testHarness(Component, config);
49
+
50
+ // Assert
51
+ expect(harnessFake).toHaveBeenCalledWith(Component, config);
52
+ });
53
+
54
+ it("should return the returned value of the function made by makeTestHarness", async () => {
55
+ // Arrange
56
+ const Component = () => null;
57
+ const config = {
58
+ router: "/boo",
59
+ };
60
+ // $FlowIgnore[prop-missing] - we add this into our mock at the top.
61
+ const [{returnValueFake}, {testHarness}] = await ws.isolateModules(() =>
62
+ Promise.all([
63
+ import("../make-test-harness.js"),
64
+ import("../test-harness.js"),
65
+ ]),
66
+ );
67
+
68
+ // Act
69
+ const result = testHarness(Component, config);
70
+
71
+ // Assert
72
+ expect(result).toBe(returnValueFake);
73
+ });
74
+ });
@@ -0,0 +1,115 @@
1
+ // @flow
2
+ import * as React from "react";
3
+
4
+ import type {
5
+ TestHarnessAdapter,
6
+ TestHarnessAdapters,
7
+ TestHarnessConfig,
8
+ TestHarnessConfigs,
9
+ } from "../types.js";
10
+
11
+ /**
12
+ * TestHarnessAdapter<TConfig>
13
+ */
14
+
15
+ //> should assert type of config.
16
+ ((
17
+ children: React.Node,
18
+ // TConfig is string, but we typed this arg as a number
19
+ // $FlowExpectedError[incompatible-cast]
20
+ config: number,
21
+ ): React.Element<any> => <div />: TestHarnessAdapter<string>);
22
+ //<
23
+
24
+ //> should work for correct definition
25
+ ((children: React.Node, config: string): React.Element<any> => (
26
+ <div />
27
+ ): TestHarnessAdapter<string>);
28
+ //<
29
+
30
+ /**
31
+ * TestHarnessAdapters
32
+ */
33
+
34
+ //> should work for empty case
35
+ ({}: TestHarnessAdapters);
36
+ //<
37
+
38
+ //> should assert if adapter is not Adapter<TConfig>
39
+ ({
40
+ // String is not a adapter function
41
+ // $FlowExpectedError[incompatible-cast]
42
+ adapterString: "string",
43
+ }: TestHarnessAdapters);
44
+ //<
45
+
46
+ //> should work for a function matching Adapter<TConfig>
47
+ ({
48
+ adapterA: (children, config) => <div>test</div>,
49
+ }: TestHarnessAdapters);
50
+ //<
51
+
52
+ /**
53
+ * TestHarnessConfig<TAdapter>
54
+ */
55
+ //> should give the config type of an adapter
56
+ ("string": TestHarnessConfig<TestHarnessAdapter<string>>);
57
+ //<
58
+
59
+ //> should error if the config type is wrong
60
+ // 45 is not a string
61
+ // $FlowExpectedError[incompatible-cast]
62
+ (45: TestHarnessConfig<TestHarnessAdapter<string>>);
63
+ //<
64
+
65
+ /**
66
+ * TestHarnessConfigs<TAdapters>
67
+ *
68
+ * NOTE: This only works if the properties of the passed THarnasses type
69
+ * are explicitly typed as `TestHarnessAdapter<TConfig>` so if passing in a
70
+ * non-Adapters type (which we should be, to get strong TConfig types instead
71
+ * of `any`), then that object should make sure that each adapter is strongly
72
+ * marked as `TestHarnessAdapter<TConfig>` - flow does not appear to pattern
73
+ * match against the type definition when invoking the ExtractConfig type and I
74
+ * haven't worked out how to get it to multi-dispatch so that it matches
75
+ * functions too. Even worse, if the type doesn't match, it just allows `any`
76
+ * in the configs object, rather than indicating any kind of problem.
77
+ */
78
+ const notadapters = "this is wrong";
79
+ const adapterA: TestHarnessAdapter<string> = (
80
+ children: React.Node,
81
+ config: ?string,
82
+ ): React.Element<any> => <div />;
83
+ const adapterB: TestHarnessAdapter<number> = (
84
+ children: React.Node,
85
+ config: ?number,
86
+ ): React.Element<any> => <div />;
87
+ const adapters = {
88
+ adapterA,
89
+ adapterB,
90
+ };
91
+
92
+ //> should assert if parameterized type is not valid Adapters
93
+ // string is not a valid Adapter
94
+ // $FlowExpectedError[incompatible-use]
95
+ // $FlowExpectedError[incompatible-type-arg]
96
+ ({}: TestHarnessConfigs<typeof notadapters>);
97
+ //<
98
+
99
+ //> should expect one config per adapter
100
+ // both adapter configs missing
101
+ // $FlowExpectedError[incompatible-exact]
102
+ ({}: TestHarnessConfigs<typeof adapters>);
103
+ // adapterB config missing
104
+ // $FlowExpectedError[prop-missing]
105
+ ({adapterA: "test"}: TestHarnessConfigs<typeof adapters>);
106
+ //<
107
+
108
+ //> should assert if config does not match adapter config
109
+ ({
110
+ adapterA: "a string, this is correct",
111
+ // the config type here is a number, not a string
112
+ // $FlowExpectedError[incompatible-cast]
113
+ adapterB: "a string, but it should be a number",
114
+ }: TestHarnessConfigs<typeof adapters>);
115
+ //<
@@ -0,0 +1,5 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`Router.adapter with full config including path should throw if the path does not match the location 1`] = `"The configured path must match the configured location or your harnessed component will not render."`;
4
+
5
+ exports[`Router.adapter with location config including path should throw if the path does not match the location 1`] = `"The configured path must match the configured location or your harnessed component will not render."`;
@@ -0,0 +1,96 @@
1
+ // @flow
2
+ import * as React from "react";
3
+ import {render, screen} from "@testing-library/react";
4
+
5
+ import * as Css from "../css.js";
6
+
7
+ describe("Css.adapter", () => {
8
+ it("should throw if the config is invalid", () => {
9
+ // Arrange
10
+ const badConfig: any = 42;
11
+
12
+ // Act
13
+ const underTest = () => Css.adapter("CHILDREN", badConfig);
14
+
15
+ // Assert
16
+ expect(underTest).toThrowErrorMatchingInlineSnapshot(
17
+ `"Invalid config: 42"`,
18
+ );
19
+ });
20
+
21
+ it("should render the children", () => {
22
+ // Arrange
23
+ const children = <div data-test-id="children">CHILDREN!</div>;
24
+
25
+ // Act
26
+ render(Css.adapter(children, "test"));
27
+ const result = screen.getByTestId("children");
28
+
29
+ // Assert
30
+ expect(result).toBeInTheDocument();
31
+ });
32
+
33
+ it("should render a container element", () => {
34
+ // Arrange
35
+ const children = <div data-test-id="children">CHILDREN!</div>;
36
+
37
+ // Act
38
+ render(Css.adapter(children, "test"));
39
+ const result = screen.getByTestId("css-adapter-container");
40
+
41
+ // Assert
42
+ expect(result).toBeInTheDocument();
43
+ });
44
+
45
+ it("should render children as a child of the container element", () => {
46
+ // Arrange
47
+ const children = <div data-test-id="children">CHILDREN!</div>;
48
+
49
+ // Act
50
+ render(Css.adapter(children, "test"));
51
+ const renderedContainer = screen.getByTestId("css-adapter-container");
52
+ const renderedChildren = screen.getByTestId("children");
53
+
54
+ // Assert
55
+ expect(renderedContainer).toContainElement(renderedChildren);
56
+ });
57
+
58
+ it.each`
59
+ config | expectation
60
+ ${"class1"} | ${"class1"}
61
+ ${["class1", "class2"]} | ${"class1 class2"}
62
+ ${{classes: ["class1", "class2"], style: {backgroundColor: "red"}}} | ${"class1 class2"}
63
+ `(
64
+ "should apply the given class names from $config to the container element",
65
+ ({config, expectation}) => {
66
+ // Arrange
67
+ const children = <div data-test-id="children">CHILDREN!</div>;
68
+
69
+ // Act
70
+ render(Css.adapter(children, config));
71
+ const result = screen.getByTestId("css-adapter-container");
72
+
73
+ // Assert
74
+ expect(result).toHaveClass(expectation);
75
+ },
76
+ );
77
+
78
+ it.each`
79
+ config | expectation
80
+ ${{backgroundColor: "red"}} | ${{backgroundColor: "red"}}
81
+ ${{style: {backgroundColor: "red"}, classes: []}} | ${{backgroundColor: "red"}}
82
+ `(
83
+ "should apply the given styles from $config to the container element",
84
+ ({config, expectation}) => {
85
+ // Arrange
86
+ const children = <div data-test-id="children">CHILDREN!</div>;
87
+
88
+ // Act
89
+ render(Css.adapter(children, config));
90
+ const result = screen.getByTestId("css-adapter-container");
91
+
92
+ // Assert
93
+ expect(result).toHaveStyle(expectation);
94
+ },
95
+ );
96
+ });
@@ -0,0 +1,66 @@
1
+ // @flow
2
+ import * as React from "react";
3
+ import {mount} from "enzyme"; // eslint-disable-line no-restricted-imports
4
+ import "jest-enzyme";
5
+ import * as Data from "../data.js";
6
+
7
+ describe("WonderBlocksData.adapter", () => {
8
+ it("should render children when configuration arrays are empty", () => {
9
+ // Arrange
10
+ const children = <div>CONTENT</div>;
11
+
12
+ // Act
13
+ const wrapper = mount(Data.adapter(children, []), {
14
+ includeDefaultTestHarness: false,
15
+ });
16
+
17
+ // Assert
18
+ expect(wrapper).toHaveHTML("<div>CONTENT</div>");
19
+ });
20
+
21
+ it("should render children within InterceptRequests when dataIntercepts configured", () => {
22
+ // Arrange
23
+ const children = <div>CONTENT</div>;
24
+
25
+ // Act
26
+ const wrapper = mount(
27
+ Data.adapter(children, () =>
28
+ Promise.resolve(("INTERCEPTED!": any)),
29
+ ),
30
+ {
31
+ includeDefaultTestHarness: false,
32
+ },
33
+ );
34
+
35
+ // Assert
36
+ expect(wrapper).toContainMatchingElement("InterceptRequests");
37
+ });
38
+
39
+ it("should render like we expect", () => {
40
+ // Snapshot test is handy to visualize what's going on and help debug
41
+ // test failures of the other cases. The other cases assert specifics.
42
+ // Arrange
43
+ const children = <div>CONTENT</div>;
44
+
45
+ // Act
46
+ const wrapper = mount(
47
+ Data.adapter(children, () =>
48
+ Promise.resolve(("INTERCEPTED!": any)),
49
+ ),
50
+ {
51
+ includeDefaultTestHarness: false,
52
+ },
53
+ );
54
+
55
+ // Assert
56
+ expect(wrapper).toMatchInlineSnapshot(`
57
+ <InterceptRequests
58
+ interceptor={[Function]}
59
+ >
60
+ <div>
61
+ CONTENT
62
+ </div>
63
+ </InterceptRequests>
64
+ `);
65
+ });
66
+ });
@@ -0,0 +1,31 @@
1
+ // @flow
2
+ import * as React from "react";
3
+ import {render, screen} from "@testing-library/react";
4
+
5
+ import * as Portal from "../portal.js";
6
+
7
+ describe("Portal.adapter", () => {
8
+ it("should render a portal root element", () => {
9
+ // Arrange
10
+ const children = <div>CHILDREN!</div>;
11
+ const portalId = "portal-test-id";
12
+
13
+ // Act
14
+ render(Portal.adapter(children, portalId));
15
+
16
+ // Assert
17
+ expect(screen.getByTestId(portalId)).toBeInTheDocument();
18
+ });
19
+
20
+ it("should render the children correctly", () => {
21
+ // Arrange
22
+ const portalId = "portal-test-id";
23
+ const children = <div>CHILDREN!</div>;
24
+
25
+ // Act
26
+ render(Portal.adapter(children, portalId));
27
+
28
+ // Assert
29
+ expect(screen.getByText("CHILDREN!")).toBeInTheDocument();
30
+ });
31
+ });