@khanacademy/wonder-blocks-testing 9.0.0 → 9.2.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.
- package/CHANGELOG.md +19 -0
- package/dist/es/index.js +21 -390
- package/dist/harness/adapt.d.ts +17 -0
- package/dist/index.js +22 -390
- package/package.json +3 -2
- package/src/harness/__tests__/adapt.test.tsx +200 -0
- package/src/harness/__tests__/make-test-harness.test.tsx +16 -10
- package/src/harness/adapt.tsx +36 -0
- package/src/harness/adapters/__tests__/ssr.test.tsx +46 -5
- package/src/harness/adapters/ssr.tsx +7 -3
- package/src/harness/make-test-harness.tsx +6 -8
- package/tsconfig-build.json +1 -0
- package/tsconfig-build.tsbuildinfo +1 -1
- package/dist/harness/render-adapters.d.ts +0 -6
- package/src/harness/__tests__/render-adapters.test.tsx +0 -97
- package/src/harness/render-adapters.tsx +0 -26
|
@@ -2,7 +2,7 @@ import * as React from "react";
|
|
|
2
2
|
import {Route} from "react-router-dom";
|
|
3
3
|
import {render} from "@testing-library/react";
|
|
4
4
|
|
|
5
|
-
import * as RA from "../
|
|
5
|
+
import * as RA from "../adapt";
|
|
6
6
|
import {makeTestHarness} from "../make-test-harness";
|
|
7
7
|
import {DefaultConfigs, DefaultAdapters} from "../adapters/adapters";
|
|
8
8
|
|
|
@@ -75,7 +75,7 @@ describe("#makeTestHarness", () => {
|
|
|
75
75
|
DefaultConfigs,
|
|
76
76
|
);
|
|
77
77
|
const Component = () => <div>test</div>;
|
|
78
|
-
const renderSpy = jest.spyOn(RA, "
|
|
78
|
+
const renderSpy = jest.spyOn(RA, "Adapt");
|
|
79
79
|
|
|
80
80
|
// Act
|
|
81
81
|
const HarnessedComponent = testHarness(Component);
|
|
@@ -83,9 +83,12 @@ describe("#makeTestHarness", () => {
|
|
|
83
83
|
|
|
84
84
|
// Assert
|
|
85
85
|
expect(renderSpy).toHaveBeenCalledWith(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
{
|
|
87
|
+
adapters: DefaultAdapters,
|
|
88
|
+
configs: DefaultConfigs,
|
|
89
|
+
children: expect.anything(),
|
|
90
|
+
},
|
|
91
|
+
{},
|
|
89
92
|
);
|
|
90
93
|
});
|
|
91
94
|
|
|
@@ -132,7 +135,7 @@ describe("#makeTestHarness", () => {
|
|
|
132
135
|
router: "/mysecretplace",
|
|
133
136
|
};
|
|
134
137
|
const Component = () => <div>test</div>;
|
|
135
|
-
const renderSpy = jest.spyOn(RA, "
|
|
138
|
+
const renderSpy = jest.spyOn(RA, "Adapt");
|
|
136
139
|
|
|
137
140
|
// Act
|
|
138
141
|
const HarnessedComponent = testHarness(
|
|
@@ -143,12 +146,15 @@ describe("#makeTestHarness", () => {
|
|
|
143
146
|
|
|
144
147
|
// Assert
|
|
145
148
|
expect(renderSpy).toHaveBeenCalledWith(
|
|
146
|
-
DefaultAdapters,
|
|
147
149
|
{
|
|
148
|
-
|
|
149
|
-
|
|
150
|
+
adapters: DefaultAdapters,
|
|
151
|
+
configs: {
|
|
152
|
+
...DefaultConfigs,
|
|
153
|
+
router: configOverrides.router,
|
|
154
|
+
},
|
|
155
|
+
children: expect.anything(),
|
|
150
156
|
},
|
|
151
|
-
|
|
157
|
+
{},
|
|
152
158
|
);
|
|
153
159
|
});
|
|
154
160
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import type {TestHarnessConfigs, TestHarnessAdapters} from "./types";
|
|
4
|
+
|
|
5
|
+
type Props<TAdapters extends TestHarnessAdapters> = {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
adapters: TAdapters;
|
|
8
|
+
configs: TestHarnessConfigs<TAdapters>;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Render a set of adapters around the given children.
|
|
13
|
+
*
|
|
14
|
+
* Adapters are rendered with the last adapter being the outermost and the first
|
|
15
|
+
* adapter being the innermost, with children being the innermost of all. This
|
|
16
|
+
* ensures that we are backwards compatible with previous releases of the
|
|
17
|
+
* test harness.
|
|
18
|
+
*/
|
|
19
|
+
export const Adapt = <TAdapters extends TestHarnessAdapters>({
|
|
20
|
+
children,
|
|
21
|
+
adapters,
|
|
22
|
+
configs,
|
|
23
|
+
}: Props<TAdapters>): React.ReactElement =>
|
|
24
|
+
// Here we reduce the adapters in order, such that each one becomes the
|
|
25
|
+
// child of the next, that way the first adapter in the list is the
|
|
26
|
+
// innermost and the last is the outermost.
|
|
27
|
+
Object.entries(adapters).reduce((newChildren, [name, adapter]) => {
|
|
28
|
+
const config = configs[name];
|
|
29
|
+
if (config == null) {
|
|
30
|
+
return newChildren;
|
|
31
|
+
}
|
|
32
|
+
const Adapter: React.FunctionComponent = ({children}) =>
|
|
33
|
+
adapter(children, config);
|
|
34
|
+
Adapter.displayName = `Adapter(${name})`;
|
|
35
|
+
return <Adapter>{newChildren}</Adapter>;
|
|
36
|
+
}, <>{children}</>);
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import {render, screen} from "@testing-library/react";
|
|
3
|
-
|
|
4
3
|
import * as WBCore from "@khanacademy/wonder-blocks-core";
|
|
4
|
+
import {makeTestHarness} from "../../make-test-harness";
|
|
5
5
|
|
|
6
6
|
import * as SSR from "../ssr";
|
|
7
7
|
|
|
8
|
-
jest.mock("@khanacademy/wonder-stuff-core", () =>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
jest.mock("@khanacademy/wonder-stuff-core", () => {
|
|
9
|
+
const actualCore = jest.requireActual("@khanacademy/wonder-stuff-core");
|
|
10
|
+
return {
|
|
11
|
+
...actualCore,
|
|
12
|
+
RenderStateRoot: (props: any) => (
|
|
13
|
+
<actualCore.RenderStateRoot {...props} />
|
|
14
|
+
),
|
|
15
|
+
};
|
|
16
|
+
});
|
|
12
17
|
|
|
13
18
|
describe("SSR.adapter", () => {
|
|
14
19
|
it("should render the RenderStateRoot", () => {
|
|
@@ -38,4 +43,40 @@ describe("SSR.adapter", () => {
|
|
|
38
43
|
// Assert
|
|
39
44
|
expect(screen.getByText("CHILDREN!")).toBeInTheDocument();
|
|
40
45
|
});
|
|
46
|
+
|
|
47
|
+
it("should enable harnessing of components that require RenderStateRoot", () => {
|
|
48
|
+
// Arrange
|
|
49
|
+
const ComponentNeedsSsr = (props: any) => {
|
|
50
|
+
const idf = WBCore.useUniqueIdWithoutMock();
|
|
51
|
+
return <div>{idf?.get("my-id")}</div>;
|
|
52
|
+
};
|
|
53
|
+
const testHarness = makeTestHarness(
|
|
54
|
+
{
|
|
55
|
+
ssr: SSR.adapter,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
ssr: true,
|
|
59
|
+
},
|
|
60
|
+
);
|
|
61
|
+
const Harnessed = testHarness(ComponentNeedsSsr);
|
|
62
|
+
|
|
63
|
+
// Act
|
|
64
|
+
const underTest = () => render(<Harnessed />);
|
|
65
|
+
|
|
66
|
+
// Assert
|
|
67
|
+
expect(underTest).not.toThrowError();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("should throw on bad configuration", () => {
|
|
71
|
+
// Arrange
|
|
72
|
+
const children = <div>CHILDREN!</div>;
|
|
73
|
+
|
|
74
|
+
// Act
|
|
75
|
+
const underTest = () => render(SSR.adapter(children, false as any));
|
|
76
|
+
|
|
77
|
+
// Assert
|
|
78
|
+
expect(underTest).toThrowErrorMatchingInlineSnapshot(
|
|
79
|
+
`"Unexpected configuration: set config to null to turn this adapter off"`,
|
|
80
|
+
);
|
|
81
|
+
});
|
|
41
82
|
});
|
|
@@ -25,9 +25,13 @@ export const adapter: TestHarnessAdapter<Config> = (
|
|
|
25
25
|
config: Config,
|
|
26
26
|
): React.ReactElement<any> => {
|
|
27
27
|
if (config !== true) {
|
|
28
|
-
throw new KindError(
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
throw new KindError(
|
|
29
|
+
"Unexpected configuration: set config to null to turn this adapter off",
|
|
30
|
+
Errors.InvalidInput,
|
|
31
|
+
{
|
|
32
|
+
metadata: {config},
|
|
33
|
+
},
|
|
34
|
+
);
|
|
31
35
|
}
|
|
32
36
|
return <RenderStateRoot>{children}</RenderStateRoot>;
|
|
33
37
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {Adapt} from "./adapt";
|
|
4
4
|
|
|
5
5
|
import type {TestHarnessAdapters, TestHarnessConfigs} from "./types";
|
|
6
6
|
|
|
@@ -43,13 +43,11 @@ export const makeTestHarness = <TAdapters extends TestHarnessAdapters>(
|
|
|
43
43
|
...defaultConfigs,
|
|
44
44
|
...configs,
|
|
45
45
|
};
|
|
46
|
-
const harnessedComponent = React.forwardRef((props: TProps, ref) =>
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
),
|
|
52
|
-
);
|
|
46
|
+
const harnessedComponent = React.forwardRef((props: TProps, ref) => (
|
|
47
|
+
<Adapt adapters={adapters} configs={fullConfig}>
|
|
48
|
+
<Component {...(props as TProps)} ref={ref} />
|
|
49
|
+
</Adapt>
|
|
50
|
+
));
|
|
53
51
|
|
|
54
52
|
// We add a name for the component here so that we can detect that
|
|
55
53
|
// later and also see it in traces and what have you.
|