@khanacademy/wonder-blocks-testing 10.1.0 → 11.0.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 +25 -0
- package/dist/es/index.js +25 -386
- package/dist/gql/types.d.ts +1 -2
- package/dist/harness/adapters/data.d.ts +1 -1
- package/dist/harness/adapters/index.d.ts +41 -0
- package/dist/harness/adapters/ssr.d.ts +1 -1
- package/dist/index.d.ts +8 -13
- package/dist/index.js +61 -395
- package/package.json +8 -6
- package/src/gql/__tests__/mock-gql-fetch.test.tsx +1 -1
- package/src/gql/__tests__/types.typestest.ts +1 -1
- package/src/gql/__tests__/wb-data-integration.test.tsx +1 -1
- package/src/gql/mock-gql-fetch.ts +1 -1
- package/src/gql/types.ts +4 -2
- package/src/harness/adapters/__tests__/ssr.test.tsx +1 -1
- package/src/harness/adapters/data.tsx +1 -1
- package/src/harness/adapters/{adapters.ts → index.ts} +10 -11
- package/src/harness/adapters/ssr.tsx +1 -1
- package/src/index.ts +32 -13
- package/tsconfig-build.json +1 -0
- package/tsconfig-build.tsbuildinfo +1 -1
- package/dist/fetch/fetch-request-matches-mock.d.ts +0 -5
- package/dist/fetch/mock-fetch.d.ts +0 -5
- package/dist/fetch/types.d.ts +0 -9
- package/dist/fixtures/fixtures.basic.stories.d.ts +0 -13
- package/dist/fixtures/fixtures.d.ts +0 -13
- package/dist/fixtures/fixtures.defaultwrapper.stories.d.ts +0 -9
- package/dist/fixtures/types.d.ts +0 -36
- package/dist/harness/adapt.d.ts +0 -17
- package/dist/harness/adapters/adapters.d.ts +0 -36
- package/dist/harness/adapters/css.d.ts +0 -12
- package/dist/harness/adapters/portal.d.ts +0 -12
- package/dist/harness/adapters/router.d.ts +0 -94
- package/dist/harness/get-named-adapter-component.d.ts +0 -16
- package/dist/harness/hook-harness.d.ts +0 -13
- package/dist/harness/make-hook-harness.d.ts +0 -17
- package/dist/harness/make-test-harness.d.ts +0 -15
- package/dist/harness/test-harness.d.ts +0 -33
- package/dist/harness/types.d.ts +0 -36
- package/dist/mock-requester.d.ts +0 -5
- package/dist/respond-with.d.ts +0 -75
- package/dist/response-impl.d.ts +0 -1
- package/dist/settle-controller.d.ts +0 -19
- package/dist/settle-signal.d.ts +0 -18
- package/dist/types.d.ts +0 -25
- package/src/__tests__/mock-requester.test.ts +0 -212
- package/src/__tests__/respond-with.test.ts +0 -524
- package/src/__tests__/response-impl.test.js +0 -47
- package/src/__tests__/settle-controller.test.ts +0 -28
- package/src/__tests__/settle-signal.test.ts +0 -104
- package/src/fetch/__tests__/__snapshots__/mock-fetch.test.ts.snap +0 -29
- package/src/fetch/__tests__/fetch-request-matches-mock.test.ts +0 -98
- package/src/fetch/__tests__/mock-fetch.test.ts +0 -83
- package/src/fetch/fetch-request-matches-mock.ts +0 -42
- package/src/fetch/mock-fetch.ts +0 -20
- package/src/fetch/types.ts +0 -14
- package/src/fixtures/__tests__/fixtures.test.tsx +0 -147
- package/src/fixtures/fixtures.basic.stories.tsx +0 -62
- package/src/fixtures/fixtures.defaultwrapper.stories.tsx +0 -49
- package/src/fixtures/fixtures.tsx +0 -72
- package/src/fixtures/types.ts +0 -42
- package/src/harness/__tests__/adapt.test.tsx +0 -248
- package/src/harness/__tests__/hook-harness.test.ts +0 -73
- package/src/harness/__tests__/make-hook-harness.test.tsx +0 -93
- package/src/harness/__tests__/make-test-harness.test.tsx +0 -195
- package/src/harness/__tests__/test-harness.test.ts +0 -75
- package/src/harness/__tests__/types.typestest.tsx +0 -103
- package/src/harness/adapt.tsx +0 -41
- package/src/harness/adapters/__tests__/__snapshots__/router.test.tsx.snap +0 -5
- package/src/harness/adapters/__tests__/css.test.tsx +0 -95
- package/src/harness/adapters/__tests__/portal.test.tsx +0 -30
- package/src/harness/adapters/__tests__/router.test.tsx +0 -252
- package/src/harness/adapters/css.tsx +0 -66
- package/src/harness/adapters/portal.tsx +0 -25
- package/src/harness/adapters/router.tsx +0 -205
- package/src/harness/get-named-adapter-component.tsx +0 -36
- package/src/harness/hook-harness.ts +0 -22
- package/src/harness/make-hook-harness.tsx +0 -40
- package/src/harness/make-test-harness.tsx +0 -60
- package/src/harness/test-harness.ts +0 -13
- package/src/harness/types.ts +0 -47
- package/src/mock-requester.ts +0 -68
- package/src/respond-with.ts +0 -263
- package/src/response-impl.ts +0 -8
- package/src/settle-controller.ts +0 -34
- package/src/settle-signal.ts +0 -42
- package/src/types.ts +0 -40
|
@@ -1,248 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import {render, screen} from "@testing-library/react";
|
|
3
|
-
|
|
4
|
-
import {Adapt} from "../adapt";
|
|
5
|
-
|
|
6
|
-
import type {TestHarnessAdapter, TestHarnessConfigs} from "../types";
|
|
7
|
-
|
|
8
|
-
describe("Adapt", () => {
|
|
9
|
-
it("should render children if no adapters", () => {
|
|
10
|
-
// Arrange
|
|
11
|
-
const children = <div>Adapt me!</div>;
|
|
12
|
-
|
|
13
|
-
// Act
|
|
14
|
-
const {container: result} = render(
|
|
15
|
-
<Adapt adapters={{}} configs={{}}>
|
|
16
|
-
{children}
|
|
17
|
-
</Adapt>,
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
// Assert
|
|
21
|
-
expect(result).toMatchInlineSnapshot(`
|
|
22
|
-
<div>
|
|
23
|
-
<div>
|
|
24
|
-
Adapt me!
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
27
|
-
`);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it("should invoke the adapter with its corresponding config", () => {
|
|
31
|
-
// Arrange
|
|
32
|
-
const children = <div>Adapt me!</div>;
|
|
33
|
-
const adapters = {
|
|
34
|
-
adapterA: jest
|
|
35
|
-
.fn()
|
|
36
|
-
.mockReturnValue("ADAPTER A") as TestHarnessAdapter<string>,
|
|
37
|
-
} as const;
|
|
38
|
-
const configs: TestHarnessConfigs<typeof adapters> = {
|
|
39
|
-
adapterA: "APPLY A CONFIG",
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
// Act
|
|
43
|
-
render(
|
|
44
|
-
<Adapt adapters={adapters} configs={configs}>
|
|
45
|
-
{children}
|
|
46
|
-
</Adapt>,
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
// Assert
|
|
50
|
-
expect(adapters.adapterA).toHaveBeenCalledWith(
|
|
51
|
-
expect.anything(),
|
|
52
|
-
"APPLY A CONFIG",
|
|
53
|
-
);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("should render each adapter and the children", () => {
|
|
57
|
-
// Arrange
|
|
58
|
-
const children = "Adapt me!";
|
|
59
|
-
const adapter: TestHarnessAdapter<string> = (c: any, conf: any) => (
|
|
60
|
-
<>
|
|
61
|
-
{conf}
|
|
62
|
-
{c}
|
|
63
|
-
</>
|
|
64
|
-
);
|
|
65
|
-
const adapters = {
|
|
66
|
-
adapterA: adapter,
|
|
67
|
-
adapterB: adapter,
|
|
68
|
-
adapterC: adapter,
|
|
69
|
-
} as const;
|
|
70
|
-
const configs: TestHarnessConfigs<typeof adapters> = {
|
|
71
|
-
adapterA: "A",
|
|
72
|
-
adapterB: "B",
|
|
73
|
-
adapterC: "C",
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
// Act
|
|
77
|
-
const {container: result} = render(
|
|
78
|
-
<Adapt adapters={adapters} configs={configs}>
|
|
79
|
-
{children}
|
|
80
|
-
</Adapt>,
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
// Assert
|
|
84
|
-
expect(result).toMatchInlineSnapshot(`
|
|
85
|
-
<div>
|
|
86
|
-
C
|
|
87
|
-
B
|
|
88
|
-
A
|
|
89
|
-
Adapt me!
|
|
90
|
-
</div>
|
|
91
|
-
`);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it("should skip adapters where the corresponding config is null", () => {
|
|
95
|
-
// Arrange
|
|
96
|
-
const children = "Adapt me!";
|
|
97
|
-
const adapter: TestHarnessAdapter<string> = (c: any, conf: any) => (
|
|
98
|
-
<>
|
|
99
|
-
{conf}
|
|
100
|
-
{c}
|
|
101
|
-
</>
|
|
102
|
-
);
|
|
103
|
-
const adapters = {
|
|
104
|
-
adapterA: adapter,
|
|
105
|
-
adapterB: adapter,
|
|
106
|
-
adapterC: adapter,
|
|
107
|
-
} as const;
|
|
108
|
-
const configs: TestHarnessConfigs<typeof adapters> = {
|
|
109
|
-
adapterA: "A",
|
|
110
|
-
adapterB: null,
|
|
111
|
-
adapterC: "C",
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
// Act
|
|
115
|
-
const {container: result} = render(
|
|
116
|
-
<Adapt adapters={adapters} configs={configs}>
|
|
117
|
-
{children}
|
|
118
|
-
</Adapt>,
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
// Assert
|
|
122
|
-
expect(result).toMatchInlineSnapshot(`
|
|
123
|
-
<div>
|
|
124
|
-
C
|
|
125
|
-
A
|
|
126
|
-
Adapt me!
|
|
127
|
-
</div>
|
|
128
|
-
`);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it("should render such that contexts are properly setup in order", () => {
|
|
132
|
-
// Arrange
|
|
133
|
-
const MyContext = React.createContext("root");
|
|
134
|
-
const ContextRoot = ({children}: any): React.ReactElement => {
|
|
135
|
-
const value = React.useContext(MyContext);
|
|
136
|
-
if (value !== "root") {
|
|
137
|
-
throw new Error("Don't nest this");
|
|
138
|
-
}
|
|
139
|
-
return (
|
|
140
|
-
<MyContext.Provider value={"other"}>
|
|
141
|
-
{children}
|
|
142
|
-
</MyContext.Provider>
|
|
143
|
-
);
|
|
144
|
-
};
|
|
145
|
-
const adapterNoContext: TestHarnessAdapter<string> = (
|
|
146
|
-
c: any,
|
|
147
|
-
conf: any,
|
|
148
|
-
) => (
|
|
149
|
-
<>
|
|
150
|
-
{conf}
|
|
151
|
-
{c}
|
|
152
|
-
</>
|
|
153
|
-
);
|
|
154
|
-
const adapterWithContext: TestHarnessAdapter<string> = (
|
|
155
|
-
c: any,
|
|
156
|
-
conf: string,
|
|
157
|
-
) => (
|
|
158
|
-
<ContextRoot>
|
|
159
|
-
{conf}
|
|
160
|
-
{c}
|
|
161
|
-
</ContextRoot>
|
|
162
|
-
);
|
|
163
|
-
const adapters = {
|
|
164
|
-
adapterA: adapterNoContext,
|
|
165
|
-
adapterB: adapterWithContext,
|
|
166
|
-
adapterC: adapterNoContext,
|
|
167
|
-
} as const;
|
|
168
|
-
const configs: TestHarnessConfigs<typeof adapters> = {
|
|
169
|
-
adapterA: "A",
|
|
170
|
-
adapterB: "B",
|
|
171
|
-
adapterC: "C",
|
|
172
|
-
};
|
|
173
|
-
const ChildComponent = (props: any): React.ReactElement => {
|
|
174
|
-
const value = React.useContext(MyContext);
|
|
175
|
-
if (value === "default") {
|
|
176
|
-
throw new Error("Context not setup properly");
|
|
177
|
-
}
|
|
178
|
-
return <div>{value}</div>;
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
// Act
|
|
182
|
-
const {container: result} = render(
|
|
183
|
-
<Adapt adapters={adapters} configs={configs}>
|
|
184
|
-
<ChildComponent />
|
|
185
|
-
</Adapt>,
|
|
186
|
-
);
|
|
187
|
-
|
|
188
|
-
// Assert
|
|
189
|
-
expect(result).toMatchInlineSnapshot(`
|
|
190
|
-
<div>
|
|
191
|
-
C
|
|
192
|
-
B
|
|
193
|
-
A
|
|
194
|
-
<div>
|
|
195
|
-
other
|
|
196
|
-
</div>
|
|
197
|
-
</div>
|
|
198
|
-
`);
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it("should not remount the component under test when rerendered", () => {
|
|
202
|
-
// Arrange
|
|
203
|
-
const MyComponent = ({value}: any) => {
|
|
204
|
-
const ref = React.useRef(value);
|
|
205
|
-
|
|
206
|
-
// If the ref matches the value, then things were just mounted
|
|
207
|
-
// as the ref was initialized with the value.
|
|
208
|
-
// If they don't match then we got re-rendered with a new value
|
|
209
|
-
// and the existing ref.
|
|
210
|
-
if (ref.current !== value) {
|
|
211
|
-
return <>RE-RENDERED</>;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return <>JUST MOUNTED</>;
|
|
215
|
-
};
|
|
216
|
-
const adapter: TestHarnessAdapter<string> = (c: any, conf: any) => (
|
|
217
|
-
<>
|
|
218
|
-
{conf}
|
|
219
|
-
{c}
|
|
220
|
-
</>
|
|
221
|
-
);
|
|
222
|
-
const adapters = {
|
|
223
|
-
adapterA: adapter,
|
|
224
|
-
adapterB: adapter,
|
|
225
|
-
adapterC: adapter,
|
|
226
|
-
} as const;
|
|
227
|
-
const configs: TestHarnessConfigs<typeof adapters> = {
|
|
228
|
-
adapterA: "A",
|
|
229
|
-
adapterB: null,
|
|
230
|
-
adapterC: "C",
|
|
231
|
-
};
|
|
232
|
-
const {rerender} = render(
|
|
233
|
-
<Adapt adapters={adapters} configs={configs}>
|
|
234
|
-
<MyComponent value={1} />
|
|
235
|
-
</Adapt>,
|
|
236
|
-
);
|
|
237
|
-
|
|
238
|
-
// Act
|
|
239
|
-
rerender(
|
|
240
|
-
<Adapt adapters={adapters} configs={configs}>
|
|
241
|
-
<MyComponent value={2} />
|
|
242
|
-
</Adapt>,
|
|
243
|
-
);
|
|
244
|
-
|
|
245
|
-
// Assert
|
|
246
|
-
expect(screen.getByText(/RE-RENDERED/)).toBeInTheDocument();
|
|
247
|
-
});
|
|
248
|
-
});
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import {jest as ws} from "@khanacademy/wonder-stuff-testing";
|
|
2
|
-
import * as MHH from "../make-hook-harness";
|
|
3
|
-
import {DefaultAdapters, DefaultConfigs} from "../adapters/adapters";
|
|
4
|
-
|
|
5
|
-
jest.mock("../make-hook-harness", () => {
|
|
6
|
-
const returnValueFake = {
|
|
7
|
-
thisisa: "PRETEND REACT COMPONENT",
|
|
8
|
-
} as const;
|
|
9
|
-
const harnessFake = jest.fn().mockReturnValue(returnValueFake);
|
|
10
|
-
return {
|
|
11
|
-
harnessFake,
|
|
12
|
-
returnValueFake,
|
|
13
|
-
makeHookHarness: jest.fn().mockReturnValue(harnessFake),
|
|
14
|
-
};
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
describe("#hookHarness", () => {
|
|
18
|
-
it("should be created by calling makeHookHarness with the DefaultAdapters and DefaultConfigs", async () => {
|
|
19
|
-
// Arrange
|
|
20
|
-
const makeHookHarnessSpy = jest.spyOn(MHH, "makeHookHarness");
|
|
21
|
-
|
|
22
|
-
// Act
|
|
23
|
-
await ws.isolateModules(() => import("../hook-harness"));
|
|
24
|
-
|
|
25
|
-
// Assert
|
|
26
|
-
expect(makeHookHarnessSpy).toHaveBeenCalledWith(
|
|
27
|
-
DefaultAdapters,
|
|
28
|
-
DefaultConfigs,
|
|
29
|
-
);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it("should invoke the function made by makeHookHarness", async () => {
|
|
33
|
-
// Arrange
|
|
34
|
-
const config = {
|
|
35
|
-
router: "/boo",
|
|
36
|
-
} as const;
|
|
37
|
-
// @ts-expect-error We know harnessFake isn't real, we add it in the
|
|
38
|
-
// mocks at the top of this file.
|
|
39
|
-
const [{harnessFake}, {hookHarness}] = await ws.isolateModules(() =>
|
|
40
|
-
Promise.all([
|
|
41
|
-
import("../make-hook-harness"),
|
|
42
|
-
import("../hook-harness"),
|
|
43
|
-
]),
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
// Act
|
|
47
|
-
hookHarness(config);
|
|
48
|
-
|
|
49
|
-
// Assert
|
|
50
|
-
expect(harnessFake).toHaveBeenCalledWith(config);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("should return the returned value of the function made by makeHookHarness", async () => {
|
|
54
|
-
// Arrange
|
|
55
|
-
const config = {
|
|
56
|
-
router: "/boo",
|
|
57
|
-
} as const;
|
|
58
|
-
// @ts-expect-error We know harnessFake isn't real, we add it in the
|
|
59
|
-
// mocks at the top of this file.
|
|
60
|
-
const [{returnValueFake}, {hookHarness}] = await ws.isolateModules(() =>
|
|
61
|
-
Promise.all([
|
|
62
|
-
import("../make-hook-harness"),
|
|
63
|
-
import("../hook-harness"),
|
|
64
|
-
]),
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
// Act
|
|
68
|
-
const result = hookHarness(config);
|
|
69
|
-
|
|
70
|
-
// Assert
|
|
71
|
-
expect(result).toBe(returnValueFake);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import {render} from "@testing-library/react";
|
|
3
|
-
import {makeHookHarness} from "../make-hook-harness";
|
|
4
|
-
import * as MTH from "../make-test-harness";
|
|
5
|
-
|
|
6
|
-
describe("#makeHookHarness", () => {
|
|
7
|
-
it("should call makeTestHarness", () => {
|
|
8
|
-
// Arrange
|
|
9
|
-
const makeTestHarnessSpy = jest.spyOn(MTH, "makeTestHarness");
|
|
10
|
-
const adapters = {
|
|
11
|
-
adapter: jest.fn(),
|
|
12
|
-
} as const;
|
|
13
|
-
const defaultConfigs = {
|
|
14
|
-
adapter: {},
|
|
15
|
-
} as const;
|
|
16
|
-
|
|
17
|
-
// Act
|
|
18
|
-
makeHookHarness(adapters, defaultConfigs);
|
|
19
|
-
|
|
20
|
-
// Assert
|
|
21
|
-
expect(makeTestHarnessSpy).toHaveBeenCalledWith(
|
|
22
|
-
adapters,
|
|
23
|
-
defaultConfigs,
|
|
24
|
-
);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("should return a function", () => {
|
|
28
|
-
const adapters = {
|
|
29
|
-
adapter: jest.fn(),
|
|
30
|
-
} as const;
|
|
31
|
-
const defaultConfigs = {
|
|
32
|
-
adapter: {},
|
|
33
|
-
} as const;
|
|
34
|
-
|
|
35
|
-
// Act
|
|
36
|
-
const result = makeHookHarness(adapters, defaultConfigs);
|
|
37
|
-
|
|
38
|
-
// Assert
|
|
39
|
-
expect(result).toBeFunction();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
describe("returned function", () => {
|
|
43
|
-
it("should invoke the function returned by makeTestHarness with component and the configs", () => {
|
|
44
|
-
// Arrange
|
|
45
|
-
const harnessSpy = jest.fn();
|
|
46
|
-
jest.spyOn(MTH, "makeTestHarness").mockReturnValue(harnessSpy);
|
|
47
|
-
const adapters = {
|
|
48
|
-
adapter: jest.fn(),
|
|
49
|
-
} as const;
|
|
50
|
-
const defaultConfigs = {
|
|
51
|
-
adapter: {},
|
|
52
|
-
} as const;
|
|
53
|
-
const configs = {
|
|
54
|
-
adapter: {},
|
|
55
|
-
} as const;
|
|
56
|
-
const hookHarness = makeHookHarness(adapters, defaultConfigs);
|
|
57
|
-
|
|
58
|
-
// Act
|
|
59
|
-
hookHarness(configs);
|
|
60
|
-
|
|
61
|
-
// Assert
|
|
62
|
-
expect(harnessSpy).toHaveBeenCalledWith(
|
|
63
|
-
expect.any(Function),
|
|
64
|
-
configs,
|
|
65
|
-
);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it("should pass a component that just renders the children it is given", () => {
|
|
69
|
-
// Arrange
|
|
70
|
-
const harnessSpy = jest.fn();
|
|
71
|
-
jest.spyOn(MTH, "makeTestHarness").mockReturnValue(harnessSpy);
|
|
72
|
-
const adapters = {
|
|
73
|
-
adapter: jest.fn(),
|
|
74
|
-
} as const;
|
|
75
|
-
const defaultConfigs = {
|
|
76
|
-
adapter: {},
|
|
77
|
-
} as const;
|
|
78
|
-
const configs = {
|
|
79
|
-
adapter: {},
|
|
80
|
-
} as const;
|
|
81
|
-
const children = "THE CHILDREN";
|
|
82
|
-
|
|
83
|
-
// Act
|
|
84
|
-
const hookHarness = makeHookHarness(adapters, defaultConfigs);
|
|
85
|
-
hookHarness(configs);
|
|
86
|
-
const Component = harnessSpy.mock.calls[0][0];
|
|
87
|
-
const {container} = render(<Component>{children}</Component>);
|
|
88
|
-
|
|
89
|
-
// Assert
|
|
90
|
-
expect(container).toHaveTextContent(children);
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
});
|
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import * as React from "react";
|
|
2
|
-
import {Route} from "react-router-dom";
|
|
3
|
-
import {render} from "@testing-library/react";
|
|
4
|
-
|
|
5
|
-
import * as RA from "../adapt";
|
|
6
|
-
import {makeTestHarness} from "../make-test-harness";
|
|
7
|
-
import {DefaultConfigs, DefaultAdapters} from "../adapters/adapters";
|
|
8
|
-
|
|
9
|
-
describe("#makeTestHarness", () => {
|
|
10
|
-
it("should return a function", () => {
|
|
11
|
-
// Arrange
|
|
12
|
-
|
|
13
|
-
// Act
|
|
14
|
-
const result = makeTestHarness(DefaultAdapters, DefaultConfigs);
|
|
15
|
-
|
|
16
|
-
// Assert
|
|
17
|
-
expect(result).toBeFunction();
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
describe("returned function", () => {
|
|
21
|
-
describe("returned component", () => {
|
|
22
|
-
it("should have displayName generated from component displayName", () => {
|
|
23
|
-
// Arrange
|
|
24
|
-
const testHarness = makeTestHarness(
|
|
25
|
-
DefaultAdapters,
|
|
26
|
-
DefaultConfigs,
|
|
27
|
-
);
|
|
28
|
-
const Component = () => <div>test</div>;
|
|
29
|
-
Component.displayName = "MyNamedComponent";
|
|
30
|
-
|
|
31
|
-
// Act
|
|
32
|
-
const {displayName: result} = testHarness(Component);
|
|
33
|
-
|
|
34
|
-
// Assert
|
|
35
|
-
expect(result).toBe("testHarness(MyNamedComponent)");
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("should have displayName generated from component name in absence of displayName", () => {
|
|
39
|
-
// Arrange
|
|
40
|
-
const testHarness = makeTestHarness(
|
|
41
|
-
DefaultAdapters,
|
|
42
|
-
DefaultConfigs,
|
|
43
|
-
);
|
|
44
|
-
const Component = function MyFunctionNamedComponent() {
|
|
45
|
-
return <div>test</div>;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
// Act
|
|
49
|
-
const {displayName: result} = testHarness(Component);
|
|
50
|
-
|
|
51
|
-
// Assert
|
|
52
|
-
expect(result).toBe("testHarness(MyFunctionNamedComponent)");
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("should have default displayName in absence of displayName or name", () => {
|
|
56
|
-
// Arrange
|
|
57
|
-
const testHarness = makeTestHarness(
|
|
58
|
-
DefaultAdapters,
|
|
59
|
-
DefaultConfigs,
|
|
60
|
-
);
|
|
61
|
-
const Component = () => <div>test</div>;
|
|
62
|
-
|
|
63
|
-
// Act
|
|
64
|
-
const {displayName: result} = testHarness(Component);
|
|
65
|
-
|
|
66
|
-
// Assert
|
|
67
|
-
expect(result).toBe("testHarness(Component)");
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
describe("if config is omitted", () => {
|
|
71
|
-
it("should render with defaults", () => {
|
|
72
|
-
// Arrange
|
|
73
|
-
const testHarness = makeTestHarness(
|
|
74
|
-
DefaultAdapters,
|
|
75
|
-
DefaultConfigs,
|
|
76
|
-
);
|
|
77
|
-
const Component = () => <div>test</div>;
|
|
78
|
-
const renderSpy = jest.spyOn(RA, "Adapt");
|
|
79
|
-
|
|
80
|
-
// Act
|
|
81
|
-
const HarnessedComponent = testHarness(Component);
|
|
82
|
-
render(<HarnessedComponent />);
|
|
83
|
-
|
|
84
|
-
// Assert
|
|
85
|
-
expect(renderSpy).toHaveBeenCalledWith(
|
|
86
|
-
{
|
|
87
|
-
adapters: DefaultAdapters,
|
|
88
|
-
configs: DefaultConfigs,
|
|
89
|
-
children: expect.anything(),
|
|
90
|
-
},
|
|
91
|
-
{},
|
|
92
|
-
);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("should render harnessed component", () => {
|
|
96
|
-
// Arrange
|
|
97
|
-
const testHarness = makeTestHarness(
|
|
98
|
-
DefaultAdapters,
|
|
99
|
-
DefaultConfigs,
|
|
100
|
-
);
|
|
101
|
-
const Component = (props: {text: string}) => (
|
|
102
|
-
<div>{props.text}</div>
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
// Act
|
|
106
|
-
const HarnessedComponent = testHarness(Component, {
|
|
107
|
-
// Need to provide a key as this a snapshot test that will
|
|
108
|
-
// break because of MemoryRouter using random keys
|
|
109
|
-
// otherwise. Could also use `forceStatic` to avoid this.
|
|
110
|
-
router: {location: {pathname: "/", key: "root"}},
|
|
111
|
-
});
|
|
112
|
-
const {container} = render(
|
|
113
|
-
<HarnessedComponent text="Test!" />,
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
// Assert
|
|
117
|
-
expect(container).toMatchInlineSnapshot(`
|
|
118
|
-
<div>
|
|
119
|
-
<div>
|
|
120
|
-
Test!
|
|
121
|
-
</div>
|
|
122
|
-
</div>
|
|
123
|
-
`);
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
describe("if config overrides a default", () => {
|
|
128
|
-
it("should render with updated config", () => {
|
|
129
|
-
// Arrange
|
|
130
|
-
const testHarness = makeTestHarness(
|
|
131
|
-
DefaultAdapters,
|
|
132
|
-
DefaultConfigs,
|
|
133
|
-
);
|
|
134
|
-
const configOverrides: Partial<typeof DefaultConfigs> = {
|
|
135
|
-
router: "/mysecretplace",
|
|
136
|
-
};
|
|
137
|
-
const Component = () => <div>test</div>;
|
|
138
|
-
const renderSpy = jest.spyOn(RA, "Adapt");
|
|
139
|
-
|
|
140
|
-
// Act
|
|
141
|
-
const HarnessedComponent = testHarness(
|
|
142
|
-
Component,
|
|
143
|
-
configOverrides,
|
|
144
|
-
);
|
|
145
|
-
render(<HarnessedComponent />);
|
|
146
|
-
|
|
147
|
-
// Assert
|
|
148
|
-
expect(renderSpy).toHaveBeenCalledWith(
|
|
149
|
-
{
|
|
150
|
-
adapters: DefaultAdapters,
|
|
151
|
-
configs: {
|
|
152
|
-
...DefaultConfigs,
|
|
153
|
-
router: configOverrides.router,
|
|
154
|
-
},
|
|
155
|
-
children: expect.anything(),
|
|
156
|
-
},
|
|
157
|
-
{},
|
|
158
|
-
);
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it("should render harnessed component", () => {
|
|
162
|
-
// Arrange
|
|
163
|
-
const testHarness = makeTestHarness(
|
|
164
|
-
DefaultAdapters,
|
|
165
|
-
DefaultConfigs,
|
|
166
|
-
);
|
|
167
|
-
const configOverrides: Partial<typeof DefaultConfigs> = {
|
|
168
|
-
router: "/mysecretplace/test",
|
|
169
|
-
};
|
|
170
|
-
// Render a route match that only works if we render our
|
|
171
|
-
// overridden location.
|
|
172
|
-
const Component = (props: {text: string}) => (
|
|
173
|
-
<Route path="/mysecretplace/*">{props.text}</Route>
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
// Act
|
|
177
|
-
const HarnessedComponent = testHarness(
|
|
178
|
-
Component,
|
|
179
|
-
configOverrides,
|
|
180
|
-
);
|
|
181
|
-
const {container} = render(
|
|
182
|
-
<HarnessedComponent text="Test!" />,
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
// Assert
|
|
186
|
-
expect(container).toMatchInlineSnapshot(`
|
|
187
|
-
<div>
|
|
188
|
-
Test!
|
|
189
|
-
</div>
|
|
190
|
-
`);
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
});
|
|
195
|
-
});
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import {jest as ws} from "@khanacademy/wonder-stuff-testing";
|
|
2
|
-
import * as MTH from "../make-test-harness";
|
|
3
|
-
import {DefaultAdapters, DefaultConfigs} from "../adapters/adapters";
|
|
4
|
-
|
|
5
|
-
jest.mock("../make-test-harness", () => {
|
|
6
|
-
const returnValueFake = {
|
|
7
|
-
thisisa: "PRETEND REACT COMPONENT",
|
|
8
|
-
} as const;
|
|
9
|
-
const harnessFake = jest.fn().mockReturnValue(returnValueFake);
|
|
10
|
-
return {
|
|
11
|
-
harnessFake,
|
|
12
|
-
returnValueFake,
|
|
13
|
-
makeTestHarness: jest.fn().mockReturnValue(harnessFake),
|
|
14
|
-
};
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
describe("#testHarness", () => {
|
|
18
|
-
it("should be created by calling makeTestHarness with the DefaultAdapters and DefaultConfigs", async () => {
|
|
19
|
-
// Arrange
|
|
20
|
-
const makeTestHarnessSpy = jest.spyOn(MTH, "makeTestHarness");
|
|
21
|
-
|
|
22
|
-
// Act
|
|
23
|
-
await ws.isolateModules(() => import("../hook-harness"));
|
|
24
|
-
|
|
25
|
-
// Assert
|
|
26
|
-
expect(makeTestHarnessSpy).toHaveBeenCalledWith(
|
|
27
|
-
DefaultAdapters,
|
|
28
|
-
DefaultConfigs,
|
|
29
|
-
);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it("should invoke the function made by makeTestHarness", async () => {
|
|
33
|
-
// Arrange
|
|
34
|
-
const Component = () => null;
|
|
35
|
-
const config = {
|
|
36
|
-
router: "/boo",
|
|
37
|
-
} as const;
|
|
38
|
-
// @ts-expect-error We know harnessFake isn't real, we add it in the
|
|
39
|
-
// mocks at the top of this file.
|
|
40
|
-
const [{harnessFake}, {testHarness}] = await ws.isolateModules(() =>
|
|
41
|
-
Promise.all([
|
|
42
|
-
import("../make-test-harness"),
|
|
43
|
-
import("../test-harness"),
|
|
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
|
-
} as const;
|
|
60
|
-
// @ts-expect-error We know harnessFake isn't real, we add it in the
|
|
61
|
-
// mocks at the top of this file.
|
|
62
|
-
const [{returnValueFake}, {testHarness}] = await ws.isolateModules(() =>
|
|
63
|
-
Promise.all([
|
|
64
|
-
import("../make-test-harness"),
|
|
65
|
-
import("../test-harness"),
|
|
66
|
-
]),
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
// Act
|
|
70
|
-
const result = testHarness(Component, config);
|
|
71
|
-
|
|
72
|
-
// Assert
|
|
73
|
-
expect(result).toBe(returnValueFake);
|
|
74
|
-
});
|
|
75
|
-
});
|