@khanacademy/wonder-blocks-testing 4.0.4 → 5.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 +7 -0
- package/dist/es/index.js +212 -26
- package/dist/index.js +589 -62
- package/package.json +4 -2
- package/src/__docs__/_overview_.stories.mdx +3 -4
- package/src/__docs__/_overview_fixtures.stories.mdx +22 -0
- package/src/__docs__/_overview_mocking.stories.mdx +14 -0
- package/src/__docs__/_overview_test_harness.stories.mdx +18 -0
- package/src/__docs__/exports.fixture-adapters.stories.mdx +49 -0
- package/src/__docs__/exports.fixtures.stories.mdx +53 -0
- package/src/__docs__/exports.harness-adapters.stories.mdx +187 -0
- package/src/__docs__/exports.hook-harness.stories.mdx +22 -0
- package/src/__docs__/exports.make-hook-harness.stories.mdx +25 -0
- package/src/__docs__/exports.make-test-harness.stories.mdx +28 -0
- package/src/__docs__/exports.mock-fetch.stories.mdx +40 -0
- package/src/__docs__/exports.mock-gql-fetch.stories.mdx +13 -8
- package/src/__docs__/exports.respond-with.stories.mdx +54 -8
- package/src/__docs__/exports.setup-fixtures.stories.mdx +22 -0
- package/src/__docs__/exports.test-harness.stories.mdx +23 -0
- package/src/__docs__/types.custom-mount-props.stories.mdx +35 -0
- package/src/__docs__/types.fetch-mock-fn.stories.mdx +22 -0
- package/src/__docs__/types.fetch-mock-operation.stories.mdx +18 -0
- package/src/__docs__/types.fixtures-adapter-factory.stories.mdx +23 -0
- package/src/__docs__/types.fixtures-adapter-fixture-options.stories.mdx +35 -0
- package/src/__docs__/types.fixtures-adapter-group-options.stories.mdx +37 -0
- package/src/__docs__/types.fixtures-adapter-group.stories.mdx +43 -0
- package/src/__docs__/types.fixtures-adapter-options.stories.mdx +21 -0
- package/src/__docs__/types.fixtures-adapter.stories.mdx +35 -0
- package/src/__docs__/types.fixtures-configuration.stories.mdx +35 -0
- package/src/__docs__/types.fixtures-options.stories.mdx +51 -0
- package/src/__docs__/types.get-props-options.stories.mdx +25 -0
- package/src/__docs__/types.gql-fetch-mock-fn.stories.mdx +27 -0
- package/src/__docs__/types.gql-mock-operation.stories.mdx +26 -0
- package/src/__docs__/types.mock-response.stories.mdx +18 -0
- package/src/__docs__/types.test-harness-adapter.stories.mdx +21 -0
- package/src/__docs__/types.test-harness-adapters.stories.mdx +46 -0
- package/src/__docs__/types.test-harness-config.stories.mdx +18 -0
- package/src/__docs__/types.test-harness-configs.stories.mdx +59 -0
- package/src/fetch/types.js +0 -3
- package/src/fixtures/adapters/adapter-group.js +11 -11
- package/src/fixtures/adapters/adapter.js +8 -8
- package/src/fixtures/adapters/storybook.js +11 -8
- package/src/fixtures/fixtures.basic.stories.js +6 -2
- package/src/fixtures/fixtures.defaultwrapper.stories.js +6 -2
- package/src/fixtures/setup.js +8 -4
- package/src/fixtures/types.js +27 -16
- package/src/gql/types.js +1 -3
- package/src/harness/__tests__/hook-harness.test.js +72 -0
- package/src/harness/__tests__/make-hook-harness.test.js +94 -0
- package/src/harness/__tests__/make-test-harness.test.js +190 -0
- package/src/harness/__tests__/render-adapters.test.js +88 -0
- package/src/harness/__tests__/test-harness.test.js +74 -0
- package/src/harness/adapters/__tests__/__snapshots__/router.test.js.snap +5 -0
- package/src/harness/adapters/__tests__/css.test.js +96 -0
- package/src/harness/adapters/__tests__/data.test.js +66 -0
- package/src/harness/adapters/__tests__/portal.test.js +31 -0
- package/src/harness/adapters/__tests__/router.test.js +233 -0
- package/src/harness/adapters/adapters.js +33 -0
- package/src/harness/adapters/css.js +65 -0
- package/src/harness/adapters/data.js +46 -0
- package/src/harness/adapters/portal.js +26 -0
- package/src/harness/adapters/router.js +206 -0
- package/src/harness/hook-harness.js +23 -0
- package/src/harness/make-hook-harness.js +39 -0
- package/src/harness/make-test-harness.js +68 -0
- package/src/harness/render-adapters.js +27 -0
- package/src/harness/test-harness.js +24 -0
- package/src/harness/types.js +57 -0
- package/src/index.js +22 -18
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
FixturesAdapterGroup,
|
|
4
|
+
FixturesAdapterGroupOptions,
|
|
5
|
+
FixturesAdapterFixtureOptions,
|
|
6
6
|
} from "../types.js";
|
|
7
7
|
|
|
8
8
|
export type CloseGroupFn<TProps: {...}, Options: {...}, Exports: {...}> = (
|
|
9
|
-
options: $ReadOnly<
|
|
9
|
+
options: $ReadOnly<FixturesAdapterGroupOptions>,
|
|
10
10
|
adapterOptions: ?$ReadOnly<Options>,
|
|
11
|
-
declaredFixtures: $ReadOnlyArray<
|
|
11
|
+
declaredFixtures: $ReadOnlyArray<FixturesAdapterFixtureOptions<TProps>>,
|
|
12
12
|
) => ?$ReadOnly<Exports>;
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Simple adapter group implementation.
|
|
16
16
|
*/
|
|
17
17
|
export class AdapterGroup<TProps: {...}, Options: {...}, Exports: {...}>
|
|
18
|
-
implements
|
|
18
|
+
implements FixturesAdapterGroup<TProps, Options, Exports>
|
|
19
19
|
{
|
|
20
20
|
_closeGroupFn: ?CloseGroupFn<TProps, Options, Exports>;
|
|
21
|
-
+_fixtures: Array<
|
|
22
|
-
+_options: $ReadOnly<
|
|
21
|
+
+_fixtures: Array<FixturesAdapterFixtureOptions<TProps>>;
|
|
22
|
+
+_options: $ReadOnly<FixturesAdapterGroupOptions>;
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Create an adapter group.
|
|
@@ -30,7 +30,7 @@ export class AdapterGroup<TProps: {...}, Options: {...}, Exports: {...}>
|
|
|
30
30
|
*/
|
|
31
31
|
constructor(
|
|
32
32
|
closeGroupFn: CloseGroupFn<TProps, Options, Exports>,
|
|
33
|
-
options: $ReadOnly<
|
|
33
|
+
options: $ReadOnly<FixturesAdapterGroupOptions>,
|
|
34
34
|
) {
|
|
35
35
|
if (typeof closeGroupFn !== "function") {
|
|
36
36
|
throw new TypeError("closeGroupFn must be a function");
|
|
@@ -71,11 +71,11 @@ export class AdapterGroup<TProps: {...}, Options: {...}, Exports: {...}>
|
|
|
71
71
|
/**
|
|
72
72
|
* Declare a fixture within the group.
|
|
73
73
|
*
|
|
74
|
-
* @param {
|
|
74
|
+
* @param {FixturesAdapterFixtureOptions<TProps>} fixtureOptions The options
|
|
75
75
|
* describing the fixture.
|
|
76
76
|
*/
|
|
77
77
|
+declareFixture: (
|
|
78
|
-
options: $ReadOnly<
|
|
78
|
+
options: $ReadOnly<FixturesAdapterFixtureOptions<TProps>>,
|
|
79
79
|
) => void = (options) => {
|
|
80
80
|
if (typeof options !== "object" || options === null) {
|
|
81
81
|
throw new TypeError("options must be an object");
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import {AdapterGroup, type CloseGroupFn} from "./adapter-group.js";
|
|
3
3
|
import type {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
FixturesAdapter,
|
|
5
|
+
FixturesAdapterGroup,
|
|
6
|
+
FixturesAdapterGroupOptions,
|
|
7
7
|
} from "../types.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Class for implementing a custom adapter.
|
|
11
11
|
*/
|
|
12
12
|
export class Adapter<Options: {...}, Exports: {...}>
|
|
13
|
-
implements
|
|
13
|
+
implements FixturesAdapter<Options, Exports>
|
|
14
14
|
{
|
|
15
15
|
+_name: string;
|
|
16
16
|
+_closeGroupFn: CloseGroupFn<any, Options, Exports>;
|
|
@@ -51,13 +51,13 @@ export class Adapter<Options: {...}, Exports: {...}>
|
|
|
51
51
|
/**
|
|
52
52
|
* Declare a new fixture group.
|
|
53
53
|
*
|
|
54
|
-
* @param {
|
|
54
|
+
* @param {FixturesAdapterGroupOptions} options The options describing the fixture
|
|
55
55
|
* group.
|
|
56
|
-
* @returns {
|
|
56
|
+
* @returns {FixturesAdapterGroup} The new fixture group.
|
|
57
57
|
*/
|
|
58
58
|
declareGroup<Config: {...}>(
|
|
59
|
-
options: $ReadOnly<
|
|
60
|
-
):
|
|
59
|
+
options: $ReadOnly<FixturesAdapterGroupOptions>,
|
|
60
|
+
): FixturesAdapterGroup<Config, Options, Exports> {
|
|
61
61
|
return new AdapterGroup(this._closeGroupFn, options);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -4,9 +4,9 @@ import {action} from "@storybook/addon-actions";
|
|
|
4
4
|
import {Adapter} from "./adapter.js";
|
|
5
5
|
|
|
6
6
|
import type {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
FixturesAdapterGroupOptions,
|
|
8
|
+
FixturesAdapterFixtureOptions,
|
|
9
|
+
FixturesAdapterFactory,
|
|
10
10
|
} from "../types.js";
|
|
11
11
|
|
|
12
12
|
type StoryContext = {|
|
|
@@ -38,9 +38,10 @@ type Exports<TProps: {...}> = {|
|
|
|
38
38
|
/**
|
|
39
39
|
* Get a fixture framework adapter for Storybook support.
|
|
40
40
|
*/
|
|
41
|
-
export const getAdapter:
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
export const getAdapter: FixturesAdapterFactory<
|
|
42
|
+
StorybookOptions,
|
|
43
|
+
Exports<any>,
|
|
44
|
+
> = (MountingComponent = null) =>
|
|
44
45
|
new Adapter<StorybookOptions, Exports<any>>(
|
|
45
46
|
"storybook",
|
|
46
47
|
<TProps: {...}>(
|
|
@@ -50,9 +51,11 @@ export const getAdapter: AdapterFactory<StorybookOptions, Exports<any>> = (
|
|
|
50
51
|
// We don't use the default title in Storybook as storybook
|
|
51
52
|
// will generate titles for us if we pass a nullish title.
|
|
52
53
|
getDefaultTitle: _,
|
|
53
|
-
}: $ReadOnly<
|
|
54
|
+
}: $ReadOnly<FixturesAdapterGroupOptions>,
|
|
54
55
|
adapterOptions: ?$ReadOnly<StorybookOptions>,
|
|
55
|
-
declaredFixtures: $ReadOnlyArray<
|
|
56
|
+
declaredFixtures: $ReadOnlyArray<
|
|
57
|
+
FixturesAdapterFixtureOptions<TProps>,
|
|
58
|
+
>,
|
|
56
59
|
): ?$ReadOnly<Exports<TProps>> => {
|
|
57
60
|
const templateMap = new WeakMap();
|
|
58
61
|
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
setupFixtures,
|
|
6
|
+
fixtures,
|
|
7
|
+
fixtureAdapters as adapters,
|
|
8
|
+
} from "../index.js";
|
|
5
9
|
|
|
6
10
|
// Normally would call setup from the storybook.preview.js for a project.
|
|
7
11
|
setupFixtures({
|
|
@@ -23,7 +27,7 @@ const stories: Array<mixed> = Object.values(
|
|
|
23
27
|
fixtures(
|
|
24
28
|
{
|
|
25
29
|
component: MyComponent,
|
|
26
|
-
title: "Testing/Fixtures/Basic",
|
|
30
|
+
title: "Testing / Fixtures / Basic",
|
|
27
31
|
},
|
|
28
32
|
(fixture) => {
|
|
29
33
|
fixture("This is a fixture with some regular props", {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
setupFixtures,
|
|
6
|
+
fixtures,
|
|
7
|
+
fixtureAdapters as adapters,
|
|
8
|
+
} from "../index.js";
|
|
5
9
|
|
|
6
10
|
// Normally would call setup from the storybook.preview.js for a project.
|
|
7
11
|
setupFixtures({
|
|
@@ -30,7 +34,7 @@ const stories: Array<mixed> = Object.values(
|
|
|
30
34
|
fixtures(
|
|
31
35
|
{
|
|
32
36
|
component: MyComponent,
|
|
33
|
-
title: "Testing/Fixtures/DefaultWrapper",
|
|
37
|
+
title: "Testing / Fixtures / DefaultWrapper",
|
|
34
38
|
defaultWrapper: DefaultWrapper,
|
|
35
39
|
},
|
|
36
40
|
(fixture) => {
|
package/src/fixtures/setup.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
// @flow
|
|
2
|
-
import type {
|
|
2
|
+
import type {FixturesConfiguration} from "./types.js";
|
|
3
3
|
|
|
4
|
-
let _configuration: ?$ReadOnly<
|
|
4
|
+
let _configuration: ?$ReadOnly<FixturesConfiguration<any, any>> = null;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Setup the fixture framework.
|
|
8
8
|
*/
|
|
9
9
|
export const setup = <TAdapterOptions: {...}, TAdapterExports: {...}>(
|
|
10
|
-
configuration: $ReadOnly<
|
|
10
|
+
configuration: $ReadOnly<
|
|
11
|
+
FixturesConfiguration<TAdapterOptions, TAdapterExports>,
|
|
12
|
+
>,
|
|
11
13
|
) => {
|
|
12
14
|
_configuration = configuration;
|
|
13
15
|
};
|
|
@@ -18,7 +20,9 @@ export const setup = <TAdapterOptions: {...}, TAdapterExports: {...}>(
|
|
|
18
20
|
* @returns {Configuration} The configuration as provided via setup().
|
|
19
21
|
* @throws {Error} If the configuration has not been set.
|
|
20
22
|
*/
|
|
21
|
-
export const getConfiguration = (): $ReadOnly<
|
|
23
|
+
export const getConfiguration = (): $ReadOnly<
|
|
24
|
+
FixturesConfiguration<any, any>,
|
|
25
|
+
> => {
|
|
22
26
|
if (_configuration == null) {
|
|
23
27
|
throw new Error("Not configured");
|
|
24
28
|
}
|
package/src/fixtures/types.js
CHANGED
|
@@ -15,7 +15,7 @@ export type GetPropsOptions = {|
|
|
|
15
15
|
/**
|
|
16
16
|
* Adapter options keyed by the adapter name.
|
|
17
17
|
*/
|
|
18
|
-
export type
|
|
18
|
+
export type FixturesAdapterOptions = {|
|
|
19
19
|
storybook?: StorybookOptions,
|
|
20
20
|
[adapterName: string]: {...},
|
|
21
21
|
|};
|
|
@@ -49,13 +49,13 @@ export type FixturesOptions<TProps: {...}> = {|
|
|
|
49
49
|
/**
|
|
50
50
|
* Additional options to apply to specific adapters.
|
|
51
51
|
*/
|
|
52
|
-
additionalAdapterOptions?:
|
|
52
|
+
additionalAdapterOptions?: FixturesAdapterOptions,
|
|
53
53
|
|};
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* Describes a single fixture.
|
|
57
57
|
*/
|
|
58
|
-
export type
|
|
58
|
+
export type FixturesAdapterFixtureOptions<TProps: {...}> = {|
|
|
59
59
|
/**
|
|
60
60
|
* Description of the fixture.
|
|
61
61
|
*/
|
|
@@ -78,7 +78,7 @@ export type AdapterFixtureOptions<TProps: {...}> = {|
|
|
|
78
78
|
/**
|
|
79
79
|
* Describes a group of fixtures.
|
|
80
80
|
*/
|
|
81
|
-
export type
|
|
81
|
+
export type FixturesAdapterGroupOptions = {|
|
|
82
82
|
/**
|
|
83
83
|
* The title of the group.
|
|
84
84
|
*
|
|
@@ -100,9 +100,9 @@ export type AdapterGroupOptions = {|
|
|
|
100
100
|
|};
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
* Describes
|
|
103
|
+
* Describes props that an adapter will inject for custom mounting components.
|
|
104
104
|
*/
|
|
105
|
-
export type
|
|
105
|
+
export type CustomMountProps<TProps: {...}> = {|
|
|
106
106
|
/**
|
|
107
107
|
* The fixture props for the component to be rendered.
|
|
108
108
|
*/
|
|
@@ -122,7 +122,7 @@ export type CustomWrapperProps<TProps: {...}> = {|
|
|
|
122
122
|
/**
|
|
123
123
|
* Declares the API for describing a fixture group provided by an adapter.
|
|
124
124
|
*/
|
|
125
|
-
export interface
|
|
125
|
+
export interface FixturesAdapterGroup<
|
|
126
126
|
TProps: {...},
|
|
127
127
|
TAdapterOptions: {...},
|
|
128
128
|
TAdapterExports: {...},
|
|
@@ -130,7 +130,9 @@ export interface AdapterGroup<
|
|
|
130
130
|
/**
|
|
131
131
|
* Declare a fixture.
|
|
132
132
|
*/
|
|
133
|
-
declareFixture(
|
|
133
|
+
declareFixture(
|
|
134
|
+
options: $ReadOnly<FixturesAdapterFixtureOptions<TProps>>,
|
|
135
|
+
): void;
|
|
134
136
|
|
|
135
137
|
/**
|
|
136
138
|
* Close the group and obtain the exports, if the adapter requires any.
|
|
@@ -150,7 +152,10 @@ export interface AdapterGroup<
|
|
|
150
152
|
/**
|
|
151
153
|
* Declares the API for an adapter.
|
|
152
154
|
*/
|
|
153
|
-
export interface
|
|
155
|
+
export interface FixturesAdapter<
|
|
156
|
+
TAdapterOptions: {...},
|
|
157
|
+
TAdapterExports: {...},
|
|
158
|
+
> {
|
|
154
159
|
/**
|
|
155
160
|
* The name of the adapter.
|
|
156
161
|
*/
|
|
@@ -163,18 +168,21 @@ export interface Adapter<TAdapterOptions: {...}, TAdapterExports: {...}> {
|
|
|
163
168
|
* declared group.
|
|
164
169
|
*/
|
|
165
170
|
declareGroup<TProps: {...}>(
|
|
166
|
-
options: $ReadOnly<
|
|
167
|
-
):
|
|
171
|
+
options: $ReadOnly<FixturesAdapterGroupOptions>,
|
|
172
|
+
): FixturesAdapterGroup<TProps, TAdapterOptions, TAdapterExports>;
|
|
168
173
|
}
|
|
169
174
|
|
|
170
175
|
/**
|
|
171
176
|
* Describes the configuration for the fixture framework.
|
|
172
177
|
*/
|
|
173
|
-
export type
|
|
178
|
+
export type FixturesConfiguration<
|
|
179
|
+
TAdapterOptions: {...},
|
|
180
|
+
TAdapterExports: {...},
|
|
181
|
+
> = {|
|
|
174
182
|
/**
|
|
175
183
|
* The adapter to use for declaring fixtures.
|
|
176
184
|
*/
|
|
177
|
-
+adapter:
|
|
185
|
+
+adapter: FixturesAdapter<TAdapterOptions, TAdapterExports>,
|
|
178
186
|
|
|
179
187
|
/**
|
|
180
188
|
* Default options to apply to every fixture group.
|
|
@@ -186,6 +194,9 @@ export type Configuration<TAdapterOptions: {...}, TAdapterExports: {...}> = {|
|
|
|
186
194
|
+defaultAdapterOptions?: $ReadOnly<Partial<TAdapterOptions>>,
|
|
187
195
|
|};
|
|
188
196
|
|
|
189
|
-
export type
|
|
190
|
-
|
|
191
|
-
|
|
197
|
+
export type FixturesAdapterFactory<
|
|
198
|
+
TAdapterOptions: {...},
|
|
199
|
+
TAdapterExports: {...},
|
|
200
|
+
> = (
|
|
201
|
+
MountingComponent: ?React.ComponentType<CustomMountProps<any>>,
|
|
202
|
+
) => FixturesAdapter<TAdapterOptions, TAdapterExports>;
|
package/src/gql/types.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//@flow
|
|
2
2
|
import type {GqlOperation, GqlContext} from "@khanacademy/wonder-blocks-data";
|
|
3
|
-
import type {
|
|
3
|
+
import type {GraphQLJson} from "../types.js";
|
|
4
4
|
import type {MockResponse} from "../make-mock-response.js";
|
|
5
5
|
|
|
6
6
|
export type GqlMockOperation<
|
|
@@ -32,5 +32,3 @@ export type GqlFetchMockFn = {|
|
|
|
32
32
|
mockOperation: GqlMockOperationFn,
|
|
33
33
|
mockOperationOnce: GqlMockOperationFn,
|
|
34
34
|
|};
|
|
35
|
-
|
|
36
|
-
export type GqlMock = OperationMock<GqlMockOperation<any, any, any>>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
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";
|
|
5
|
+
|
|
6
|
+
jest.mock("../make-hook-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
|
+
makeHookHarness: jest.fn().mockReturnValue(harnessFake),
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe("#hookHarness", () => {
|
|
19
|
+
it("should be created by calling makeHookHarness with the DefaultAdapters and DefaultConfigs", async () => {
|
|
20
|
+
// Arrange
|
|
21
|
+
const makeHookHarnessSpy = jest.spyOn(MHH, "makeHookHarness");
|
|
22
|
+
|
|
23
|
+
// Act
|
|
24
|
+
await ws.isolateModules(() => import("../hook-harness.js"));
|
|
25
|
+
|
|
26
|
+
// Assert
|
|
27
|
+
expect(makeHookHarnessSpy).toHaveBeenCalledWith(
|
|
28
|
+
DefaultAdapters,
|
|
29
|
+
DefaultConfigs,
|
|
30
|
+
);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("should invoke the function made by makeHookHarness", async () => {
|
|
34
|
+
// Arrange
|
|
35
|
+
const config = {
|
|
36
|
+
router: "/boo",
|
|
37
|
+
};
|
|
38
|
+
// $FlowIgnore[prop-missing] - we add this into our mock at the top.
|
|
39
|
+
const [{harnessFake}, {hookHarness}] = await ws.isolateModules(() =>
|
|
40
|
+
Promise.all([
|
|
41
|
+
import("../make-hook-harness.js"),
|
|
42
|
+
import("../hook-harness.js"),
|
|
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
|
+
};
|
|
58
|
+
// $FlowIgnore[prop-missing] - we add this into our mock at the top.
|
|
59
|
+
const [{returnValueFake}, {hookHarness}] = await ws.isolateModules(() =>
|
|
60
|
+
Promise.all([
|
|
61
|
+
import("../make-hook-harness.js"),
|
|
62
|
+
import("../hook-harness.js"),
|
|
63
|
+
]),
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// Act
|
|
67
|
+
const result = hookHarness(config);
|
|
68
|
+
|
|
69
|
+
// Assert
|
|
70
|
+
expect(result).toBe(returnValueFake);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import {render} from "@testing-library/react";
|
|
4
|
+
import {makeHookHarness} from "../make-hook-harness.js";
|
|
5
|
+
import * as MTH from "../make-test-harness.js";
|
|
6
|
+
|
|
7
|
+
describe("#makeHookHarness", () => {
|
|
8
|
+
it("should call makeTestHarness", () => {
|
|
9
|
+
// Arrange
|
|
10
|
+
const makeTestHarnessSpy = jest.spyOn(MTH, "makeTestHarness");
|
|
11
|
+
const adapters = {
|
|
12
|
+
adapter: jest.fn(),
|
|
13
|
+
};
|
|
14
|
+
const defaultConfigs = {
|
|
15
|
+
adapter: {},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// Act
|
|
19
|
+
makeHookHarness(adapters, defaultConfigs);
|
|
20
|
+
|
|
21
|
+
// Assert
|
|
22
|
+
expect(makeTestHarnessSpy).toHaveBeenCalledWith(
|
|
23
|
+
adapters,
|
|
24
|
+
defaultConfigs,
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("should return a function", () => {
|
|
29
|
+
const adapters = {
|
|
30
|
+
adapter: jest.fn(),
|
|
31
|
+
};
|
|
32
|
+
const defaultConfigs = {
|
|
33
|
+
adapter: {},
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// Act
|
|
37
|
+
const result = makeHookHarness(adapters, defaultConfigs);
|
|
38
|
+
|
|
39
|
+
// Assert
|
|
40
|
+
expect(result).toBeFunction();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe("returned function", () => {
|
|
44
|
+
it("should invoke the function returned by makeTestHarness with component and the configs", () => {
|
|
45
|
+
// Arrange
|
|
46
|
+
const harnessSpy = jest.fn();
|
|
47
|
+
jest.spyOn(MTH, "makeTestHarness").mockReturnValue(harnessSpy);
|
|
48
|
+
const adapters = {
|
|
49
|
+
adapter: jest.fn(),
|
|
50
|
+
};
|
|
51
|
+
const defaultConfigs = {
|
|
52
|
+
adapter: {},
|
|
53
|
+
};
|
|
54
|
+
const configs = {
|
|
55
|
+
adapter: {},
|
|
56
|
+
};
|
|
57
|
+
const hookHarness = makeHookHarness(adapters, defaultConfigs);
|
|
58
|
+
|
|
59
|
+
// Act
|
|
60
|
+
hookHarness(configs);
|
|
61
|
+
|
|
62
|
+
// Assert
|
|
63
|
+
expect(harnessSpy).toHaveBeenCalledWith(
|
|
64
|
+
expect.any(Function),
|
|
65
|
+
configs,
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("should pass a component that just renders the children it is given", () => {
|
|
70
|
+
// Arrange
|
|
71
|
+
const harnessSpy = jest.fn();
|
|
72
|
+
jest.spyOn(MTH, "makeTestHarness").mockReturnValue(harnessSpy);
|
|
73
|
+
const adapters = {
|
|
74
|
+
adapter: jest.fn(),
|
|
75
|
+
};
|
|
76
|
+
const defaultConfigs = {
|
|
77
|
+
adapter: {},
|
|
78
|
+
};
|
|
79
|
+
const configs = {
|
|
80
|
+
adapter: {},
|
|
81
|
+
};
|
|
82
|
+
const children = "THE CHILDREN";
|
|
83
|
+
|
|
84
|
+
// Act
|
|
85
|
+
const hookHarness = makeHookHarness(adapters, defaultConfigs);
|
|
86
|
+
hookHarness(configs);
|
|
87
|
+
const Component = harnessSpy.mock.calls[0][0];
|
|
88
|
+
const {container} = render(<Component>{children}</Component>);
|
|
89
|
+
|
|
90
|
+
// Assert
|
|
91
|
+
expect(container).toHaveTextContent(children);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|