@equinor/fusion-framework-vitest-plugin-react-app 0.2.0-next.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 +104 -0
- package/LICENSE +21 -0
- package/README.md +349 -0
- package/dist/esm/app-test.js +9 -0
- package/dist/esm/app-test.js.map +1 -0
- package/dist/esm/define-project.js +68 -0
- package/dist/esm/define-project.js.map +1 -0
- package/dist/esm/index.js +99 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/render-app-component.js +52 -0
- package/dist/esm/render-app-component.js.map +1 -0
- package/dist/esm/render-app-hook.js +63 -0
- package/dist/esm/render-app-hook.js.map +1 -0
- package/dist/esm/render.js +49 -0
- package/dist/esm/render.js.map +1 -0
- package/dist/esm/resolve-app-test-env.js +85 -0
- package/dist/esm/resolve-app-test-env.js.map +1 -0
- package/dist/esm/scope/create-app-scope-wrapper.js +15 -0
- package/dist/esm/scope/create-app-scope-wrapper.js.map +1 -0
- package/dist/esm/scope/default-app-env.js +12 -0
- package/dist/esm/scope/default-app-env.js.map +1 -0
- package/dist/esm/scope/index.js +5 -0
- package/dist/esm/scope/index.js.map +1 -0
- package/dist/esm/scope/resolve-app-scope.js +21 -0
- package/dist/esm/scope/resolve-app-scope.js.map +1 -0
- package/dist/esm/scope/resolve-fusion.js +18 -0
- package/dist/esm/scope/resolve-fusion.js.map +1 -0
- package/dist/esm/test-app.js +59 -0
- package/dist/esm/test-app.js.map +1 -0
- package/dist/esm/test.js +33 -0
- package/dist/esm/test.js.map +1 -0
- package/dist/esm/version.js +3 -0
- package/dist/esm/version.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/app-test.d.ts +6 -0
- package/dist/types/define-project.d.ts +41 -0
- package/dist/types/index.d.ts +45 -0
- package/dist/types/render-app-component.d.ts +86 -0
- package/dist/types/render-app-hook.d.ts +99 -0
- package/dist/types/render.d.ts +37 -0
- package/dist/types/resolve-app-test-env.d.ts +56 -0
- package/dist/types/scope/create-app-scope-wrapper.d.ts +14 -0
- package/dist/types/scope/default-app-env.d.ts +5 -0
- package/dist/types/scope/index.d.ts +4 -0
- package/dist/types/scope/resolve-app-scope.d.ts +31 -0
- package/dist/types/scope/resolve-fusion.d.ts +13 -0
- package/dist/types/test-app.d.ts +68 -0
- package/dist/types/test.d.ts +66 -0
- package/dist/types/version.d.ts +1 -0
- package/docs/advanced.md +140 -0
- package/docs/configuration.md +109 -0
- package/docs/getting-started.md +66 -0
- package/docs/migrating-an-existing-app.md +197 -0
- package/docs/module-mocks.md +120 -0
- package/docs/overview.md +49 -0
- package/docs/troubleshooting.md +64 -0
- package/docs/why-browser-mode.md +113 -0
- package/package.json +87 -0
- package/src/__tests__/app-test-vite-plugin.test.ts +109 -0
- package/src/__tests__/resolve-app-test-env.test.ts +83 -0
- package/src/app-test.ts +18 -0
- package/src/define-project.ts +84 -0
- package/src/index.ts +124 -0
- package/src/render-app-component.tsx +116 -0
- package/src/render-app-hook.tsx +135 -0
- package/src/render.tsx +64 -0
- package/src/resolve-app-test-env.ts +132 -0
- package/src/scope/create-app-scope-wrapper.tsx +26 -0
- package/src/scope/default-app-env.ts +13 -0
- package/src/scope/index.ts +4 -0
- package/src/scope/resolve-app-scope.ts +46 -0
- package/src/scope/resolve-fusion.ts +29 -0
- package/src/test-app.tsx +72 -0
- package/src/test.tsx +35 -0
- package/src/version.ts +2 -0
- package/src/virtual-modules.d.ts +12 -0
- package/tsconfig.json +24 -0
- package/vitest.config.ts +10 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AppEnv } from '@equinor/fusion-framework-app';
|
|
2
|
+
import type { Fusion } from '@equinor/fusion-framework';
|
|
3
|
+
import { mockFramework } from '@equinor/fusion-framework/mock';
|
|
4
|
+
import { enableAppManifestMock } from '@equinor/fusion-framework-app/mock';
|
|
5
|
+
import type { AppModule } from '@equinor/fusion-framework-module-app';
|
|
6
|
+
|
|
7
|
+
import { defaultAppEnv } from './default-app-env';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Resolves the parent Fusion instance backing an application module scope, building a
|
|
11
|
+
* fresh {@link mockFramework} instance with this app's own manifest served when none is
|
|
12
|
+
* given.
|
|
13
|
+
*
|
|
14
|
+
* @template TEnv - The application environment descriptor.
|
|
15
|
+
* @param env - The application environment; defaults to {@link defaultAppEnv}.
|
|
16
|
+
* @param fusion - An already-built parent Fusion instance to reuse instead.
|
|
17
|
+
* @returns The given `fusion`, or a fresh mocked parent Fusion instance.
|
|
18
|
+
*/
|
|
19
|
+
export async function resolveFusion<TEnv extends AppEnv = AppEnv>(
|
|
20
|
+
env?: TEnv,
|
|
21
|
+
fusion?: Fusion,
|
|
22
|
+
): Promise<Fusion> {
|
|
23
|
+
return (
|
|
24
|
+
fusion ??
|
|
25
|
+
mockFramework<[AppModule]>((configurator) =>
|
|
26
|
+
enableAppManifestMock(configurator, env ?? (defaultAppEnv as TEnv)),
|
|
27
|
+
)
|
|
28
|
+
);
|
|
29
|
+
}
|
package/src/test-app.tsx
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import { test as baseTest } from 'vitest';
|
|
3
|
+
import { render, renderHook } from 'vitest-browser-react';
|
|
4
|
+
import type { RenderOptions, RenderHookOptions } from 'vitest-browser-react';
|
|
5
|
+
|
|
6
|
+
import { mockAppModules } from '@equinor/fusion-framework-app/mock';
|
|
7
|
+
import type { AppMockConfigureFn } from '@equinor/fusion-framework-app/mock';
|
|
8
|
+
import type { AppEnv } from '@equinor/fusion-framework-app';
|
|
9
|
+
|
|
10
|
+
import { defaultAppEnv, resolveFusion, createAppScopeWrapper } from './scope';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* `vitest`'s `test`, extended with an application module scope fixture.
|
|
14
|
+
*
|
|
15
|
+
* @remarks
|
|
16
|
+
* An alternative to {@link renderAppComponent}/{@link renderAppHook} for a test file whose
|
|
17
|
+
* cases share seeded fixture defaults: `env`/`configure` become suite-level concerns,
|
|
18
|
+
* overridden once per file (or per `describe` block) with `testApp.extend(...)`, rather than
|
|
19
|
+
* an options object repeated on every call. `fusion`/`app` are still instantiated fresh per
|
|
20
|
+
* test — only the seeded defaults are shared, not state between tests. They also resolve
|
|
21
|
+
* lazily: a test that only destructures `app` never pays for rendering anything, and one
|
|
22
|
+
* that only destructures `render`/`renderHook` gets the same fixture wiring automatically.
|
|
23
|
+
*
|
|
24
|
+
* Both entry points stay supported: reach for `renderAppComponent`/`renderAppHook` for a
|
|
25
|
+
* one-off test whose configuration is not shared by the rest of the file; reach for
|
|
26
|
+
* `testApp` when several cases in a file share one set of seeded fixture defaults.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* testApp('resolves current context', async ({ app, render }) => {
|
|
31
|
+
* const screen = await render(<App />);
|
|
32
|
+
* expect(app.context).toBeDefined();
|
|
33
|
+
* });
|
|
34
|
+
* ```
|
|
35
|
+
*
|
|
36
|
+
* @example Seed a module for every test in a suite
|
|
37
|
+
* ```tsx
|
|
38
|
+
* describe('with a seeded context module', () => {
|
|
39
|
+
* const test = testApp.extend('configure', { injected: true }, () =>
|
|
40
|
+
* (configurator) => enableContextMock(configurator, (mock) => mock.setCurrentContext(projectA)),
|
|
41
|
+
* );
|
|
42
|
+
*
|
|
43
|
+
* test('starts on the seeded context', async ({ render }) => {
|
|
44
|
+
* const screen = await render(<App />);
|
|
45
|
+
* await expect.element(screen.getByText(projectA.title)).toBeVisible();
|
|
46
|
+
* });
|
|
47
|
+
* });
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export const testApp = baseTest
|
|
51
|
+
.extend('env', { injected: true }, defaultAppEnv)
|
|
52
|
+
// `test.extend`'s plain-`value` overload rejects function types (ambiguous with the
|
|
53
|
+
// resolver-`fn` overload), so a function-typed fixture default must go through `fn` instead.
|
|
54
|
+
.extend('configure', { injected: true }, () => undefined as AppMockConfigureFn | undefined)
|
|
55
|
+
.extend('fusion', async ({ env }) => resolveFusion(env))
|
|
56
|
+
.extend('app', async ({ configure, env, fusion }) =>
|
|
57
|
+
mockAppModules<unknown, AppEnv>(configure, env as AppEnv, fusion),
|
|
58
|
+
)
|
|
59
|
+
.extend('render', ({ fusion, app }) => {
|
|
60
|
+
const wrapper = createAppScopeWrapper({ framework: fusion, app });
|
|
61
|
+
return (ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>) =>
|
|
62
|
+
render(ui, { ...options, wrapper });
|
|
63
|
+
})
|
|
64
|
+
.extend('renderHook', ({ fusion, app }) => {
|
|
65
|
+
const wrapper = createAppScopeWrapper({ framework: fusion, app });
|
|
66
|
+
return <Result, Props = undefined>(
|
|
67
|
+
cb: (initialProps?: Props) => Result,
|
|
68
|
+
options?: Omit<RenderHookOptions<Props>, 'wrapper'>,
|
|
69
|
+
) => renderHook(cb, { ...options, wrapper });
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
export default testApp;
|
package/src/test.tsx
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { testApp as baseTestApp } from './test-app';
|
|
2
|
+
|
|
3
|
+
// resolved at test-time by `appTestVitePlugin` (@equinor/fusion-framework-vitest-plugin-react-app);
|
|
4
|
+
// see virtual-modules.d.ts for the ambient module declarations
|
|
5
|
+
import { manifest, config } from 'virtual:fusion-app-test-env';
|
|
6
|
+
import { configure } from 'virtual:fusion-app-test-configure';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* `vitest`'s `test`, pre-seeded with the application's own manifest, config, and
|
|
10
|
+
* module-configurator, resolved the same way `ffc app build`/`ffc app dev` resolve them.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* Requires `appTestVitePlugin` (`@equinor/fusion-framework-vitest-plugin-react-app`) registered in
|
|
14
|
+
* your `vitest.config.ts` `plugins`, which serves the virtual modules backing this fixture.
|
|
15
|
+
* Running the same test file without the plugin registered fails to resolve those imports.
|
|
16
|
+
*
|
|
17
|
+
* Per-test mocking still works exactly like the base `testApp`: `.extend('configure', ...)` or
|
|
18
|
+
* a per-case `test.override('env', ...)` layers on top of the resolved values.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* import { test } from '@equinor/fusion-framework-vitest-plugin-react-app/test';
|
|
23
|
+
* import { App } from '../App';
|
|
24
|
+
*
|
|
25
|
+
* test('renders the app', async ({ render }) => {
|
|
26
|
+
* const screen = await render(<App />);
|
|
27
|
+
* await expect.element(screen.getByRole('heading')).toBeVisible();
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export const test = baseTestApp
|
|
32
|
+
.extend('env', { injected: true }, { manifest, config })
|
|
33
|
+
.extend('configure', { injected: true }, () => configure);
|
|
34
|
+
|
|
35
|
+
export default test;
|
package/src/version.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare module 'virtual:fusion-app-test-env' {
|
|
2
|
+
import type { AppEnv } from '@equinor/fusion-framework-app';
|
|
3
|
+
|
|
4
|
+
export const manifest: AppEnv['manifest'];
|
|
5
|
+
export const config: AppEnv['config'];
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
declare module 'virtual:fusion-app-test-configure' {
|
|
9
|
+
import type { AppMockConfigureFn } from '@equinor/fusion-framework-app/mock';
|
|
10
|
+
|
|
11
|
+
export const configure: AppMockConfigureFn | undefined;
|
|
12
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"jsx": "react-jsx",
|
|
5
|
+
"outDir": "dist/esm",
|
|
6
|
+
"rootDir": "src",
|
|
7
|
+
"declarationDir": "./dist/types",
|
|
8
|
+
"paths": {
|
|
9
|
+
"*": ["./*"]
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"references": [
|
|
13
|
+
{ "path": "../../cli" },
|
|
14
|
+
{ "path": "../../framework" },
|
|
15
|
+
{ "path": "../../app" },
|
|
16
|
+
{ "path": "../../modules/module" },
|
|
17
|
+
{ "path": "../../modules/app" },
|
|
18
|
+
{ "path": "../../react/framework" },
|
|
19
|
+
{ "path": "../../react/modules/module" },
|
|
20
|
+
{ "path": "../../utils/imports" }
|
|
21
|
+
],
|
|
22
|
+
"include": ["src/**/*"],
|
|
23
|
+
"exclude": ["node_modules", "dist", "src/__tests__/**/*"]
|
|
24
|
+
}
|
package/vitest.config.ts
ADDED