@khanacademy/wonder-blocks-testing 7.1.9 → 7.1.11

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 (147) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/dist/es/index.js +183 -120
  3. package/dist/fetch/fetch-request-matches-mock.d.ts +5 -0
  4. package/dist/fetch/fetch-request-matches-mock.js.flow +17 -0
  5. package/dist/fetch/mock-fetch.d.ts +5 -0
  6. package/dist/fetch/mock-fetch.js.flow +13 -0
  7. package/dist/fetch/types.d.ts +9 -0
  8. package/dist/fetch/types.js.flow +19 -0
  9. package/dist/fixtures/fixtures.basic.stories.d.ts +13 -0
  10. package/dist/fixtures/fixtures.basic.stories.js.flow +22 -0
  11. package/dist/fixtures/fixtures.d.ts +19 -0
  12. package/dist/fixtures/fixtures.defaultwrapper.stories.d.ts +9 -0
  13. package/dist/fixtures/fixtures.defaultwrapper.stories.js.flow +17 -0
  14. package/dist/fixtures/fixtures.js.flow +33 -0
  15. package/dist/fixtures/types.d.ts +36 -0
  16. package/dist/fixtures/types.js.flow +37 -0
  17. package/dist/gql/gql-request-matches-mock.d.ts +3 -0
  18. package/dist/gql/gql-request-matches-mock.js.flow +15 -0
  19. package/dist/gql/mock-gql-fetch.d.ts +5 -0
  20. package/dist/gql/mock-gql-fetch.js.flow +13 -0
  21. package/dist/gql/types.d.ts +15 -0
  22. package/dist/gql/types.js.flow +39 -0
  23. package/dist/harness/adapters/adapters.d.ts +35 -0
  24. package/dist/harness/adapters/adapters.js.flow +69 -0
  25. package/dist/harness/adapters/css.d.ts +12 -0
  26. package/dist/harness/adapters/css.js.flow +23 -0
  27. package/dist/harness/adapters/data.d.ts +18 -0
  28. package/dist/harness/adapters/data.js.flow +32 -0
  29. package/dist/harness/adapters/portal.d.ts +12 -0
  30. package/dist/harness/adapters/portal.js.flow +18 -0
  31. package/dist/harness/adapters/router.d.ts +94 -0
  32. package/dist/harness/adapters/router.js.flow +122 -0
  33. package/dist/harness/hook-harness.d.ts +13 -0
  34. package/dist/harness/hook-harness.js.flow +23 -0
  35. package/dist/harness/make-hook-harness.d.ts +17 -0
  36. package/dist/harness/make-hook-harness.js.flow +42 -0
  37. package/dist/harness/make-test-harness.d.ts +18 -0
  38. package/dist/harness/make-test-harness.js.flow +48 -0
  39. package/dist/harness/render-adapters.d.ts +6 -0
  40. package/dist/harness/render-adapters.js.flow +24 -0
  41. package/dist/harness/test-harness.d.ts +32 -0
  42. package/dist/harness/test-harness.js.flow +83 -0
  43. package/dist/harness/types.d.ts +46 -0
  44. package/dist/harness/types.js.flow +66 -0
  45. package/dist/index.d.ts +15 -0
  46. package/dist/index.js +185 -127
  47. package/dist/index.js.flow +26 -2
  48. package/dist/mock-requester.d.ts +5 -0
  49. package/dist/mock-requester.js.flow +22 -0
  50. package/dist/respond-with.d.ts +57 -0
  51. package/dist/respond-with.js.flow +91 -0
  52. package/dist/response-impl.d.ts +1 -0
  53. package/dist/response-impl.js.flow +8 -0
  54. package/dist/settle-controller.d.ts +19 -0
  55. package/dist/settle-controller.js.flow +26 -0
  56. package/dist/settle-signal.d.ts +18 -0
  57. package/dist/settle-signal.js.flow +26 -0
  58. package/dist/types.d.ts +25 -0
  59. package/dist/types.js.flow +46 -0
  60. package/package.json +6 -6
  61. package/src/__tests__/{mock-requester.test.js → mock-requester.test.ts} +3 -4
  62. package/src/__tests__/{respond-with.test.js → respond-with.test.ts} +2 -3
  63. package/src/__tests__/response-impl.test.js +3 -3
  64. package/src/__tests__/{settle-controller.test.js → settle-controller.test.ts} +2 -3
  65. package/src/__tests__/{settle-signal.test.js → settle-signal.test.ts} +1 -2
  66. package/src/fetch/__tests__/__snapshots__/{mock-fetch.test.js.snap → mock-fetch.test.ts.snap} +3 -3
  67. package/src/fetch/__tests__/{fetch-request-matches-mock.test.js → fetch-request-matches-mock.test.ts} +6 -7
  68. package/src/fetch/__tests__/{mock-fetch.test.js → mock-fetch.test.ts} +3 -4
  69. package/src/fetch/{fetch-request-matches-mock.js → fetch-request-matches-mock.ts} +4 -3
  70. package/src/fetch/{mock-fetch.js → mock-fetch.ts} +5 -6
  71. package/src/fetch/types.ts +14 -0
  72. package/src/fixtures/__tests__/{fixtures.test.js → fixtures.test.tsx} +7 -5
  73. package/src/fixtures/{fixtures.basic.stories.js → fixtures.basic.stories.tsx} +17 -14
  74. package/src/fixtures/{fixtures.defaultwrapper.stories.js → fixtures.defaultwrapper.stories.tsx} +9 -9
  75. package/src/fixtures/{fixtures.js → fixtures.tsx} +17 -12
  76. package/src/fixtures/{types.js → types.ts} +9 -13
  77. package/src/gql/__tests__/{gql-request-matches-mock.test.js → gql-request-matches-mock.test.ts} +18 -19
  78. package/src/gql/__tests__/{mock-gql-fetch.test.js → mock-gql-fetch.test.tsx} +46 -47
  79. package/src/gql/__tests__/{wb-data-integration.test.js → wb-data-integration.test.tsx} +23 -24
  80. package/src/gql/{gql-request-matches-mock.js → gql-request-matches-mock.ts} +2 -5
  81. package/src/gql/mock-gql-fetch.ts +15 -0
  82. package/src/gql/types.ts +33 -0
  83. package/src/harness/__tests__/{hook-harness.test.js → hook-harness.test.ts} +13 -14
  84. package/src/harness/__tests__/{make-hook-harness.test.js → make-hook-harness.test.tsx} +12 -13
  85. package/src/harness/__tests__/{make-test-harness.test.js → make-test-harness.test.tsx} +7 -8
  86. package/src/harness/__tests__/{render-adapters.test.js → render-adapters.test.tsx} +10 -11
  87. package/src/harness/__tests__/{test-harness.test.js → test-harness.test.ts} +13 -14
  88. package/src/harness/__tests__/{types.flowtest.js → types.flowtest.tsx} +25 -28
  89. package/src/harness/adapters/__tests__/{css.test.js → css.test.tsx} +3 -4
  90. package/src/harness/adapters/__tests__/{data.test.js → data.test.tsx} +5 -4
  91. package/src/harness/adapters/__tests__/{portal.test.js → portal.test.tsx} +1 -2
  92. package/src/harness/adapters/__tests__/{router.test.js → router.test.tsx} +76 -57
  93. package/src/harness/adapters/{adapters.js → adapters.ts} +6 -7
  94. package/src/harness/adapters/{css.js → css.tsx} +22 -19
  95. package/src/harness/adapters/{data.js → data.tsx} +8 -6
  96. package/src/harness/adapters/{portal.js → portal.tsx} +4 -5
  97. package/src/harness/adapters/router.tsx +218 -0
  98. package/src/harness/{hook-harness.js → hook-harness.ts} +5 -6
  99. package/src/harness/{make-hook-harness.js → make-hook-harness.ts} +8 -8
  100. package/src/harness/{make-test-harness.js → make-test-harness.tsx} +19 -22
  101. package/src/harness/{render-adapters.js → render-adapters.ts} +5 -5
  102. package/src/harness/test-harness.ts +13 -0
  103. package/src/harness/{types.js → types.ts} +14 -12
  104. package/src/index.ts +20 -0
  105. package/src/{mock-requester.js → mock-requester.ts} +6 -5
  106. package/src/{respond-with.js → respond-with.ts} +45 -40
  107. package/src/{response-impl.js → response-impl.ts} +1 -2
  108. package/src/settle-controller.ts +37 -0
  109. package/src/{settle-signal.js → settle-signal.ts} +10 -7
  110. package/src/types.ts +40 -0
  111. package/tsconfig.json +11 -0
  112. package/tsconfig.tsbuildinfo +1 -0
  113. package/src/__docs__/_overview_.stories.mdx +0 -18
  114. package/src/__docs__/_overview_fixtures.stories.mdx +0 -18
  115. package/src/__docs__/_overview_mocking.stories.mdx +0 -14
  116. package/src/__docs__/_overview_test_harness.stories.mdx +0 -18
  117. package/src/__docs__/exports.fixtures.stories.mdx +0 -31
  118. package/src/__docs__/exports.harness-adapters.stories.mdx +0 -187
  119. package/src/__docs__/exports.hook-harness.stories.mdx +0 -22
  120. package/src/__docs__/exports.make-hook-harness.stories.mdx +0 -25
  121. package/src/__docs__/exports.make-test-harness.stories.mdx +0 -28
  122. package/src/__docs__/exports.mock-fetch.stories.mdx +0 -40
  123. package/src/__docs__/exports.mock-gql-fetch.stories.mdx +0 -64
  124. package/src/__docs__/exports.respond-with.stories.mdx +0 -84
  125. package/src/__docs__/exports.settle-controller.stories.mdx +0 -32
  126. package/src/__docs__/exports.test-harness.stories.mdx +0 -23
  127. package/src/__docs__/types.fetch-mock-fn.stories.mdx +0 -22
  128. package/src/__docs__/types.fetch-mock-operation.stories.mdx +0 -18
  129. package/src/__docs__/types.fixture-fn.stories.mdx +0 -46
  130. package/src/__docs__/types.fixture-props.stories.mdx +0 -20
  131. package/src/__docs__/types.get-props-options.stories.mdx +0 -52
  132. package/src/__docs__/types.gql-fetch-mock-fn.stories.mdx +0 -27
  133. package/src/__docs__/types.gql-mock-operation.stories.mdx +0 -26
  134. package/src/__docs__/types.mock-response.stories.mdx +0 -22
  135. package/src/__docs__/types.test-harness-adapter.stories.mdx +0 -21
  136. package/src/__docs__/types.test-harness-adapters.stories.mdx +0 -46
  137. package/src/__docs__/types.test-harness-config.stories.mdx +0 -18
  138. package/src/__docs__/types.test-harness-configs.stories.mdx +0 -59
  139. package/src/fetch/types.js +0 -15
  140. package/src/gql/mock-gql-fetch.js +0 -18
  141. package/src/gql/types.js +0 -34
  142. package/src/harness/adapters/router.js +0 -206
  143. package/src/harness/test-harness.js +0 -24
  144. package/src/index.js +0 -26
  145. package/src/settle-controller.js +0 -35
  146. package/src/types.js +0 -39
  147. /package/src/harness/adapters/__tests__/__snapshots__/{router.test.js.snap → router.test.tsx.snap} +0 -0
@@ -1,23 +1,22 @@
1
- // @flow
2
1
  import * as React from "react";
3
2
  import {render, screen, waitFor} from "@testing-library/react";
4
3
 
5
4
  import {GqlRouter, useGql} from "@khanacademy/wonder-blocks-data";
6
- import {RespondWith} from "../../respond-with.js";
7
- import {mockGqlFetch} from "../mock-gql-fetch.js";
5
+ import {RespondWith} from "../../respond-with";
6
+ import {mockGqlFetch} from "../mock-gql-fetch";
8
7
 
9
8
  describe("integrating mockGqlFetch, RespondWith, GqlRouter and useGql", () => {
10
9
  it("should reject with error indicating there are no mocks", async () => {
11
10
  // Arrange
12
11
  const mockFetch = mockGqlFetch();
13
12
  const RenderError = () => {
14
- const [result, setResult] = React.useState(null);
13
+ const [result, setResult] = React.useState<any>(null);
15
14
  const gqlFetch = useGql();
16
15
  React.useEffect(() => {
17
16
  gqlFetch({
18
17
  type: "query",
19
18
  id: "getMyStuff",
20
- }).catch((e) => {
19
+ }).catch((e: any) => {
21
20
  setResult(e.message);
22
21
  });
23
22
  }, [gqlFetch]);
@@ -47,14 +46,14 @@ describe("integrating mockGqlFetch, RespondWith, GqlRouter and useGql", () => {
47
46
  const query = {
48
47
  type: "query",
49
48
  id: "getMyStuff",
50
- };
51
- const data = {myStuff: "stuff"};
49
+ } as const;
50
+ const data = {myStuff: "stuff"} as const;
52
51
  const RenderData = () => {
53
- const [result, setResult] = React.useState(null);
52
+ const [result, setResult] = React.useState<any>(null);
54
53
  const gqlFetch = useGql();
55
54
  React.useEffect(() => {
56
55
  // eslint-disable-next-line promise/catch-or-return
57
- gqlFetch(query).then((r) => {
56
+ gqlFetch(query).then((r: any) => {
58
57
  setResult(JSON.stringify(r ?? "(null)"));
59
58
  return;
60
59
  });
@@ -87,13 +86,13 @@ describe("integrating mockGqlFetch, RespondWith, GqlRouter and useGql", () => {
87
86
  const query = {
88
87
  type: "query",
89
88
  id: "getMyStuff",
90
- };
89
+ } as const;
91
90
  const RenderError = () => {
92
- const [result, setResult] = React.useState(null);
91
+ const [result, setResult] = React.useState<any>(null);
93
92
  const gqlFetch = useGql();
94
93
  React.useEffect(() => {
95
94
  // eslint-disable-next-line promise/catch-or-return
96
- gqlFetch(query).catch((e) => {
95
+ gqlFetch(query).catch((e: any) => {
97
96
  setResult(e.message);
98
97
  return;
99
98
  });
@@ -124,13 +123,13 @@ describe("integrating mockGqlFetch, RespondWith, GqlRouter and useGql", () => {
124
123
  const query = {
125
124
  type: "query",
126
125
  id: "getMyStuff",
127
- };
126
+ } as const;
128
127
  const RenderError = () => {
129
- const [result, setResult] = React.useState(null);
128
+ const [result, setResult] = React.useState<any>(null);
130
129
  const gqlFetch = useGql();
131
130
  React.useEffect(() => {
132
131
  // eslint-disable-next-line promise/catch-or-return
133
- gqlFetch(query).catch((e) => {
132
+ gqlFetch(query).catch((e: any) => {
134
133
  setResult(e.message);
135
134
  });
136
135
  }, [gqlFetch]);
@@ -162,13 +161,13 @@ describe("integrating mockGqlFetch, RespondWith, GqlRouter and useGql", () => {
162
161
  const query = {
163
162
  type: "query",
164
163
  id: "getMyStuff",
165
- };
164
+ } as const;
166
165
  const RenderError = () => {
167
- const [result, setResult] = React.useState(null);
166
+ const [result, setResult] = React.useState<any>(null);
168
167
  const gqlFetch = useGql();
169
168
  React.useEffect(() => {
170
169
  // eslint-disable-next-line promise/catch-or-return
171
- gqlFetch(query).catch((e) => {
170
+ gqlFetch(query).catch((e: any) => {
172
171
  setResult(e.message);
173
172
  });
174
173
  }, [gqlFetch]);
@@ -200,13 +199,13 @@ describe("integrating mockGqlFetch, RespondWith, GqlRouter and useGql", () => {
200
199
  const query = {
201
200
  type: "query",
202
201
  id: "getMyStuff",
203
- };
202
+ } as const;
204
203
  const RenderError = () => {
205
- const [result, setResult] = React.useState(null);
204
+ const [result, setResult] = React.useState<any>(null);
206
205
  const gqlFetch = useGql();
207
206
  React.useEffect(() => {
208
207
  // eslint-disable-next-line promise/catch-or-return
209
- gqlFetch(query).catch((e) => {
208
+ gqlFetch(query).catch((e: any) => {
210
209
  setResult(e.message);
211
210
  });
212
211
  }, [gqlFetch]);
@@ -238,13 +237,13 @@ describe("integrating mockGqlFetch, RespondWith, GqlRouter and useGql", () => {
238
237
  const query = {
239
238
  type: "query",
240
239
  id: "getMyStuff",
241
- };
240
+ } as const;
242
241
  const RenderError = () => {
243
- const [result, setResult] = React.useState(null);
242
+ const [result, setResult] = React.useState<any>(null);
244
243
  const gqlFetch = useGql();
245
244
  React.useEffect(() => {
246
245
  // eslint-disable-next-line promise/catch-or-return
247
- gqlFetch(query).catch((e) => {
246
+ gqlFetch(query).catch((e: any) => {
248
247
  setResult(e.message);
249
248
  });
250
249
  }, [gqlFetch]);
@@ -1,10 +1,7 @@
1
- // @flow
2
1
  import type {GqlOperation, GqlContext} from "@khanacademy/wonder-blocks-data";
3
- import type {GqlMockOperation} from "./types.js";
2
+ import type {GqlMockOperation} from "./types";
4
3
 
5
4
  const safeHasOwnProperty = (obj: any, prop: string): boolean =>
6
- // Flow really shouldn't be raising this error here.
7
- // $FlowFixMe[method-unbinding]
8
5
  Object.prototype.hasOwnProperty.call(obj, prop);
9
6
 
10
7
  // TODO(somewhatabstract, FEI-4268): use a third-party library to do this and
@@ -38,7 +35,7 @@ const areObjectsEqual = (a: any, b: any): boolean => {
38
35
  export const gqlRequestMatchesMock = (
39
36
  mock: GqlMockOperation<any, any, any>,
40
37
  operation: GqlOperation<any, any>,
41
- variables: ?{...},
38
+ variables: Record<any, any> | null | undefined,
42
39
  context: GqlContext,
43
40
  ): boolean => {
44
41
  // If they don't represent the same operation, then they can't match.
@@ -0,0 +1,15 @@
1
+ import {gqlRequestMatchesMock} from "./gql-request-matches-mock";
2
+ import {mockRequester} from "../mock-requester";
3
+ import type {GqlFetchMockFn, GqlMockOperation} from "./types";
4
+
5
+ /**
6
+ * A mock for the fetch function passed to GqlRouter.
7
+ */
8
+ export const mockGqlFetch = (): GqlFetchMockFn =>
9
+ mockRequester<GqlMockOperation<any, any, any>, any>(
10
+ gqlRequestMatchesMock,
11
+ (operation, variables, context) =>
12
+ `Operation: ${operation.type} ${operation.id}
13
+ Variables: ${variables == null ? "None" : JSON.stringify(variables, null, 2)}
14
+ Context: ${JSON.stringify(context, null, 2)}`,
15
+ );
@@ -0,0 +1,33 @@
1
+ import type {GqlOperation, GqlContext} from "@khanacademy/wonder-blocks-data";
2
+ import type {GraphQLJson} from "../types";
3
+ import type {MockResponse} from "../respond-with";
4
+
5
+ export type GqlMockOperation<
6
+ TData extends Record<any, any>,
7
+ TVariables extends Record<any, any>,
8
+ TContext extends GqlContext,
9
+ > = {
10
+ operation: GqlOperation<TData, TVariables>;
11
+ variables?: TVariables;
12
+ context?: TContext;
13
+ };
14
+
15
+ type GqlMockOperationFn = <
16
+ TData extends Record<any, any>,
17
+ TVariables extends Record<any, any>,
18
+ TContext extends GqlContext,
19
+ TResponseData extends GraphQLJson<TData>,
20
+ >(
21
+ operation: GqlMockOperation<TData, TVariables, TContext>,
22
+ response: MockResponse<TResponseData>,
23
+ ) => GqlFetchMockFn;
24
+
25
+ export type GqlFetchMockFn = {
26
+ (
27
+ operation: GqlOperation<any, any>,
28
+ variables: Record<any, any> | null | undefined,
29
+ context: GqlContext,
30
+ ): Promise<Response>;
31
+ mockOperation: GqlMockOperationFn;
32
+ mockOperationOnce: GqlMockOperationFn;
33
+ };
@@ -1,12 +1,11 @@
1
- // @flow
2
1
  import {jest as ws} from "@khanacademy/wonder-stuff-testing";
3
- import * as MHH from "../make-hook-harness.js";
4
- import {DefaultAdapters, DefaultConfigs} from "../adapters/adapters.js";
2
+ import * as MHH from "../make-hook-harness";
3
+ import {DefaultAdapters, DefaultConfigs} from "../adapters/adapters";
5
4
 
6
- jest.mock("../make-hook-harness.js", () => {
5
+ jest.mock("../make-hook-harness", () => {
7
6
  const returnValueFake = {
8
7
  thisisa: "PRETEND REACT COMPONENT",
9
- };
8
+ } as const;
10
9
  const harnessFake = jest.fn().mockReturnValue(returnValueFake);
11
10
  return {
12
11
  harnessFake,
@@ -21,7 +20,7 @@ describe("#hookHarness", () => {
21
20
  const makeHookHarnessSpy = jest.spyOn(MHH, "makeHookHarness");
22
21
 
23
22
  // Act
24
- await ws.isolateModules(() => import("../hook-harness.js"));
23
+ await ws.isolateModules(() => import("../hook-harness"));
25
24
 
26
25
  // Assert
27
26
  expect(makeHookHarnessSpy).toHaveBeenCalledWith(
@@ -34,12 +33,12 @@ describe("#hookHarness", () => {
34
33
  // Arrange
35
34
  const config = {
36
35
  router: "/boo",
37
- };
38
- // $FlowIgnore[prop-missing] - we add this into our mock at the top.
36
+ } as const;
37
+ // @ts-expect-error [FEI-5019] - TS2339 - Property 'harnessFake' does not exist on type 'typeof import("/Users/kevinbarabash/khan/wonder-blocks/packages/wonder-blocks-testing/src/harness/make-hook-harness")'.
39
38
  const [{harnessFake}, {hookHarness}] = await ws.isolateModules(() =>
40
39
  Promise.all([
41
- import("../make-hook-harness.js"),
42
- import("../hook-harness.js"),
40
+ import("../make-hook-harness"),
41
+ import("../hook-harness"),
43
42
  ]),
44
43
  );
45
44
 
@@ -54,12 +53,12 @@ describe("#hookHarness", () => {
54
53
  // Arrange
55
54
  const config = {
56
55
  router: "/boo",
57
- };
58
- // $FlowIgnore[prop-missing] - we add this into our mock at the top.
56
+ } as const;
57
+ // @ts-expect-error [FEI-5019] - TS2339 - Property 'returnValueFake' does not exist on type 'typeof import("/Users/kevinbarabash/khan/wonder-blocks/packages/wonder-blocks-testing/src/harness/make-hook-harness")'.
59
58
  const [{returnValueFake}, {hookHarness}] = await ws.isolateModules(() =>
60
59
  Promise.all([
61
- import("../make-hook-harness.js"),
62
- import("../hook-harness.js"),
60
+ import("../make-hook-harness"),
61
+ import("../hook-harness"),
63
62
  ]),
64
63
  );
65
64
 
@@ -1,8 +1,7 @@
1
- // @flow
2
1
  import * as React from "react";
3
2
  import {render} from "@testing-library/react";
4
- import {makeHookHarness} from "../make-hook-harness.js";
5
- import * as MTH from "../make-test-harness.js";
3
+ import {makeHookHarness} from "../make-hook-harness";
4
+ import * as MTH from "../make-test-harness";
6
5
 
7
6
  describe("#makeHookHarness", () => {
8
7
  it("should call makeTestHarness", () => {
@@ -10,10 +9,10 @@ describe("#makeHookHarness", () => {
10
9
  const makeTestHarnessSpy = jest.spyOn(MTH, "makeTestHarness");
11
10
  const adapters = {
12
11
  adapter: jest.fn(),
13
- };
12
+ } as const;
14
13
  const defaultConfigs = {
15
14
  adapter: {},
16
- };
15
+ } as const;
17
16
 
18
17
  // Act
19
18
  makeHookHarness(adapters, defaultConfigs);
@@ -28,10 +27,10 @@ describe("#makeHookHarness", () => {
28
27
  it("should return a function", () => {
29
28
  const adapters = {
30
29
  adapter: jest.fn(),
31
- };
30
+ } as const;
32
31
  const defaultConfigs = {
33
32
  adapter: {},
34
- };
33
+ } as const;
35
34
 
36
35
  // Act
37
36
  const result = makeHookHarness(adapters, defaultConfigs);
@@ -47,13 +46,13 @@ describe("#makeHookHarness", () => {
47
46
  jest.spyOn(MTH, "makeTestHarness").mockReturnValue(harnessSpy);
48
47
  const adapters = {
49
48
  adapter: jest.fn(),
50
- };
49
+ } as const;
51
50
  const defaultConfigs = {
52
51
  adapter: {},
53
- };
52
+ } as const;
54
53
  const configs = {
55
54
  adapter: {},
56
- };
55
+ } as const;
57
56
  const hookHarness = makeHookHarness(adapters, defaultConfigs);
58
57
 
59
58
  // Act
@@ -72,13 +71,13 @@ describe("#makeHookHarness", () => {
72
71
  jest.spyOn(MTH, "makeTestHarness").mockReturnValue(harnessSpy);
73
72
  const adapters = {
74
73
  adapter: jest.fn(),
75
- };
74
+ } as const;
76
75
  const defaultConfigs = {
77
76
  adapter: {},
78
- };
77
+ } as const;
79
78
  const configs = {
80
79
  adapter: {},
81
- };
80
+ } as const;
82
81
  const children = "THE CHILDREN";
83
82
 
84
83
  // Act
@@ -1,11 +1,10 @@
1
- // @flow
2
1
  import * as React from "react";
3
2
  import {Route} from "react-router-dom";
4
3
  import {render} from "@testing-library/react";
5
4
 
6
- import * as RA from "../render-adapters.js";
7
- import {makeTestHarness} from "../make-test-harness.js";
8
- import {DefaultConfigs, DefaultAdapters} from "../adapters/adapters.js";
5
+ import * as RA from "../render-adapters";
6
+ import {makeTestHarness} from "../make-test-harness";
7
+ import {DefaultConfigs, DefaultAdapters} from "../adapters/adapters";
9
8
 
10
9
  describe("#makeTestHarness", () => {
11
10
  it("should return a function", () => {
@@ -96,7 +95,7 @@ describe("#makeTestHarness", () => {
96
95
  DefaultAdapters,
97
96
  DefaultConfigs,
98
97
  );
99
- const Component = (props: {|text: string|}) => (
98
+ const Component = (props: {text: string}) => (
100
99
  <div>{props.text}</div>
101
100
  );
102
101
 
@@ -129,7 +128,7 @@ describe("#makeTestHarness", () => {
129
128
  DefaultAdapters,
130
129
  DefaultConfigs,
131
130
  );
132
- const configOverrides: $Shape<typeof DefaultConfigs> = {
131
+ const configOverrides: Partial<typeof DefaultConfigs> = {
133
132
  router: "/mysecretplace",
134
133
  };
135
134
  const Component = () => <div>test</div>;
@@ -159,12 +158,12 @@ describe("#makeTestHarness", () => {
159
158
  DefaultAdapters,
160
159
  DefaultConfigs,
161
160
  );
162
- const configOverrides: $Shape<typeof DefaultConfigs> = {
161
+ const configOverrides: Partial<typeof DefaultConfigs> = {
163
162
  router: "/mysecretplace/test",
164
163
  };
165
164
  // Render a route match that only works if we render our
166
165
  // overridden location.
167
- const Component = (props: {|text: string|}) => (
166
+ const Component = (props: {text: string}) => (
168
167
  <Route path="/mysecretplace/*">{props.text}</Route>
169
168
  );
170
169
 
@@ -1,8 +1,7 @@
1
- // @flow
2
1
  import * as React from "react";
3
- import {renderAdapters} from "../render-adapters.js";
2
+ import {renderAdapters} from "../render-adapters";
4
3
 
5
- import type {TestHarnessAdapter, TestHarnessConfigs} from "../types.js";
4
+ import type {TestHarnessAdapter, TestHarnessConfigs} from "../types";
6
5
 
7
6
  describe("#renderAdapters", () => {
8
7
  it("should return children if no adapters", () => {
@@ -20,8 +19,8 @@ describe("#renderAdapters", () => {
20
19
  // Arrange
21
20
  const children = <div>Adapt me!</div>;
22
21
  const adapters = {
23
- adapterA: ((jest.fn(): any): TestHarnessAdapter<string>),
24
- };
22
+ adapterA: jest.fn() as TestHarnessAdapter<string>,
23
+ } as const;
25
24
  const configs: TestHarnessConfigs<typeof adapters> = {
26
25
  adapterA: "APPLY A CONFIG",
27
26
  };
@@ -39,15 +38,15 @@ describe("#renderAdapters", () => {
39
38
  it("should render each adapter and the children", () => {
40
39
  // Arrange
41
40
  const children = "Adapt me!";
42
- const adapter: TestHarnessAdapter<string> = (c, conf) => {
43
- // $FlowIgnore[incompatible-type] We know, it's ok.
41
+ // @ts-expect-error: `string` is not a valid `ReactElement`.
42
+ const adapter: TestHarnessAdapter<string> = (c: any, conf: any) => {
44
43
  return `${conf}:${c}`;
45
44
  };
46
45
  const adapters = {
47
46
  adapterA: adapter,
48
47
  adapterB: adapter,
49
48
  adapterC: adapter,
50
- };
49
+ } as const;
51
50
  const configs: TestHarnessConfigs<typeof adapters> = {
52
51
  adapterA: "A",
53
52
  adapterB: "B",
@@ -64,15 +63,15 @@ describe("#renderAdapters", () => {
64
63
  it("should skip adapters where the corresponding config is null", () => {
65
64
  // Arrange
66
65
  const children = "Adapt me!";
67
- const adapter: TestHarnessAdapter<string> = (c, conf) => {
68
- // $FlowIgnore[incompatible-type] We know, it's ok.
66
+ // @ts-expect-error: `string` is not a valid `ReactElement`.
67
+ const adapter: TestHarnessAdapter<string> = (c: any, conf: any) => {
69
68
  return `${conf}:${c}`;
70
69
  };
71
70
  const adapters = {
72
71
  adapterA: adapter,
73
72
  adapterB: adapter,
74
73
  adapterC: adapter,
75
- };
74
+ } as const;
76
75
  const configs: TestHarnessConfigs<typeof adapters> = {
77
76
  adapterA: "A",
78
77
  adapterB: null,
@@ -1,12 +1,11 @@
1
- // @flow
2
1
  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";
2
+ import * as MTH from "../make-test-harness";
3
+ import {DefaultAdapters, DefaultConfigs} from "../adapters/adapters";
5
4
 
6
- jest.mock("../make-test-harness.js", () => {
5
+ jest.mock("../make-test-harness", () => {
7
6
  const returnValueFake = {
8
7
  thisisa: "PRETEND REACT COMPONENT",
9
- };
8
+ } as const;
10
9
  const harnessFake = jest.fn().mockReturnValue(returnValueFake);
11
10
  return {
12
11
  harnessFake,
@@ -21,7 +20,7 @@ describe("#testHarness", () => {
21
20
  const makeTestHarnessSpy = jest.spyOn(MTH, "makeTestHarness");
22
21
 
23
22
  // Act
24
- await ws.isolateModules(() => import("../hook-harness.js"));
23
+ await ws.isolateModules(() => import("../hook-harness"));
25
24
 
26
25
  // Assert
27
26
  expect(makeTestHarnessSpy).toHaveBeenCalledWith(
@@ -35,12 +34,12 @@ describe("#testHarness", () => {
35
34
  const Component = () => null;
36
35
  const config = {
37
36
  router: "/boo",
38
- };
39
- // $FlowIgnore[prop-missing] - we add this into our mock at the top.
37
+ } as const;
38
+ // @ts-expect-error [FEI-5019] - TS2339 - Property 'harnessFake' does not exist on type 'typeof import("/Users/kevinbarabash/khan/wonder-blocks/packages/wonder-blocks-testing/src/harness/make-test-harness")'.
40
39
  const [{harnessFake}, {testHarness}] = await ws.isolateModules(() =>
41
40
  Promise.all([
42
- import("../make-test-harness.js"),
43
- import("../test-harness.js"),
41
+ import("../make-test-harness"),
42
+ import("../test-harness"),
44
43
  ]),
45
44
  );
46
45
 
@@ -56,12 +55,12 @@ describe("#testHarness", () => {
56
55
  const Component = () => null;
57
56
  const config = {
58
57
  router: "/boo",
59
- };
60
- // $FlowIgnore[prop-missing] - we add this into our mock at the top.
58
+ } as const;
59
+ // @ts-expect-error [FEI-5019] - TS2339 - Property 'returnValueFake' does not exist on type 'typeof import("/Users/kevinbarabash/khan/wonder-blocks/packages/wonder-blocks-testing/src/harness/make-test-harness")'.
61
60
  const [{returnValueFake}, {testHarness}] = await ws.isolateModules(() =>
62
61
  Promise.all([
63
- import("../make-test-harness.js"),
64
- import("../test-harness.js"),
62
+ import("../make-test-harness"),
63
+ import("../test-harness"),
65
64
  ]),
66
65
  );
67
66
 
@@ -1,4 +1,3 @@
1
- // @flow
2
1
  import * as React from "react";
3
2
 
4
3
  import type {
@@ -6,25 +5,26 @@ import type {
6
5
  TestHarnessAdapters,
7
6
  TestHarnessConfig,
8
7
  TestHarnessConfigs,
9
- } from "../types.js";
8
+ } from "../types";
10
9
 
11
10
  /**
12
11
  * TestHarnessAdapter<TConfig>
13
12
  */
14
13
 
15
14
  //> should assert type of config.
15
+ // @ts-expect-error [FEI-5019] - TS2352 - Conversion of type '(children: React.ReactNode, config: number) => React.ReactElement<any>' to type 'TestHarnessAdapter<string>' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
16
16
  ((
17
- children: React.Node,
17
+ children: React.ReactNode,
18
18
  // TConfig is string, but we typed this arg as a number
19
19
  // $FlowExpectedError[incompatible-cast]
20
20
  config: number,
21
- ): React.Element<any> => <div />: TestHarnessAdapter<string>);
21
+ ): React.ReactElement<any> => <div />) as TestHarnessAdapter<string>;
22
22
  //<
23
23
 
24
24
  //> should work for correct definition
25
- ((children: React.Node, config: string): React.Element<any> => (
25
+ ((children: React.ReactNode, config: string): React.ReactElement<any> => (
26
26
  <div />
27
- ): TestHarnessAdapter<string>);
27
+ )) as TestHarnessAdapter<string>;
28
28
  //<
29
29
 
30
30
  /**
@@ -32,34 +32,34 @@ import type {
32
32
  */
33
33
 
34
34
  //> should work for empty case
35
- ({}: TestHarnessAdapters);
35
+ ({} as TestHarnessAdapters);
36
36
  //<
37
37
 
38
38
  //> should assert if adapter is not Adapter<TConfig>
39
+ // @ts-expect-error [FEI-5019] - TS2352 - Conversion of type '{ adapterString: string; }' to type 'TestHarnessAdapters' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
39
40
  ({
40
41
  // String is not a adapter function
41
42
  // $FlowExpectedError[incompatible-cast]
42
43
  adapterString: "string",
43
- }: TestHarnessAdapters);
44
+ } as TestHarnessAdapters);
44
45
  //<
45
46
 
46
47
  //> should work for a function matching Adapter<TConfig>
47
48
  ({
48
49
  adapterA: (children, config) => <div>test</div>,
49
- }: TestHarnessAdapters);
50
+ } as TestHarnessAdapters);
50
51
  //<
51
52
 
52
53
  /**
53
54
  * TestHarnessConfig<TAdapter>
54
55
  */
55
56
  //> should give the config type of an adapter
56
- ("string": TestHarnessConfig<TestHarnessAdapter<string>>);
57
+ "string" as TestHarnessConfig<TestHarnessAdapter<string>>;
57
58
  //<
58
59
 
59
60
  //> should error if the config type is wrong
60
61
  // 45 is not a string
61
- // $FlowExpectedError[incompatible-cast]
62
- (45: TestHarnessConfig<TestHarnessAdapter<string>>);
62
+ 45 as TestHarnessConfig<TestHarnessAdapter<string>>;
63
63
  //<
64
64
 
65
65
  /**
@@ -69,7 +69,7 @@ import type {
69
69
  * are explicitly typed as `TestHarnessAdapter<TConfig>` so if passing in a
70
70
  * non-Adapters type (which we should be, to get strong TConfig types instead
71
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
72
+ * marked as `TestHarnessAdapter<TConfig>` - TypeScript does not appear to pattern
73
73
  * match against the type definition when invoking the ExtractConfig type and I
74
74
  * haven't worked out how to get it to multi-dispatch so that it matches
75
75
  * functions too. Even worse, if the type doesn't match, it just allows `any`
@@ -77,32 +77,29 @@ import type {
77
77
  */
78
78
  const notadapters = "this is wrong";
79
79
  const adapterA: TestHarnessAdapter<string> = (
80
- children: React.Node,
81
- config: ?string,
82
- ): React.Element<any> => <div />;
80
+ children: React.ReactNode,
81
+ config?: string | null,
82
+ ): React.ReactElement<any> => <div />;
83
83
  const adapterB: TestHarnessAdapter<number> = (
84
- children: React.Node,
85
- config: ?number,
86
- ): React.Element<any> => <div />;
84
+ children: React.ReactNode,
85
+ config?: number | null,
86
+ ): React.ReactElement<any> => <div />;
87
87
  const adapters = {
88
88
  adapterA,
89
89
  adapterB,
90
- };
90
+ } as const;
91
91
 
92
92
  //> should assert if parameterized type is not valid Adapters
93
93
  // string is not a valid Adapter
94
- // $FlowExpectedError[incompatible-use]
95
- // $FlowExpectedError[incompatible-type-arg]
96
- ({}: TestHarnessConfigs<typeof notadapters>);
94
+ // @ts-expect-error: Type 'string' does not satisfy the constraint 'TestHarnessAdapters'
95
+ ({} as TestHarnessConfigs<typeof notadapters>);
97
96
  //<
98
97
 
99
98
  //> should expect one config per adapter
100
99
  // both adapter configs missing
101
- // $FlowExpectedError[incompatible-exact]
102
- ({}: TestHarnessConfigs<typeof adapters>);
100
+ ({} as TestHarnessConfigs<typeof adapters>);
103
101
  // adapterB config missing
104
- // $FlowExpectedError[prop-missing]
105
- ({adapterA: "test"}: TestHarnessConfigs<typeof adapters>);
102
+ ({adapterA: "test"} as TestHarnessConfigs<typeof adapters>);
106
103
  //<
107
104
 
108
105
  //> should assert if config does not match adapter config
@@ -111,5 +108,5 @@ const adapters = {
111
108
  // the config type here is a number, not a string
112
109
  // $FlowExpectedError[incompatible-cast]
113
110
  adapterB: "a string, but it should be a number",
114
- }: TestHarnessConfigs<typeof adapters>);
111
+ } as TestHarnessConfigs<typeof adapters>);
115
112
  //<