From 8c7f3769a86bed5209ba33b99ac0ee0d39497a0d Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 14 Sep 2023 15:13:18 +0200 Subject: [PATCH 001/105] add vitest to the monorepo - WIP --- code/addons/a11y/vitest.config.ts | 12 + code/addons/actions/vitest.config.ts | 12 + code/addons/backgrounds/vitest.config.ts | 12 + code/addons/controls/vitest.config.ts | 12 + code/addons/docs/vitest.config.ts | 12 + code/addons/essentials/vitest.config.ts | 12 + code/addons/gfm/vitest.config.ts | 12 + code/addons/highlight/vitest.config.ts | 12 + code/addons/interactions/vitest.config.ts | 12 + code/addons/jest/vitest.config.ts | 12 + code/addons/links/vitest.config.ts | 12 + code/addons/measure/vitest.config.ts | 12 + code/addons/outline/vitest.config.ts | 12 + code/addons/storyshots-core/.eslintrc.js | 12 - code/addons/storyshots-core/README.md | 795 ------------------ .../storyshots-core/docs/storyshots-fail.png | Bin 174514 -> 0 bytes .../storyshots-core/docs/storyshots.png | Bin 121731 -> 0 bytes code/addons/storyshots-core/injectFileName.js | 23 - code/addons/storyshots-core/jest.config.js | 12 - code/addons/storyshots-core/package.json | 153 ---- code/addons/storyshots-core/preset.js | 4 - code/addons/storyshots-core/project.json | 6 - .../src/Stories2SnapsConverter.test.ts | 52 -- .../src/Stories2SnapsConverter.ts | 76 -- .../src/api/StoryshotsOptions.ts | 42 - .../src/api/ensureOptionsDefaults.ts | 55 -- code/addons/storyshots-core/src/api/index.ts | 109 --- .../src/api/integrityTestTemplate.ts | 61 -- .../src/api/snapshotsTestsTemplate.ts | 64 -- .../storyshots-core/src/frameworks/Loader.ts | 25 - .../src/frameworks/SupportedFramework.ts | 10 - .../src/frameworks/angular/loader.ts | 70 -- .../src/frameworks/angular/renderTree.ts | 38 - .../src/frameworks/angular/types.ts | 17 - .../src/frameworks/configure.test.ts | 53 -- .../src/frameworks/configure.ts | 157 ---- .../src/frameworks/frameworkLoader.ts | 48 -- .../src/frameworks/hasDependency.ts | 18 - .../src/frameworks/html/loader.ts | 59 -- .../src/frameworks/html/renderTree.ts | 22 - .../storyshots-core/src/frameworks/index.ts | 1 - .../src/frameworks/preact/loader.ts | 65 -- .../src/frameworks/preact/renderTree.ts | 15 - .../src/frameworks/react-native/loader.ts | 44 - .../src/frameworks/react/loader.ts | 55 -- .../src/frameworks/react/renderShallowTree.ts | 10 - .../src/frameworks/react/renderTree.ts | 13 - .../src/frameworks/svelte/loader.ts | 61 -- .../src/frameworks/svelte/renderTree.ts | 41 - .../src/frameworks/vue/loader.ts | 64 -- .../src/frameworks/vue/renderTree.ts | 25 - .../src/frameworks/vue3/loader.ts | 60 -- .../src/frameworks/vue3/renderTree.ts | 23 - .../src/frameworks/web-components/loader.ts | 59 -- .../frameworks/web-components/renderTree.ts | 6 - code/addons/storyshots-core/src/index.ts | 23 - .../addons/storyshots-core/src/test-bodies.ts | 85 -- code/addons/storyshots-core/src/typings.d.ts | 16 - .../storyshot.defaultExport.test.js.snap | 44 - .../storyshot.enzyme.test.js.snap | 56 -- .../storyshot.metadata.test.js.snap | 44 - .../storyshot.shallow.test.js.snap | 31 - .../storyshot.shallowWithOptions.test.js.snap | 31 - ...t.snapshotWithOptionsFunction.test.js.snap | 44 - .../stories/default_export/Extra.stories.jsx | 15 - .../stories/default_export/Text.stories.jsx | 5 - ...s@Another-_-Button@with-_-some-_-emoji.boo | 14 - ...a.stories@Another-_-Button@with-_-text.boo | 9 - .../stories/default_export/main.js | 5 - .../stories/default_export/preview.jsx | 15 - .../exported_metadata/Async.stories.jsx | 34 - .../exported_metadata/Extra.stories.jsx | 15 - .../exported_metadata/Text.stories.jsx | 5 - .../__snapshots__/Extra.stories.storyshot | 34 - ...s@Another-_-Button@with-_-some-_-emoji.boo | 14 - ...a.stories@Another-_-Button@with-_-text.boo | 9 - .../__snapshots__/Text.stories.storyshot | 11 - .../stories/exported_metadata/main.js | 3 - .../stories/exported_metadata/preview.jsx | 15 - .../stories/storyshot.async.test.js | 41 - .../stories/storyshot.configFunc.test.js | 50 -- .../stories/storyshot.defaultExport.test.js | 7 - .../stories/storyshot.enzyme.test.js | 13 - .../stories/storyshot.metadata.test.js | 9 - .../stories/storyshot.renderOnly.test.js | 8 - .../storyshot.renderWithOptions.test.js | 8 - .../stories/storyshot.shallow.test.js | 8 - .../storyshot.shallowWithOptions.test.js | 11 - ...ryshot.snapshotWithOptionsFunction.test.js | 8 - .../storyshots-core/stories/storyshot.test.js | 13 - .../storyshots-core/tsconfig.build.json | 23 - code/addons/storyshots-core/tsconfig.json | 11 - code/addons/storyshots-puppeteer/.eslintrc.js | 5 - code/addons/storyshots-puppeteer/README.md | 361 -------- .../storyshots-puppeteer/jest.config.js | 12 - code/addons/storyshots-puppeteer/package.json | 66 -- code/addons/storyshots-puppeteer/preset.js | 4 - code/addons/storyshots-puppeteer/project.json | 6 - .../src/__tests__/url.test.ts | 65 -- .../storyshots-puppeteer/src/axeTest.ts | 45 - .../addons/storyshots-puppeteer/src/config.ts | 105 --- .../storyshots-puppeteer/src/imageSnapshot.ts | 22 - code/addons/storyshots-puppeteer/src/index.ts | 4 - .../storyshots-puppeteer/src/puppeteerTest.ts | 100 --- code/addons/storyshots-puppeteer/src/url.ts | 8 - .../storyshots-puppeteer/tsconfig.build.json | 23 - .../addons/storyshots-puppeteer/tsconfig.json | 10 - code/addons/storysource/vitest.config.ts | 12 + code/addons/themes/vitest.config.ts | 12 + code/addons/toolbars/vitest.config.ts | 12 + code/addons/viewport/vitest.config.ts | 12 + .../builders/builder-manager/vitest.config.ts | 12 + code/builders/builder-vite/vitest.config.ts | 12 + .../builder-webpack5/vitest.config.ts | 12 + .../channel-postmessage/vitest.config.ts | 12 + .../channel-websocket/vitest.config.ts | 12 + code/frameworks/angular/__vitest.config.ts | 29 + code/frameworks/ember/vitest.config.ts | 12 + .../frameworks/html-webpack5/vitest.config.ts | 12 + code/frameworks/nextjs/vitest.config.ts | 12 + code/frameworks/preact-vite/vitest.config.ts | 12 + .../preact-webpack5/vitest.config.ts | 12 + code/frameworks/react-vite/vitest.config.ts | 12 + .../react-webpack5/vitest.config.ts | 12 + .../server-webpack5/vitest.config.ts | 12 + code/frameworks/svelte-vite/vitest.config.ts | 12 + .../svelte-webpack5/vitest.config.ts | 12 + code/frameworks/sveltekit/vitest.config.ts | 12 + code/frameworks/vue-vite/vitest.config.ts | 12 + code/frameworks/vue-webpack5/vitest.config.ts | 12 + code/frameworks/vue3-vite/vitest.config.ts | 12 + .../frameworks/vue3-webpack5/vitest.config.ts | 12 + .../web-components-vite/vitest.config.ts | 12 + .../web-components-webpack5/vitest.config.ts | 12 + code/lib/channels/vitest.config.ts | 12 + code/lib/cli-sb/vitest.config.ts | 12 + code/lib/cli-storybook/vitest.config.ts | 12 + code/lib/cli/package.json | 2 +- code/lib/cli/vitest.config.ts | 12 + code/lib/client-logger/vitest.config.ts | 12 + code/lib/codemod/vitest.config.ts | 12 + code/lib/core-common/vitest.config.ts | 12 + code/lib/core-events/vitest.config.ts | 12 + code/lib/core-server/vitest.config.ts | 12 + code/lib/core-webpack/vitest.config.ts | 12 + code/lib/csf-plugin/vitest.config.ts | 12 + code/lib/csf-tools/vitest.config.ts | 12 + code/lib/docs-tools/vitest.config.ts | 12 + code/lib/instrumenter/vitest.config.ts | 12 + code/lib/manager-api/vitest.config.ts | 12 + code/lib/node-logger/vitest.config.ts | 12 + code/lib/postinstall/vitest.config.ts | 12 + code/lib/preview-api/vitest.config.ts | 12 + code/lib/preview/vitest.config.ts | 12 + code/lib/router/vitest.config.ts | 12 + code/lib/source-loader/vitest.config.ts | 12 + code/lib/telemetry/vitest.config.ts | 12 + code/lib/theming/vitest.config.ts | 12 + code/lib/types/vitest.config.ts | 12 + code/package.json | 3 +- code/renderers/html/vitest.config.ts | 12 + code/renderers/preact/vitest.config.ts | 12 + code/renderers/react/vitest.config.ts | 12 + code/renderers/server/vitest.config.ts | 12 + code/renderers/svelte/vitest.config.ts | 12 + code/renderers/vue/vitest.config.ts | 12 + code/renderers/vue3/vitest.config.ts | 12 + .../renderers/web-components/vitest.config.ts | 12 + code/ui/blocks/vitest.config.ts | 12 + code/ui/components/vitest.config.ts | 12 + code/ui/manager/src/__tests__/index.test.ts | 1 + code/ui/manager/vitest.config.ts | 12 + code/vitest.config.base.ts | 118 +++ code/vitest.config.browser.ts | 9 + code/vitest.config.node.ts | 7 + code/vitest.config.ts | 16 + code/vitest.workspace.ts | 12 + code/yarn.lock | 370 +++++++- scripts/package.json | 1 + scripts/vitest.config.ts | 1 + scripts/yarn.lock | 448 +++++++++- 181 files changed, 1886 insertions(+), 4165 deletions(-) create mode 100644 code/addons/a11y/vitest.config.ts create mode 100644 code/addons/actions/vitest.config.ts create mode 100644 code/addons/backgrounds/vitest.config.ts create mode 100644 code/addons/controls/vitest.config.ts create mode 100644 code/addons/docs/vitest.config.ts create mode 100644 code/addons/essentials/vitest.config.ts create mode 100644 code/addons/gfm/vitest.config.ts create mode 100644 code/addons/highlight/vitest.config.ts create mode 100644 code/addons/interactions/vitest.config.ts create mode 100644 code/addons/jest/vitest.config.ts create mode 100644 code/addons/links/vitest.config.ts create mode 100644 code/addons/measure/vitest.config.ts create mode 100644 code/addons/outline/vitest.config.ts delete mode 100644 code/addons/storyshots-core/.eslintrc.js delete mode 100644 code/addons/storyshots-core/README.md delete mode 100644 code/addons/storyshots-core/docs/storyshots-fail.png delete mode 100644 code/addons/storyshots-core/docs/storyshots.png delete mode 100644 code/addons/storyshots-core/injectFileName.js delete mode 100644 code/addons/storyshots-core/jest.config.js delete mode 100644 code/addons/storyshots-core/package.json delete mode 100644 code/addons/storyshots-core/preset.js delete mode 100644 code/addons/storyshots-core/project.json delete mode 100644 code/addons/storyshots-core/src/Stories2SnapsConverter.test.ts delete mode 100644 code/addons/storyshots-core/src/Stories2SnapsConverter.ts delete mode 100644 code/addons/storyshots-core/src/api/StoryshotsOptions.ts delete mode 100644 code/addons/storyshots-core/src/api/ensureOptionsDefaults.ts delete mode 100644 code/addons/storyshots-core/src/api/index.ts delete mode 100644 code/addons/storyshots-core/src/api/integrityTestTemplate.ts delete mode 100644 code/addons/storyshots-core/src/api/snapshotsTestsTemplate.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/Loader.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/SupportedFramework.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/angular/loader.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/angular/renderTree.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/angular/types.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/configure.test.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/configure.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/frameworkLoader.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/hasDependency.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/html/loader.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/html/renderTree.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/index.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/preact/loader.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/preact/renderTree.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/react-native/loader.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/react/loader.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/react/renderShallowTree.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/react/renderTree.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/svelte/loader.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/svelte/renderTree.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/vue/loader.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/vue/renderTree.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/vue3/loader.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/vue3/renderTree.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/web-components/loader.ts delete mode 100644 code/addons/storyshots-core/src/frameworks/web-components/renderTree.ts delete mode 100644 code/addons/storyshots-core/src/index.ts delete mode 100644 code/addons/storyshots-core/src/test-bodies.ts delete mode 100644 code/addons/storyshots-core/src/typings.d.ts delete mode 100644 code/addons/storyshots-core/stories/__snapshots__/storyshot.defaultExport.test.js.snap delete mode 100644 code/addons/storyshots-core/stories/__snapshots__/storyshot.enzyme.test.js.snap delete mode 100644 code/addons/storyshots-core/stories/__snapshots__/storyshot.metadata.test.js.snap delete mode 100644 code/addons/storyshots-core/stories/__snapshots__/storyshot.shallow.test.js.snap delete mode 100644 code/addons/storyshots-core/stories/__snapshots__/storyshot.shallowWithOptions.test.js.snap delete mode 100644 code/addons/storyshots-core/stories/__snapshots__/storyshot.snapshotWithOptionsFunction.test.js.snap delete mode 100644 code/addons/storyshots-core/stories/default_export/Extra.stories.jsx delete mode 100644 code/addons/storyshots-core/stories/default_export/Text.stories.jsx delete mode 100644 code/addons/storyshots-core/stories/default_export/__snapshots__/Extra.stories@Another-_-Button@with-_-some-_-emoji.boo delete mode 100644 code/addons/storyshots-core/stories/default_export/__snapshots__/Extra.stories@Another-_-Button@with-_-text.boo delete mode 100644 code/addons/storyshots-core/stories/default_export/main.js delete mode 100644 code/addons/storyshots-core/stories/default_export/preview.jsx delete mode 100644 code/addons/storyshots-core/stories/exported_metadata/Async.stories.jsx delete mode 100644 code/addons/storyshots-core/stories/exported_metadata/Extra.stories.jsx delete mode 100644 code/addons/storyshots-core/stories/exported_metadata/Text.stories.jsx delete mode 100644 code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Extra.stories.storyshot delete mode 100644 code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Extra.stories@Another-_-Button@with-_-some-_-emoji.boo delete mode 100644 code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Extra.stories@Another-_-Button@with-_-text.boo delete mode 100644 code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Text.stories.storyshot delete mode 100644 code/addons/storyshots-core/stories/exported_metadata/main.js delete mode 100644 code/addons/storyshots-core/stories/exported_metadata/preview.jsx delete mode 100644 code/addons/storyshots-core/stories/storyshot.async.test.js delete mode 100644 code/addons/storyshots-core/stories/storyshot.configFunc.test.js delete mode 100644 code/addons/storyshots-core/stories/storyshot.defaultExport.test.js delete mode 100644 code/addons/storyshots-core/stories/storyshot.enzyme.test.js delete mode 100644 code/addons/storyshots-core/stories/storyshot.metadata.test.js delete mode 100644 code/addons/storyshots-core/stories/storyshot.renderOnly.test.js delete mode 100644 code/addons/storyshots-core/stories/storyshot.renderWithOptions.test.js delete mode 100644 code/addons/storyshots-core/stories/storyshot.shallow.test.js delete mode 100644 code/addons/storyshots-core/stories/storyshot.shallowWithOptions.test.js delete mode 100644 code/addons/storyshots-core/stories/storyshot.snapshotWithOptionsFunction.test.js delete mode 100644 code/addons/storyshots-core/stories/storyshot.test.js delete mode 100644 code/addons/storyshots-core/tsconfig.build.json delete mode 100644 code/addons/storyshots-core/tsconfig.json delete mode 100644 code/addons/storyshots-puppeteer/.eslintrc.js delete mode 100644 code/addons/storyshots-puppeteer/README.md delete mode 100644 code/addons/storyshots-puppeteer/jest.config.js delete mode 100644 code/addons/storyshots-puppeteer/package.json delete mode 100644 code/addons/storyshots-puppeteer/preset.js delete mode 100644 code/addons/storyshots-puppeteer/project.json delete mode 100644 code/addons/storyshots-puppeteer/src/__tests__/url.test.ts delete mode 100644 code/addons/storyshots-puppeteer/src/axeTest.ts delete mode 100644 code/addons/storyshots-puppeteer/src/config.ts delete mode 100644 code/addons/storyshots-puppeteer/src/imageSnapshot.ts delete mode 100644 code/addons/storyshots-puppeteer/src/index.ts delete mode 100644 code/addons/storyshots-puppeteer/src/puppeteerTest.ts delete mode 100644 code/addons/storyshots-puppeteer/src/url.ts delete mode 100644 code/addons/storyshots-puppeteer/tsconfig.build.json delete mode 100644 code/addons/storyshots-puppeteer/tsconfig.json create mode 100644 code/addons/storysource/vitest.config.ts create mode 100644 code/addons/themes/vitest.config.ts create mode 100644 code/addons/toolbars/vitest.config.ts create mode 100644 code/addons/viewport/vitest.config.ts create mode 100644 code/builders/builder-manager/vitest.config.ts create mode 100644 code/builders/builder-vite/vitest.config.ts create mode 100644 code/builders/builder-webpack5/vitest.config.ts create mode 100644 code/deprecated/channel-postmessage/vitest.config.ts create mode 100644 code/deprecated/channel-websocket/vitest.config.ts create mode 100644 code/frameworks/angular/__vitest.config.ts create mode 100644 code/frameworks/ember/vitest.config.ts create mode 100644 code/frameworks/html-webpack5/vitest.config.ts create mode 100644 code/frameworks/nextjs/vitest.config.ts create mode 100644 code/frameworks/preact-vite/vitest.config.ts create mode 100644 code/frameworks/preact-webpack5/vitest.config.ts create mode 100644 code/frameworks/react-vite/vitest.config.ts create mode 100644 code/frameworks/react-webpack5/vitest.config.ts create mode 100644 code/frameworks/server-webpack5/vitest.config.ts create mode 100644 code/frameworks/svelte-vite/vitest.config.ts create mode 100644 code/frameworks/svelte-webpack5/vitest.config.ts create mode 100644 code/frameworks/sveltekit/vitest.config.ts create mode 100644 code/frameworks/vue-vite/vitest.config.ts create mode 100644 code/frameworks/vue-webpack5/vitest.config.ts create mode 100644 code/frameworks/vue3-vite/vitest.config.ts create mode 100644 code/frameworks/vue3-webpack5/vitest.config.ts create mode 100644 code/frameworks/web-components-vite/vitest.config.ts create mode 100644 code/frameworks/web-components-webpack5/vitest.config.ts create mode 100644 code/lib/channels/vitest.config.ts create mode 100644 code/lib/cli-sb/vitest.config.ts create mode 100644 code/lib/cli-storybook/vitest.config.ts create mode 100644 code/lib/cli/vitest.config.ts create mode 100644 code/lib/client-logger/vitest.config.ts create mode 100644 code/lib/codemod/vitest.config.ts create mode 100644 code/lib/core-common/vitest.config.ts create mode 100644 code/lib/core-events/vitest.config.ts create mode 100644 code/lib/core-server/vitest.config.ts create mode 100644 code/lib/core-webpack/vitest.config.ts create mode 100644 code/lib/csf-plugin/vitest.config.ts create mode 100644 code/lib/csf-tools/vitest.config.ts create mode 100644 code/lib/docs-tools/vitest.config.ts create mode 100644 code/lib/instrumenter/vitest.config.ts create mode 100644 code/lib/manager-api/vitest.config.ts create mode 100644 code/lib/node-logger/vitest.config.ts create mode 100644 code/lib/postinstall/vitest.config.ts create mode 100644 code/lib/preview-api/vitest.config.ts create mode 100644 code/lib/preview/vitest.config.ts create mode 100644 code/lib/router/vitest.config.ts create mode 100644 code/lib/source-loader/vitest.config.ts create mode 100644 code/lib/telemetry/vitest.config.ts create mode 100644 code/lib/theming/vitest.config.ts create mode 100644 code/lib/types/vitest.config.ts create mode 100644 code/renderers/html/vitest.config.ts create mode 100644 code/renderers/preact/vitest.config.ts create mode 100644 code/renderers/react/vitest.config.ts create mode 100644 code/renderers/server/vitest.config.ts create mode 100644 code/renderers/svelte/vitest.config.ts create mode 100644 code/renderers/vue/vitest.config.ts create mode 100644 code/renderers/vue3/vitest.config.ts create mode 100644 code/renderers/web-components/vitest.config.ts create mode 100644 code/ui/blocks/vitest.config.ts create mode 100644 code/ui/components/vitest.config.ts create mode 100644 code/ui/manager/vitest.config.ts create mode 100644 code/vitest.config.base.ts create mode 100644 code/vitest.config.browser.ts create mode 100644 code/vitest.config.node.ts create mode 100644 code/vitest.config.ts create mode 100644 code/vitest.workspace.ts create mode 100644 scripts/vitest.config.ts diff --git a/code/addons/a11y/vitest.config.ts b/code/addons/a11y/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/a11y/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/actions/vitest.config.ts b/code/addons/actions/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/actions/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/backgrounds/vitest.config.ts b/code/addons/backgrounds/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/backgrounds/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/controls/vitest.config.ts b/code/addons/controls/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/controls/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/docs/vitest.config.ts b/code/addons/docs/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/docs/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/essentials/vitest.config.ts b/code/addons/essentials/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/essentials/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/gfm/vitest.config.ts b/code/addons/gfm/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/gfm/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/highlight/vitest.config.ts b/code/addons/highlight/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/highlight/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/interactions/vitest.config.ts b/code/addons/interactions/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/interactions/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/jest/vitest.config.ts b/code/addons/jest/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/jest/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/links/vitest.config.ts b/code/addons/links/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/links/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/measure/vitest.config.ts b/code/addons/measure/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/measure/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/outline/vitest.config.ts b/code/addons/outline/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/outline/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/storyshots-core/.eslintrc.js b/code/addons/storyshots-core/.eslintrc.js deleted file mode 100644 index 79e820da0d30..000000000000 --- a/code/addons/storyshots-core/.eslintrc.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - settings: { - 'import/core-modules': [ - '@storybook/angular', - '@storybook/html', - '@storybook/react', - '@storybook/preact', - '@storybook/vue', - '@storybook/svelte', - ], - }, -}; diff --git a/code/addons/storyshots-core/README.md b/code/addons/storyshots-core/README.md deleted file mode 100644 index 8a20edd2c7f3..000000000000 --- a/code/addons/storyshots-core/README.md +++ /dev/null @@ -1,795 +0,0 @@ -# StoryShots - -StoryShots adds automatic Jest Snapshot Testing for [Storybook](https://storybook.js.org/). - -[Framework Support](https://storybook.js.org/docs/react/api/frameworks-feature-support) - -![StoryShots In Action](https://raw.githubusercontent.com/storybookjs/storybook/next/code/addons/storyshots/storyshots-core/docs/storyshots-fail.png) - -To use StoryShots, you must use your existing Storybook stories as the input for Jest Snapshot Testing. - -## Getting Started - -Add the following module into your app. - -```sh -yarn add @storybook/addon-storyshots --dev -``` - -## Configure Storyshots for HTML snapshots - -Create a new test file with the name `Storyshots.test.js`. (Or whatever the name you prefer, as long as it matches Jest's config [`testMatch`](http://facebook.github.io/jest/docs/en/configuration.html#testmatch-array-string)). -Then add following content to it: - -```js -import initStoryshots from '@storybook/addon-storyshots'; - -initStoryshots(); -``` - -That's all. - -Now run your Jest test command. (Usually, `npm test`.) Then you can see all of your stories are converted as Jest snapshot tests. - -![Screenshot](https://raw.githubusercontent.com/storybookjs/storybook/next/code/addons/storyshots/storyshots-core/docs/storyshots.png) - -### Testing stories that rely on addon-added decorators - -If you have stories in your Storybook that can only render inside a decorator (for instance the [`apollo-storybook-decorator`](https://github.com/abhiaiyer91/apollo-storybook-decorator)), you'll need to ensure those decorators are applied in Storyshots. - -If you export those decorators from your `.storybook/preview.js` then Storyshots will apply those decorators for you in the same way that Storybook does. However if the addon _automatically_ adds the decorator for you (which is a new feature in Storybook 6.0), you will find the decorator does not get added in Storyshots. This is a limitation in Storyshots currently. - -To ensure such decorators get added, export them from `.storybook/preview.js`: - -```js -import addonDecorator from 'some-addon'; - -export const decorators = [addonDecorator]; -``` - -## Configure your app for Jest - -In many cases, for example Create React App, it's already configured for Jest. You need to create a filename with the extension `.test.js`. - -If you still need to configure jest you can use the resources mentioned below: - -- [Getting Started - Jest Official Documentation](https://facebook.github.io/jest/docs/en/getting-started.html) -- [Javascript Testing with Jest - Egghead](https://egghead.io/lessons/javascript-test-javascript-with-jest). **_paid content_** - -> Note: If you use React 16, you'll need to follow [these additional instructions](https://github.com/facebook/react/issues/9102#issuecomment-283873039). -> -> Note: Make sure you have added the `json` extension to `moduleFileExtensions` in `jest.config.json`. If this is missing it leads to the [following error](https://github.com/storybookjs/storybook/issues/3728): `Cannot find module 'spdx-license-ids' from 'scan.js'`. -> -> Note: Please make sure you are using `jsdom` as the testEnvironment on your jest config file. - -### Configure Jest to work with Webpack's [require.context()](https://webpack.js.org/guides/dependency-management/#require-context) - -**NOTE**: if you are using Storybook 5.3's `main.js` to list story files, this is no longer needed. - -Sometimes it's useful to configure Storybook with Webpack's require.context feature. You could be loading stories [one of two ways](https://github.com/storybookjs/storybook/blob/release/5.3/docs/src/pages/basics/writing-stories/index.md#loading-stories). - -1. If you're using the `storiesOf` API, you can integrate it this way: - -```js -import { configure } from '@storybook/react'; - -const req = require.context('../stories', true, /\.stories\.js$/); // <- import all the stories at once - -function loadStories() { - req.keys().forEach((filename) => req(filename)); -} - -configure(loadStories, module); -``` - -2. If you're using Component Story Format (CSF), you'll integrate it like so: - -```js -import { configure } from '@storybook/react'; - -const req = require.context('../stories', true, /\.stories\.js$/); // <- import all the stories at once - -configure(req, module); -``` - -The problem here is that it will work only during the build with webpack, -other tools may lack this feature. Since Storyshot is running under Jest, -we need to polyfill this functionality to work with Jest. The easiest -way is to integrate it to babel. - -You can do this with a Babel [plugin](https://github.com/smrq/babel-plugin-require-context-hook) or [macro](https://github.com/storybookjs/require-context.macro). If you're using `create-react-app` (v2 or above), use the macro. - -#### Option 1: Plugin - -First, install it: - -```sh -yarn add babel-plugin-require-context-hook --dev -``` - -Next, it needs to be registered and loaded before each test. To register it, create a file with the following register function `.jest/register-context.js`: - -```js -import registerRequireContextHook from 'babel-plugin-require-context-hook/register'; -registerRequireContextHook(); -``` - -That file needs to be added as a setup file for Jest. To do that, add (or create) a property in Jest's config called [`setupFiles`](https://jestjs.io/docs/en/configuration.html#setupfiles-array). Add the file name and path to this array. - -```json -setupFiles: ['/.jest/register-context.js'] -``` - -Finally, add the plugin to `.babelrc`: - -```json -{ - "presets": ["..."], - "plugins": ["..."], - "env": { - "test": { - "plugins": ["require-context-hook"] - } - } -} -``` - -The plugin is only added to the test environment otherwise it could replace webpack's version of it. - -#### Option 2: Macro - -First, install it: - -```sh -yarn add require-context.macro --dev -``` - -Now, inside of your Storybook config file, import the macro and run it in place of `require.context`, like so: - -```javascript -import requireContext from 'require-context.macro'; - -// const req = require.context('../stories', true, /\.stories\.js$/); <-- replaced -const req = requireContext('../stories', true, /\.stories\.js$/); -``` - -### Configure Jest for React - -StoryShots addon for React is dependent on [react-test-renderer](https://github.com/facebook/react/tree/master/packages/react-test-renderer), but -[doesn't](#deps-issue) install it, so you need to install it separately. - -```sh -yarn add react-test-renderer --dev -``` - -### Configure Jest for Angular - -StoryShots addon for Angular is dependent on [jest-preset-angular](https://github.com/thymikee/jest-preset-angular), but -[doesn't](#deps-issue) install it, so you need to install it separately. - -```sh -yarn add jest-preset-angular -``` - -If you already use Jest for testing your angular app - probably you already have the needed jest configuration. -Anyway you can add these lines to your jest config: - -```js -module.exports = { - globals: { - __TRANSFORM_HTML__: true, - }, - transform: { - '^.+\\.jsx?$': 'babel-jest', - '^.+\\.(ts|html)$': '/node_modules/jest-preset-angular/preprocessor.js', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node', '.html'], -}; -``` - -### Configure Jest for Vue - -StoryShots addon for Vue is dependent on [jest-vue-preprocessor](https://github.com/vire/jest-vue-preprocessor), but -[doesn't](#deps-issue) install it, so you need to install it separately. - -```sh -yarn add jest-vue-preprocessor -``` - -If you already use Jest for testing your vue app - probably you already have the needed jest configuration. -Anyway you can add these lines to your jest config: - -```js -module.exports = { - transform: { - '^.+\\.jsx?$': 'babel-jest', - '.*\\.(vue)$': '/node_modules/jest-vue-preprocessor', - }, - transformIgnorePatterns: ['/node_modules/(?!(@storybook/.*\\.vue$))'], - moduleFileExtensions: ['vue', 'js', 'jsx', 'json', 'node'], -}; -``` - -### Configure Jest for Vue 3 - -StoryShots addon for Vue is dependent on [vue-jest v5](https://www.npmjs.com/package/vue-jest/v/5.0.0-alpha.8), but -[doesn't](#deps-issue) install it, so you need to install it separately. - -```sh -yarn add vue-jest@5.0.0-alpha.8 -``` - -If you already use Jest for testing your vue app - probably you already have the needed jest configuration. -Anyway you can add these lines to your jest config: - -```js -module.exports = { - transform: { - '^.+\\.jsx?$': 'babel-jest', - '.*\\.(vue)$': '/node_modules/vue-jest', - }, - transformIgnorePatterns: ['/node_modules/(?!(@storybook/.*\\.vue$))'], - moduleFileExtensions: ['vue', 'js', 'jsx', 'json', 'node'], -}; -``` - -### Configure Jest for Preact - -StoryShots addon for Preact is dependent on [preact-render-to-string](https://github.com/preactjs/preact-render-to-string), but -[doesn't](#deps-issue) install it, so you need to install it separately. - -```sh -yarn add preact-render-to-string --dev -``` - -### Configure Jest for Web Components - -StoryShots addon for Web Components requires [jsdom](https://github.com/jsdom/jsdom) 16 or later to fully support the -web component shadow dom. To use jsdom 16 or later you can set the Jest `testEnvironment` configuration key to -`jest-environment-jsdom-sixteen`. This should work back to Jest 24 and is the default in Jest 26 and later. - -### Configure Jest for MDX Docs Add-On Stories - -If using the [Docs add-on](../../docs/README.md) with -[MDX stories](../../docs/docs/mdx.md) you will need -to configure Jest to transform MDX stories into something Storyshots can understand: - -Add the following to your Jest configuration: - -```json -{ - "transform": { - "^.+\\.[tj]sx?$": "babel-jest", - "^.+\\.mdx?$": "@storybook/addon-docs/jest-transform-mdx" - } -} -``` - -### Why don't we install dependencies of each framework ? - -Storyshots addon is currently supporting React, Angular and Vue. Each framework needs its own packages to be integrated with Jest. We don't want people that use only React will need to bring other dependencies that do not make sense for them. - -`dependencies` - will installed an exact version of the particular dep - Storyshots can work with different versions of the same framework (let's say React v16 and React v15), that have to be compatible with a version of its plugin (react-test-renderer). - -`optionalDependencies` - behaves like a regular dependency, but do not fail the installation in case there is a problem to bring the dep. - -`peerDependencies` - listing all the deps in peer will trigger warnings during the installation - we don't want users to install unneeded deps by hand. - -`optionalPeerDependencies` - unfortunately there is nothing like this =( - -For more information read npm [docs](https://docs.npmjs.com/files/package.json#dependencies) - -### Using `createNodeMock` to mock refs - -`react-test-renderer` doesn't provide refs for rendered components. By -default, it returns null when the refs are referenced. In order to mock -out elements that rely on refs, you will have to use the -`createNodeMock` option [added to React](https://reactjs.org/blog/2016/11/16/react-v15.4.0.html#mocking-refs-for-snapshot-testing) starting with version 15.4.0. - -Here is an example of how to specify the `createNodeMock` option in Storyshots: - -```js -import initStoryshots, { snapshotWithOptions } from '@storybook/addon-storyshots'; -import TextareaThatUsesRefs from '../component/TextareaThatUsesRefs'; - -initStoryshots({ - test: snapshotWithOptions({ - createNodeMock: (element) => { - if (element.type === TextareaThatUsesRefs) { - return document.createElement('textarea'); - } - }, - }), -}); -``` - -Provide a function to have story-specific options: - -```js -initStoryshots({ - test: snapshotWithOptions((story) => ({ - createNodeMock: (element) => { - if (story.name == 'foobar') { - return null; - } - return element; - }, - })), -}); -``` - -### Using a custom renderer - -By design, [`react-test-renderer` doesn't use a browser environment or JSDOM](https://github.com/facebook/react/issues/20589). Because of this difference, some stories might render in your browser, but not in Storyshots. If you encounter this problem, you may want to switch for an higher level renderer such as `mount` from Enzyme or `render` from React Testing Library. - -#### Example with React Testing Library - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { render } from '@testing-library/react'; - -const reactTestingLibrarySerializer = { - print: (val, serialize, indent) => serialize(val.container.firstChild), - test: (val) => val && val.hasOwnProperty('container'), -}; - -initStoryshots({ - renderer: render, - snapshotSerializers: [reactTestingLibrarySerializer], -}); -``` - -#### Example with Enzyme - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { mount } from 'enzyme'; - -initStoryshots({ - renderer: mount, -}); -``` - -If you are using enzyme, you need to make sure jest knows how to serialize rendered components. -For that, you can pass an enzyme-compatible snapshotSerializer (like [enzyme-to-json](https://github.com/adriantoine/enzyme-to-json), [jest-serializer-enzyme](https://github.com/rogeliog/jest-serializer-enzyme) etc.) with the `snapshotSerializer` option (see below). - -### StoryShots for async rendered components - -You can make use of [Jest done callback](https://jestjs.io/docs/en/asynchronous) to test components that render asynchronously. This callback is passed as param to test method passed to `initStoryshots(...)` when the `asyncJest` option is given as true. - -#### Example - -The following example shows how we can use the **done callback** to take StoryShots of a [Relay](http://facebook.github.io/relay/) component. Each kind of story is written into its own snapshot file with the use of `getSnapshotFileName`. - -Add _stories of UserForm_ in the file: UserForm.story.jsx - -```jsx -/* global module */ -import React from 'react'; -import { QueryRenderer } from 'react-relay'; -import { storiesOf } from '@storybook/react'; - -// Use the same queries used in YOUR app routes -import { newUserFormQuery, editUserFormQuery } from 'app/routes'; -import UserFormContainer from 'app/users/UserForm'; - -// YOUR function to generate a Relay Environment mock. -// See https://github.com/1stdibs/relay-mock-network-layer for more info -import getEnvironment from 'test/support/relay-environment-mock'; - -// User test data YOU generated for your tests -import { user } from 'test/support/data/index'; - -// Use this function to return a new Environment for each story -const Environment = () => - getEnvironment({ - mocks: { - Node: () => ({ __typename: 'User' }), - User: () => user, - }, - }); - -/** - - NOTICE that the QueryRenderer render its children via its render props. - - If we don't take the StoryShot async then we will only see the QueryRenderer in the StoryShot. - - The following QueryRenderer returns null in the first render (it can be a loading indicator instead in real file) and then when it gets the data to respond to query, it renders again with props containing the data for the Component - */ -const renderStory = (query, environment, variables = {}) => ( - { - if (error) { - console.error(error); - } else if (props) { - return ; - } - return null; - }} - /> -); - -storiesOf('users/UserForm', module) - .add('New User', () => { - const environment = new Environment(); - return renderStory(newUserFormQuery, environment); - }) - .add('Editing User', () => { - const environment = new Environment(); - return renderStory(editUserFormQuery, environment, { id: user.id }); - }); -``` - -Then, init Storyshots for async component in the file: StoryShots.test.js - -```jsx -import initStoryshots, { Stories2SnapsConverter } from '@storybook/addon-storyshots'; -import { mount } from 'enzyme'; -import toJson from 'enzyme-to-json'; - -// Runner -initStoryshots({ - asyncJest: true, // this is the option that activates the async behaviour - test: ({ - story, - context, - done, // --> callback passed to test method when asyncJest option is true - }) => { - const converter = new Stories2SnapsConverter(); - const snapshotFilename = converter.getSnapshotFileName(context); - const storyElement = story.render(); - - // mount the story - const tree = mount(storyElement); - - // wait until the mount is updated, in our app mostly by Relay - // but maybe something else updating the state of the component - // somewhere - const waitTime = 1; - setTimeout(() => { - if (snapshotFilename) { - expect(toJson(tree.update())).toMatchSpecificSnapshot(snapshotFilename); - } - - done(); - }, waitTime); - }, - // other options here -}); -``` - -NOTICE that When using the `asyncJest: true` option, you also must specify a `test` method that calls the `done()` callback. - -This is a really powerful technique to write stories of Relay components because it integrates data fetching with component rendering. So instead of passing data props manually, we can let Relay do the job for us as it does in our application. - -Whenever you change your data requirements by adding (and rendering) or (accidentally) deleting fields in your graphql query fragments, you'll get a different snapshot and thus an error in the StoryShot test. - -## Using a custom directory - -Depending on your project's needs, you can configure the `@storybook/addon-storyshots` to use a custom directory for the snapshots. You can read more about it in the [official docs](https://storybook.js.org/docs/react/writing-tests/snapshot-testing). - -## Options - -### `config` - -The `config` parameter must be a function that helps to configure storybook like the `preview.js` does. -If it's not specified, storyshots will try to use [configPath](#configPath) parameter. - -```js -import initStoryshots from '@storybook/addon-storyshots'; - -initStoryshots({ - config: ({ configure }) => - configure(() => { - require('../stories/Button.story.js'); - }, module), -}); -``` - -### `configPath` - -By default, Storyshots assumes the config directory path for your project as below: - -- Storybook for React: `.storybook` -- Storybook for React Native: `storybook` - -If you are using a different config directory path, you could change it like this: - -```js -import initStoryshots from '@storybook/addon-storyshots'; - -initStoryshots({ - configPath: '.my-storybook-config-dir', -}); -``` - -Or, as a more complex example, if we have a package in our `lerna` project called `app` with the path `./packages/app/src/__tests__/storyshots.js` and the storybook config directory `./packages/app/.storybook`: - -```js -import path from 'path'; -import initStoryshots from '@storybook/addon-storyshots'; - -initStoryshots({ configPath: path.resolve(__dirname, '../../.storybook') }); -``` - -`configPath` can also specify path to the `preview.js` itself. In this case, config directory will be -a base directory of the `configPath`. It may be useful when the `preview.js` for test should differ from the -original one. It also may be useful for separating tests to different test configs: - -```js -initStoryshots({ - configPath: '.my-storybook-config-dir/testConfig1.js', -}); - -initStoryshots({ - configPath: '.my-storybook-config-dir/testConfig2.js', -}); -``` - -### `suite` - -By default, Storyshots groups stories inside a Jest test suite called "Storyshots". You could change it like this: - -```js -import initStoryshots from '@storybook/addon-storyshots'; - -initStoryshots({ - suite: 'MyStoryshots', -}); -``` - -### `storyKindRegex` - -If you'd like to only run a subset of the stories for your snapshot tests based on the story's kind: - -```js -import initStoryshots from '@storybook/addon-storyshots'; - -initStoryshots({ - storyKindRegex: /^MyComponent$/, -}); -``` - -This can be useful if you want to separate the snapshots in directories next to each component. See an example [here](https://github.com/storybookjs/storybook/issues/892). - -If you want to run all stories except stories of a specific kind, you can write an inverse regex which is true for all kinds except those with a specific word such as `DontTest` - -```js -import initStoryshots from '@storybook/addon-storyshots'; - -initStoryshots({ - storyKindRegex: /^((?!.*?DontTest).)*$/, -}); -``` - -This can be useful while testing react components which make use of the findDomNode API since they always fail with snapshot testing -while using react-test-renderer see [here](https://github.com/facebook/react/issues/8324) - -### `storyNameRegex` - -If you'd like to only run a subset of the stories for your snapshot tests based on the story's name: - -```js -import initStoryshots from '@storybook/addon-storyshots'; - -initStoryshots({ - storyNameRegex: /buttons/, -}); -``` - -### `framework` - -If you are running tests from outside of your app's directory, storyshots' detection of which framework you are using may fail. Pass `"react"` or `"react-native"` to short-circuit this. - -For example: - -```js -// storybook.test.js - -import path from 'path'; -import initStoryshots from '@storybook/addon-storyshots'; - -initStoryshots({ - framework: 'react', // Manually specify the project's framework - configPath: path.join(__dirname, '.storybook'), - integrityOptions: { cwd: path.join(__dirname, 'src', 'stories') }, - // Other configurations -}); -``` - -Use this table as a reference for manually specifying the framework. - -| angular | html | preact | -| ------- | ------------ | -------------- | -| react | react-native | vue3 | -| svelte | vue | web-components | - -### `test` - -Run a custom test function for each story, rather than the default (a vanilla snapshot test). -Setting `test` will take precedence over the `renderer` option. -You can still overwrite what renderer is used for the test function: - -```js -import initStoryshots, { renderWithOptions } from '@storybook/addon-storyshots'; -import { mount } from 'enzyme'; - -initStoryshots({ - test: renderWithOptions({ - renderer: mount, - }), -}); -``` - -### `renderer` - -Pass a custom renderer (such as enzymes `mount`) to record snapshots. -This may be necessary if you want to use React features that are not supported by the default test renderer, -such as **ref** or **Portals**. -Note that setting `test` overrides `renderer`. - -### `snapshotSerializers` - -Pass an array of snapshotSerializers to the jest runtime that serializes your story (such as enzyme-to-json). - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { createSerializer } from 'enzyme-to-json'; - -initStoryshots({ - renderer: mount, - snapshotSerializers: [createSerializer()], -}); -``` - -This option needs to be set if either: - -- the multiSnapshot function is used to create multiple snapshot files (i.e. one per story), since it ignores any serializers specified in your jest config. -- serializers not specified in your jest config should be used when snapshotting stories. - -### `serializer` (deprecated) - -Pass a custom serializer (such as enzyme-to-json) to serialize components to snapshot-comparable data. The functionality of this option is completely covered by [snapshotSerializers](#snapshotserializers) which should be used instead. - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import toJSON from 'enzyme-to-json'; - -initStoryshots({ - renderer: mount, - serializer: toJSON, -}); -``` - -This option only needs to be set if the default `snapshotSerializers` is not set in your jest config. - -### `stories2snapsConverter` - -This parameter should be an instance of the [`Stories2SnapsConverter`](src/Stories2SnapsConverter.js) (or a derived from it) Class that is used to convert story-file name to snapshot-file name and vice versa. - -By default, the instance of this class is created with these default options: - -```js -{ - snapshotsDirName: '__snapshots__', - snapshotExtension: '.storyshot', - storiesExtensions: ['.js', '.jsx', '.ts', '.tsx'], -} -``` - -This class might be overridden to extend the existing conversion functionality or instantiated to provide different options: - -```js -import initStoryshots, { Stories2SnapsConverter } from '@storybook/addon-storyshots'; - -initStoryshots({ - stories2snapsConverter: new Stories2SnapsConverter({ - snapshotExtension: '.storypuke', - storiesExtensions: ['.foo'], - }), -}); -``` - -## Exports - -Apart from the default export (`initStoryshots`), Storyshots also exports some named test functions (see the `test` option above): - -### `snapshot` - -The default, render the story as normal and take a Jest snapshot. - -### `renderOnly` - -Just render the story, don't check the output at all. This is useful as a low-effort way of smoke testing your -components to ensure they do not error. - -### `snapshotWithOptions(options)` - -Like the default, but allows you to specify a set of options for the test renderer. [See for example here](https://github.com/storybookjs/storybook/blob/b915b5439786e0edb17d7f5ab404bba9f7919381/examples/test-cra/src/storyshots.test.js#L14-L16). - -### `renderWithOptions(options)` - -Like the default, but allows you to specify a set of options for the renderer, just like `snapshotWithOptions`. - -### `multiSnapshotWithOptions(options)` - -Like `snapshotWithOptions`, but generate a separate snapshot file for each stories file rather than a single monolithic file (as is the convention in Jest). This makes it dramatically easier to review changes. If you'd like the benefit of separate snapshot files, but don't have custom options to pass, you can pass an empty object. -If you use [Component Story Format](https://storybook.js.org/docs/react/api/csf), you may also need to add an additional Jest transform to automate detecting story file names: - -```js -// jest.config.js -export default { - transform: { - '^.+\\.stories\\.jsx?$': '@storybook/addon-storyshots/injectFileName', - '^.+\\.jsx?$': 'babel-jest', - }, -}; -``` - -#### integrityOptions - -This option is useful when running test with `multiSnapshotWithOptions(options)` in order to track snapshots are matching the stories. (disabled by default). -The value is a [settings](https://github.com/isaacs/node-glob#options) to a `glob` object, that searches for the snapshot files. - -```js -initStoryshots({ - integrityOptions: { cwd: __dirname }, // it will start searching from the current directory - test: multiSnapshotWithOptions(), -}); -``` - -### `shallowSnapshot` - -Take a snapshot of a shallow-rendered version of the component. Note that this option will be overridden if you pass a `renderer` option. - -### `Stories2SnapsConverter` - -This is a class that generates snapshot's name based on the story (kind, story & filename) and vice versa. - -###### Example: - -Let's say we wanted to create a test function for shallow && multi-file snapshots: - -```js -import initStoryshots, { Stories2SnapsConverter } from '@storybook/addon-storyshots'; -import { shallow } from 'enzyme'; -import toJson from 'enzyme-to-json'; - -const converter = new Stories2SnapsConverter(); - -initStoryshots({ - test: ({ story, context }) => { - const snapshotFileName = converter.getSnapshotFileName(context); - const storyElement = story.render(); - const shallowTree = shallow(storyElement); - - if (snapshotFileName) { - expect(toJson(shallowTree)).toMatchSpecificSnapshot(snapshotFileName); - } - }, -}); -``` - -### `asyncJest` - -Enables Jest `done()` callback in the StoryShots tests for async testing. See [StoryShots for async rendered components](#storyshots-for-async-rendered-components) for more info. - -## Story Parameters - -### `disable` - -Some stories are difficult or impossible to snapshot, such as those covering components that use external DOM-modifying libraries, and those that deliberately throw errors. It is possible to skip stories like these by giving them a parameter of `storyshots: {disable: true}`. There is also a shorthand for this, `storyshots: false`. - -```js -export const Exception = () => { - throw new Error('storyFn threw an error! WHOOPS'); -}; -Exception.storyName = 'story throws exception'; -Exception.parameters = { - storyshots: { disable: true }, -}; -``` diff --git a/code/addons/storyshots-core/docs/storyshots-fail.png b/code/addons/storyshots-core/docs/storyshots-fail.png deleted file mode 100644 index a85498d2ff2fdc909e866b4575b770e5b886bbc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174514 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%0APMLn=ALSqdFky-gmV?76ctVgv>BM9JvuKnr} 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.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 z⁢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 L`njxgN@xNAJ)fss diff --git a/code/addons/storyshots-core/injectFileName.js b/code/addons/storyshots-core/injectFileName.js deleted file mode 100644 index 991bce4fc5f3..000000000000 --- a/code/addons/storyshots-core/injectFileName.js +++ /dev/null @@ -1,23 +0,0 @@ -const { ScriptTransformer } = require('@jest/transform'); - -const getNextTransformer = (fileName, config) => { - const self = config.transform.find(([pattern]) => new RegExp(pattern).test(fileName)); - return new ScriptTransformer({ - ...config, - transform: config.transform.filter((entry) => entry !== self), - }); -}; - -module.exports = { - process(src, fileName, config, { instrument }) { - const transformer = getNextTransformer(fileName, config); - const { code } = transformer.transformSource(fileName, src, instrument); - - return `${code}; -if(exports.default != null) { - exports.default.parameters = exports.default.parameters || {}; - exports.default.parameters.fileName = '${fileName.replace(/\\/g, '\\\\')}'; -} -`; - }, -}; diff --git a/code/addons/storyshots-core/jest.config.js b/code/addons/storyshots-core/jest.config.js deleted file mode 100644 index 0115c67e5629..000000000000 --- a/code/addons/storyshots-core/jest.config.js +++ /dev/null @@ -1,12 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - snapshotSerializers: [...baseConfig.snapshotSerializers, 'enzyme-to-json/serializer'], - transform: { - ...baseConfig.transform, - '^.+\\.stories\\.[jt]sx?$': '@storybook/addon-storyshots/injectFileName', - }, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/storyshots-core/package.json b/code/addons/storyshots-core/package.json deleted file mode 100644 index 71c1d44b0f8f..000000000000 --- a/code/addons/storyshots-core/package.json +++ /dev/null @@ -1,153 +0,0 @@ -{ - "name": "@storybook/addon-storyshots", - "version": "7.5.0-alpha.2", - "description": "Take a code snapshot of every story automatically with Jest", - "keywords": [ - "addon", - "storybook", - "test" - ], - "homepage": "https://github.com/storybookjs/storybook/tree/next/code/addons/storyshots-core", - "bugs": { - "url": "https://github.com/storybookjs/storybook/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/storybookjs/storybook.git", - "directory": "code/addons/storyshots-core" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "license": "MIT", - "main": "dist/index.js", - "module": "dist/index.mjs", - "types": "dist/index.d.ts", - "files": [ - "dist/**/*", - "README.md", - "*.js", - "*.mjs", - "*.d.ts", - "!src/**/*" - ], - "scripts": { - "check": "../../../scripts/prepare/check.ts", - "prep": "../../../scripts/prepare/tsc.ts" - }, - "dependencies": { - "@jest/transform": "^29.3.1", - "@storybook/babel-plugin-require-context-hook": "1.0.1", - "@storybook/client-api": "workspace:*", - "@storybook/core-common": "workspace:*", - "@storybook/core-webpack": "workspace:*", - "@storybook/global": "^5.0.0", - "@storybook/preview-api": "workspace:*", - "@storybook/types": "workspace:*", - "@types/jest-specific-snapshot": "^0.5.6", - "glob": "^10.0.0", - "jest-specific-snapshot": "^8.0.0", - "preact-render-to-string": "^5.1.19", - "pretty-format": "^29.0.0", - "react-test-renderer": "^16.8.0 || ^17.0.0 || ^18.0.0", - "read-pkg-up": "^7.0.1", - "ts-dedent": "^2.0.0" - }, - "devDependencies": { - "@angular/core": "^16.0.0-rc.4", - "@angular/platform-browser-dynamic": "^16.0.0-rc.4", - "@emotion/jest": "^11.8.0", - "@storybook/addon-docs": "workspace:*", - "@storybook/angular": "workspace:*", - "@storybook/react": "workspace:*", - "@storybook/vue": "workspace:*", - "@storybook/vue3": "workspace:*", - "babel-loader": "^9.1.2", - "enzyme": "^3.11.0", - "enzyme-adapter-react-16": "^1.15.5", - "enzyme-to-json": "^3.6.1", - "jest-preset-angular": "^13.0.1", - "jest-vue-preprocessor": "^1.7.1", - "react-test-renderer": "^16", - "rxjs": "^6.6.3", - "vue-jest": "^5.0.0-alpha.8" - }, - "peerDependencies": { - "@angular/core": ">=13.0.0", - "@angular/platform-browser-dynamic": ">=13.0.0", - "@storybook/angular": "*", - "@storybook/react": "*", - "@storybook/vue": "*", - "@storybook/vue3": "*", - "jest": "*", - "jest-preset-angular": " >= 12.2.3", - "jest-vue-preprocessor": "*", - "preact": "^10.5.13", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "rxjs": "*", - "svelte": "*", - "vue": "*", - "vue-jest": "*" - }, - "peerDependenciesMeta": { - "@angular/core": { - "optional": true - }, - "@angular/platform-browser-dynamic": { - "optional": true - }, - "@storybook/angular": { - "optional": true - }, - "@storybook/react": { - "optional": true - }, - "@storybook/vue": { - "optional": true - }, - "@storybook/vue3": { - "optional": true - }, - "jest-preset-angular": { - "optional": true - }, - "jest-vue-preprocessor": { - "optional": true - }, - "preact": { - "optional": true - }, - "react": { - "optional": true - }, - "react-dom": { - "optional": true - }, - "rxjs": { - "optional": true - }, - "svelte": { - "optional": true - }, - "vue": { - "optional": true - }, - "vue-jest": { - "optional": true - } - }, - "publishConfig": { - "access": "public" - }, - "bundler": {}, - "gitHead": "e6a7fd8a655c69780bc20b9749c2699e44beae17", - "storybook": { - "displayName": "Storyshots", - "icon": "https://user-images.githubusercontent.com/263385/101991676-48cdf300-3c7c-11eb-8aa1-944dab6ab29b.png", - "unsupportedFrameworks": [ - "ember" - ] - } -} diff --git a/code/addons/storyshots-core/preset.js b/code/addons/storyshots-core/preset.js deleted file mode 100644 index 501f6e0c1310..000000000000 --- a/code/addons/storyshots-core/preset.js +++ /dev/null @@ -1,4 +0,0 @@ -// storyshots is not a typical addon because it's just a command-line tool -// nevertheless if you add it to .storybook/main.js it shouldn't complain -// https://github.com/storybookjs/storybook/issues/7959 -module.exports = {}; diff --git a/code/addons/storyshots-core/project.json b/code/addons/storyshots-core/project.json deleted file mode 100644 index d4369a8485c9..000000000000 --- a/code/addons/storyshots-core/project.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@storybook/addon-storyshots", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": [], - "type": "library" -} diff --git a/code/addons/storyshots-core/src/Stories2SnapsConverter.test.ts b/code/addons/storyshots-core/src/Stories2SnapsConverter.test.ts deleted file mode 100644 index 916ee94eb34c..000000000000 --- a/code/addons/storyshots-core/src/Stories2SnapsConverter.test.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Stories2SnapsConverter } from './Stories2SnapsConverter'; - -const target = new Stories2SnapsConverter(); - -describe('getSnapshotFileName', () => { - it('fileName is provided - snapshot is stored in __snapshots__ dir', () => { - const context = { fileName: 'foo.js', kind: 'kind' }; - - const result = target.getSnapshotFileName(context); - const platformAgnosticResult = result?.replace(/\\|\//g, '/'); - - // This is an absolute path, so we need to use `toContain()` - expect(platformAgnosticResult).toContain('__snapshots__/foo.storyshot'); - }); - - it('fileName with multiple extensions is provided - only the last extension is replaced', () => { - const context = { fileName: 'foo.web.stories.js', kind: 'kind' }; - - const result = target.getSnapshotFileName(context); - const platformAgnosticResult = result?.replace(/\\|\//g, '/'); - - // This is an absolute path, so we need to use `toContain()` - expect(platformAgnosticResult).toContain('__snapshots__/foo.web.stories.storyshot'); - }); - - it('fileName with dir is provided - __snapshots__ dir is created inside another dir', () => { - const context = { fileName: 'test/foo.js', kind: 'kind' }; - - const result = target.getSnapshotFileName(context); - const platformAgnosticResult = result?.replace(/\\|\//g, '/'); - - // This is an absolute path, so we need to use `toContain()` - expect(platformAgnosticResult).toContain('test/__snapshots__/foo.storyshot'); - }); -}); - -describe('getPossibleStoriesFiles', () => { - it('storyshots is provided and all the posible stories file names are returned', () => { - const storyshots = 'test/__snapshots__/foo.web.stories.storyshot'; - - const result = target.getPossibleStoriesFiles(storyshots); - const platformAgnosticResult = result.map((path) => path.replace(/\\|\//g, '/')); - - expect(platformAgnosticResult).toEqual([ - 'test/foo.web.stories.js', - 'test/foo.web.stories.jsx', - 'test/foo.web.stories.ts', - 'test/foo.web.stories.tsx', - 'test/foo.web.stories.mdx', - ]); - }); -}); diff --git a/code/addons/storyshots-core/src/Stories2SnapsConverter.ts b/code/addons/storyshots-core/src/Stories2SnapsConverter.ts deleted file mode 100644 index 4d6788e6b278..000000000000 --- a/code/addons/storyshots-core/src/Stories2SnapsConverter.ts +++ /dev/null @@ -1,76 +0,0 @@ -import path from 'path'; -import { dedent } from 'ts-dedent'; - -const defaultOptions: Stories2SnapsConverterOptions = { - snapshotsDirName: '__snapshots__', - snapshotExtension: '.storyshot', - storiesExtensions: ['.js', '.jsx', '.ts', '.tsx', '.mdx'], -}; - -export interface Stories2SnapsConverterOptions { - storiesExtensions: string[]; - snapshotExtension: string; - snapshotsDirName: string; -} - -export class Stories2SnapsConverter { - options: Stories2SnapsConverterOptions; - - constructor(options: Partial = {}) { - this.options = { - ...defaultOptions, - ...options, - }; - } - - getSnapshotExtension = () => this.options.snapshotExtension; - - getStoryshotFile(fileName: string) { - const { dir, name } = path.parse(fileName); - const { snapshotsDirName, snapshotExtension } = this.options; - - // Convert to absolute path, in case jest is not running in CWD, - // else it will create snapshots with the wrong path - const absDir = path.isAbsolute(dir) ? dir : path.resolve(dir); - - return path.format({ - dir: path.join(absDir, snapshotsDirName), - name, - ext: snapshotExtension, - }); - } - - getSnapshotFileName(context: { fileName?: string; kind: any }) { - const { fileName, kind } = context; - - if (!fileName) { - // eslint-disable-next-line no-console - console.warn( - dedent` - Storybook was unable to detect filename for stories of kind "${kind}". - To fix it, add following to your jest.config.js: - transform: { - // should be above any other js transform like babel-jest - '^.+\\.stories\\.js$': '@storybook/addon-storyshots/injectFileName', - } - ` - ); - return undefined; - } - - return this.getStoryshotFile(fileName); - } - - getPossibleStoriesFiles(storyshotFile: string) { - const { dir, name } = path.parse(storyshotFile); - const { storiesExtensions } = this.options; - - return storiesExtensions.map((ext) => - path.format({ - dir: path.dirname(dir), - name, - ext, - }) - ); - } -} diff --git a/code/addons/storyshots-core/src/api/StoryshotsOptions.ts b/code/addons/storyshots-core/src/api/StoryshotsOptions.ts deleted file mode 100644 index cbc853717de3..000000000000 --- a/code/addons/storyshots-core/src/api/StoryshotsOptions.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { GlobOptionsWithFileTypesFalse } from 'glob'; -import type { Stories2SnapsConverter } from '../Stories2SnapsConverter'; -import type { SupportedFramework } from '../frameworks'; -import type { RenderTree } from '../frameworks/Loader'; - -export interface TestMethodOptions { - story: any; - context: any; - renderTree: RenderTree; - renderShallowTree: RenderTree; - stories2snapsConverter: Stories2SnapsConverter; - snapshotFileName?: string; - options: any; - done?: () => void; -} - -export interface StoryshotsTestMethod { - (args: TestMethodOptions): any; - beforeAll?: () => void | Promise; - beforeEach?: () => void | Promise; - afterAll?: () => void | Promise; - afterEach?: () => void | Promise; -} - -export interface StoryshotsOptions { - asyncJest?: boolean; - config?: (options: any) => void; - integrityOptions?: GlobOptionsWithFileTypesFalse | false; - configPath?: string; - suite?: string; - storyKindRegex?: RegExp | string; - storyNameRegex?: RegExp | string; - framework?: SupportedFramework; - test?: StoryshotsTestMethod; - renderer?: Function; - snapshotSerializers?: jest.SnapshotSerializerPlugin[]; - /** - * @Deprecated The functionality of this option is completely covered by snapshotSerializers which should be used instead. - */ - serializer?: any; - stories2snapsConverter?: Stories2SnapsConverter; -} diff --git a/code/addons/storyshots-core/src/api/ensureOptionsDefaults.ts b/code/addons/storyshots-core/src/api/ensureOptionsDefaults.ts deleted file mode 100644 index 742c85173bb7..000000000000 --- a/code/addons/storyshots-core/src/api/ensureOptionsDefaults.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { snapshotWithOptions } from '../test-bodies'; -import { Stories2SnapsConverter } from '../Stories2SnapsConverter'; -import type { StoryshotsOptions } from './StoryshotsOptions'; - -const ignore = ['**/node_modules/**']; -const defaultStories2SnapsConverter = new Stories2SnapsConverter(); - -function getIntegrityOptions({ integrityOptions }: StoryshotsOptions) { - if (integrityOptions === false) { - return false; - } - - if (typeof integrityOptions !== 'object') { - return false; - } - - const ignoreOption: string[] = Array.isArray(integrityOptions.ignore) - ? integrityOptions.ignore - : []; - - return { - ...integrityOptions, - ignore: [...ignore, ...ignoreOption], - absolute: true, - }; -} - -function ensureOptionsDefaults(options: StoryshotsOptions) { - const { - suite = 'Storyshots', - asyncJest, - storyNameRegex, - storyKindRegex, - renderer, - serializer, - snapshotSerializers, - stories2snapsConverter = defaultStories2SnapsConverter, - test: testMethod = snapshotWithOptions({ renderer, serializer }), - } = options; - - const integrityOptions = getIntegrityOptions(options); - - return { - asyncJest, - suite, - storyNameRegex, - storyKindRegex, - stories2snapsConverter, - testMethod, - snapshotSerializers, - integrityOptions, - } as any; -} - -export default ensureOptionsDefaults; diff --git a/code/addons/storyshots-core/src/api/index.ts b/code/addons/storyshots-core/src/api/index.ts deleted file mode 100644 index 932d728a6345..000000000000 --- a/code/addons/storyshots-core/src/api/index.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { global } from '@storybook/global'; -import { addons, mockChannel } from '@storybook/preview-api'; -import ensureOptionsDefaults from './ensureOptionsDefaults'; -import snapshotsTests from './snapshotsTestsTemplate'; -import integrityTest from './integrityTestTemplate'; -import loadFramework from '../frameworks/frameworkLoader'; -import type { StoryshotsOptions } from './StoryshotsOptions'; - -const { describe, window: globalWindow } = global; - -type TestMethod = 'beforeAll' | 'beforeEach' | 'afterEach' | 'afterAll'; -const methods: TestMethod[] = ['beforeAll', 'beforeEach', 'afterEach', 'afterAll']; - -function callTestMethodGlobals( - testMethod: { [key in TestMethod]?: Function & { timeout?: number } } & { [key in string]: any } -) { - methods.forEach((method) => { - if (typeof testMethod[method] === 'function') { - // @ts-expect-error (ignore) - global[method](testMethod[method], testMethod[method].timeout); - } - }); -} - -const isDisabled = (parameter: any) => - parameter === false || (parameter && parameter.disable === true); -function testStorySnapshots(options: StoryshotsOptions = {}) { - if (typeof describe !== 'function') { - throw new Error('testStorySnapshots is intended only to be used inside jest'); - } - - addons.setChannel(mockChannel()); - - const { storybook, framework, renderTree, renderShallowTree } = loadFramework(options); - const { - asyncJest, - suite, - storyNameRegex, - storyKindRegex, - stories2snapsConverter, - testMethod, - integrityOptions, - snapshotSerializers, - } = ensureOptionsDefaults(options); - const testMethodParams = { - renderTree, - renderShallowTree, - stories2snapsConverter, - }; - - // NOTE: as the store + preview's initialization process entirely uses - // `SychronousPromise`s in the v6 store case, the callback to the `then()` here - // will run *immediately* (in the same tick), and thus the `snapshotsTests`, and - // subsequent calls to `it()` etc will all happen within this tick, which is required - // by Jest (cannot add tests asynchronously) - globalWindow.__STORYBOOK_STORY_STORE__.initializationPromise.then(() => { - const data = storybook.raw()?.reduce( - (acc, item) => { - if (storyNameRegex && !item.name.match(storyNameRegex)) { - return acc; - } - - if (storyKindRegex && !item.kind.match(storyKindRegex)) { - return acc; - } - - const { kind, storyFn: render, parameters } = item; - const existing = acc.find((i: any) => i.kind === kind); - const { fileName } = item.parameters; - - if (!isDisabled(parameters.storyshots)) { - if (existing) { - existing.children.push({ ...item, render, fileName }); - } else { - acc.push({ - kind, - children: [{ ...item, render, fileName }], - }); - } - } - return acc; - }, - [] as { - kind: string; - children: any[]; - }[] - ); - - if (data && data.length) { - callTestMethodGlobals(testMethod); - - snapshotsTests({ - data, - asyncJest, - suite, - framework, - testMethod, - testMethodParams, - snapshotSerializers, - }); - - integrityTest(integrityOptions, stories2snapsConverter); - } else { - throw new Error('storyshots found 0 stories'); - } - }); -} - -export default testStorySnapshots; diff --git a/code/addons/storyshots-core/src/api/integrityTestTemplate.ts b/code/addons/storyshots-core/src/api/integrityTestTemplate.ts deleted file mode 100644 index be6cd5bf79fe..000000000000 --- a/code/addons/storyshots-core/src/api/integrityTestTemplate.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* eslint-disable jest/no-export */ -import fs from 'fs'; -import { globSync } from 'glob'; -import { global } from '@storybook/global'; -import { dedent } from 'ts-dedent'; - -const { describe, it } = global; - -expect.extend({ - notToBeAbandoned(storyshots, stories2snapsConverter) { - const abandonedStoryshots = storyshots.filter((fileName: string) => { - const possibleStoriesFiles = stories2snapsConverter.getPossibleStoriesFiles(fileName); - return !possibleStoriesFiles.some(fs.existsSync); - }); - - if (abandonedStoryshots.length === 0) { - return { pass: true, message: () => '' }; - } - - const formattedList = abandonedStoryshots.join('\n '); - - // See https://github.com/facebook/jest/issues/8732#issuecomment-516445064 - // eslint-disable-next-line no-underscore-dangle - const isUpdate = expect.getState().snapshotState._updateSnapshot === 'all'; - if (isUpdate) { - abandonedStoryshots.forEach((file: string) => fs.unlinkSync(file)); - // eslint-disable-next-line no-console - console.log(dedent` - Removed abandoned storyshots: - ${formattedList} - `); - return { pass: true, message: () => '' }; - } - - return { - pass: false, - message: () => dedent` - Found abandoned storyshots. Run jest with -u to remove them: - ${formattedList} - `, - }; - }, -}); - -function integrityTest(integrityOptions: any, stories2snapsConverter: any) { - if (integrityOptions === false) { - return; - } - - describe('Storyshots Integrity', () => { - it('Abandoned Storyshots', () => { - const snapshotExtension = stories2snapsConverter.getSnapshotExtension(); - const storyshots = globSync(`**/*${snapshotExtension}`, integrityOptions); - - // @ts-expect-error (ts doesn't 'get' the extension happening on line 9) - expect(storyshots).notToBeAbandoned(stories2snapsConverter); - }); - }); -} - -export default integrityTest; diff --git a/code/addons/storyshots-core/src/api/snapshotsTestsTemplate.ts b/code/addons/storyshots-core/src/api/snapshotsTestsTemplate.ts deleted file mode 100644 index 1e2ee8cbf9f4..000000000000 --- a/code/addons/storyshots-core/src/api/snapshotsTestsTemplate.ts +++ /dev/null @@ -1,64 +0,0 @@ -/* eslint-disable jest/no-export */ -/* eslint-disable jest/expect-expect */ -import { global } from '@storybook/global'; -import { addSerializer } from 'jest-specific-snapshot'; - -const { describe, it } = global; - -function snapshotTest({ item, asyncJest, framework, testMethod, testMethodParams }: any) { - const { name } = item; - const context = { ...item, framework }; - - if (asyncJest === true) { - it( - `${name}`, - () => - new Promise((resolve, reject) => - testMethod({ - done: (error: any) => (error ? reject(error) : resolve()), - story: item, - context, - ...testMethodParams, - }) - ), - testMethod.timeout - ); - } else { - it( - `${name}`, - () => - testMethod({ - story: item, - context, - ...testMethodParams, - }), - testMethod.timeout - ); - } -} - -function snapshotTestSuite({ item, suite, ...restParams }: any) { - const { kind, children } = item; - describe(`${suite}`, () => { - describe(`${kind}`, () => { - children.forEach((c: any) => { - snapshotTest({ item: c, ...restParams }); - }); - }); - }); -} - -function snapshotsTests({ data, snapshotSerializers, ...restParams }: any) { - if (snapshotSerializers) { - snapshotSerializers.forEach((serializer: any) => { - addSerializer(serializer); - expect.addSnapshotSerializer(serializer); - }); - } - - data.forEach((item: any) => { - snapshotTestSuite({ item, ...restParams }); - }); -} - -export default snapshotsTests; diff --git a/code/addons/storyshots-core/src/frameworks/Loader.ts b/code/addons/storyshots-core/src/frameworks/Loader.ts deleted file mode 100644 index b7d93898aa1f..000000000000 --- a/code/addons/storyshots-core/src/frameworks/Loader.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { Renderer, Addon_Loadable } from '@storybook/types'; -import type { ClientApi as ClientApiClass } from '@storybook/preview-api'; -import type { StoryshotsOptions } from '../api/StoryshotsOptions'; -import type { SupportedFramework } from './SupportedFramework'; - -export type RenderTree = (story: any, context?: any, options?: any) => any; - -export interface ClientApi extends ClientApiClass { - configure( - loader: Addon_Loadable, - module: NodeModule | false, - showDeprecationWarning?: boolean - ): void; - forceReRender(): void; -} - -export interface Loader { - load: (options: StoryshotsOptions) => { - framework: SupportedFramework; - renderTree: RenderTree; - renderShallowTree: any; - storybook: ClientApi; - }; - test: (options: StoryshotsOptions) => boolean; -} diff --git a/code/addons/storyshots-core/src/frameworks/SupportedFramework.ts b/code/addons/storyshots-core/src/frameworks/SupportedFramework.ts deleted file mode 100644 index dfc20d8163ce..000000000000 --- a/code/addons/storyshots-core/src/frameworks/SupportedFramework.ts +++ /dev/null @@ -1,10 +0,0 @@ -export type SupportedFramework = - | 'angular' - | 'html' - | 'preact' - | 'react' - | 'react-native' - | 'svelte' - | 'vue' - | 'vue3' - | 'web-components'; diff --git a/code/addons/storyshots-core/src/frameworks/angular/loader.ts b/code/addons/storyshots-core/src/frameworks/angular/loader.ts deleted file mode 100644 index 48b367bb4d27..000000000000 --- a/code/addons/storyshots-core/src/frameworks/angular/loader.ts +++ /dev/null @@ -1,70 +0,0 @@ -import hasDependency from '../hasDependency'; -import configure from '../configure'; -import type { Loader } from '../Loader'; -import type { StoryshotsOptions } from '../../api/StoryshotsOptions'; - -function setupAngularJestPreset() { - // Angular + Jest + Storyshots = Crazy Shit: - // We need to require 'jest-preset-angular/build/setupJest' before any storybook code - // is running inside jest - one of the things that `jest-preset-angular/build/setupJest` does is - // extending the `window.Reflect` with all the needed metadata functions, that are required - // for emission of the TS decorations like 'design:paramtypes' - jest.requireActual('jest-preset-angular/setup-jest'); -} - -function test(options: StoryshotsOptions): boolean { - return ( - options.framework === 'angular' || (!options.framework && hasDependency('@storybook/angular')) - ); -} - -function load(options: StoryshotsOptions) { - setupAngularJestPreset(); - - let mockStartedAPI: any; - - jest.mock('@storybook/preview-api', () => { - const previewAPI = jest.requireActual('@storybook/preview-api'); - - return { - ...previewAPI, - start: (...args: any[]) => { - mockStartedAPI = previewAPI.start(...args); - return mockStartedAPI; - }, - }; - }); - - jest.mock('@storybook/angular', () => { - const renderAPI = jest.requireActual('@storybook/angular'); - - renderAPI.addDecorator = mockStartedAPI.clientApi.addDecorator; - renderAPI.addParameters = mockStartedAPI.clientApi.addParameters; - - return renderAPI; - }); - - // eslint-disable-next-line global-require - const storybook = require('@storybook/angular'); - - configure({ - ...options, - storybook, - }); - - return { - framework: 'angular' as const, - renderTree: jest.requireActual('./renderTree').default, - renderShallowTree: () => { - throw new Error('Shallow renderer is not supported for angular'); - }, - storybook, - }; -} - -const angularLoader: Loader = { - load, - test, -}; - -export default angularLoader; diff --git a/code/addons/storyshots-core/src/frameworks/angular/renderTree.ts b/code/addons/storyshots-core/src/frameworks/angular/renderTree.ts deleted file mode 100644 index 3c501c70dcc5..000000000000 --- a/code/addons/storyshots-core/src/frameworks/angular/renderTree.ts +++ /dev/null @@ -1,38 +0,0 @@ -import AngularSnapshotSerializer from 'jest-preset-angular/build/serializers/ng-snapshot'; -import HTMLCommentSerializer from 'jest-preset-angular/build/serializers/html-comment'; -import { TestBed } from '@angular/core/testing'; -import { addSerializer } from 'jest-specific-snapshot'; -import { getApplication, storyPropsProvider, PropertyExtractor } from '@storybook/angular/renderer'; -import { BehaviorSubject } from 'rxjs'; - -addSerializer(HTMLCommentSerializer); -addSerializer(AngularSnapshotSerializer); - -function getRenderedTree(story: any) { - const currentStory = story.render(); - - const analyzedMetadata = new PropertyExtractor(currentStory.moduleMetadata, story.component); - - const application = getApplication({ - storyFnAngular: currentStory, - component: story.component, - // TODO : To change with the story Id in v7. Currently keep with static id to avoid changes in snapshots - targetSelector: 'storybook-wrapper', - analyzedMetadata, - }); - - TestBed.configureTestingModule({ - imports: [application], - providers: [storyPropsProvider(new BehaviorSubject(currentStory.props))], - }); - - return TestBed.compileComponents().then(() => { - const tree = TestBed.createComponent(application); - tree.detectChanges(); - - // Empty componentInstance remove attributes of the internal main component () in snapshot - return { ...tree, componentInstance: {} }; - }); -} - -export default getRenderedTree; diff --git a/code/addons/storyshots-core/src/frameworks/angular/types.ts b/code/addons/storyshots-core/src/frameworks/angular/types.ts deleted file mode 100644 index b97c5d24fdc9..000000000000 --- a/code/addons/storyshots-core/src/frameworks/angular/types.ts +++ /dev/null @@ -1,17 +0,0 @@ -export interface NgModuleMetadata { - declarations?: any[]; - entryComponents?: any[]; - imports?: any[]; - schemas?: any[]; - providers?: any[]; -} - -export interface ICollection { - [p: string]: any; -} - -export interface NgStory { - props: ICollection; - moduleMetadata?: NgModuleMetadata; - template?: string; -} diff --git a/code/addons/storyshots-core/src/frameworks/configure.test.ts b/code/addons/storyshots-core/src/frameworks/configure.test.ts deleted file mode 100644 index 0e4377e9dede..000000000000 --- a/code/addons/storyshots-core/src/frameworks/configure.test.ts +++ /dev/null @@ -1,53 +0,0 @@ -import path from 'path'; -import { getPreviewFile, getMainFile } from './configure'; - -// eslint-disable-next-line global-require, jest/no-mocks-import -jest.mock('fs', () => require('../../../../__mocks__/fs')); -const setupFiles = (files: Record) => { - // eslint-disable-next-line no-underscore-dangle, global-require - require('fs').__setMockFiles(files); -}; - -describe('preview files', () => { - it.each` - filepath - ${'preview.ts'} - ${'preview.tsx'} - ${'preview.js'} - ${'preview.jsx'} - ${'config.ts'} - ${'config.tsx'} - ${'config.js'} - ${'config.jsx'} - `('resolves a valid preview file from $filepath', ({ filepath }) => { - setupFiles({ [path.join('test', filepath)]: 'true' }); - - expect(getPreviewFile('test/')).toEqual(`test${path.sep}${filepath}`); - }); - - it('returns false when none of the paths exist', () => { - setupFiles(Object.create(null)); - - expect(getPreviewFile('test/')).toEqual(false); - }); -}); - -describe('main files', () => { - it.each` - filepath - ${'main.ts'} - ${'main.tsx'} - ${'main.js'} - ${'main.jsx'} - `('resolves a valid main file path from $filepath', ({ filepath }) => { - setupFiles({ [path.join('test', filepath)]: 'true' }); - - expect(getMainFile('test/')).toEqual(`test${path.sep}${filepath}`); - }); - - it('returns false when none of the paths exist', () => { - setupFiles(Object.create(null)); - - expect(getPreviewFile('test/')).toEqual(false); - }); -}); diff --git a/code/addons/storyshots-core/src/frameworks/configure.ts b/code/addons/storyshots-core/src/frameworks/configure.ts deleted file mode 100644 index 5532a2dfea8c..000000000000 --- a/code/addons/storyshots-core/src/frameworks/configure.ts +++ /dev/null @@ -1,157 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import type { - Renderer, - ArgsEnhancer, - ArgTypesEnhancer, - NormalizedStoriesSpecifier, - StoriesEntry, - DecoratorFunction, -} from '@storybook/types'; -import { toRequireContext } from '@storybook/core-webpack'; -import { normalizeStoriesEntry } from '@storybook/core-common'; -import registerRequireContextHook from '@storybook/babel-plugin-require-context-hook/register'; -import { global } from '@storybook/global'; - -import type { ClientApi } from './Loader'; -import type { StoryshotsOptions } from '../api/StoryshotsOptions'; - -registerRequireContextHook(); - -const isFile = (file: string): boolean => { - try { - return fs.lstatSync(file).isFile(); - } catch (e) { - return false; - } -}; - -interface Output { - features?: Record; - preview?: string; - stories?: NormalizedStoriesSpecifier[]; - requireContexts?: string[]; -} - -const supportedExtensions = ['ts', 'tsx', 'js', 'jsx', 'cjs', 'mjs']; - -const resolveFile = (configDir: string, supportedFilenames: string[]) => - supportedFilenames - .flatMap((filename) => - supportedExtensions.map((ext) => path.join(configDir, `${filename}.${ext}`)) - ) - .find(isFile) || false; - -export const getPreviewFile = (configDir: string): string | false => - resolveFile(configDir, ['preview', 'config']); - -export const getMainFile = (configDir: string): string | false => resolveFile(configDir, ['main']); - -function getConfigPathParts(input: string): Output { - const configDir = path.resolve(input); - - if (fs.lstatSync(configDir).isDirectory()) { - const output: Output = {}; - - const preview = getPreviewFile(configDir); - const main = getMainFile(configDir); - - if (preview) { - output.preview = preview; - } - if (main) { - const { default: defaultExport, ...rest } = jest.requireActual(main); - const { stories = [], features = {} } = defaultExport || rest; - - output.features = features; - - const workingDir = process.cwd(); - output.stories = stories.map((entry: StoriesEntry) => { - const specifier = normalizeStoriesEntry(entry, { - configDir, - workingDir, - }); - - return specifier; - }); - output.requireContexts = output.stories?.map((specifier) => { - const { path: basePath, recursive, match } = toRequireContext(specifier); - - // eslint-disable-next-line no-underscore-dangle - return global.__requireContext(workingDir, basePath, recursive, match); - }); - } - - return output; - } - - return { preview: configDir }; -} - -function configure( - options: { - storybook: ClientApi; - } & StoryshotsOptions -): void { - const { configPath = '.storybook', config, storybook } = options; - - if (config && typeof config === 'function') { - config(storybook); - return; - } - - const { - preview, - features = {}, - stories = [], - requireContexts = [], - } = getConfigPathParts(configPath); - - global.FEATURES = features; - global.CONFIG_TYPE = 'DEVELOPMENT'; - global.STORIES = stories.map((specifier) => ({ - ...specifier, - importPathMatcher: specifier.importPathMatcher.source, - })); - - if (preview) { - // This is essentially the same code as builders/builder-webpack5/templates/virtualModuleEntry.template - const { - parameters, - decorators, - globals, - globalTypes, - argsEnhancers, - argTypesEnhancers, - runStep, - } = jest.requireActual(preview); - - if (decorators) { - decorators.forEach((decorator: DecoratorFunction) => - storybook.addDecorator(decorator) - ); - } - if (parameters || globals || globalTypes) { - storybook.addParameters({ ...parameters, globals, globalTypes }); - } - if (runStep) { - storybook.addStepRunner(runStep); - } - if (argsEnhancers) { - argsEnhancers.forEach((enhancer: ArgsEnhancer) => - storybook.addArgsEnhancer(enhancer as any) - ); - } - if (argTypesEnhancers) { - argTypesEnhancers.forEach((enhancer: ArgTypesEnhancer) => - storybook.addArgTypesEnhancer(enhancer as any) - ); - } - } - - if (requireContexts && requireContexts.length) { - storybook.configure(requireContexts, false, false); - } -} - -export default configure; diff --git a/code/addons/storyshots-core/src/frameworks/frameworkLoader.ts b/code/addons/storyshots-core/src/frameworks/frameworkLoader.ts deleted file mode 100644 index 40fbed19b2a3..000000000000 --- a/code/addons/storyshots-core/src/frameworks/frameworkLoader.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* eslint-disable global-require,import/no-dynamic-require */ -import fs from 'fs'; -import path from 'path'; -import type { Loader } from './Loader'; -import type { StoryshotsOptions } from '../api/StoryshotsOptions'; - -const loaderScriptName = 'loader.js'; - -const isDirectory = (source: string) => fs.lstatSync(source).isDirectory(); - -function getLoaders(): Loader[] { - return fs - .readdirSync(__dirname) - .map((name) => path.join(__dirname, name)) - .filter(isDirectory) - .map((framework) => { - const pa = path.join(framework, loaderScriptName); - const pb = path.join(framework, 'loader.ts'); - - if (fs.existsSync(pa)) { - return pa; - } - - if (fs.existsSync(pb)) { - return pb; - } - - return null; - }) - .filter(Boolean) - .map((loader) => loader && require(loader).default); -} - -function loadFramework(options: StoryshotsOptions) { - const loaders = getLoaders(); - - const loader = loaders.find((frameworkLoader) => frameworkLoader.test(options)); - - if (!loader) { - throw new Error( - "Couldn't find an appropriate framework loader -- do you need to set the `framework` option?" - ); - } - - return loader.load(options); -} - -export default loadFramework; diff --git a/code/addons/storyshots-core/src/frameworks/hasDependency.ts b/code/addons/storyshots-core/src/frameworks/hasDependency.ts deleted file mode 100644 index c88d5347b116..000000000000 --- a/code/addons/storyshots-core/src/frameworks/hasDependency.ts +++ /dev/null @@ -1,18 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import readPkgUp from 'read-pkg-up'; - -const { - packageJson: { dependencies, devDependencies } = { - dependencies: undefined, - devDependencies: undefined, - }, -} = readPkgUp.sync() || {}; - -export default function hasDependency(name: string): boolean { - return Boolean( - (devDependencies && devDependencies[name]) || - (dependencies && dependencies[name]) || - fs.existsSync(path.join('node_modules', name, 'package.json')) - ); -} diff --git a/code/addons/storyshots-core/src/frameworks/html/loader.ts b/code/addons/storyshots-core/src/frameworks/html/loader.ts deleted file mode 100644 index df86afc1961e..000000000000 --- a/code/addons/storyshots-core/src/frameworks/html/loader.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { global } from '@storybook/global'; -import configure from '../configure'; -import type { Loader } from '../Loader'; -import type { StoryshotsOptions } from '../../api/StoryshotsOptions'; - -function test(options: StoryshotsOptions): boolean { - return options.framework === 'html'; -} - -function load(options: StoryshotsOptions) { - global.STORYBOOK_ENV = 'html'; - - let mockStartedAPI: any; - - jest.mock('@storybook/preview-api', () => { - const previewAPI = jest.requireActual('@storybook/preview-api'); - - return { - ...previewAPI, - start: (...args: any[]) => { - mockStartedAPI = previewAPI.start(...args); - return mockStartedAPI; - }, - }; - }); - - jest.mock('@storybook/html', () => { - const renderAPI = jest.requireActual('@storybook/html'); - - renderAPI.addDecorator = mockStartedAPI.clientApi.addDecorator; - renderAPI.addParameters = mockStartedAPI.clientApi.addParameters; - - return renderAPI; - }); - - // eslint-disable-next-line global-require - const storybook = require('@storybook/html'); - - configure({ - ...options, - storybook, - }); - - return { - framework: 'html' as const, - renderTree: jest.requireActual('./renderTree').default, - renderShallowTree: () => { - throw new Error('Shallow renderer is not supported for HTML'); - }, - storybook, - }; -} - -const htmLoader: Loader = { - load, - test, -}; - -export default htmLoader; diff --git a/code/addons/storyshots-core/src/frameworks/html/renderTree.ts b/code/addons/storyshots-core/src/frameworks/html/renderTree.ts deleted file mode 100644 index 2347acb15867..000000000000 --- a/code/addons/storyshots-core/src/frameworks/html/renderTree.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { global } from '@storybook/global'; - -const { document, Node } = global; - -function getRenderedTree(story: { render: () => any }) { - const component = story.render(); - - if (component instanceof Node) { - return component; - } - - const section: HTMLElement = document.createElement('section'); - section.innerHTML = component; - - if (section.childElementCount > 1) { - return section; - } - - return section.firstChild; -} - -export default getRenderedTree; diff --git a/code/addons/storyshots-core/src/frameworks/index.ts b/code/addons/storyshots-core/src/frameworks/index.ts deleted file mode 100644 index 3eb9b3a990b0..000000000000 --- a/code/addons/storyshots-core/src/frameworks/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './SupportedFramework'; diff --git a/code/addons/storyshots-core/src/frameworks/preact/loader.ts b/code/addons/storyshots-core/src/frameworks/preact/loader.ts deleted file mode 100644 index b938dac3f928..000000000000 --- a/code/addons/storyshots-core/src/frameworks/preact/loader.ts +++ /dev/null @@ -1,65 +0,0 @@ -/** @jsxRuntime classic */ -/** @jsx h */ - -import { global } from '@storybook/global'; -import configure from '../configure'; -import hasDependency from '../hasDependency'; -import type { Loader } from '../Loader'; -import type { StoryshotsOptions } from '../../api/StoryshotsOptions'; - -function test(options: StoryshotsOptions): boolean { - return ( - options.framework === 'preact' || (!options.framework && hasDependency('@storybook/preact')) - ); -} - -function load(options: StoryshotsOptions) { - global.STORYBOOK_ENV = 'preact'; - - let mockStartedAPI: any; - - jest.mock('@storybook/preview-api', () => { - const previewAPI = jest.requireActual('@storybook/preview-api'); - - return { - ...previewAPI, - start: (...args: any[]) => { - mockStartedAPI = previewAPI.start(...args); - return mockStartedAPI; - }, - }; - }); - - jest.mock('@storybook/preact', () => { - const renderAPI = jest.requireActual('@storybook/preact'); - - renderAPI.addDecorator = mockStartedAPI.clientApi.addDecorator; - renderAPI.addParameters = mockStartedAPI.clientApi.addParameters; - - return renderAPI; - }); - - // eslint-disable-next-line global-require - const storybook = require('@storybook/preact'); - - configure({ - ...options, - storybook, - }); - - return { - framework: 'preact' as const, - renderTree: jest.requireActual('./renderTree').default, - renderShallowTree: () => { - throw new Error('Shallow renderer is not supported for preact'); - }, - storybook, - }; -} - -const preactLoader: Loader = { - load, - test, -}; - -export default preactLoader; diff --git a/code/addons/storyshots-core/src/frameworks/preact/renderTree.ts b/code/addons/storyshots-core/src/frameworks/preact/renderTree.ts deleted file mode 100644 index 5e95dbe95920..000000000000 --- a/code/addons/storyshots-core/src/frameworks/preact/renderTree.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** @jsx h */ -import { h } from 'preact'; -import preactRenderer from 'preact-render-to-string/jsx'; - -const boundRenderer = (_storyElement: any, _rendererOptions: any) => - preactRenderer(_storyElement, null, { pretty: ' ' }); - -function getRenderedTree(story: any, context: any, { renderer, ...rendererOptions }: any) { - const currentRenderer = renderer || boundRenderer; - const tree = currentRenderer(h(story.render, null), rendererOptions); - - return tree; -} - -export default getRenderedTree; diff --git a/code/addons/storyshots-core/src/frameworks/react-native/loader.ts b/code/addons/storyshots-core/src/frameworks/react-native/loader.ts deleted file mode 100644 index 7c0e51d23f0f..000000000000 --- a/code/addons/storyshots-core/src/frameworks/react-native/loader.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* eslint-disable global-require */ -import path from 'path'; -import hasDependency from '../hasDependency'; -import type { Loader } from '../Loader'; -import type { StoryshotsOptions } from '../../api/StoryshotsOptions'; - -function test(options: StoryshotsOptions): boolean { - return ( - options.framework === 'react-native' || - (!options.framework && hasDependency('@storybook/react-native')) - ); -} - -function configure(options: StoryshotsOptions, storybook: any) { - const { configPath = 'storybook', config } = options; - - if (config && typeof config === 'function') { - config(storybook); - return; - } - - const resolvedConfigPath = path.resolve(configPath); - jest.requireActual(resolvedConfigPath); -} - -function load(options: StoryshotsOptions) { - const storybook = jest.requireActual('@storybook/react-native'); - - configure(options, storybook); - - return { - renderTree: require('../react/renderTree').default, - renderShallowTree: require('../react/renderShallowTree').default, - framework: 'react-native' as const, - storybook, - }; -} - -const reactNativeLoader: Loader = { - load, - test, -}; - -export default reactNativeLoader; diff --git a/code/addons/storyshots-core/src/frameworks/react/loader.ts b/code/addons/storyshots-core/src/frameworks/react/loader.ts deleted file mode 100644 index 35d62098d183..000000000000 --- a/code/addons/storyshots-core/src/frameworks/react/loader.ts +++ /dev/null @@ -1,55 +0,0 @@ -import configure from '../configure'; -import hasDependency from '../hasDependency'; -import type { Loader } from '../Loader'; -import type { StoryshotsOptions } from '../../api/StoryshotsOptions'; - -function test(options: StoryshotsOptions): boolean { - return options.framework === 'react' || (!options.framework && hasDependency('@storybook/react')); -} - -function load(options: StoryshotsOptions) { - let mockStartedAPI: any; - - jest.mock('@storybook/preview-api', () => { - const previewAPI = jest.requireActual('@storybook/preview-api'); - - return { - ...previewAPI, - start: (...args: any[]) => { - mockStartedAPI = previewAPI.start(...args); - return mockStartedAPI; - }, - }; - }); - - jest.mock('@storybook/react', () => { - const renderAPI = jest.requireActual('@storybook/react'); - - renderAPI.addDecorator = mockStartedAPI.clientApi.addDecorator; - renderAPI.addParameters = mockStartedAPI.clientApi.addParameters; - - return renderAPI; - }); - - // eslint-disable-next-line global-require - const storybook = require('@storybook/react'); - - configure({ - ...options, - storybook, - }); - - return { - framework: 'react' as const, - renderTree: jest.requireActual('./renderTree').default, - renderShallowTree: jest.requireActual('./renderShallowTree').default, - storybook, - }; -} - -const reactLoader: Loader = { - load, - test, -}; - -export default reactLoader; diff --git a/code/addons/storyshots-core/src/frameworks/react/renderShallowTree.ts b/code/addons/storyshots-core/src/frameworks/react/renderShallowTree.ts deleted file mode 100644 index d8ac7b865b4e..000000000000 --- a/code/addons/storyshots-core/src/frameworks/react/renderShallowTree.ts +++ /dev/null @@ -1,10 +0,0 @@ -import shallow from 'react-test-renderer/shallow'; - -function getRenderedTree(story: any, context: any, { renderer, serializer }: any) { - const storyElement = story.render(); - const shallowRenderer = renderer || shallow.createRenderer(); - const tree = shallowRenderer.render(storyElement); - return serializer ? serializer(tree) : tree; -} - -export default getRenderedTree; diff --git a/code/addons/storyshots-core/src/frameworks/react/renderTree.ts b/code/addons/storyshots-core/src/frameworks/react/renderTree.ts deleted file mode 100644 index d92a55710ab1..000000000000 --- a/code/addons/storyshots-core/src/frameworks/react/renderTree.ts +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import reactTestRenderer from 'react-test-renderer'; - -function getRenderedTree(story: any, context: any, { renderer, ...rendererOptions }: any) { - const StoryFn = story.render; - const storyElement = React.createElement(StoryFn); - const currentRenderer = renderer || reactTestRenderer.create; - const tree = currentRenderer(storyElement, rendererOptions); - - return tree; -} - -export default getRenderedTree; diff --git a/code/addons/storyshots-core/src/frameworks/svelte/loader.ts b/code/addons/storyshots-core/src/frameworks/svelte/loader.ts deleted file mode 100644 index 5bd09594013c..000000000000 --- a/code/addons/storyshots-core/src/frameworks/svelte/loader.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { global } from '@storybook/global'; -import hasDependency from '../hasDependency'; -import configure from '../configure'; -import type { Loader } from '../Loader'; -import type { StoryshotsOptions } from '../../api/StoryshotsOptions'; - -function test(options: StoryshotsOptions): boolean { - return ( - options.framework === 'svelte' || (!options.framework && hasDependency('@storybook/svelte')) - ); -} - -function load(options: StoryshotsOptions) { - global.STORYBOOK_ENV = 'svelte'; - - let mockStartedAPI: any; - - jest.mock('@storybook/preview-api', () => { - const previewAPI = jest.requireActual('@storybook/preview-api'); - - return { - ...previewAPI, - start: (...args: any[]) => { - mockStartedAPI = previewAPI.start(...args); - return mockStartedAPI; - }, - }; - }); - - jest.mock('@storybook/svelte', () => { - const renderAPI = jest.requireActual('@storybook/svelte'); - - renderAPI.addDecorator = mockStartedAPI.clientApi.addDecorator; - renderAPI.addParameters = mockStartedAPI.clientApi.addParameters; - - return renderAPI; - }); - - // eslint-disable-next-line global-require - const storybook = require('@storybook/svelte'); - - configure({ - ...options, - storybook, - }); - return { - framework: 'svelte' as const, - renderTree: jest.requireActual('./renderTree').default, - renderShallowTree: () => { - throw new Error('Shallow renderer is not supported for svelte'); - }, - storybook, - }; -} - -const svelteLoader: Loader = { - load, - test, -}; - -export default svelteLoader; diff --git a/code/addons/storyshots-core/src/frameworks/svelte/renderTree.ts b/code/addons/storyshots-core/src/frameworks/svelte/renderTree.ts deleted file mode 100644 index d39cf95008e9..000000000000 --- a/code/addons/storyshots-core/src/frameworks/svelte/renderTree.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { global } from '@storybook/global'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore - types are removed in Svelte 4 but it still works. ts-ignore is safer than ts-expect-error because it's not an error in Svelte 3 -// eslint-disable-next-line import/no-unresolved -import { set_current_component } from 'svelte/internal'; - -const { document } = global; - -/** - * Provides functionality to convert your raw story to the resulting markup. - * - * Storybook snapshots need the rendered markup that svelte outputs, - * but since we only have the story config data ({ Component, data }) in - * the Svelte stories, we need to mount the component, and then return the - * resulting HTML. - * - * If we don't render to HTML, we will get a snapshot of the raw story - * i.e. ({ Component, data }). - */ -function getRenderedTree(story: any) { - // allow setContext to work - set_current_component({ $$: { context: new Map() } }); - - const { Component, props } = story.render(); - - const DefaultCompatComponent = Component.default || Component; - - // We need to create a target to mount onto. - const target = document.createElement('section'); - - // eslint-disable-next-line no-new - new DefaultCompatComponent({ target, props }); - - // Classify the target so that it is clear where the markup - // originates from, and that it is specific for snapshot tests. - target.className = 'storybook-snapshot-container'; - - return target; -} - -export default getRenderedTree; diff --git a/code/addons/storyshots-core/src/frameworks/vue/loader.ts b/code/addons/storyshots-core/src/frameworks/vue/loader.ts deleted file mode 100644 index a29a88a2d98b..000000000000 --- a/code/addons/storyshots-core/src/frameworks/vue/loader.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { global } from '@storybook/global'; -import hasDependency from '../hasDependency'; -import configure from '../configure'; -import type { Loader } from '../Loader'; -import type { StoryshotsOptions } from '../../api/StoryshotsOptions'; - -function mockVueToIncludeCompiler() { - jest.mock('vue', () => jest.requireActual('vue/dist/vue.common.js')); -} - -function test(options: StoryshotsOptions): boolean { - return options.framework === 'vue' || (!options.framework && hasDependency('@storybook/vue')); -} - -function load(options: StoryshotsOptions) { - global.STORYBOOK_ENV = 'vue'; - mockVueToIncludeCompiler(); - - let mockStartedAPI: any; - - jest.mock('@storybook/preview-api', () => { - const previewAPI = jest.requireActual('@storybook/preview-api'); - - return { - ...previewAPI, - start: (...args: any[]) => { - mockStartedAPI = previewAPI.start(...args); - return mockStartedAPI; - }, - }; - }); - - jest.mock('@storybook/vue', () => { - const renderAPI = jest.requireActual('@storybook/vue'); - - renderAPI.addDecorator = mockStartedAPI.clientApi.addDecorator; - renderAPI.addParameters = mockStartedAPI.clientApi.addParameters; - - return renderAPI; - }); - - // eslint-disable-next-line global-require - const storybook = require('@storybook/vue'); - - configure({ - ...options, - storybook, - }); - return { - framework: 'vue' as const, - renderTree: jest.requireActual('./renderTree').default, - renderShallowTree: () => { - throw new Error('Shallow renderer is not supported for vue'); - }, - storybook, - }; -} - -const vueLoader: Loader = { - load, - test, -}; - -export default vueLoader; diff --git a/code/addons/storyshots-core/src/frameworks/vue/renderTree.ts b/code/addons/storyshots-core/src/frameworks/vue/renderTree.ts deleted file mode 100644 index d37139e813ea..000000000000 --- a/code/addons/storyshots-core/src/frameworks/vue/renderTree.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-disable @typescript-eslint/ban-ts-comment */ -import Vue from 'vue'; - -// this is defined in @storybook/vue but not exported, -// and we need it to inject args into the story component's props -const VALUES = 'STORYBOOK_VALUES'; - -function getRenderedTree(story: any) { - const component = story.render(); - - // @ts-ignore FIXME storyshots type error - const vm = new Vue({ - // @ts-ignore FIXME storyshots type error - render(h) { - return h(component); - }, - }); - - // @ts-ignore FIXME storyshots type error - vm[VALUES] = story.initialArgs; - - return vm.$mount().$el; -} - -export default getRenderedTree; diff --git a/code/addons/storyshots-core/src/frameworks/vue3/loader.ts b/code/addons/storyshots-core/src/frameworks/vue3/loader.ts deleted file mode 100644 index 3fed6869e1a2..000000000000 --- a/code/addons/storyshots-core/src/frameworks/vue3/loader.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { global } from '@storybook/global'; -import hasDependency from '../hasDependency'; -import configure from '../configure'; -import type { Loader } from '../Loader'; -import type { StoryshotsOptions } from '../../api/StoryshotsOptions'; - -function test(options: StoryshotsOptions): boolean { - return options.framework === 'vue3' || (!options.framework && hasDependency('@storybook/vue3')); -} - -function load(options: StoryshotsOptions) { - global.STORYBOOK_ENV = 'vue3'; - - let mockStartedAPI: any; - - jest.mock('@storybook/preview-api', () => { - const previewAPI = jest.requireActual('@storybook/preview-api'); - - return { - ...previewAPI, - start: (...args: any[]) => { - mockStartedAPI = previewAPI.start(...args); - return mockStartedAPI; - }, - }; - }); - - jest.mock('@storybook/vue3', () => { - const renderAPI = jest.requireActual('@storybook/vue3'); - - renderAPI.addDecorator = mockStartedAPI.clientApi.addDecorator; - renderAPI.addParameters = mockStartedAPI.clientApi.addParameters; - - return renderAPI; - }); - - // eslint-disable-next-line global-require - const storybook = require('@storybook/vue3'); - - configure({ - ...options, - storybook, - }); - - return { - framework: 'vue3' as const, - renderTree: jest.requireActual('./renderTree').default, - renderShallowTree: () => { - throw new Error('Shallow renderer is not supported for Vue 3'); - }, - storybook, - }; -} - -const vueLoader: Loader = { - load, - test, -}; - -export default vueLoader; diff --git a/code/addons/storyshots-core/src/frameworks/vue3/renderTree.ts b/code/addons/storyshots-core/src/frameworks/vue3/renderTree.ts deleted file mode 100644 index 854cb485b3c1..000000000000 --- a/code/addons/storyshots-core/src/frameworks/vue3/renderTree.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as Vue from 'vue'; -import { global } from '@storybook/global'; - -const { document } = global; - -// This is cast as `any` to workaround type errors caused by Vue 2 types -const { h, createApp } = Vue as any; - -function getRenderedTree(story: any) { - const component = story.render(); - - const app = createApp({ - render() { - return h(component, story.args); - }, - }); - - const vm = app.mount(document.createElement('div')); - vm.$forceUpdate(); - return vm.$el; -} - -export default getRenderedTree; diff --git a/code/addons/storyshots-core/src/frameworks/web-components/loader.ts b/code/addons/storyshots-core/src/frameworks/web-components/loader.ts deleted file mode 100644 index e3536d85d99d..000000000000 --- a/code/addons/storyshots-core/src/frameworks/web-components/loader.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { global } from '@storybook/global'; -import configure from '../configure'; -import type { Loader } from '../Loader'; -import type { StoryshotsOptions } from '../../api/StoryshotsOptions'; - -function test(options: StoryshotsOptions): boolean { - return options.framework === 'web-components'; -} - -function load(options: StoryshotsOptions) { - global.STORYBOOK_ENV = 'web-components'; - - let mockStartedAPI: any; - - jest.mock('@storybook/preview-api', () => { - const previewAPI = jest.requireActual('@storybook/preview-api'); - - return { - ...previewAPI, - start: (...args: any[]) => { - mockStartedAPI = previewAPI.start(...args); - return mockStartedAPI; - }, - }; - }); - - jest.mock('@storybook/html', () => { - const renderAPI = jest.requireActual('@storybook/html'); - - renderAPI.addDecorator = mockStartedAPI.clientApi.addDecorator; - renderAPI.addParameters = mockStartedAPI.clientApi.addParameters; - - return renderAPI; - }); - - // eslint-disable-next-line global-require - const storybook = require('@storybook/html'); - - configure({ - ...options, - storybook, - }); - - return { - framework: 'web-components' as const, - renderTree: jest.requireActual('./renderTree').default, - renderShallowTree: () => { - throw new Error('Shallow renderer is not supported for web-components'); - }, - storybook, - }; -} - -const webComponentsLoader: Loader = { - load, - test, -}; - -export default webComponentsLoader; diff --git a/code/addons/storyshots-core/src/frameworks/web-components/renderTree.ts b/code/addons/storyshots-core/src/frameworks/web-components/renderTree.ts deleted file mode 100644 index 8c45ea52eaca..000000000000 --- a/code/addons/storyshots-core/src/frameworks/web-components/renderTree.ts +++ /dev/null @@ -1,6 +0,0 @@ -function getRenderedTree(story: { render: () => any }) { - const component = story.render(); - return component.getHTML ? component.getHTML() : component; -} - -export default getRenderedTree; diff --git a/code/addons/storyshots-core/src/index.ts b/code/addons/storyshots-core/src/index.ts deleted file mode 100644 index 1ded51620241..000000000000 --- a/code/addons/storyshots-core/src/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -import api from './api'; -import { - snapshotWithOptions, - multiSnapshotWithOptions, - renderOnly, - renderWithOptions, - shallowSnapshot, - snapshot, -} from './test-bodies'; - -export { - snapshotWithOptions, - multiSnapshotWithOptions, - renderOnly, - renderWithOptions, - shallowSnapshot, - snapshot, -}; - -export * from './Stories2SnapsConverter'; -export * from './frameworks'; - -export default api; diff --git a/code/addons/storyshots-core/src/test-bodies.ts b/code/addons/storyshots-core/src/test-bodies.ts deleted file mode 100644 index 3dc307d6b847..000000000000 --- a/code/addons/storyshots-core/src/test-bodies.ts +++ /dev/null @@ -1,85 +0,0 @@ -import 'jest-specific-snapshot'; -import type { - StoryshotsTestMethod, - TestMethodOptions, - StoryshotsOptions, -} from './api/StoryshotsOptions'; - -const isFunction = (obj: any) => !!(obj && obj.constructor && obj.call && obj.apply); -const optionsOrCallOptions = (opts: any, story: any) => (isFunction(opts) ? opts(story) : opts); - -type SnapshotsWithOptionsArgType = Pick | Function; - -type SnapshotsWithOptionsReturnType = ( - options: Pick -) => any; - -export function snapshotWithOptions( - options: SnapshotsWithOptionsArgType = {} -): SnapshotsWithOptionsReturnType { - return ({ story, context, renderTree, snapshotFileName }) => { - const result = renderTree(story, context, optionsOrCallOptions(options, story)); - - function match(tree: any) { - let target = tree; - const isReact = story.parameters.renderer === 'react'; - - if (isReact && typeof tree.childAt === 'function') { - target = tree.childAt(0); - } - if (isReact && Array.isArray(tree.children)) { - [target] = tree.children; - } - - if (snapshotFileName) { - expect(target).toMatchSpecificSnapshot(snapshotFileName); - } else { - expect(target).toMatchSnapshot(); - } - - if (typeof tree.unmount === 'function') { - tree.unmount(); - } - } - - if (typeof result.then === 'function') { - return result.then(match); - } - - return match(result); - }; -} - -export function multiSnapshotWithOptions( - options: SnapshotsWithOptionsArgType = {} -): StoryshotsTestMethod { - return ({ story, context, renderTree, stories2snapsConverter }) => { - const snapshotFileName = stories2snapsConverter.getSnapshotFileName(context); - return snapshotWithOptions(options)({ story, context, renderTree, snapshotFileName }); - }; -} - -export const shallowSnapshot: StoryshotsTestMethod = ({ - story, - context, - renderShallowTree, - options = {}, -}) => { - const result = renderShallowTree(story, context, options); - expect(result).toMatchSnapshot(); -}; - -export function renderWithOptions(options = {}): StoryshotsTestMethod { - return ({ story, context, renderTree }) => { - const result = renderTree(story, context, options); - if (typeof result.then === 'function') { - return result; - } - - return undefined; - }; -} - -export const renderOnly = renderWithOptions(); - -export const snapshot = snapshotWithOptions(); diff --git a/code/addons/storyshots-core/src/typings.d.ts b/code/addons/storyshots-core/src/typings.d.ts deleted file mode 100644 index 2ae47a5617de..000000000000 --- a/code/addons/storyshots-core/src/typings.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -/* eslint-disable @typescript-eslint/naming-convention */ -declare module 'jest-preset-angular/*'; -declare module 'preact-render-to-string/jsx'; -declare module 'react-test-renderer*'; - -declare module '@storybook/babel-plugin-require-context-hook/register'; - -declare var STORYBOOK_ENV: any; -declare var STORIES: any; - -declare var CONFIG_TYPE: 'DEVELOPMENT' | 'PRODUCTION'; -declare var FEATURES: import('@storybook/types').StorybookConfig['features']; - -declare var __STORYBOOK_STORY_STORE__: any; -declare var __requireContext: any; diff --git a/code/addons/storyshots-core/stories/__snapshots__/storyshot.defaultExport.test.js.snap b/code/addons/storyshots-core/stories/__snapshots__/storyshot.defaultExport.test.js.snap deleted file mode 100644 index 42d99ae740ca..000000000000 --- a/code/addons/storyshots-core/stories/__snapshots__/storyshot.defaultExport.test.js.snap +++ /dev/null @@ -1,44 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Another Button with some emoji 1`] = ` -

- prefix - - - - suffix -
-`; - -exports[`Storyshots Another Button with text 1`] = ` -
- prefix - - - - suffix -
-`; - -exports[`Storyshots Text Simple 1`] = ` -
- prefix - - contents - - suffix -
-`; diff --git a/code/addons/storyshots-core/stories/__snapshots__/storyshot.enzyme.test.js.snap b/code/addons/storyshots-core/stories/__snapshots__/storyshot.enzyme.test.js.snap deleted file mode 100644 index 984165bef39c..000000000000 --- a/code/addons/storyshots-core/stories/__snapshots__/storyshot.enzyme.test.js.snap +++ /dev/null @@ -1,56 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Another Button with some emoji 1`] = ` - -
- prefix - - - - - - suffix -
-
-`; - -exports[`Storyshots Another Button with text 1`] = ` - -
- prefix - - - - - - suffix -
-
-`; - -exports[`Storyshots Text Simple 1`] = ` - -
- prefix - - - contents - - - suffix -
-
-`; diff --git a/code/addons/storyshots-core/stories/__snapshots__/storyshot.metadata.test.js.snap b/code/addons/storyshots-core/stories/__snapshots__/storyshot.metadata.test.js.snap deleted file mode 100644 index 42d99ae740ca..000000000000 --- a/code/addons/storyshots-core/stories/__snapshots__/storyshot.metadata.test.js.snap +++ /dev/null @@ -1,44 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Another Button with some emoji 1`] = ` -
- prefix - - - - suffix -
-`; - -exports[`Storyshots Another Button with text 1`] = ` -
- prefix - - - - suffix -
-`; - -exports[`Storyshots Text Simple 1`] = ` -
- prefix - - contents - - suffix -
-`; diff --git a/code/addons/storyshots-core/stories/__snapshots__/storyshot.shallow.test.js.snap b/code/addons/storyshots-core/stories/__snapshots__/storyshot.shallow.test.js.snap deleted file mode 100644 index d7def107120a..000000000000 --- a/code/addons/storyshots-core/stories/__snapshots__/storyshot.shallow.test.js.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Another Button with some emoji 1`] = ` -
- prefix - - - - suffix -
-`; - -exports[`Storyshots Another Button with text 1`] = ` -
- prefix - - - - suffix -
-`; - -exports[`Storyshots Text Simple 1`] = ` -
- prefix - - - - suffix -
-`; diff --git a/code/addons/storyshots-core/stories/__snapshots__/storyshot.shallowWithOptions.test.js.snap b/code/addons/storyshots-core/stories/__snapshots__/storyshot.shallowWithOptions.test.js.snap deleted file mode 100644 index d7def107120a..000000000000 --- a/code/addons/storyshots-core/stories/__snapshots__/storyshot.shallowWithOptions.test.js.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Another Button with some emoji 1`] = ` -
- prefix - - - - suffix -
-`; - -exports[`Storyshots Another Button with text 1`] = ` -
- prefix - - - - suffix -
-`; - -exports[`Storyshots Text Simple 1`] = ` -
- prefix - - - - suffix -
-`; diff --git a/code/addons/storyshots-core/stories/__snapshots__/storyshot.snapshotWithOptionsFunction.test.js.snap b/code/addons/storyshots-core/stories/__snapshots__/storyshot.snapshotWithOptionsFunction.test.js.snap deleted file mode 100644 index 42d99ae740ca..000000000000 --- a/code/addons/storyshots-core/stories/__snapshots__/storyshot.snapshotWithOptionsFunction.test.js.snap +++ /dev/null @@ -1,44 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Another Button with some emoji 1`] = ` -
- prefix - - - - suffix -
-`; - -exports[`Storyshots Another Button with text 1`] = ` -
- prefix - - - - suffix -
-`; - -exports[`Storyshots Text Simple 1`] = ` -
- prefix - - contents - - suffix -
-`; diff --git a/code/addons/storyshots-core/stories/default_export/Extra.stories.jsx b/code/addons/storyshots-core/stories/default_export/Extra.stories.jsx deleted file mode 100644 index 4886a1c158f7..000000000000 --- a/code/addons/storyshots-core/stories/default_export/Extra.stories.jsx +++ /dev/null @@ -1,15 +0,0 @@ -/* eslint-disable react/button-has-type */ -import React from 'react'; - -import { storiesOf } from '@storybook/react'; -import { action } from '@storybook/addon-actions'; - -storiesOf('Another Button', module) - .add('with text', () => ) - .add('with some emoji', () => ( - - )); diff --git a/code/addons/storyshots-core/stories/default_export/Text.stories.jsx b/code/addons/storyshots-core/stories/default_export/Text.stories.jsx deleted file mode 100644 index e87143f2c786..000000000000 --- a/code/addons/storyshots-core/stories/default_export/Text.stories.jsx +++ /dev/null @@ -1,5 +0,0 @@ -export default { - title: 'Text', -}; - -export const Simple = () => 'contents'; diff --git a/code/addons/storyshots-core/stories/default_export/__snapshots__/Extra.stories@Another-_-Button@with-_-some-_-emoji.boo b/code/addons/storyshots-core/stories/default_export/__snapshots__/Extra.stories@Another-_-Button@with-_-some-_-emoji.boo deleted file mode 100644 index a1027859204f..000000000000 --- a/code/addons/storyshots-core/stories/default_export/__snapshots__/Extra.stories@Another-_-Button@with-_-some-_-emoji.boo +++ /dev/null @@ -1,14 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Another Button with some emoji 1`] = ` - -`; diff --git a/code/addons/storyshots-core/stories/default_export/__snapshots__/Extra.stories@Another-_-Button@with-_-text.boo b/code/addons/storyshots-core/stories/default_export/__snapshots__/Extra.stories@Another-_-Button@with-_-text.boo deleted file mode 100644 index e344c7924619..000000000000 --- a/code/addons/storyshots-core/stories/default_export/__snapshots__/Extra.stories@Another-_-Button@with-_-text.boo +++ /dev/null @@ -1,9 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Another Button with text 1`] = ` - -`; diff --git a/code/addons/storyshots-core/stories/default_export/main.js b/code/addons/storyshots-core/stories/default_export/main.js deleted file mode 100644 index 233070243d8a..000000000000 --- a/code/addons/storyshots-core/stories/default_export/main.js +++ /dev/null @@ -1,5 +0,0 @@ -const config = { - stories: ['./Text.stories.jsx', './Extra.stories.jsx'], -}; - -export default config; diff --git a/code/addons/storyshots-core/stories/default_export/preview.jsx b/code/addons/storyshots-core/stories/default_export/preview.jsx deleted file mode 100644 index 54fec6401462..000000000000 --- a/code/addons/storyshots-core/stories/default_export/preview.jsx +++ /dev/null @@ -1,15 +0,0 @@ -/* eslint-disable react/prop-types */ -import React from 'react'; - -const Container = ({ children }) =>
{children}
; - -export const decorators = [ - (StoryFn, { parameters, globals }) => ( - - {parameters.prefix} {globals.suffix} - - ), -]; - -export const parameters = { prefix: 'prefix' }; -export const globals = { suffix: 'suffix' }; diff --git a/code/addons/storyshots-core/stories/exported_metadata/Async.stories.jsx b/code/addons/storyshots-core/stories/exported_metadata/Async.stories.jsx deleted file mode 100644 index f469d8b2a638..000000000000 --- a/code/addons/storyshots-core/stories/exported_metadata/Async.stories.jsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; - -export const EXPECTED_VALUE = 'THIS IS SO DONE'; -export const TIMEOUT = 5; - -class AsyncTestComponent extends React.Component { - constructor(props) { - super(props); - this.state = { - value: '', - }; - } - - componentDidMount() { - setTimeout(() => { - this.setState({ - value: EXPECTED_VALUE, - }); - }, TIMEOUT); - } - - render() { - const { value } = this.state; - return

{value}

; - } -} - -export default { - title: 'Async', - includeStories: ['WithTimeout'], -}; - -export const WithTimeout = () => ; -WithTimeout.storyName = `with ${TIMEOUT}ms timeout simulating async operation`; diff --git a/code/addons/storyshots-core/stories/exported_metadata/Extra.stories.jsx b/code/addons/storyshots-core/stories/exported_metadata/Extra.stories.jsx deleted file mode 100644 index 4886a1c158f7..000000000000 --- a/code/addons/storyshots-core/stories/exported_metadata/Extra.stories.jsx +++ /dev/null @@ -1,15 +0,0 @@ -/* eslint-disable react/button-has-type */ -import React from 'react'; - -import { storiesOf } from '@storybook/react'; -import { action } from '@storybook/addon-actions'; - -storiesOf('Another Button', module) - .add('with text', () => ) - .add('with some emoji', () => ( - - )); diff --git a/code/addons/storyshots-core/stories/exported_metadata/Text.stories.jsx b/code/addons/storyshots-core/stories/exported_metadata/Text.stories.jsx deleted file mode 100644 index e87143f2c786..000000000000 --- a/code/addons/storyshots-core/stories/exported_metadata/Text.stories.jsx +++ /dev/null @@ -1,5 +0,0 @@ -export default { - title: 'Text', -}; - -export const Simple = () => 'contents'; diff --git a/code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Extra.stories.storyshot b/code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Extra.stories.storyshot deleted file mode 100644 index 841630b0fc01..000000000000 --- a/code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Extra.stories.storyshot +++ /dev/null @@ -1,34 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Another Button with some emoji 1`] = ` -
- prefix - - - - suffix -
-`; - -exports[`Storyshots Another Button with text 1`] = ` -
- prefix - - - - suffix -
-`; diff --git a/code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Extra.stories@Another-_-Button@with-_-some-_-emoji.boo b/code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Extra.stories@Another-_-Button@with-_-some-_-emoji.boo deleted file mode 100644 index a1027859204f..000000000000 --- a/code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Extra.stories@Another-_-Button@with-_-some-_-emoji.boo +++ /dev/null @@ -1,14 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Another Button with some emoji 1`] = ` - -`; diff --git a/code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Extra.stories@Another-_-Button@with-_-text.boo b/code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Extra.stories@Another-_-Button@with-_-text.boo deleted file mode 100644 index e344c7924619..000000000000 --- a/code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Extra.stories@Another-_-Button@with-_-text.boo +++ /dev/null @@ -1,9 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Another Button with text 1`] = ` - -`; diff --git a/code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Text.stories.storyshot b/code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Text.stories.storyshot deleted file mode 100644 index c9965e394a4c..000000000000 --- a/code/addons/storyshots-core/stories/exported_metadata/__snapshots__/Text.stories.storyshot +++ /dev/null @@ -1,11 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Storyshots Text Simple 1`] = ` -
- prefix - - contents - - suffix -
-`; diff --git a/code/addons/storyshots-core/stories/exported_metadata/main.js b/code/addons/storyshots-core/stories/exported_metadata/main.js deleted file mode 100644 index fbb87ec1dfc5..000000000000 --- a/code/addons/storyshots-core/stories/exported_metadata/main.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - stories: ['./Text.stories.jsx', './Extra.stories.jsx'], -}; diff --git a/code/addons/storyshots-core/stories/exported_metadata/preview.jsx b/code/addons/storyshots-core/stories/exported_metadata/preview.jsx deleted file mode 100644 index 54fec6401462..000000000000 --- a/code/addons/storyshots-core/stories/exported_metadata/preview.jsx +++ /dev/null @@ -1,15 +0,0 @@ -/* eslint-disable react/prop-types */ -import React from 'react'; - -const Container = ({ children }) =>
{children}
; - -export const decorators = [ - (StoryFn, { parameters, globals }) => ( - - {parameters.prefix} {globals.suffix} - - ), -]; - -export const parameters = { prefix: 'prefix' }; -export const globals = { suffix: 'suffix' }; diff --git a/code/addons/storyshots-core/stories/storyshot.async.test.js b/code/addons/storyshots-core/stories/storyshot.async.test.js deleted file mode 100644 index a4f13e34ddc6..000000000000 --- a/code/addons/storyshots-core/stories/storyshot.async.test.js +++ /dev/null @@ -1,41 +0,0 @@ -import path from 'path'; -import { render, screen, waitFor } from '@testing-library/react'; -import initStoryshots, { Stories2SnapsConverter } from '../src'; -import { EXPECTED_VALUE } from './exported_metadata/Async.stories.jsx'; - -initStoryshots({ - asyncJest: true, - framework: 'react', - integrityOptions: false, - configPath: path.join(__dirname, 'exported_metadata'), - - // When async is true we need to provide a test method that - // calls done() when at the end of the test method - test: async ({ story, context, done }) => { - expect(done).toBeDefined(); - - // This is a storyOf Async (see ./required_with_context/Async.stories) - if (context.kind === 'Async') { - const converter = new Stories2SnapsConverter({ snapshotExtension: '.async.storyshot' }); - const snapshotFilename = converter.getSnapshotFileName(context); - const storyElement = story.render(); - - // Mount the component - const { container } = render(storyElement); - - // The Async component should not contain the expected value - expect(screen.queryByText(EXPECTED_VALUE)).toBeFalsy(); - - await waitFor(() => { - expect(screen.getByText(EXPECTED_VALUE)).toBeInTheDocument(); - expect(container.firstChild).toMatchSpecificSnapshot(snapshotFilename); - }); - - // finally mark test as done - done(); - } else { - // If not async, mark the test as done - done(); - } - }, -}); diff --git a/code/addons/storyshots-core/stories/storyshot.configFunc.test.js b/code/addons/storyshots-core/stories/storyshot.configFunc.test.js deleted file mode 100644 index 346c581207b9..000000000000 --- a/code/addons/storyshots-core/stories/storyshot.configFunc.test.js +++ /dev/null @@ -1,50 +0,0 @@ -import path from 'path'; -import initStoryshots, { multiSnapshotWithOptions, Stories2SnapsConverter } from '../src'; - -/* deprecated and will be removed in Storybook 8.0 */ - -class AnotherStories2SnapsConverter extends Stories2SnapsConverter { - getSnapshotFileName(context) { - const { fileName, kind, name } = context; - const { dir, name: filename } = path.parse(fileName); - const uniqueName = `${filename}@${kind.replace(/ /g, '-_-')}@${name.replace(/ /g, '-_-')}`; - const { snapshotsDirName, snapshotExtension } = this.options; - - return path.format({ - dir: path.join(dir, snapshotsDirName), - name: uniqueName, - ext: snapshotExtension, - }); - } - - getPossibleStoriesFiles(storyshotFile) { - const { dir, name } = path.parse(storyshotFile); - const { storiesExtensions } = this.options; - - const [fileName] = name.split('@'); - - return storiesExtensions.map((ext) => - path.format({ - dir: path.dirname(dir), - name: fileName, - ext, - }) - ); - } -} - -initStoryshots({ - framework: 'react', - integrityOptions: { cwd: __dirname }, - stories2snapsConverter: new AnotherStories2SnapsConverter({ snapshotExtension: '.boo' }), - config: ({ configure }) => - configure( - () => { - // eslint-disable-next-line global-require - require('./exported_metadata/Extra.stories.jsx'); - }, - module, - false - ), - test: multiSnapshotWithOptions(), -}); diff --git a/code/addons/storyshots-core/stories/storyshot.defaultExport.test.js b/code/addons/storyshots-core/stories/storyshot.defaultExport.test.js deleted file mode 100644 index 0d88bddea1ff..000000000000 --- a/code/addons/storyshots-core/stories/storyshot.defaultExport.test.js +++ /dev/null @@ -1,7 +0,0 @@ -import path from 'path'; -import initStoryshots from '../src'; - -initStoryshots({ - framework: 'react', - configPath: path.join(__dirname, 'default_export'), -}); diff --git a/code/addons/storyshots-core/stories/storyshot.enzyme.test.js b/code/addons/storyshots-core/stories/storyshot.enzyme.test.js deleted file mode 100644 index afaaf9b3b537..000000000000 --- a/code/addons/storyshots-core/stories/storyshot.enzyme.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import path from 'path'; -import { mount, configure } from 'enzyme'; -// @ts-expect-error (Converted from ts-ignore) -import Adapter from 'enzyme-adapter-react-16'; -import initStoryshots from '../src'; - -configure({ adapter: new Adapter() }); - -initStoryshots({ - framework: 'react', - configPath: path.join(__dirname, 'exported_metadata'), - renderer: mount, -}); diff --git a/code/addons/storyshots-core/stories/storyshot.metadata.test.js b/code/addons/storyshots-core/stories/storyshot.metadata.test.js deleted file mode 100644 index 971390d2b513..000000000000 --- a/code/addons/storyshots-core/stories/storyshot.metadata.test.js +++ /dev/null @@ -1,9 +0,0 @@ -import path from 'path'; -import initStoryshots from '../src'; - -// jest.mock('@storybook/node-logger'); - -initStoryshots({ - framework: 'react', - configPath: path.join(__dirname, 'exported_metadata'), -}); diff --git a/code/addons/storyshots-core/stories/storyshot.renderOnly.test.js b/code/addons/storyshots-core/stories/storyshot.renderOnly.test.js deleted file mode 100644 index e620fd15ed47..000000000000 --- a/code/addons/storyshots-core/stories/storyshot.renderOnly.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import path from 'path'; -import initStoryshots, { renderOnly } from '../src'; - -initStoryshots({ - framework: 'react', - configPath: path.join(__dirname, 'exported_metadata'), - test: renderOnly, -}); diff --git a/code/addons/storyshots-core/stories/storyshot.renderWithOptions.test.js b/code/addons/storyshots-core/stories/storyshot.renderWithOptions.test.js deleted file mode 100644 index 4aac113cedd4..000000000000 --- a/code/addons/storyshots-core/stories/storyshot.renderWithOptions.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import path from 'path'; -import initStoryshots, { renderWithOptions } from '../src'; - -initStoryshots({ - framework: 'react', - configPath: path.join(__dirname, 'exported_metadata'), - test: renderWithOptions({}), -}); diff --git a/code/addons/storyshots-core/stories/storyshot.shallow.test.js b/code/addons/storyshots-core/stories/storyshot.shallow.test.js deleted file mode 100644 index 62cf107e089a..000000000000 --- a/code/addons/storyshots-core/stories/storyshot.shallow.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import path from 'path'; -import initStoryshots, { shallowSnapshot } from '../src'; - -initStoryshots({ - framework: 'react', - configPath: path.join(__dirname, 'exported_metadata'), - test: shallowSnapshot, -}); diff --git a/code/addons/storyshots-core/stories/storyshot.shallowWithOptions.test.js b/code/addons/storyshots-core/stories/storyshot.shallowWithOptions.test.js deleted file mode 100644 index 5a4c45b78257..000000000000 --- a/code/addons/storyshots-core/stories/storyshot.shallowWithOptions.test.js +++ /dev/null @@ -1,11 +0,0 @@ -import path from 'path'; -import initStoryshots, { shallowSnapshot } from '../src'; - -initStoryshots({ - framework: 'react', - configPath: path.join(__dirname, 'exported_metadata'), - test: (data) => - shallowSnapshot({ - ...data, - }), -}); diff --git a/code/addons/storyshots-core/stories/storyshot.snapshotWithOptionsFunction.test.js b/code/addons/storyshots-core/stories/storyshot.snapshotWithOptionsFunction.test.js deleted file mode 100644 index f6fc73770aa9..000000000000 --- a/code/addons/storyshots-core/stories/storyshot.snapshotWithOptionsFunction.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import path from 'path'; -import initStoryshots, { snapshotWithOptions } from '../src'; - -initStoryshots({ - framework: 'react', - configPath: path.join(__dirname, 'exported_metadata'), - test: snapshotWithOptions(() => ({})), -}); diff --git a/code/addons/storyshots-core/stories/storyshot.test.js b/code/addons/storyshots-core/stories/storyshot.test.js deleted file mode 100644 index 9a1dde49cb99..000000000000 --- a/code/addons/storyshots-core/stories/storyshot.test.js +++ /dev/null @@ -1,13 +0,0 @@ -import path from 'path'; -import initStoryshots, { multiSnapshotWithOptions } from '../src'; - -jest.mock('@storybook/node-logger'); - -// with react-test-renderer -initStoryshots({ - framework: 'react', - // Ignore integrityOptions for async.storyshot because only run when asyncJest is true - integrityOptions: { cwd: __dirname, ignore: ['**/**.async.storyshot'] }, - configPath: path.join(__dirname, 'exported_metadata'), - test: multiSnapshotWithOptions(), -}); diff --git a/code/addons/storyshots-core/tsconfig.build.json b/code/addons/storyshots-core/tsconfig.build.json deleted file mode 100644 index dae6c1e39197..000000000000 --- a/code/addons/storyshots-core/tsconfig.build.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compileOnSave": false, - "compilerOptions": { - "target": "ES2020", - "module": "CommonJS", - "lib": ["es2020", "dom"], - "esModuleInterop": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "declaration": true, - "outDir": "dist", - "types": ["node"], - "skipLibCheck": true, - "resolveJsonModule": true, - "allowJs": true, - "pretty": true, - "noErrorTruncation": true, - "listEmittedFiles": false, - "noUnusedLocals": false - }, - "include": ["src/**/*", "src/**/*.json"] -} diff --git a/code/addons/storyshots-core/tsconfig.json b/code/addons/storyshots-core/tsconfig.json deleted file mode 100644 index 6d43397802f1..000000000000 --- a/code/addons/storyshots-core/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "declaration": true, - "jsx": "preserve", - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "strict": true - }, - "include": ["src/**/*.ts"] -} diff --git a/code/addons/storyshots-puppeteer/.eslintrc.js b/code/addons/storyshots-puppeteer/.eslintrc.js deleted file mode 100644 index cc34d2deab0f..000000000000 --- a/code/addons/storyshots-puppeteer/.eslintrc.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = { - settings: { - 'import/core-modules': ['puppeteer'], - }, -}; diff --git a/code/addons/storyshots-puppeteer/README.md b/code/addons/storyshots-puppeteer/README.md deleted file mode 100644 index 2175c1d436d4..000000000000 --- a/code/addons/storyshots-puppeteer/README.md +++ /dev/null @@ -1,361 +0,0 @@ -# StoryShots + [Puppeteer](https://github.com/GoogleChrome/puppeteer) - -## Getting Started - -Add the following modules into your app. - -```sh -npm install @storybook/addon-storyshots-puppeteer puppeteer --save-dev -``` - -⚠️ As of Storybook 5.3 `puppeteer` is no longer included in the addon dependencies and must be added to your project directly. - -## Configure Storyshots for Puppeteer tests - -⚠️ **React-native** is **not supported** by this test function. - -When running Puppeteer tests for your stories, you have two options: - -- Have a storybook running (ie. accessible via http(s), for instance using `npm run storybook`) -- Have a static build of the storybook (for instance, using `npm run build-storybook`) - -Then you will need to reference the storybook URL (`file://...` if local, `http(s)://...` if served) - -## _puppeteerTest_ - -Allows to define arbitrary Puppeteer tests as `story.parameters.puppeteerTest` function. - -You can either create a new Storyshots instance or edit the one you previously used: - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer'; - -initStoryshots({ suite: 'Puppeteer storyshots', test: puppeteerTest() }); -``` - -Then, in your stories: - -```js -export const myExample = () => { - ... -}; -myExample.parameters = { - async puppeteerTest(page) { - const element = await page.$(''); - await element.click(); - expect(something).toBe(something); - }, -}; -``` - -This will assume you have a storybook running on at __. -Internally here are the steps: - -- Launches a Chrome headless using [puppeteer](https://github.com/GoogleChrome/puppeteer) -- Browses each stories (calling __ URL), -- Runs the `parameters.puppeteerTest` function if it's defined. - -### Specifying the storybook URL - -If you want to set specific storybook URL, you can specify via the `storybookUrl` parameter, see below: - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer'; - -initStoryshots({ - suite: 'Puppeteer storyshots', - test: puppeteerTest({ storybookUrl: 'http://my-specific-domain.com:9010' }), -}); -``` - -The above config will use __ for tests. You can also use query parameters in your URL (e.g. for setting a different background for your storyshots, if you use `@storybook/addon-backgrounds`). - -You may also use a local static build of storybook if you do not want to run the webpack dev-server: - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer'; - -initStoryshots({ - suite: 'Puppeteer storyshots', - test: puppeteerTest({ - storybookUrl: 'file:///path/to/my/storybook-static', - // storybookUrl: 'file://${path.resolve(__dirname, '../storybook-static')}' - }), -}); -``` - -### Specifying options to _goto()_ (Puppeteer API) - -You might use `getGotoOptions` to specify options when the storybook is navigating to a story (using the `goto` method). Will be passed to [Puppeteer .goto() fn](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagegotourl-options) - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer'; - -const getGotoOptions = ({ context, url }) => { - return { - waitUntil: 'networkidle0', - }; -}; - -initStoryshots({ - suite: 'Puppeteer storyshots', - test: puppeteerTest({ storybookUrl: 'http://localhost:6006', getGotoOptions }), -}); -``` - -### Customizing browser launch options (Puppeteer API) - -You might use the `browserLaunchOptions` to specify options for the default browser instance. Will be passed to [puppeteer.launch()](https://pptr.dev/api/puppeteer.puppeteernode.launch) - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer'; - -initStoryshots({ - suite: 'Puppeteer storyshots', - test: puppeteerTest({ - storybookUrl: 'https://some-local-ssl-url:7777', - browserLaunchOptions: { - // For ignoring self-signed certificates - ignoreHTTPSErrors: true, - }, - }), -}); -``` - -### Specifying custom Chrome executable path (Puppeteer API) - -You might use `chromeExecutablePath` to specify the path to a different version of Chrome, without downloading Chromium. Will be passed to [Runs a bundled version of Chromium](https://github.com/GoogleChrome/puppeteer#default-runtime-settings) - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer'; - -const chromeExecutablePath = '/usr/local/bin/chrome'; - -initStoryshots({ - suite: 'Puppeteer storyshots', - test: puppeteerTest({ storybookUrl: 'http://localhost:6006', chromeExecutablePath }), -}); -``` - -Alternatively, you may set the `SB_CHROMIUM_PATH` environment variable. If both are set, then `chromeExecutablePath` will take precedence. - -### Specifying a custom Puppeteer `browser` instance - -You might use the async `getCustomBrowser` function to obtain a custom instance of a Puppeteer `browser` object. This will prevent `storyshots-puppeteer` from creating its own `browser`. It will create and close pages within the `browser`, and it is your responsibility to manage the lifecycle of the `browser` itself. - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer'; -import puppeteer from 'puppeteer'; - -(async function () { - initStoryshots({ - suite: 'Puppeteer storyshots', - test: puppeteerTest({ - storybookUrl: 'http://localhost:6006', - getCustomBrowser: () => puppeteer.connect({ browserWSEndpoint: 'ws://yourUrl' }), - }), - }); -})(); -``` - -### Customizing a `page` instance - -Sometimes, there is a need to customize a page before it calls the `goto` api. - -An example of device emulation: - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { puppeteerTest } from '@storybook/addon-storyshots-puppeteer'; -const devices = require('puppeteer/DeviceDescriptors'); - -const iPhone = devices['iPhone 6']; - -function customizePage(page) { - return page.emulate(iPhone); -} - -initStoryshots({ - suite: 'Puppeteer storyshots', - test: puppeteerTest({ - storybookUrl: 'http://localhost:6006', - customizePage, - }), -}); -``` - -### Specifying setup and tests timeout - -By default, `@storybook/addon-storyshots-puppeteer` uses 15 second timeouts for browser setup and test functions. -Those can be customized with `setupTimeout` and `testTimeout` parameters. - -### Integrate Puppeteer storyshots with regular app - -You may want to use another Jest project to run your Puppeteer storyshots as they require more resources: Chrome and Storybook built/served. - -### Integrate Puppeteer storyshots with [Create React App](https://github.com/facebookincubator/create-react-app) - -You have two options here, you can either: - -- Add the storyshots configuration inside any of your `test.js` file. You must ensure you have either a running storybook or a static build available. - -- Create a custom test file using Jest outside of the CRA scope: - - A more robust approach would be to separate existing test files ran by create-react-app (anything `(test|spec).js` suffixed files) from the test files to run Puppeteer storyshots. - This use case can be achieved by using a custom name for the test file, ie something like `puppeteer-storyshots.runner.js`. This file will contain the `initStoryshots` call with Puppeteer storyshots configuration. - Then you will create a separate script entry in your package.json, for instance - - ```json - { - "scripts": { - "puppeteer-storyshots": "jest puppeteer-storyshots.runner.js --config path/to/custom/jest.config.json" - } - } - ``` - - Note that you will certainly need a custom config file for Jest as you run it outside of the CRA scope and thus you do not have the built-in config. - - Once that's setup, you can run `npm run puppeteer-storyshots`. - -### Reminder - -Puppeteer launches a web browser (Chrome) internally. - -The browser opens a page (either using the static build of storybook or a running instance of Storybook) - -If you run your test without either the static build or a running instance, this wont work. - -To make sure your tests run against the latest changes of your Storybook, you must keep your static build or running Storybook up-to-date. -This can be achieved by adding a step before running the test ie: `npm run build-storybook && npm run image-snapshots`. -If you run the Puppeteer storyshots against a running Storybook in dev mode, you don't have to worry about the stories being up-to-date because the dev-server is watching changes and rebuilds automatically. - -## _axeTest_ - -Runs [Axe](https://www.deque.com/axe/) accessibility checks and verifies that they pass using [jest-puppeteer-axe](https://github.com/WordPress/gutenberg/tree/master/packages/jest-puppeteer-axe). - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { axeTest } from '@storybook/addon-storyshots-puppeteer'; - -initStoryshots({ suite: 'A11y checks', test: axeTest() }); -``` - -For configuration, it uses the same `story.parameters.a11y` parameter as [`@storybook/addon-a11y`](https://github.com/storybookjs/storybook/tree/next/code/addons/a11y#parameters) - -### Specifying options to `axeTest` - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { axeTest } from '@storybook/addon-storyshots-puppeteer'; - -const beforeAxeTest = (page, { context: { kind, story }, url }) => { - return new Promise((resolve) => - setTimeout(() => { - resolve(); - }, 600) - ); -}; - -initStoryshots({ suite: 'A11y checks', test: axeTest({ beforeAxeTest }) }); -``` - -`beforeAxeTest` receives the [Puppeteer page instance](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-page) and an object: `{ context: {kind, story}, url}`. _kind_ is the kind of the story and the _story_ its name. _url_ is the URL the browser will use to screenshot. `beforeAxeTest` is part of the promise chain and is called after the browser navigation is completed but before the screenshot is taken. It allows for triggering events on the page elements and delaying the axe test . - -## _imageSnapshots_ - -Generates and compares screenshots of your stories using [jest-image-snapshot](https://github.com/americanexpress/jest-image-snapshot). - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer'; - -initStoryshots({ suite: 'Image storyshots', test: imageSnapshot() }); -``` - -It saves all images under \_\_image_snapshots\_\_ folder. - -### Specifying options to _jest-image-snapshots_ - -If you wish to customize [jest-image-snapshot](https://github.com/americanexpress/jest-image-snapshot), then you can provide a `getMatchOptions` parameter that should return the options config object. Additionally, you can provide `beforeScreenshot` which is called before the screenshot is captured and a `afterScreenshot` handler which is called after the screenshot and receives the just created image. - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer'; -const getMatchOptions = ({ context: { kind, story }, url }) => { - return { - failureThreshold: 0.2, - failureThresholdType: 'percent', - }; -}; -const beforeScreenshot = (page, { context: { kind, story }, url }) => { - return new Promise((resolve) => - setTimeout(() => { - resolve(); - }, 600) - ); -}; -const afterScreenshot = ({ image, context }) => { - return new Promise((resolve) => - setTimeout(() => { - resolve(); - }, 600) - ); -}; -initStoryshots({ - suite: 'Image storyshots', - test: imageSnapshot({ - storybookUrl: 'http://localhost:6006', - getMatchOptions, - beforeScreenshot, - afterScreenshot, - }), -}); -``` - -`getMatchOptions` receives an object: `{ context: {kind, story}, url}`. _kind_ is the kind of the story and the _story_ its name. _url_ is the URL the browser will use to screenshot. - -`beforeScreenshot` receives the [Puppeteer page instance](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-page) and an object: `{ context: {kind, story}, url}`. _kind_ is the kind of the story and the _story_ its name. _url_ is the URL the browser will use to screenshot. `beforeScreenshot` is part of the promise chain and is called after the browser navigation is completed but before the screenshot is taken. It allows for triggering events on the page elements and delaying the screenshot and can be used avoid regressions due to mounting animations. - -`afterScreenshot` receives the created image from puppeteer. - -### Specifying options to _screenshot()_ (Puppeteer API) - -You might use `getScreenshotOptions` to specify options for screenshot. Will be passed to [Puppeteer .screenshot() fn](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagescreenshotoptions) - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer'; -const getScreenshotOptions = ({ context, url }) => { - return { - encoding: 'base64', // encoding: 'base64' is a property required by puppeteer - fullPage: false, // Do not take the full page screenshot. Default is 'true' in Storyshots., - }; -}; -initStoryshots({ - suite: 'Image storyshots', - test: imageSnapshot({ storybookUrl: 'http://localhost:6006', getScreenshotOptions }), -}); -``` - -`getScreenshotOptions` receives an object `{ context: {kind, story}, url}`. _kind_ is the kind of the story and the _story_ its name. _url_ is the URL the browser will use to screenshot. - -To create a screenshot of just a single element (with its children), rather than the page or current viewport, an ElementHandle can be returned from `beforeScreenshot`: - -```js -import initStoryshots from '@storybook/addon-storyshots'; -import { imageSnapshot } from '@storybook/addon-storyshots-puppeteer'; - -const beforeScreenshot = (page) => page.$('#storybook-root > *'); - -initStoryshots({ - suite: 'Image storyshots', - test: imageSnapshot({ storybookUrl: 'http://localhost:6006', beforeScreenshot }), -}); -``` diff --git a/code/addons/storyshots-puppeteer/jest.config.js b/code/addons/storyshots-puppeteer/jest.config.js deleted file mode 100644 index 0115c67e5629..000000000000 --- a/code/addons/storyshots-puppeteer/jest.config.js +++ /dev/null @@ -1,12 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - snapshotSerializers: [...baseConfig.snapshotSerializers, 'enzyme-to-json/serializer'], - transform: { - ...baseConfig.transform, - '^.+\\.stories\\.[jt]sx?$': '@storybook/addon-storyshots/injectFileName', - }, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/storyshots-puppeteer/package.json b/code/addons/storyshots-puppeteer/package.json deleted file mode 100644 index 71a8d68fec08..000000000000 --- a/code/addons/storyshots-puppeteer/package.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "name": "@storybook/addon-storyshots-puppeteer", - "version": "7.5.0-alpha.2", - "description": "Image snapshots addition to StoryShots based on puppeteer", - "keywords": [ - "addon", - "storybook" - ], - "homepage": "https://github.com/storybookjs/storybook/tree/next/code/addons/storyshots-puppeteer", - "bugs": { - "url": "https://github.com/storybookjs/storybook/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/storybookjs/storybook.git", - "directory": "code/addons/storyshots-puppeteer" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "license": "MIT", - "main": "dist/index.js", - "module": "dist/index.mjs", - "types": "dist/index.d.ts", - "files": [ - "dist/**/*", - "README.md", - "*.js", - "*.mjs", - "*.d.ts", - "!src/**/*" - ], - "scripts": { - "check": "../../../scripts/prepare/check.ts", - "prep": "../../../scripts/prepare/tsc.ts" - }, - "dependencies": { - "@axe-core/puppeteer": "^4.2.0", - "@storybook/csf": "^0.1.0", - "@storybook/node-logger": "workspace:*", - "@storybook/types": "workspace:*", - "@types/jest-image-snapshot": "^6.0.0", - "jest-image-snapshot": "^6.0.0" - }, - "devDependencies": { - "@types/puppeteer": "^5.4.0", - "enzyme": "^3.11.0", - "enzyme-to-json": "^3.6.1", - "puppeteer": "^2.0.0 || ^3.0.0" - }, - "peerDependencies": { - "@storybook/addon-storyshots": "workspace:*", - "puppeteer": ">=2.0.0" - }, - "peerDependenciesMeta": { - "puppeteer": { - "optional": true - } - }, - "publishConfig": { - "access": "public" - }, - "bundler": {}, - "gitHead": "e6a7fd8a655c69780bc20b9749c2699e44beae17" -} diff --git a/code/addons/storyshots-puppeteer/preset.js b/code/addons/storyshots-puppeteer/preset.js deleted file mode 100644 index 501f6e0c1310..000000000000 --- a/code/addons/storyshots-puppeteer/preset.js +++ /dev/null @@ -1,4 +0,0 @@ -// storyshots is not a typical addon because it's just a command-line tool -// nevertheless if you add it to .storybook/main.js it shouldn't complain -// https://github.com/storybookjs/storybook/issues/7959 -module.exports = {}; diff --git a/code/addons/storyshots-puppeteer/project.json b/code/addons/storyshots-puppeteer/project.json deleted file mode 100644 index 7625e336cc8d..000000000000 --- a/code/addons/storyshots-puppeteer/project.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "@storybook/addon-storyshots-puppeteer", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "implicitDependencies": [], - "type": "library" -} diff --git a/code/addons/storyshots-puppeteer/src/__tests__/url.test.ts b/code/addons/storyshots-puppeteer/src/__tests__/url.test.ts deleted file mode 100644 index cf36929dee62..000000000000 --- a/code/addons/storyshots-puppeteer/src/__tests__/url.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { toId } from '@storybook/csf'; - -import { constructUrl } from '../url'; - -jest.mock('@storybook/node-logger'); - -const id = toId('someKind', 'someStory'); - -describe('Construct URL for Storyshots', () => { - it('can use a url without path and without query params', () => { - expect(constructUrl('http://localhost:9001', id)).toEqual( - 'http://localhost:9001/iframe.html?id=somekind--somestory' - ); - }); - - it('can use a url without path (but slash) and without query params', () => { - expect(constructUrl('http://localhost:9001/', id)).toEqual( - 'http://localhost:9001/iframe.html?id=somekind--somestory' - ); - }); - - it('can use a url without path and with query params', () => { - expect(constructUrl('http://localhost:9001?hello=world', id)).toEqual( - 'http://localhost:9001/iframe.html?hello=world&id=somekind--somestory' - ); - }); - - it('can use a url without path (buth slash) and with query params', () => { - expect(constructUrl('http://localhost:9001/?hello=world', id)).toEqual( - 'http://localhost:9001/iframe.html?hello=world&id=somekind--somestory' - ); - }); - - it('can use a url with some path and query params', () => { - expect(constructUrl('http://localhost:9001/nice-path?hello=world', id)).toEqual( - 'http://localhost:9001/nice-path/iframe.html?hello=world&id=somekind--somestory' - ); - }); - - it('can use a url with some path (slash) and query params', () => { - expect(constructUrl('http://localhost:9001/nice-path/?hello=world', id)).toEqual( - 'http://localhost:9001/nice-path/iframe.html?hello=world&id=somekind--somestory' - ); - }); - - it('can use a url with username and password and query params', () => { - expect( - constructUrl('http://username:password@localhost:9001/nice-path/?hello=world', id) - ).toEqual( - 'http://username:password@localhost:9001/nice-path/iframe.html?hello=world&id=somekind--somestory' - ); - }); - - it('can use a url with username and query params', () => { - expect(constructUrl('http://username@localhost:9001/nice-path/?hello=world', id)).toEqual( - 'http://username@localhost:9001/nice-path/iframe.html?hello=world&id=somekind--somestory' - ); - }); - - it('can use a url with file protocol', () => { - expect(constructUrl('file://users/storybook', id)).toEqual( - 'file://users/storybook/iframe.html?id=somekind--somestory' - ); - }); -}); diff --git a/code/addons/storyshots-puppeteer/src/axeTest.ts b/code/addons/storyshots-puppeteer/src/axeTest.ts deleted file mode 100644 index b2a7bdb603ff..000000000000 --- a/code/addons/storyshots-puppeteer/src/axeTest.ts +++ /dev/null @@ -1,45 +0,0 @@ -import AxePuppeteer from '@axe-core/puppeteer'; -import type { AxeConfig } from './config'; -import { defaultAxeConfig } from './config'; -import { puppeteerTest } from './puppeteerTest'; - -export const axeTest = (customConfig: Partial = {}) => { - const extendedConfig = { ...defaultAxeConfig, ...customConfig }; - const { beforeAxeTest } = extendedConfig; - - return puppeteerTest({ - ...extendedConfig, - async testBody(page, testOptions) { - const { - element = '#storybook-root', - exclude, - disabledRules, - options, - config, - } = testOptions.context.parameters.a11y || {}; - await beforeAxeTest(page, options); - const axe = new AxePuppeteer(page); - axe.include(element); - - if (exclude) { - axe.exclude(exclude); - } - - if (options) { - axe.options(options); - } - - if (disabledRules) { - axe.disableRules(disabledRules); - } - - if (config) { - axe.configure(config); - } - - const { violations } = await axe.analyze(); - - expect(violations).toHaveLength(0); - }, - }); -}; diff --git a/code/addons/storyshots-puppeteer/src/config.ts b/code/addons/storyshots-puppeteer/src/config.ts deleted file mode 100644 index 25d6633540bc..000000000000 --- a/code/addons/storyshots-puppeteer/src/config.ts +++ /dev/null @@ -1,105 +0,0 @@ -import type { MatchImageSnapshotOptions } from 'jest-image-snapshot'; -import type { ScreenshotOptions, Browser, Page, ElementHandle, LaunchOptions } from 'puppeteer'; - -type PuppeteerLifeCycleEvent = 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2'; - -export interface Context { - kind: string; - story: string; - parameters: { - [key: string]: any; - }; -} - -interface Options { - context: Context; - url: string; -} - -interface Base64ScreenShotOptions extends ScreenshotOptions { - encoding: 'base64'; -} - -interface DirectNavigationOptions { - referer?: string; - timeout?: number; - waitUntil?: PuppeteerLifeCycleEvent | PuppeteerLifeCycleEvent[]; -} - -export interface CommonConfig { - storybookUrl: string; - chromeExecutablePath?: string; - getGotoOptions: (options: Options) => DirectNavigationOptions | undefined; - customizePage: (page: Page) => Promise; - getCustomBrowser?: () => Promise; - /** - * Puppeteer browser launch options: - * {@link https://pptr.dev/api/puppeteer.puppeteernode.launch/ puppeteer.launch()} - */ - browserLaunchOptions: LaunchOptions; - setupTimeout: number; - testTimeout: number; -} - -export interface PuppeteerTestConfig extends CommonConfig { - testBody: ((page: Page, options: Options) => void | Promise) & { - filter?: (options: Options) => boolean; - }; -} - -export interface ImageSnapshotConfig extends CommonConfig { - getMatchOptions: (options: Options) => MatchImageSnapshotOptions | undefined; - getScreenshotOptions: (options: Options) => Base64ScreenShotOptions; - beforeScreenshot: (page: Page, options: Options) => Promise; - afterScreenshot: (options: { image: string | void | Buffer; context: Context }) => Promise; -} - -export interface AxeConfig extends CommonConfig { - beforeAxeTest: (page: Page, options: Options) => Promise; -} - -const noop: () => undefined = () => undefined; -const asyncNoop: () => Promise = async () => undefined; - -export const defaultCommonConfig: CommonConfig = { - storybookUrl: 'http://localhost:6006', - chromeExecutablePath: process.env.SB_CHROMIUM_PATH, - getGotoOptions: noop, - customizePage: asyncNoop, - getCustomBrowser: undefined, - browserLaunchOptions: {}, - setupTimeout: 15000, - testTimeout: 15000, -}; - -const getTestBody = (options: Options) => options.context.parameters.puppeteerTest; - -function defaultTestBody(page: Page, options: Options) { - const testBody = getTestBody(options); - if (testBody != null) { - return testBody(page, options); - } - return null; -} - -defaultTestBody.filter = (options: Options) => getTestBody(options) != null; - -export const defaultPuppeteerTestConfig: PuppeteerTestConfig = { - ...defaultCommonConfig, - testBody: defaultTestBody, -}; - -// We consider taking the full page is a reasonable default. -const defaultScreenshotOptions = () => ({ fullPage: true, encoding: 'base64' } as const); -export const defaultImageSnapshotConfig: ImageSnapshotConfig = { - ...defaultCommonConfig, - getMatchOptions: noop, - getScreenshotOptions: defaultScreenshotOptions, - beforeScreenshot: asyncNoop, - afterScreenshot: asyncNoop, -}; - -export const defaultAxeConfig: AxeConfig = { - ...defaultCommonConfig, - beforeAxeTest: asyncNoop, -}; diff --git a/code/addons/storyshots-puppeteer/src/imageSnapshot.ts b/code/addons/storyshots-puppeteer/src/imageSnapshot.ts deleted file mode 100644 index b61552be7787..000000000000 --- a/code/addons/storyshots-puppeteer/src/imageSnapshot.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { toMatchImageSnapshot } from 'jest-image-snapshot'; -import type { ImageSnapshotConfig } from './config'; -import { defaultImageSnapshotConfig } from './config'; -import { puppeteerTest } from './puppeteerTest'; - -expect.extend({ toMatchImageSnapshot }); - -export const imageSnapshot = (customConfig: Partial = {}) => { - const config = { ...defaultImageSnapshotConfig, ...customConfig }; - const { getMatchOptions, getScreenshotOptions, beforeScreenshot, afterScreenshot } = config; - - return puppeteerTest({ - ...config, - async testBody(page, options) { - expect.hasAssertions(); - const element = await beforeScreenshot(page, options); - const image = await (element || page).screenshot(getScreenshotOptions(options)); - await afterScreenshot({ image, context: options.context }); - expect(image).toMatchImageSnapshot(getMatchOptions(options)); - }, - }); -}; diff --git a/code/addons/storyshots-puppeteer/src/index.ts b/code/addons/storyshots-puppeteer/src/index.ts deleted file mode 100644 index dd2e0b715fee..000000000000 --- a/code/addons/storyshots-puppeteer/src/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './config'; -export * from './puppeteerTest'; -export * from './axeTest'; -export * from './imageSnapshot'; diff --git a/code/addons/storyshots-puppeteer/src/puppeteerTest.ts b/code/addons/storyshots-puppeteer/src/puppeteerTest.ts deleted file mode 100644 index 03517979d31b..000000000000 --- a/code/addons/storyshots-puppeteer/src/puppeteerTest.ts +++ /dev/null @@ -1,100 +0,0 @@ -import type { Browser, Page } from 'puppeteer'; -import { logger } from '@storybook/node-logger'; -import { constructUrl } from './url'; -import type { PuppeteerTestConfig } from './config'; -import { defaultPuppeteerTestConfig } from './config'; - -export const puppeteerTest = (customConfig: Partial = {}) => { - const { - storybookUrl, - chromeExecutablePath, - getGotoOptions, - customizePage, - getCustomBrowser, - browserLaunchOptions, - testBody, - setupTimeout, - testTimeout, - } = { ...defaultPuppeteerTestConfig, ...customConfig }; - - let browser: Browser; // holds ref to browser. (ie. Chrome) - let page: Page; // Hold ref to the page to screenshot. - - const testFn = async ({ context }: any) => { - const { kind, framework, name, id } = context; - if (framework === 'react-native') { - // Skip tests since RN is not a browser environment. - logger.error( - "It seems you are running puppeteer test on RN app and it's not supported. Skipping test." - ); - - return; - } - - const url = constructUrl(storybookUrl, id); - const options = { context, url }; - if (testBody.filter != null && !testBody.filter(options)) { - return; - } - - if (!browser || !page) { - logger.error( - `Error when running puppeteer test for ${kind} - ${name} : It seems the headless browser is not running.` - ); - - throw new Error('no-headless-browser-running'); - } - - try { - await customizePage(page); - await page.goto(url, getGotoOptions(options)); - } catch (e) { - logger.error( - `Error when connecting to ${url}, did you start or build the storybook first? A storybook instance should be running or a static version should be built when using puppeteer test feature.` - ); - throw e; - } - await testBody(page, options); - }; - testFn.timeout = testTimeout; - - const cleanup = async () => { - if (getCustomBrowser && page) { - await page.close(); - } else if (browser) { - await browser.close(); - } - }; - - process.on('SIGINT', async () => { - await cleanup(); - process.exit(); - }); - testFn.afterAll = cleanup; - - const beforeAll = async () => { - if (getCustomBrowser) { - browser = await getCustomBrowser(); - } else { - // eslint-disable-next-line global-require - const puppeteer = require('puppeteer'); - // add some options "no-sandbox" to make it work properly on some Linux systems as proposed here: https://github.com/Googlechrome/puppeteer/issues/290#issuecomment-322851507 - browser = await puppeteer.launch({ - ...browserLaunchOptions, - args: [ - '--no-sandbox ', - '--disable-setuid-sandbox', - '--disable-dev-shm-usage', - ...(browserLaunchOptions?.args || []), - ], - executablePath: chromeExecutablePath, - }); - } - - page = await browser.newPage(); - }; - beforeAll.timeout = setupTimeout; - testFn.beforeAll = beforeAll; - - return testFn; -}; diff --git a/code/addons/storyshots-puppeteer/src/url.ts b/code/addons/storyshots-puppeteer/src/url.ts deleted file mode 100644 index 036fc76200c6..000000000000 --- a/code/addons/storyshots-puppeteer/src/url.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { URL } from 'url'; - -export const constructUrl = (storybookUrl: string, id: string) => { - const url = new URL(storybookUrl); - url.pathname = url.pathname.replace(/\/$/, '').concat('/iframe.html'); - url.searchParams.append('id', id); - return url.toString(); -}; diff --git a/code/addons/storyshots-puppeteer/tsconfig.build.json b/code/addons/storyshots-puppeteer/tsconfig.build.json deleted file mode 100644 index dae6c1e39197..000000000000 --- a/code/addons/storyshots-puppeteer/tsconfig.build.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compileOnSave": false, - "compilerOptions": { - "target": "ES2020", - "module": "CommonJS", - "lib": ["es2020", "dom"], - "esModuleInterop": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "declaration": true, - "outDir": "dist", - "types": ["node"], - "skipLibCheck": true, - "resolveJsonModule": true, - "allowJs": true, - "pretty": true, - "noErrorTruncation": true, - "listEmittedFiles": false, - "noUnusedLocals": false - }, - "include": ["src/**/*", "src/**/*.json"] -} diff --git a/code/addons/storyshots-puppeteer/tsconfig.json b/code/addons/storyshots-puppeteer/tsconfig.json deleted file mode 100644 index b32dad6f525c..000000000000 --- a/code/addons/storyshots-puppeteer/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "skipLibCheck": true, - "types": ["node"], - "declaration": true, - "strict": true - }, - "include": ["src/**/*"] -} diff --git a/code/addons/storysource/vitest.config.ts b/code/addons/storysource/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/storysource/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/themes/vitest.config.ts b/code/addons/themes/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/themes/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/toolbars/vitest.config.ts b/code/addons/toolbars/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/toolbars/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/addons/viewport/vitest.config.ts b/code/addons/viewport/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/addons/viewport/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/builders/builder-manager/vitest.config.ts b/code/builders/builder-manager/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/builders/builder-manager/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/builders/builder-vite/vitest.config.ts b/code/builders/builder-vite/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/builders/builder-vite/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/builders/builder-webpack5/vitest.config.ts b/code/builders/builder-webpack5/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/builders/builder-webpack5/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/deprecated/channel-postmessage/vitest.config.ts b/code/deprecated/channel-postmessage/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/deprecated/channel-postmessage/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/deprecated/channel-websocket/vitest.config.ts b/code/deprecated/channel-websocket/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/deprecated/channel-websocket/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/angular/__vitest.config.ts b/code/frameworks/angular/__vitest.config.ts new file mode 100644 index 000000000000..913d2c6f5d54 --- /dev/null +++ b/code/frameworks/angular/__vitest.config.ts @@ -0,0 +1,29 @@ +module.exports = { + displayName: __dirname.split(sep).slice(-2).join(posix.sep), + preset: 'jest-preset-angular/presets/defaults-esm', + setupFilesAfterEnv: ['/setup-jest.ts'], + transformIgnorePatterns: ['/node_modules/(?!@angular|rxjs|nanoid|uuid)'], + snapshotFormat: { + escapeString: true, + printBasicPrototype: true, + }, + coverageDirectory: './coverage/testapp', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], + testMatch: [ + '/src/**/__tests__/**/*.[jt]s?(x)', + '/src/**/?(*.)+(spec|test).[jt]s?(x)', + ], +}; diff --git a/code/frameworks/ember/vitest.config.ts b/code/frameworks/ember/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/ember/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/html-webpack5/vitest.config.ts b/code/frameworks/html-webpack5/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/html-webpack5/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/nextjs/vitest.config.ts b/code/frameworks/nextjs/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/nextjs/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/preact-vite/vitest.config.ts b/code/frameworks/preact-vite/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/preact-vite/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/preact-webpack5/vitest.config.ts b/code/frameworks/preact-webpack5/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/preact-webpack5/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/react-vite/vitest.config.ts b/code/frameworks/react-vite/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/react-vite/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/react-webpack5/vitest.config.ts b/code/frameworks/react-webpack5/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/react-webpack5/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/server-webpack5/vitest.config.ts b/code/frameworks/server-webpack5/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/server-webpack5/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/svelte-vite/vitest.config.ts b/code/frameworks/svelte-vite/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/svelte-vite/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/svelte-webpack5/vitest.config.ts b/code/frameworks/svelte-webpack5/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/svelte-webpack5/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/sveltekit/vitest.config.ts b/code/frameworks/sveltekit/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/sveltekit/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/vue-vite/vitest.config.ts b/code/frameworks/vue-vite/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/vue-vite/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/vue-webpack5/vitest.config.ts b/code/frameworks/vue-webpack5/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/vue-webpack5/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/vue3-vite/vitest.config.ts b/code/frameworks/vue3-vite/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/vue3-vite/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/vue3-webpack5/vitest.config.ts b/code/frameworks/vue3-webpack5/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/vue3-webpack5/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/web-components-vite/vitest.config.ts b/code/frameworks/web-components-vite/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/web-components-vite/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/frameworks/web-components-webpack5/vitest.config.ts b/code/frameworks/web-components-webpack5/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/frameworks/web-components-webpack5/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/channels/vitest.config.ts b/code/lib/channels/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/channels/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/cli-sb/vitest.config.ts b/code/lib/cli-sb/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/cli-sb/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/cli-storybook/vitest.config.ts b/code/lib/cli-storybook/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/cli-storybook/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/cli/package.json b/code/lib/cli/package.json index 378e96da98ef..385a936699a6 100644 --- a/code/lib/cli/package.json +++ b/code/lib/cli/package.json @@ -52,7 +52,7 @@ "scripts": { "check": "../../../scripts/prepare/check.ts", "prep": "../../../scripts/prepare/bundle.ts", - "test": "jest test/**/*.test.js" + "test": "vitest test/**/*.test.js" }, "dependencies": { "@babel/core": "^7.22.9", diff --git a/code/lib/cli/vitest.config.ts b/code/lib/cli/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/cli/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/client-logger/vitest.config.ts b/code/lib/client-logger/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/lib/client-logger/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/codemod/vitest.config.ts b/code/lib/codemod/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/codemod/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/core-common/vitest.config.ts b/code/lib/core-common/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/core-common/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/core-events/vitest.config.ts b/code/lib/core-events/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/core-events/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/core-server/vitest.config.ts b/code/lib/core-server/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/core-server/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/core-webpack/vitest.config.ts b/code/lib/core-webpack/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/core-webpack/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/csf-plugin/vitest.config.ts b/code/lib/csf-plugin/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/lib/csf-plugin/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/csf-tools/vitest.config.ts b/code/lib/csf-tools/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/csf-tools/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/docs-tools/vitest.config.ts b/code/lib/docs-tools/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/docs-tools/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/instrumenter/vitest.config.ts b/code/lib/instrumenter/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/lib/instrumenter/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/manager-api/vitest.config.ts b/code/lib/manager-api/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/manager-api/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/node-logger/vitest.config.ts b/code/lib/node-logger/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/node-logger/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/postinstall/vitest.config.ts b/code/lib/postinstall/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/postinstall/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/preview-api/vitest.config.ts b/code/lib/preview-api/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/preview-api/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/preview/vitest.config.ts b/code/lib/preview/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/preview/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/router/vitest.config.ts b/code/lib/router/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/router/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/source-loader/vitest.config.ts b/code/lib/source-loader/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/source-loader/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/telemetry/vitest.config.ts b/code/lib/telemetry/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/telemetry/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/theming/vitest.config.ts b/code/lib/theming/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/lib/theming/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/lib/types/vitest.config.ts b/code/lib/types/vitest.config.ts new file mode 100644 index 000000000000..aa50537cbd84 --- /dev/null +++ b/code/lib/types/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/package.json b/code/package.json index de51bf0feabf..a1c94b95e1b4 100644 --- a/code/package.json +++ b/code/package.json @@ -53,7 +53,7 @@ "storybook:ui:build": "NODE_OPTIONS=\"--preserve-symlinks --preserve-symlinks-main\" ./lib/cli/bin/index.js build --config-dir ./ui/.storybook", "storybook:ui:chromatic": "yarn chromatic --build-script-name storybook:ui:build --storybook-config-dir ./ui/.storybook --storybook-base-dir ./code --project-token=${CHROMATIC_TOKEN_STORYBOOK_UI:-MISSING_PROJECT_TOKEN} --only-changed --exit-zero-on-changes --exit-once-uploaded", "task": "cd .. && yarn task", - "test": "NODE_OPTIONS=--max_old_space_size=4096 jest --config ./jest.config.js", + "test": "NODE_OPTIONS=--max_old_space_size=4096 vitest", "test:cli": "npm --prefix lib/cli run test" }, "husky": { @@ -260,6 +260,7 @@ "util": "^0.12.4", "vite": "^4.0.0", "vite-plugin-turbosnap": "^1.0.1", + "vitest": "^0.34.4", "wait-on": "^7.0.1" }, "dependenciesMeta": { diff --git a/code/renderers/html/vitest.config.ts b/code/renderers/html/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/renderers/html/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/renderers/preact/vitest.config.ts b/code/renderers/preact/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/renderers/preact/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/renderers/react/vitest.config.ts b/code/renderers/react/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/renderers/react/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/renderers/server/vitest.config.ts b/code/renderers/server/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/renderers/server/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/renderers/svelte/vitest.config.ts b/code/renderers/svelte/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/renderers/svelte/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/renderers/vue/vitest.config.ts b/code/renderers/vue/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/renderers/vue/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/renderers/vue3/vitest.config.ts b/code/renderers/vue3/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/renderers/vue3/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/renderers/web-components/vitest.config.ts b/code/renderers/web-components/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/renderers/web-components/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/ui/blocks/vitest.config.ts b/code/ui/blocks/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/ui/blocks/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/ui/components/vitest.config.ts b/code/ui/components/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/ui/components/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/ui/manager/src/__tests__/index.test.ts b/code/ui/manager/src/__tests__/index.test.ts index 60bd0492a31c..18224d4c10b9 100644 --- a/code/ui/manager/src/__tests__/index.test.ts +++ b/code/ui/manager/src/__tests__/index.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { renderStorybookUI } from '..'; describe('Main API', () => { diff --git a/code/ui/manager/vitest.config.ts b/code/ui/manager/vitest.config.ts new file mode 100644 index 000000000000..4aaad5122170 --- /dev/null +++ b/code/ui/manager/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineProject } from 'vitest/config'; +import { sep, posix } from 'path'; +// import { fileURLToPath } from 'url'; + +// const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineProject({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, +}); diff --git a/code/vitest.config.base.ts b/code/vitest.config.base.ts new file mode 100644 index 000000000000..9fdc75f588a9 --- /dev/null +++ b/code/vitest.config.base.ts @@ -0,0 +1,118 @@ +const os = require('os'); +const fs = require('fs'); +const path = require('path'); + +const swcrc = JSON.parse(fs.readFileSync('.swcrc', 'utf8')); + +/** + * TODO: Some windows related tasks are still commented out, because they are behaving differently on + * a local Windows machine compared to the Windows Server 2022 machine running in GitHub Actions. + * The main issue is that path.sep is behaving differently on the two machines. Some more investagations + * are necessary! + * */ +const skipOnWindows = [ + 'lib/core-server/src/utils/__tests__/server-statics.test.ts', + 'lib/core-common/src/utils/__tests__/template.test.ts', + 'addons/storyshots-core/src/frameworks/configure.test.ts', + 'lib/core-common/src/utils/__tests__/interpret-files.test.ts', + 'lib/cli/src/helpers.test.ts', + 'lib/csf-tools/src/enrichCsf.test.ts', +]; + +const modulesToTransform = [ + '@angular', + '@lit', + '@mdx-js', + 'ccount', + 'character-entities', + 'decode-named-character-reference', + 'estree', + 'is-absolute-url', + 'lit-html', + 'lit', + 'mdast', + 'micromark', + 'nanoid', + 'node-fetch', + 'remark', + 'rxjs', + 'data-uri-to-buffer', + 'fetch-blob', + 'formdata-polyfill', + 'slash', + 'space-separated-tokens', + 'stringify-entities', + 'unified', + 'unist', + 'uuid', + 'vfile-message', + 'vfile', + 'zwitch', +]; + +/** @type { import('jest').Config } */ +module.exports = { + cacheDirectory: path.resolve('.cache/jest'), + clearMocks: true, + moduleNameMapper: { + // non-js files + '\\.(jpg|jpeg|png|apng|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': + path.resolve('./__mocks__/fileMock.js'), + '\\.(css|scss|stylesheet)$': path.resolve('./__mocks__/styleMock.js'), + '\\.(md)$': path.resolve('./__mocks__/htmlMock.js'), + }, + transform: { + '^.+\\.(t|j)sx?$': ['@swc/jest', swcrc], + '^.+\\.mdx$': '@storybook/addon-docs/jest-transform-mdx', + }, + transformIgnorePatterns: [`(?/addons/*', + '/frameworks/*', + '/lib/*', + '/builders/*', + '/renderers/*', + '/ui/!(node_modules)*', + ], + collectCoverage: false, + collectCoverageFrom: ['**/src/**/*.{js,jsx,ts,tsx}', '!**/e2e-tests/**', '!**/node_modules/**'], + coverageDirectory: 'coverage', + coverageReporters: ['lcov'], + reporters: ['default', 'jest-junit'], + watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'], +}; diff --git a/code/vitest.workspace.ts b/code/vitest.workspace.ts new file mode 100644 index 000000000000..b19384d0184b --- /dev/null +++ b/code/vitest.workspace.ts @@ -0,0 +1,12 @@ +import { defineWorkspace } from 'vitest/config'; + +export default defineWorkspace([ + 'addons/*', + 'frameworks/*', + 'lib/*', + 'deprecated/*', + 'builders/*', + 'ui/*', + 'presets/*', + 'renderers/*', +]); diff --git a/code/yarn.lock b/code/yarn.lock index 4ba4e1ab6559..2bc07ae18103 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -7989,6 +7989,7 @@ __metadata: util: ^0.12.4 vite: ^4.0.0 vite-plugin-turbosnap: ^1.0.1 + vitest: ^0.34.4 wait-on: ^7.0.1 dependenciesMeta: ejs: @@ -9018,6 +9019,22 @@ __metadata: languageName: node linkType: hard +"@types/chai-subset@npm:^1.3.3": + version: 1.3.3 + resolution: "@types/chai-subset@npm:1.3.3" + dependencies: + "@types/chai": "*" + checksum: 2dfb3210ce8d872288bb44329a44d4d1b7be360c72e8eb570a535c0e97246a4bd0209df304427d0e179c9e1c659d5dba07c25bdae13ef983edf41db81278fda5 + languageName: node + linkType: hard + +"@types/chai@npm:*, @types/chai@npm:^4.3.5": + version: 4.3.6 + resolution: "@types/chai@npm:4.3.6" + checksum: 388af382b11453a69808800479dcaff0323a0d1e15df1619175ebd55b294d716d560058f560ed55434e8846af46f017d7d78544822571f6322d3fac6d5f8a29d + languageName: node + linkType: hard + "@types/cheerio@npm:^0.22.22": version: 0.22.32 resolution: "@types/cheerio@npm:0.22.32" @@ -10187,6 +10204,59 @@ __metadata: languageName: node linkType: hard +"@vitest/expect@npm:0.34.4": + version: 0.34.4 + resolution: "@vitest/expect@npm:0.34.4" + dependencies: + "@vitest/spy": 0.34.4 + "@vitest/utils": 0.34.4 + chai: ^4.3.7 + checksum: 73e1d6b98cb3d2566c8d9f61db031c3a866c61beb923f6728ea714b4f0265bb9782e1356a0db5e7c593723166985f64e4daa1944af70be1420e8b24d5170f816 + languageName: node + linkType: hard + +"@vitest/runner@npm:0.34.4": + version: 0.34.4 + resolution: "@vitest/runner@npm:0.34.4" + dependencies: + "@vitest/utils": 0.34.4 + p-limit: ^4.0.0 + pathe: ^1.1.1 + checksum: 68ca71c7de105a5aa69ab8e1c8167fbb7e781c9d0011a497edaaaba13839924d59b36f03ab6076c7c0200888a05aeac90f8adc2d8e15aac83687f906040fe409 + languageName: node + linkType: hard + +"@vitest/snapshot@npm:0.34.4": + version: 0.34.4 + resolution: "@vitest/snapshot@npm:0.34.4" + dependencies: + magic-string: ^0.30.1 + pathe: ^1.1.1 + pretty-format: ^29.5.0 + checksum: 08c197c97b513c9774ce70418e3519c08a75ce7aa09dde1a686d118b7830081749dcb839e1ab36280d39e066967fb3334d21ea7631bfc969b229493c95f2edef + languageName: node + linkType: hard + +"@vitest/spy@npm:0.34.4": + version: 0.34.4 + resolution: "@vitest/spy@npm:0.34.4" + dependencies: + tinyspy: ^2.1.1 + checksum: c823a4d0fcd97fe6887a6567173ce94bb16b5e0cb4c8a6c47614e7f70d47d5d39b0ba3d0181906a2099dc87e90d17003a4dcd5762ed0b4d1e0ec79d0e4418b1a + languageName: node + linkType: hard + +"@vitest/utils@npm:0.34.4": + version: 0.34.4 + resolution: "@vitest/utils@npm:0.34.4" + dependencies: + diff-sequences: ^29.4.3 + loupe: ^2.3.6 + pretty-format: ^29.5.0 + checksum: 9464c0bec7d23be94e74e7ae0e66ab4359e5d08239d595963a4b2e851183b143a7ff0b07341d45d1db4e9fa64e38d8793176a743f637bcae12277419b1cfad7c + languageName: node + linkType: hard + "@volar/language-core@npm:1.10.1, @volar/language-core@npm:~1.10.0": version: 1.10.1 resolution: "@volar/language-core@npm:1.10.1" @@ -10852,7 +10922,7 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.0.2, acorn-walk@npm:^8.1.1": +"acorn-walk@npm:^8.0.2, acorn-walk@npm:^8.1.1, acorn-walk@npm:^8.2.0": version: 8.2.0 resolution: "acorn-walk@npm:8.2.0" checksum: dbe92f5b2452c93e960c5594e666dd1fae141b965ff2cb4a1e1d0381e3e4db4274c5ce4ffa3d681a86ca2a8d4e29d5efc0670a08e23fd2800051ea387df56ca2 @@ -11512,6 +11582,13 @@ __metadata: languageName: node linkType: hard +"assertion-error@npm:^1.1.0": + version: 1.1.0 + resolution: "assertion-error@npm:1.1.0" + checksum: 25456b2aa333250f01143968e02e4884a34588a8538fbbf65c91a637f1dbfb8069249133cd2f4e530f10f624d206a664e7df30207830b659e9f5298b00a4099b + languageName: node + linkType: hard + "assign-symbols@npm:^1.0.0": version: 1.0.0 resolution: "assign-symbols@npm:1.0.0" @@ -12762,6 +12839,13 @@ __metadata: languageName: node linkType: hard +"cac@npm:^6.7.14": + version: 6.7.14 + resolution: "cac@npm:6.7.14" + checksum: 4ee06aaa7bab8981f0d54e5f5f9d4adcd64058e9697563ce336d8a3878ed018ee18ebe5359b2430eceae87e0758e62ea2019c3f52ae6e211b1bd2e133856cd10 + languageName: node + linkType: hard + "cacache@npm:^16.1.0": version: 16.1.3 resolution: "cacache@npm:16.1.3" @@ -12940,6 +13024,21 @@ __metadata: languageName: node linkType: hard +"chai@npm:^4.3.7": + version: 4.3.8 + resolution: "chai@npm:4.3.8" + dependencies: + assertion-error: ^1.1.0 + check-error: ^1.0.2 + deep-eql: ^4.1.2 + get-func-name: ^2.0.0 + loupe: ^2.3.1 + pathval: ^1.1.1 + type-detect: ^4.0.5 + checksum: 5aa714fbbd4b3a1506f4fc9094851bf9109f184d601c1278bcd4eb98d5ee05cc75d7e84f46d072d656502c55544b38c748a1c669468d138e41e5c9d175beffc5 + languageName: node + linkType: hard + "chalk@npm:4.1.0": version: 4.1.0 resolution: "chalk@npm:4.1.0" @@ -13067,6 +13166,13 @@ __metadata: languageName: node linkType: hard +"check-error@npm:^1.0.2": + version: 1.0.2 + resolution: "check-error@npm:1.0.2" + checksum: c58ac4d6a92203209a61d025568198c073f101691eb6247f999266e1d1e3ab3af2bbe0a41af5008c1f1b95446ec7831e6ba91f03816177f2da852f316ad7921d + languageName: node + linkType: hard + "checkup@npm:^1.3.0": version: 1.3.0 resolution: "checkup@npm:1.3.0" @@ -14563,6 +14669,15 @@ __metadata: languageName: node linkType: hard +"deep-eql@npm:^4.1.2": + version: 4.1.3 + resolution: "deep-eql@npm:4.1.3" + dependencies: + type-detect: ^4.0.0 + checksum: ff34e8605d8253e1bf9fe48056e02c6f347b81d9b5df1c6650a1b0f6f847b4a86453b16dc226b34f853ef14b626e85d04e081b022e20b00cd7d54f079ce9bbdd + languageName: node + linkType: hard + "deep-equal@npm:^1.1.1": version: 1.1.1 resolution: "deep-equal@npm:1.1.1" @@ -14857,7 +14972,7 @@ __metadata: languageName: node linkType: hard -"diff-sequences@npm:^29.6.3": +"diff-sequences@npm:^29.4.3, diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" checksum: 32e27ac7dbffdf2fb0eb5a84efd98a9ad084fbabd5ac9abb8757c6770d5320d2acd172830b28c4add29bb873d59420601dfc805ac4064330ce59b1adfd0593b2 @@ -17807,6 +17922,13 @@ __metadata: languageName: node linkType: hard +"get-func-name@npm:^2.0.0": + version: 2.0.0 + resolution: "get-func-name@npm:2.0.0" + checksum: ed8791f7ba92cfd747259dff7ec8b6cc42734cebd031fb58c99a6e71d24d3532d84b46ad7806cafad6ad21784dd04ae1808a002d2b21001425e21f5f394c34e7 + languageName: node + linkType: hard + "get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0, get-intrinsic@npm:^1.2.1": version: 1.2.1 resolution: "get-intrinsic@npm:1.2.1" @@ -21899,6 +22021,13 @@ __metadata: languageName: node linkType: hard +"local-pkg@npm:^0.4.3": + version: 0.4.3 + resolution: "local-pkg@npm:0.4.3" + checksum: 361c77d7873a629f09c9e86128926227171ee0fe3435d282fb80303ff255bb4d3c053b555d47e953b4f41d2561f2a7bc0e53e9ca5c9bc9607226a77c91ea4994 + languageName: node + linkType: hard + "locate-character@npm:^3.0.0": version: 3.0.0 resolution: "locate-character@npm:3.0.0" @@ -22162,6 +22291,15 @@ __metadata: languageName: node linkType: hard +"loupe@npm:^2.3.1, loupe@npm:^2.3.6": + version: 2.3.6 + resolution: "loupe@npm:2.3.6" + dependencies: + get-func-name: ^2.0.0 + checksum: a974841ce94ef2a35aac7144e7f9e789e3887f82286cd9ffe7ff00f2ac9d117481989948657465e2b0b102f23136d89ae0a18fd4a32d9015012cd64464453289 + languageName: node + linkType: hard + "lower-case@npm:^2.0.2": version: 2.0.2 resolution: "lower-case@npm:2.0.2" @@ -22289,7 +22427,7 @@ __metadata: languageName: node linkType: hard -"magic-string@npm:^0.30.0, magic-string@npm:^0.30.2": +"magic-string@npm:^0.30.0, magic-string@npm:^0.30.1, magic-string@npm:^0.30.2": version: 0.30.3 resolution: "magic-string@npm:0.30.3" dependencies: @@ -23689,6 +23827,18 @@ __metadata: languageName: node linkType: hard +"mlly@npm:^1.2.0, mlly@npm:^1.4.0": + version: 1.4.2 + resolution: "mlly@npm:1.4.2" + dependencies: + acorn: ^8.10.0 + pathe: ^1.1.1 + pkg-types: ^1.0.3 + ufo: ^1.3.0 + checksum: 905e3a704c7d3bcaad55f31d6efe9f680eab5be053ab7f8b299b8dbc027041f741fa6a93db9a3c461be2552632f3831b6c43c50af530f5fb2e9cd6273bc9d642 + languageName: node + linkType: hard + "mock-fs@npm:^5.2.0": version: 5.2.0 resolution: "mock-fs@npm:5.2.0" @@ -25633,13 +25783,20 @@ __metadata: languageName: node linkType: hard -"pathe@npm:^1.1.0": +"pathe@npm:^1.1.0, pathe@npm:^1.1.1": version: 1.1.1 resolution: "pathe@npm:1.1.1" checksum: 3ae5a0529c3415d91c3ac9133f52cffea54a0dd46892fe059f4b80faf36fd207957d4594bdc87043b65d0761b1e5728f81f46bafff3b5302da4e2e48889b8c0e languageName: node linkType: hard +"pathval@npm:^1.1.1": + version: 1.1.1 + resolution: "pathval@npm:1.1.1" + checksum: f63e1bc1b33593cdf094ed6ff5c49c1c0dc5dc20a646ca9725cc7fe7cd9995002d51d5685b9b2ec6814342935748b711bafa840f84c0bb04e38ff40a335c94dc + languageName: node + linkType: hard + "pbkdf2@npm:^3.0.3": version: 3.1.2 resolution: "pbkdf2@npm:3.1.2" @@ -25839,6 +25996,17 @@ __metadata: languageName: node linkType: hard +"pkg-types@npm:^1.0.3": + version: 1.0.3 + resolution: "pkg-types@npm:1.0.3" + dependencies: + jsonc-parser: ^3.2.0 + mlly: ^1.2.0 + pathe: ^1.1.0 + checksum: 7f692ff2005f51b8721381caf9bdbc7f5461506ba19c34f8631660a215c8de5e6dca268f23a319dd180b8f7c47a0dc6efea14b376c485ff99e98d810b8f786c4 + languageName: node + linkType: hard + "pkg-up@npm:^2.0.0": version: 2.0.0 resolution: "pkg-up@npm:2.0.0" @@ -26241,7 +26409,7 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^29.0.0, pretty-format@npm:^29.7.0": +"pretty-format@npm:^29.0.0, pretty-format@npm:^29.5.0, pretty-format@npm:^29.7.0": version: 29.7.0 resolution: "pretty-format@npm:29.7.0" dependencies: @@ -28455,7 +28623,7 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^3.20.1, rollup@npm:^3.25.2, rollup@npm:^3.27.1": +"rollup@npm:^3.20.1, rollup@npm:^3.25.2, rollup@npm:^3.27.1, rollup@npm:^3.28.0": version: 3.29.1 resolution: "rollup@npm:3.29.1" dependencies: @@ -29028,6 +29196,13 @@ __metadata: languageName: node linkType: hard +"siginfo@npm:^2.0.0": + version: 2.0.0 + resolution: "siginfo@npm:2.0.0" + checksum: 3def8f8e516fbb34cb6ae415b07ccc5d9c018d85b4b8611e3dc6f8be6d1899f693a4382913c9ed51a06babb5201639d76453ab297d1c54a456544acf5c892e34 + languageName: node + linkType: hard + "signal-exit@npm:3.0.7, signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" @@ -29542,6 +29717,13 @@ __metadata: languageName: node linkType: hard +"stackback@npm:0.0.2": + version: 0.0.2 + resolution: "stackback@npm:0.0.2" + checksum: 89a1416668f950236dd5ac9f9a6b2588e1b9b62b1b6ad8dff1bfc5d1a15dbf0aafc9b52d2226d00c28dffff212da464eaeebfc6b7578b9d180cef3e3782c5983 + languageName: node + linkType: hard + "stackframe@npm:^1.3.4": version: 1.3.4 resolution: "stackframe@npm:1.3.4" @@ -29573,6 +29755,13 @@ __metadata: languageName: node linkType: hard +"std-env@npm:^3.3.3": + version: 3.4.3 + resolution: "std-env@npm:3.4.3" + checksum: 61c0d673eb157bbd9ff65da42ae768ff154b948737030fddfbd3f289ab4c0455285d365b1ed03319e05df58eed26622aaa009a03ee1f9159ec71087646834a9a + languageName: node + linkType: hard + "stop-iteration-iterator@npm:^1.0.0": version: 1.0.0 resolution: "stop-iteration-iterator@npm:1.0.0" @@ -29888,6 +30077,15 @@ __metadata: languageName: node linkType: hard +"strip-literal@npm:^1.0.1": + version: 1.3.0 + resolution: "strip-literal@npm:1.3.0" + dependencies: + acorn: ^8.10.0 + checksum: 3c0c9ee41eb346e827eede61ef288457f53df30e3e6ff8b94fa81b636933b0c13ca4ea5c97d00a10d72d04be326da99ac819f8769f0c6407ba8177c98344a916 + languageName: node + linkType: hard + "strong-log-transformer@npm:2.1.0, strong-log-transformer@npm:^2.1.0": version: 2.1.0 resolution: "strong-log-transformer@npm:2.1.0" @@ -30449,6 +30647,27 @@ __metadata: languageName: node linkType: hard +"tinybench@npm:^2.5.0": + version: 2.5.1 + resolution: "tinybench@npm:2.5.1" + checksum: 9c55ef25ce1689c3e2fdb89cacbf27dada4d04f846cac70023fe97fc35d2122816d8bbc5b20253e071d13688cf006355d59f0096d22958b818e1e2fe60e5165b + languageName: node + linkType: hard + +"tinypool@npm:^0.7.0": + version: 0.7.0 + resolution: "tinypool@npm:0.7.0" + checksum: ecb35d9f74e72722c059acb1947ffc3c2caccb45266b89b72f74be2d28f0784d948b50bd9c6c68fa4159afd423ac5f5a07271a5f516d18a565dd06af0a37bc44 + languageName: node + linkType: hard + +"tinyspy@npm:^2.1.1": + version: 2.1.1 + resolution: "tinyspy@npm:2.1.1" + checksum: 0e7186fd380cbc594c35a0f6270f61b79ed22d1d960cac6064c3a5ebcf8a3a70d6590ff2049cba1d58631c3c556b1a67896d0db136381da7855a37087a90fbc5 + languageName: node + linkType: hard + "tmp@npm:0.0.28": version: 0.0.28 resolution: "tmp@npm:0.0.28" @@ -30900,7 +31119,7 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:4.0.8": +"type-detect@npm:4.0.8, type-detect@npm:^4.0.0, type-detect@npm:^4.0.5": version: 4.0.8 resolution: "type-detect@npm:4.0.8" checksum: 8fb9a51d3f365a7de84ab7f73b653534b61b622aa6800aecdb0f1095a4a646d3f5eb295322127b6573db7982afcd40ab492d038cf825a42093a58b1e1353e0bd @@ -31052,6 +31271,13 @@ __metadata: languageName: node linkType: hard +"ufo@npm:^1.3.0": + version: 1.3.0 + resolution: "ufo@npm:1.3.0" + checksum: f1e163bd55b6b09573d69b1972f15a30a54bfdd20fdf3e02c5546e350a57d8b1578a05760a198e30b86d1f28918231842a6c2a8a182e30a0c155edbc353497da + languageName: node + linkType: hard + "uglify-js@npm:^3.1.4": version: 3.17.4 resolution: "uglify-js@npm:3.17.4" @@ -31882,6 +32108,22 @@ __metadata: languageName: node linkType: hard +"vite-node@npm:0.34.4": + version: 0.34.4 + resolution: "vite-node@npm:0.34.4" + dependencies: + cac: ^6.7.14 + debug: ^4.3.4 + mlly: ^1.4.0 + pathe: ^1.1.1 + picocolors: ^1.0.0 + vite: ^3.0.0 || ^4.0.0 + bin: + vite-node: vite-node.mjs + checksum: de3a75e2368716dc4d0c50e5ad78447d1dd926fb05cc913562d124746c23a175806820b19644ad09131a77328a424d07982bc193436270d8794ccd268001de65 + languageName: node + linkType: hard + "vite-plugin-turbosnap@npm:^1.0.1": version: 1.0.3 resolution: "vite-plugin-turbosnap@npm:1.0.3" @@ -31929,7 +32171,7 @@ __metadata: languageName: node linkType: hard -"vite@npm:^4.0.0, vite@npm:^4.0.4": +"vite@npm:^3.0.0 || ^4.0.0, vite@npm:^4.0.0, vite@npm:^4.0.4": version: 4.4.9 resolution: "vite@npm:4.4.9" dependencies: @@ -31969,6 +32211,46 @@ __metadata: languageName: node linkType: hard +"vite@npm:^3.1.0 || ^4.0.0 || ^5.0.0-0": + version: 5.0.0-beta.1 + resolution: "vite@npm:5.0.0-beta.1" + dependencies: + esbuild: ^0.18.10 + fsevents: ~2.3.2 + postcss: ^8.4.27 + rollup: ^3.28.0 + peerDependencies: + "@types/node": ^18.0.0 || >=20.0.0 + less: "*" + lightningcss: ^1.21.0 + sass: "*" + stylus: "*" + sugarss: "*" + terser: ^5.4.0 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + bin: + vite: bin/vite.js + checksum: 874e05072aee343d129eabb6161a44367f07416f63fe3e22a09b83913dd4d73f64b271ead9cff337841a20753ee3a7f3315e878518a6657cc024d5822c624f08 + languageName: node + linkType: hard + "vitefu@npm:^0.2.4": version: 0.2.4 resolution: "vitefu@npm:0.2.4" @@ -31981,6 +32263,66 @@ __metadata: languageName: node linkType: hard +"vitest@npm:^0.34.4": + version: 0.34.4 + resolution: "vitest@npm:0.34.4" + dependencies: + "@types/chai": ^4.3.5 + "@types/chai-subset": ^1.3.3 + "@types/node": "*" + "@vitest/expect": 0.34.4 + "@vitest/runner": 0.34.4 + "@vitest/snapshot": 0.34.4 + "@vitest/spy": 0.34.4 + "@vitest/utils": 0.34.4 + acorn: ^8.9.0 + acorn-walk: ^8.2.0 + cac: ^6.7.14 + chai: ^4.3.7 + debug: ^4.3.4 + local-pkg: ^0.4.3 + magic-string: ^0.30.1 + pathe: ^1.1.1 + picocolors: ^1.0.0 + std-env: ^3.3.3 + strip-literal: ^1.0.1 + tinybench: ^2.5.0 + tinypool: ^0.7.0 + vite: ^3.1.0 || ^4.0.0 || ^5.0.0-0 + vite-node: 0.34.4 + why-is-node-running: ^2.2.2 + peerDependencies: + "@edge-runtime/vm": "*" + "@vitest/browser": "*" + "@vitest/ui": "*" + happy-dom: "*" + jsdom: "*" + playwright: "*" + safaridriver: "*" + webdriverio: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + bin: + vitest: vitest.mjs + checksum: 1e0c2823ac06b64a2edd910470b6b8a1c739f3a8429d839807ac6ed68284d7bb573f9e0e9b6257022fb9b9f673d4e627cae7e46c85f8b1a88abc05e0764d2306 + languageName: node + linkType: hard + "vm-browserify@npm:^1.1.2": version: 1.1.2 resolution: "vm-browserify@npm:1.1.2" @@ -32797,6 +33139,18 @@ __metadata: languageName: node linkType: hard +"why-is-node-running@npm:^2.2.2": + version: 2.2.2 + resolution: "why-is-node-running@npm:2.2.2" + dependencies: + siginfo: ^2.0.0 + stackback: 0.0.2 + bin: + why-is-node-running: cli.js + checksum: 805d57eb5d33f0fb4e36bae5dceda7fd8c6932c2aeb705e30003970488f1a2bc70029ee64be1a0e1531e2268b11e65606e88e5b71d667ea745e6dc48fc9014bd + languageName: node + linkType: hard + "wide-align@npm:^1.1.2, wide-align@npm:^1.1.5": version: 1.1.5 resolution: "wide-align@npm:1.1.5" diff --git a/scripts/package.json b/scripts/package.json index d53a80db8454..c7ee5504b1fa 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -187,6 +187,7 @@ "typescript": "5.0.4", "util": "^0.12.4", "uuid": "^9.0.0", + "vitest": "^0.34.4", "wait-on": "^7.0.1", "window-size": "^1.1.1", "yaml": "^2.3.1", diff --git a/scripts/vitest.config.ts b/scripts/vitest.config.ts new file mode 100644 index 000000000000..f053ebf7976e --- /dev/null +++ b/scripts/vitest.config.ts @@ -0,0 +1 @@ +module.exports = {}; diff --git a/scripts/yarn.lock b/scripts/yarn.lock index 2eaf90151537..ec4a8f036f5e 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -2217,7 +2217,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14": +"@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.15": version: 1.4.15 resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" checksum: 0c6b5ae663087558039052a626d2d7ed5208da36cfd707dcc5cea4a07cfc918248403dcb5989a8f7afaf245ce0573b7cc6fd94c4a30453bd10e44d9363940ba5 @@ -3024,6 +3024,7 @@ __metadata: uuid: ^9.0.0 verdaccio: ^5.19.1 verdaccio-auth-memory: ^10.2.0 + vitest: ^0.34.4 wait-on: ^7.0.1 window-size: ^1.1.1 yaml: ^2.3.1 @@ -3357,6 +3358,22 @@ __metadata: languageName: node linkType: hard +"@types/chai-subset@npm:^1.3.3": + version: 1.3.3 + resolution: "@types/chai-subset@npm:1.3.3" + dependencies: + "@types/chai": "*" + checksum: 2dfb3210ce8d872288bb44329a44d4d1b7be360c72e8eb570a535c0e97246a4bd0209df304427d0e179c9e1c659d5dba07c25bdae13ef983edf41db81278fda5 + languageName: node + linkType: hard + +"@types/chai@npm:*, @types/chai@npm:^4.3.5": + version: 4.3.6 + resolution: "@types/chai@npm:4.3.6" + checksum: 388af382b11453a69808800479dcaff0323a0d1e15df1619175ebd55b294d716d560058f560ed55434e8846af46f017d7d78544822571f6322d3fac6d5f8a29d + languageName: node + linkType: hard + "@types/concat-stream@npm:^2.0.0": version: 2.0.0 resolution: "@types/concat-stream@npm:2.0.0" @@ -4235,6 +4252,59 @@ __metadata: languageName: node linkType: hard +"@vitest/expect@npm:0.34.4": + version: 0.34.4 + resolution: "@vitest/expect@npm:0.34.4" + dependencies: + "@vitest/spy": 0.34.4 + "@vitest/utils": 0.34.4 + chai: ^4.3.7 + checksum: 73e1d6b98cb3d2566c8d9f61db031c3a866c61beb923f6728ea714b4f0265bb9782e1356a0db5e7c593723166985f64e4daa1944af70be1420e8b24d5170f816 + languageName: node + linkType: hard + +"@vitest/runner@npm:0.34.4": + version: 0.34.4 + resolution: "@vitest/runner@npm:0.34.4" + dependencies: + "@vitest/utils": 0.34.4 + p-limit: ^4.0.0 + pathe: ^1.1.1 + checksum: 68ca71c7de105a5aa69ab8e1c8167fbb7e781c9d0011a497edaaaba13839924d59b36f03ab6076c7c0200888a05aeac90f8adc2d8e15aac83687f906040fe409 + languageName: node + linkType: hard + +"@vitest/snapshot@npm:0.34.4": + version: 0.34.4 + resolution: "@vitest/snapshot@npm:0.34.4" + dependencies: + magic-string: ^0.30.1 + pathe: ^1.1.1 + pretty-format: ^29.5.0 + checksum: 08c197c97b513c9774ce70418e3519c08a75ce7aa09dde1a686d118b7830081749dcb839e1ab36280d39e066967fb3334d21ea7631bfc969b229493c95f2edef + languageName: node + linkType: hard + +"@vitest/spy@npm:0.34.4": + version: 0.34.4 + resolution: "@vitest/spy@npm:0.34.4" + dependencies: + tinyspy: ^2.1.1 + checksum: c823a4d0fcd97fe6887a6567173ce94bb16b5e0cb4c8a6c47614e7f70d47d5d39b0ba3d0181906a2099dc87e90d17003a4dcd5762ed0b4d1e0ec79d0e4418b1a + languageName: node + linkType: hard + +"@vitest/utils@npm:0.34.4": + version: 0.34.4 + resolution: "@vitest/utils@npm:0.34.4" + dependencies: + diff-sequences: ^29.4.3 + loupe: ^2.3.6 + pretty-format: ^29.5.0 + checksum: 9464c0bec7d23be94e74e7ae0e66ab4359e5d08239d595963a4b2e851183b143a7ff0b07341d45d1db4e9fa64e38d8793176a743f637bcae12277419b1cfad7c + languageName: node + linkType: hard + "@yarnpkg/lockfile@npm:^1.1.0": version: 1.1.0 resolution: "@yarnpkg/lockfile@npm:1.1.0" @@ -4352,7 +4422,7 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.0.2, acorn-walk@npm:^8.1.1": +"acorn-walk@npm:^8.0.2, acorn-walk@npm:^8.1.1, acorn-walk@npm:^8.2.0": version: 8.2.0 resolution: "acorn-walk@npm:8.2.0" checksum: dbe92f5b2452c93e960c5594e666dd1fae141b965ff2cb4a1e1d0381e3e4db4274c5ce4ffa3d681a86ca2a8d4e29d5efc0670a08e23fd2800051ea387df56ca2 @@ -4368,7 +4438,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.1.0, acorn@npm:^8.4.1, acorn@npm:^8.8.1, acorn@npm:^8.9.0": +"acorn@npm:^8.1.0, acorn@npm:^8.10.0, acorn@npm:^8.4.1, acorn@npm:^8.8.1, acorn@npm:^8.9.0": version: 8.10.0 resolution: "acorn@npm:8.10.0" bin: @@ -4803,6 +4873,13 @@ __metadata: languageName: node linkType: hard +"assertion-error@npm:^1.1.0": + version: 1.1.0 + resolution: "assertion-error@npm:1.1.0" + checksum: 25456b2aa333250f01143968e02e4884a34588a8538fbbf65c91a637f1dbfb8069249133cd2f4e530f10f624d206a664e7df30207830b659e9f5298b00a4099b + languageName: node + linkType: hard + "ast-types-flow@npm:^0.0.7": version: 0.0.7 resolution: "ast-types-flow@npm:0.0.7" @@ -5378,7 +5455,7 @@ __metadata: languageName: node linkType: hard -"cac@npm:^6.7.12": +"cac@npm:^6.7.12, cac@npm:^6.7.14": version: 6.7.14 resolution: "cac@npm:6.7.14" checksum: 4ee06aaa7bab8981f0d54e5f5f9d4adcd64058e9697563ce336d8a3878ed018ee18ebe5359b2430eceae87e0758e62ea2019c3f52ae6e211b1bd2e133856cd10 @@ -5479,6 +5556,21 @@ __metadata: languageName: node linkType: hard +"chai@npm:^4.3.7": + version: 4.3.8 + resolution: "chai@npm:4.3.8" + dependencies: + assertion-error: ^1.1.0 + check-error: ^1.0.2 + deep-eql: ^4.1.2 + get-func-name: ^2.0.0 + loupe: ^2.3.1 + pathval: ^1.1.1 + type-detect: ^4.0.5 + checksum: 5aa714fbbd4b3a1506f4fc9094851bf9109f184d601c1278bcd4eb98d5ee05cc75d7e84f46d072d656502c55544b38c748a1c669468d138e41e5c9d175beffc5 + languageName: node + linkType: hard + "chalk@npm:^2.3.0, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" @@ -5559,6 +5651,13 @@ __metadata: languageName: node linkType: hard +"check-error@npm:^1.0.2": + version: 1.0.2 + resolution: "check-error@npm:1.0.2" + checksum: c58ac4d6a92203209a61d025568198c073f101691eb6247f999266e1d1e3ab3af2bbe0a41af5008c1f1b95446ec7831e6ba91f03816177f2da852f316ad7921d + languageName: node + linkType: hard + "checkup@npm:^1.3.0": version: 1.3.0 resolution: "checkup@npm:1.3.0" @@ -6373,6 +6472,15 @@ __metadata: languageName: node linkType: hard +"deep-eql@npm:^4.1.2": + version: 4.1.3 + resolution: "deep-eql@npm:4.1.3" + dependencies: + type-detect: ^4.0.0 + checksum: ff34e8605d8253e1bf9fe48056e02c6f347b81d9b5df1c6650a1b0f6f847b4a86453b16dc226b34f853ef14b626e85d04e081b022e20b00cd7d54f079ce9bbdd + languageName: node + linkType: hard + "deep-equal@npm:^2.0.5": version: 2.2.2 resolution: "deep-equal@npm:2.2.2" @@ -6561,7 +6669,7 @@ __metadata: languageName: node linkType: hard -"diff-sequences@npm:^29.6.3": +"diff-sequences@npm:^29.4.3, diff-sequences@npm:^29.6.3": version: 29.6.3 resolution: "diff-sequences@npm:29.6.3" checksum: 32e27ac7dbffdf2fb0eb5a84efd98a9ad084fbabd5ac9abb8757c6770d5320d2acd172830b28c4add29bb873d59420601dfc805ac4064330ce59b1adfd0593b2 @@ -8426,6 +8534,13 @@ __metadata: languageName: node linkType: hard +"get-func-name@npm:^2.0.0": + version: 2.0.0 + resolution: "get-func-name@npm:2.0.0" + checksum: ed8791f7ba92cfd747259dff7ec8b6cc42734cebd031fb58c99a6e71d24d3532d84b46ad7806cafad6ad21784dd04ae1808a002d2b21001425e21f5f394c34e7 + languageName: node + linkType: hard + "get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0, get-intrinsic@npm:^1.2.1": version: 1.2.1 resolution: "get-intrinsic@npm:1.2.1" @@ -10773,7 +10888,7 @@ __metadata: languageName: node linkType: hard -"jsonc-parser@npm:3.2.0, jsonc-parser@npm:^3.0.0": +"jsonc-parser@npm:3.2.0, jsonc-parser@npm:^3.0.0, jsonc-parser@npm:^3.2.0": version: 3.2.0 resolution: "jsonc-parser@npm:3.2.0" checksum: 5a12d4d04dad381852476872a29dcee03a57439574e4181d91dca71904fcdcc5e8e4706c0a68a2c61ad9810e1e1c5806b5100d52d3e727b78f5cdc595401045b @@ -11117,6 +11232,13 @@ __metadata: languageName: node linkType: hard +"local-pkg@npm:^0.4.3": + version: 0.4.3 + resolution: "local-pkg@npm:0.4.3" + checksum: 361c77d7873a629f09c9e86128926227171ee0fe3435d282fb80303ff255bb4d3c053b555d47e953b4f41d2561f2a7bc0e53e9ca5c9bc9607226a77c91ea4994 + languageName: node + linkType: hard + "locate-path@npm:^3.0.0": version: 3.0.0 resolution: "locate-path@npm:3.0.0" @@ -11329,6 +11451,15 @@ __metadata: languageName: node linkType: hard +"loupe@npm:^2.3.1, loupe@npm:^2.3.6": + version: 2.3.6 + resolution: "loupe@npm:2.3.6" + dependencies: + get-func-name: ^2.0.0 + checksum: a974841ce94ef2a35aac7144e7f9e789e3887f82286cd9ffe7ff00f2ac9d117481989948657465e2b0b102f23136d89ae0a18fd4a32d9015012cd64464453289 + languageName: node + linkType: hard + "lowdb@npm:1.0.0": version: 1.0.0 resolution: "lowdb@npm:1.0.0" @@ -11397,6 +11528,15 @@ __metadata: languageName: node linkType: hard +"magic-string@npm:^0.30.1": + version: 0.30.3 + resolution: "magic-string@npm:0.30.3" + dependencies: + "@jridgewell/sourcemap-codec": ^1.4.15 + checksum: f69f0626192131a8daf0d638a8f31fdd85fd26428dff22401ef251f3913a5c74a710b1edff91ef6203a20d2b1edcc8e55f9320ba84e9b224a3413bdd47f5339e + languageName: node + linkType: hard + "make-dir@npm:^1.0.0": version: 1.3.0 resolution: "make-dir@npm:1.3.0" @@ -12153,6 +12293,18 @@ __metadata: languageName: node linkType: hard +"mlly@npm:^1.2.0, mlly@npm:^1.4.0": + version: 1.4.2 + resolution: "mlly@npm:1.4.2" + dependencies: + acorn: ^8.10.0 + pathe: ^1.1.1 + pkg-types: ^1.0.3 + ufo: ^1.3.0 + checksum: 905e3a704c7d3bcaad55f31d6efe9f680eab5be053ab7f8b299b8dbc027041f741fa6a93db9a3c461be2552632f3831b6c43c50af530f5fb2e9cd6273bc9d642 + languageName: node + linkType: hard + "mount-point@npm:^3.0.0": version: 3.0.0 resolution: "mount-point@npm:3.0.0" @@ -12230,6 +12382,15 @@ __metadata: languageName: node linkType: hard +"nanoid@npm:^3.3.6": + version: 3.3.6 + resolution: "nanoid@npm:3.3.6" + bin: + nanoid: bin/nanoid.cjs + checksum: 606b355960d0fcbe3d27924c4c52ef7d47d3b57208808ece73279420d91469b01ec1dce10fae512b6d4a8c5a5432b352b228336a8b2202a6ea68e67fa348e2ee + languageName: node + linkType: hard + "natural-compare-lite@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare-lite@npm:1.4.0" @@ -13151,6 +13312,20 @@ __metadata: languageName: node linkType: hard +"pathe@npm:^1.1.0, pathe@npm:^1.1.1": + version: 1.1.1 + resolution: "pathe@npm:1.1.1" + checksum: 3ae5a0529c3415d91c3ac9133f52cffea54a0dd46892fe059f4b80faf36fd207957d4594bdc87043b65d0761b1e5728f81f46bafff3b5302da4e2e48889b8c0e + languageName: node + linkType: hard + +"pathval@npm:^1.1.1": + version: 1.1.1 + resolution: "pathval@npm:1.1.1" + checksum: f63e1bc1b33593cdf094ed6ff5c49c1c0dc5dc20a646ca9725cc7fe7cd9995002d51d5685b9b2ec6814342935748b711bafa840f84c0bb04e38ff40a335c94dc + languageName: node + linkType: hard + "pend@npm:~1.2.0": version: 1.2.0 resolution: "pend@npm:1.2.0" @@ -13309,6 +13484,17 @@ __metadata: languageName: node linkType: hard +"pkg-types@npm:^1.0.3": + version: 1.0.3 + resolution: "pkg-types@npm:1.0.3" + dependencies: + jsonc-parser: ^3.2.0 + mlly: ^1.2.0 + pathe: ^1.1.0 + checksum: 7f692ff2005f51b8721381caf9bdbc7f5461506ba19c34f8631660a215c8de5e6dca268f23a319dd180b8f7c47a0dc6efea14b376c485ff99e98d810b8f786c4 + languageName: node + linkType: hard + "pkginfo@npm:0.4.1": version: 0.4.1 resolution: "pkginfo@npm:0.4.1" @@ -13395,6 +13581,17 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.4.27": + version: 8.4.29 + resolution: "postcss@npm:8.4.29" + dependencies: + nanoid: ^3.3.6 + picocolors: ^1.0.0 + source-map-js: ^1.0.2 + checksum: b50b7ad4ac6c9ba029eda4381863570b7aed2672ffae2566ef109e556bae01823a51180409877ff2cce1fe186025751c7191c301eafc07b0d90c630ab5e0365c + languageName: node + linkType: hard + "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -13450,7 +13647,7 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^29.0.0, pretty-format@npm:^29.7.0": +"pretty-format@npm:^29.0.0, pretty-format@npm:^29.5.0, pretty-format@npm:^29.7.0": version: 29.7.0 resolution: "pretty-format@npm:29.7.0" dependencies: @@ -14759,7 +14956,7 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^3.2.5": +"rollup@npm:^3.2.5, rollup@npm:^3.27.1, rollup@npm:^3.28.0": version: 3.29.1 resolution: "rollup@npm:3.29.1" dependencies: @@ -15045,6 +15242,13 @@ __metadata: languageName: node linkType: hard +"siginfo@npm:^2.0.0": + version: 2.0.0 + resolution: "siginfo@npm:2.0.0" + checksum: 3def8f8e516fbb34cb6ae415b07ccc5d9c018d85b4b8611e3dc6f8be6d1899f693a4382913c9ed51a06babb5201639d76453ab297d1c54a456544acf5c892e34 + languageName: node + linkType: hard + "signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" @@ -15220,6 +15424,13 @@ __metadata: languageName: node linkType: hard +"source-map-js@npm:^1.0.2": + version: 1.0.2 + resolution: "source-map-js@npm:1.0.2" + checksum: 32f2dfd1e9b7168f9a9715eb1b4e21905850f3b50cf02cf476e47e4eebe8e6b762b63a64357896aa29b37e24922b4282df0f492e0d2ace572b43d15525976ff8 + languageName: node + linkType: hard + "source-map-support@npm:0.5.13": version: 0.5.13 resolution: "source-map-support@npm:0.5.13" @@ -15356,6 +15567,13 @@ __metadata: languageName: node linkType: hard +"stackback@npm:0.0.2": + version: 0.0.2 + resolution: "stackback@npm:0.0.2" + checksum: 89a1416668f950236dd5ac9f9a6b2588e1b9b62b1b6ad8dff1bfc5d1a15dbf0aafc9b52d2226d00c28dffff212da464eaeebfc6b7578b9d180cef3e3782c5983 + languageName: node + linkType: hard + "statuses@npm:2.0.1": version: 2.0.1 resolution: "statuses@npm:2.0.1" @@ -15363,6 +15581,13 @@ __metadata: languageName: node linkType: hard +"std-env@npm:^3.3.3": + version: 3.4.3 + resolution: "std-env@npm:3.4.3" + checksum: 61c0d673eb157bbd9ff65da42ae768ff154b948737030fddfbd3f289ab4c0455285d365b1ed03319e05df58eed26622aaa009a03ee1f9159ec71087646834a9a + languageName: node + linkType: hard + "steno@npm:^0.4.1": version: 0.4.4 resolution: "steno@npm:0.4.4" @@ -15609,6 +15834,15 @@ __metadata: languageName: node linkType: hard +"strip-literal@npm:^1.0.1": + version: 1.3.0 + resolution: "strip-literal@npm:1.3.0" + dependencies: + acorn: ^8.10.0 + checksum: 3c0c9ee41eb346e827eede61ef288457f53df30e3e6ff8b94fa81b636933b0c13ca4ea5c97d00a10d72d04be326da99ac819f8769f0c6407ba8177c98344a916 + languageName: node + linkType: hard + "strong-log-transformer@npm:^2.1.0": version: 2.1.0 resolution: "strong-log-transformer@npm:2.1.0" @@ -15898,6 +16132,27 @@ __metadata: languageName: node linkType: hard +"tinybench@npm:^2.5.0": + version: 2.5.1 + resolution: "tinybench@npm:2.5.1" + checksum: 9c55ef25ce1689c3e2fdb89cacbf27dada4d04f846cac70023fe97fc35d2122816d8bbc5b20253e071d13688cf006355d59f0096d22958b818e1e2fe60e5165b + languageName: node + linkType: hard + +"tinypool@npm:^0.7.0": + version: 0.7.0 + resolution: "tinypool@npm:0.7.0" + checksum: ecb35d9f74e72722c059acb1947ffc3c2caccb45266b89b72f74be2d28f0784d948b50bd9c6c68fa4159afd423ac5f5a07271a5f516d18a565dd06af0a37bc44 + languageName: node + linkType: hard + +"tinyspy@npm:^2.1.1": + version: 2.1.1 + resolution: "tinyspy@npm:2.1.1" + checksum: 0e7186fd380cbc594c35a0f6270f61b79ed22d1d960cac6064c3a5ebcf8a3a70d6590ff2049cba1d58631c3c556b1a67896d0db136381da7855a37087a90fbc5 + languageName: node + linkType: hard + "tmp@npm:~0.2.1": version: 0.2.1 resolution: "tmp@npm:0.2.1" @@ -16270,7 +16525,7 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:4.0.8": +"type-detect@npm:4.0.8, type-detect@npm:^4.0.0, type-detect@npm:^4.0.5": version: 4.0.8 resolution: "type-detect@npm:4.0.8" checksum: 8fb9a51d3f365a7de84ab7f73b653534b61b622aa6800aecdb0f1095a4a646d3f5eb295322127b6573db7982afcd40ab492d038cf825a42093a58b1e1353e0bd @@ -16368,6 +16623,13 @@ __metadata: languageName: node linkType: hard +"ufo@npm:^1.3.0": + version: 1.3.0 + resolution: "ufo@npm:1.3.0" + checksum: f1e163bd55b6b09573d69b1972f15a30a54bfdd20fdf3e02c5546e350a57d8b1578a05760a198e30b86d1f28918231842a6c2a8a182e30a0c155edbc353497da + languageName: node + linkType: hard + "uglify-js@npm:^3.1.4": version: 3.17.4 resolution: "uglify-js@npm:3.17.4" @@ -17219,6 +17481,162 @@ __metadata: languageName: node linkType: hard +"vite-node@npm:0.34.4": + version: 0.34.4 + resolution: "vite-node@npm:0.34.4" + dependencies: + cac: ^6.7.14 + debug: ^4.3.4 + mlly: ^1.4.0 + pathe: ^1.1.1 + picocolors: ^1.0.0 + vite: ^3.0.0 || ^4.0.0 + bin: + vite-node: vite-node.mjs + checksum: de3a75e2368716dc4d0c50e5ad78447d1dd926fb05cc913562d124746c23a175806820b19644ad09131a77328a424d07982bc193436270d8794ccd268001de65 + languageName: node + linkType: hard + +"vite@npm:^3.0.0 || ^4.0.0": + version: 4.4.9 + resolution: "vite@npm:4.4.9" + dependencies: + esbuild: ^0.18.10 + fsevents: ~2.3.2 + postcss: ^8.4.27 + rollup: ^3.27.1 + peerDependencies: + "@types/node": ">= 14" + less: "*" + lightningcss: ^1.21.0 + sass: "*" + stylus: "*" + sugarss: "*" + terser: ^5.4.0 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + bin: + vite: bin/vite.js + checksum: 80dbc632fd75b5866567c8fd605115c9d5718654dbf173f509cfd55c53f39dfbee24f62660e57fd5b11eb93f469a65abdbe6bae880ec8392bb70a5d0d7b6e6a9 + languageName: node + linkType: hard + +"vite@npm:^3.1.0 || ^4.0.0 || ^5.0.0-0": + version: 5.0.0-beta.1 + resolution: "vite@npm:5.0.0-beta.1" + dependencies: + esbuild: ^0.18.10 + fsevents: ~2.3.2 + postcss: ^8.4.27 + rollup: ^3.28.0 + peerDependencies: + "@types/node": ^18.0.0 || >=20.0.0 + less: "*" + lightningcss: ^1.21.0 + sass: "*" + stylus: "*" + sugarss: "*" + terser: ^5.4.0 + dependenciesMeta: + fsevents: + optional: true + peerDependenciesMeta: + "@types/node": + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + bin: + vite: bin/vite.js + checksum: 874e05072aee343d129eabb6161a44367f07416f63fe3e22a09b83913dd4d73f64b271ead9cff337841a20753ee3a7f3315e878518a6657cc024d5822c624f08 + languageName: node + linkType: hard + +"vitest@npm:^0.34.4": + version: 0.34.4 + resolution: "vitest@npm:0.34.4" + dependencies: + "@types/chai": ^4.3.5 + "@types/chai-subset": ^1.3.3 + "@types/node": "*" + "@vitest/expect": 0.34.4 + "@vitest/runner": 0.34.4 + "@vitest/snapshot": 0.34.4 + "@vitest/spy": 0.34.4 + "@vitest/utils": 0.34.4 + acorn: ^8.9.0 + acorn-walk: ^8.2.0 + cac: ^6.7.14 + chai: ^4.3.7 + debug: ^4.3.4 + local-pkg: ^0.4.3 + magic-string: ^0.30.1 + pathe: ^1.1.1 + picocolors: ^1.0.0 + std-env: ^3.3.3 + strip-literal: ^1.0.1 + tinybench: ^2.5.0 + tinypool: ^0.7.0 + vite: ^3.1.0 || ^4.0.0 || ^5.0.0-0 + vite-node: 0.34.4 + why-is-node-running: ^2.2.2 + peerDependencies: + "@edge-runtime/vm": "*" + "@vitest/browser": "*" + "@vitest/ui": "*" + happy-dom: "*" + jsdom: "*" + playwright: "*" + safaridriver: "*" + webdriverio: "*" + peerDependenciesMeta: + "@edge-runtime/vm": + optional: true + "@vitest/browser": + optional: true + "@vitest/ui": + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + bin: + vitest: vitest.mjs + checksum: 1e0c2823ac06b64a2edd910470b6b8a1c739f3a8429d839807ac6ed68284d7bb573f9e0e9b6257022fb9b9f673d4e627cae7e46c85f8b1a88abc05e0764d2306 + languageName: node + linkType: hard + "vscode-json-languageservice@npm:^4.1.6": version: 4.2.1 resolution: "vscode-json-languageservice@npm:4.2.1" @@ -17464,6 +17882,18 @@ __metadata: languageName: node linkType: hard +"why-is-node-running@npm:^2.2.2": + version: 2.2.2 + resolution: "why-is-node-running@npm:2.2.2" + dependencies: + siginfo: ^2.0.0 + stackback: 0.0.2 + bin: + why-is-node-running: cli.js + checksum: 805d57eb5d33f0fb4e36bae5dceda7fd8c6932c2aeb705e30003970488f1a2bc70029ee64be1a0e1531e2268b11e65606e88e5b71d667ea745e6dc48fc9014bd + languageName: node + linkType: hard + "wide-align@npm:^1.1.2, wide-align@npm:^1.1.5": version: 1.1.5 resolution: "wide-align@npm:1.1.5" From be2bf240a6f58cd5f3f52b347cba6e406083bbde Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 14 Sep 2023 15:19:49 +0200 Subject: [PATCH 002/105] remove storyshots some more and delete jest configs --- code/.eslintrc.js | 8 +- code/.yarnrc.yml | 8 -- code/jest.config.base.js | 118 ------------------ code/jest.config.browser.js | 9 -- code/jest.config.js | 16 --- code/jest.config.node.js | 7 -- code/jest.init.base.ts | 50 -------- code/jest.init.browser.ts | 48 ------- code/lib/cli/src/versions.ts | 2 - code/package.json | 2 - code/vitest.config.base.ts | 118 ------------------ code/vitest.config.browser.ts | 9 -- code/vitest.config.node.ts | 7 -- code/vitest.config.ts | 16 --- scripts/.yarnrc.yml | 8 -- scripts/tasks/check.ts | 4 +- scripts/tasks/compile.ts | 2 +- test-storybooks/ember-cli/package.json | 2 - test-storybooks/external-docs/package.json | 2 - .../server-kitchen-sink/package.json | 2 - .../standalone-preview/package.json | 2 - 21 files changed, 4 insertions(+), 436 deletions(-) delete mode 100644 code/jest.config.base.js delete mode 100644 code/jest.config.browser.js delete mode 100644 code/jest.config.js delete mode 100644 code/jest.config.node.js delete mode 100644 code/jest.init.base.ts delete mode 100644 code/jest.init.browser.ts delete mode 100644 code/vitest.config.base.ts delete mode 100644 code/vitest.config.browser.ts delete mode 100644 code/vitest.config.node.ts delete mode 100644 code/vitest.config.ts diff --git a/code/.eslintrc.js b/code/.eslintrc.js index e967113bb8eb..1df0d85c1437 100644 --- a/code/.eslintrc.js +++ b/code/.eslintrc.js @@ -94,13 +94,7 @@ module.exports = { }, }, { - files: [ - '**/__tests__/**', - '**/__testfixtures__/**', - '**/*.test.*', - '**/*.stories.*', - '**/storyshots-*/**/stories/**', - ], + files: ['**/__tests__/**', '**/__testfixtures__/**', '**/*.test.*', '**/*.stories.*'], rules: { '@typescript-eslint/no-empty-function': 'off', 'import/no-extraneous-dependencies': 'off', diff --git a/code/.yarnrc.yml b/code/.yarnrc.yml index b1f46c133b27..6bdac765d34c 100644 --- a/code/.yarnrc.yml +++ b/code/.yarnrc.yml @@ -2,14 +2,6 @@ compressionLevel: 0 enableGlobalCache: true -logFilters: - - code: YN0005 - level: discard - - code: YN0076 - level: discard - - level: discard - pattern: '@workspace:addons/storyshots-*/' - nodeLinker: node-modules npmRegistryServer: 'https://registry.yarnpkg.com' diff --git a/code/jest.config.base.js b/code/jest.config.base.js deleted file mode 100644 index 9fdc75f588a9..000000000000 --- a/code/jest.config.base.js +++ /dev/null @@ -1,118 +0,0 @@ -const os = require('os'); -const fs = require('fs'); -const path = require('path'); - -const swcrc = JSON.parse(fs.readFileSync('.swcrc', 'utf8')); - -/** - * TODO: Some windows related tasks are still commented out, because they are behaving differently on - * a local Windows machine compared to the Windows Server 2022 machine running in GitHub Actions. - * The main issue is that path.sep is behaving differently on the two machines. Some more investagations - * are necessary! - * */ -const skipOnWindows = [ - 'lib/core-server/src/utils/__tests__/server-statics.test.ts', - 'lib/core-common/src/utils/__tests__/template.test.ts', - 'addons/storyshots-core/src/frameworks/configure.test.ts', - 'lib/core-common/src/utils/__tests__/interpret-files.test.ts', - 'lib/cli/src/helpers.test.ts', - 'lib/csf-tools/src/enrichCsf.test.ts', -]; - -const modulesToTransform = [ - '@angular', - '@lit', - '@mdx-js', - 'ccount', - 'character-entities', - 'decode-named-character-reference', - 'estree', - 'is-absolute-url', - 'lit-html', - 'lit', - 'mdast', - 'micromark', - 'nanoid', - 'node-fetch', - 'remark', - 'rxjs', - 'data-uri-to-buffer', - 'fetch-blob', - 'formdata-polyfill', - 'slash', - 'space-separated-tokens', - 'stringify-entities', - 'unified', - 'unist', - 'uuid', - 'vfile-message', - 'vfile', - 'zwitch', -]; - -/** @type { import('jest').Config } */ -module.exports = { - cacheDirectory: path.resolve('.cache/jest'), - clearMocks: true, - moduleNameMapper: { - // non-js files - '\\.(jpg|jpeg|png|apng|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': - path.resolve('./__mocks__/fileMock.js'), - '\\.(css|scss|stylesheet)$': path.resolve('./__mocks__/styleMock.js'), - '\\.(md)$': path.resolve('./__mocks__/htmlMock.js'), - }, - transform: { - '^.+\\.(t|j)sx?$': ['@swc/jest', swcrc], - '^.+\\.mdx$': '@storybook/addon-docs/jest-transform-mdx', - }, - transformIgnorePatterns: [`(?/addons/*', - '/frameworks/*', - '/lib/*', - '/builders/*', - '/renderers/*', - '/ui/!(node_modules)*', - ], - collectCoverage: false, - collectCoverageFrom: ['**/src/**/*.{js,jsx,ts,tsx}', '!**/e2e-tests/**', '!**/node_modules/**'], - coverageDirectory: 'coverage', - coverageReporters: ['lcov'], - reporters: ['default', 'jest-junit'], - watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'], -}; diff --git a/code/jest.config.node.js b/code/jest.config.node.js deleted file mode 100644 index 54acf2670929..000000000000 --- a/code/jest.config.node.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('./jest.config.base'); - -module.exports = { - ...baseConfig, - setupFilesAfterEnv: [path.resolve('./jest.init.base.ts')], -}; diff --git a/code/jest.init.base.ts b/code/jest.init.base.ts deleted file mode 100644 index 5641077f934c..000000000000 --- a/code/jest.init.base.ts +++ /dev/null @@ -1,50 +0,0 @@ -import '@testing-library/jest-dom'; - -// setup file -import registerRequireContextHook from '@storybook/babel-plugin-require-context-hook/register'; - -registerRequireContextHook(); - -jest.mock('util-deprecate', () => (fn: any) => fn); - -// mock console.info calls for cleaner test execution -global.console.info = jest.fn().mockImplementation(() => {}); -global.console.debug = jest.fn().mockImplementation(() => {}); - -// mock local storage calls -const localStorageMock = { - getItem: jest.fn().mockName('getItem'), - setItem: jest.fn().mockName('setItem'), - clear: jest.fn().mockName('clear'), -}; - -Object.defineProperty(global, 'localStorage', { value: localStorageMock, writable: true }); - -/* Fail tests on PropType warnings - This allows us to throw an error in tests environments when there are prop-type warnings. - This should keep the tests free of warnings going forward. - */ - -const ignoreList = [ - (error: any) => error.message.includes('":nth-child" is potentially unsafe'), - (error: any) => error.message.includes('":first-child" is potentially unsafe'), - (error: any) => error.message.match(/Browserslist: .* is outdated. Please run:/), - (error: any) => error.message.includes('Failed prop type') && error.stack.includes('storyshots'), - (error: any) => - error.message.includes('react-async-component-lifecycle-hooks') && - error.stack.includes('addons/knobs/src/components/__tests__/Options.js'), - // Storyshots blows up if your project includes a (non stories.) mdx file. - (error: any) => error.message.match(/Unexpected error while loading .*(? { - const error = new Error(`${type}${message}`); - if (!ignoreList.reduce((acc, item) => acc || item(error), false)) { - throw error; - } -}; -const throwWarning = (message: any) => throwMessage('warn: ', message); -const throwError = (message: any) => throwMessage('error: ', message); - -global.console.error = throwError; -global.console.warn = throwWarning; diff --git a/code/jest.init.browser.ts b/code/jest.init.browser.ts deleted file mode 100644 index 0ad9f9d2e7ac..000000000000 --- a/code/jest.init.browser.ts +++ /dev/null @@ -1,48 +0,0 @@ -import './jest.init.base'; -import EventEmitter from 'events'; -import { webcrypto } from 'node:crypto'; - -// Mock for matchMedia since it's not yet implemented in JSDOM (https://jestjs.io/docs/en/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom) -global.window.matchMedia = jest.fn().mockImplementation((query) => { - return { - matches: false, - media: query, - onchange: null, - addListener: jest.fn(), // deprecated - removeListener: jest.fn(), // deprecated - addEventListener: jest.fn(), - removeEventListener: jest.fn(), - dispatchEvent: jest.fn(), - }; -}); - -class EventSourceMock { - static sources: EventSourceMock[] = []; - - static reset() { - this.sources = []; - } - - emitter: EventEmitter; - - constructor() { - this.emitter = new EventEmitter(); - EventSourceMock.sources.push(this); - } - - addEventListener(event: string, cb: (data: any) => void) { - this.emitter.on(event, cb); - } - - emit(event: string, data: any) { - this.emitter.emit(event, data); - } -} - -global.window.EventSource = EventSourceMock as any; - -Object.defineProperty(window, 'crypto', { - get() { - return webcrypto; - }, -}); diff --git a/code/lib/cli/src/versions.ts b/code/lib/cli/src/versions.ts index 2031d4360f16..cf0d1ebea43b 100644 --- a/code/lib/cli/src/versions.ts +++ b/code/lib/cli/src/versions.ts @@ -14,8 +14,6 @@ export default { '@storybook/addon-measure': '7.5.0-alpha.2', '@storybook/addon-outline': '7.5.0-alpha.2', '@storybook/addon-themes': '7.5.0-alpha.2', - '@storybook/addon-storyshots': '7.5.0-alpha.2', - '@storybook/addon-storyshots-puppeteer': '7.5.0-alpha.2', '@storybook/addon-storysource': '7.5.0-alpha.2', '@storybook/addon-toolbars': '7.5.0-alpha.2', '@storybook/addon-viewport': '7.5.0-alpha.2', diff --git a/code/package.json b/code/package.json index a1c94b95e1b4..67ac084c3a4a 100644 --- a/code/package.json +++ b/code/package.json @@ -114,8 +114,6 @@ "@storybook/addon-mdx-gfm": "workspace:*", "@storybook/addon-measure": "workspace:*", "@storybook/addon-outline": "workspace:*", - "@storybook/addon-storyshots": "workspace:*", - "@storybook/addon-storyshots-puppeteer": "workspace:*", "@storybook/addon-storysource": "workspace:*", "@storybook/addon-toolbars": "workspace:*", "@storybook/addon-viewport": "workspace:*", diff --git a/code/vitest.config.base.ts b/code/vitest.config.base.ts deleted file mode 100644 index 9fdc75f588a9..000000000000 --- a/code/vitest.config.base.ts +++ /dev/null @@ -1,118 +0,0 @@ -const os = require('os'); -const fs = require('fs'); -const path = require('path'); - -const swcrc = JSON.parse(fs.readFileSync('.swcrc', 'utf8')); - -/** - * TODO: Some windows related tasks are still commented out, because they are behaving differently on - * a local Windows machine compared to the Windows Server 2022 machine running in GitHub Actions. - * The main issue is that path.sep is behaving differently on the two machines. Some more investagations - * are necessary! - * */ -const skipOnWindows = [ - 'lib/core-server/src/utils/__tests__/server-statics.test.ts', - 'lib/core-common/src/utils/__tests__/template.test.ts', - 'addons/storyshots-core/src/frameworks/configure.test.ts', - 'lib/core-common/src/utils/__tests__/interpret-files.test.ts', - 'lib/cli/src/helpers.test.ts', - 'lib/csf-tools/src/enrichCsf.test.ts', -]; - -const modulesToTransform = [ - '@angular', - '@lit', - '@mdx-js', - 'ccount', - 'character-entities', - 'decode-named-character-reference', - 'estree', - 'is-absolute-url', - 'lit-html', - 'lit', - 'mdast', - 'micromark', - 'nanoid', - 'node-fetch', - 'remark', - 'rxjs', - 'data-uri-to-buffer', - 'fetch-blob', - 'formdata-polyfill', - 'slash', - 'space-separated-tokens', - 'stringify-entities', - 'unified', - 'unist', - 'uuid', - 'vfile-message', - 'vfile', - 'zwitch', -]; - -/** @type { import('jest').Config } */ -module.exports = { - cacheDirectory: path.resolve('.cache/jest'), - clearMocks: true, - moduleNameMapper: { - // non-js files - '\\.(jpg|jpeg|png|apng|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': - path.resolve('./__mocks__/fileMock.js'), - '\\.(css|scss|stylesheet)$': path.resolve('./__mocks__/styleMock.js'), - '\\.(md)$': path.resolve('./__mocks__/htmlMock.js'), - }, - transform: { - '^.+\\.(t|j)sx?$': ['@swc/jest', swcrc], - '^.+\\.mdx$': '@storybook/addon-docs/jest-transform-mdx', - }, - transformIgnorePatterns: [`(?/addons/*', - '/frameworks/*', - '/lib/*', - '/builders/*', - '/renderers/*', - '/ui/!(node_modules)*', - ], - collectCoverage: false, - collectCoverageFrom: ['**/src/**/*.{js,jsx,ts,tsx}', '!**/e2e-tests/**', '!**/node_modules/**'], - coverageDirectory: 'coverage', - coverageReporters: ['lcov'], - reporters: ['default', 'jest-junit'], - watchPlugins: ['jest-watch-typeahead/filename', 'jest-watch-typeahead/testname'], -}; diff --git a/scripts/.yarnrc.yml b/scripts/.yarnrc.yml index 0193aea8d545..2c1b3b93c416 100644 --- a/scripts/.yarnrc.yml +++ b/scripts/.yarnrc.yml @@ -2,14 +2,6 @@ compressionLevel: 0 enableGlobalCache: true -logFilters: - - code: YN0005 - level: discard - - code: YN0076 - level: discard - - level: discard - pattern: '@workspace:addons/storyshots-*' - nodeLinker: node-modules npmRegistryServer: 'https://registry.yarnpkg.com' diff --git a/scripts/tasks/check.ts b/scripts/tasks/check.ts index 8514d453dde4..9e8d9ce01867 100644 --- a/scripts/tasks/check.ts +++ b/scripts/tasks/check.ts @@ -4,8 +4,8 @@ import { maxConcurrentTasks } from '../utils/maxConcurrentTasks'; const parallel = process.env.CI ? 8 : maxConcurrentTasks; -const linkCommand = `nx run-many --target="check" --all --parallel=${parallel} --exclude=@storybook/addon-storyshots,@storybook/addon-storyshots-puppeteer,@storybook/vue,@storybook/svelte,@storybook/vue3,@storybook/angular`; -const nolinkCommand = `nx run-many --target="check" --all --parallel=${parallel} --exclude=@storybook/addon-storyshots,@storybook/addon-storyshots-puppeteer`; +const linkCommand = `nx run-many --target="check" --all --parallel=${parallel} --exclude=@storybook/vue,@storybook/svelte,@storybook/vue3,@storybook/angular`; +const nolinkCommand = `nx run-many --target="check" --all --parallel=${parallel}`; export const check: Task = { description: 'Typecheck the source code of the monorepo', diff --git a/scripts/tasks/compile.ts b/scripts/tasks/compile.ts index 5885d6a135f5..1d6c2678ce12 100644 --- a/scripts/tasks/compile.ts +++ b/scripts/tasks/compile.ts @@ -6,7 +6,7 @@ import { exec } from '../utils/exec'; import type { Task } from '../task'; const linkedContents = `export * from '../src/index';`; -const linkCommand = `nx run-many --target="prep" --all --parallel --max-parallel=${maxConcurrentTasks} --exclude=@storybook/addon-storyshots,@storybook/addon-storyshots-puppeteer -- --reset`; +const linkCommand = `nx run-many --target="prep" --all --parallel --max-parallel=${maxConcurrentTasks} -- --reset`; const noLinkCommand = `nx run-many --target="prep" --all --parallel=8 ${ process.env.CI ? `--max-parallel=${maxConcurrentTasks}` : '' } -- --reset --optimized`; diff --git a/test-storybooks/ember-cli/package.json b/test-storybooks/ember-cli/package.json index 8e593b60f357..8ceca49e95bc 100644 --- a/test-storybooks/ember-cli/package.json +++ b/test-storybooks/ember-cli/package.json @@ -23,8 +23,6 @@ "@storybook/addon-links": "portal:../../code/addons/links", "@storybook/addon-measure": "portal:../../code/addons/measure", "@storybook/addon-outline": "portal:../../code/addons/outline", - "@storybook/addon-storyshots": "portal:../../code/addons/storyshots-core", - "@storybook/addon-storyshots-puppeteer": "portal:../../code/addons/storyshots-puppeteer", "@storybook/addon-storysource": "portal:../../code/addons/storysource", "@storybook/addon-toolbars": "portal:../../code/addons/toolbars", "@storybook/addon-viewport": "portal:../../code/addons/viewport", diff --git a/test-storybooks/external-docs/package.json b/test-storybooks/external-docs/package.json index b8e2add1be67..08bd83c0bddc 100644 --- a/test-storybooks/external-docs/package.json +++ b/test-storybooks/external-docs/package.json @@ -23,8 +23,6 @@ "@storybook/addon-links": "portal:../../code/addons/links", "@storybook/addon-measure": "portal:../../code/addons/measure", "@storybook/addon-outline": "portal:../../code/addons/outline", - "@storybook/addon-storyshots": "portal:../../code/addons/storyshots-core", - "@storybook/addon-storyshots-puppeteer": "portal:../../code/addons/storyshots-puppeteer", "@storybook/addon-storysource": "portal:../../code/addons/storysource", "@storybook/addon-toolbars": "portal:../../code/addons/toolbars", "@storybook/addon-viewport": "portal:../../code/addons/viewport", diff --git a/test-storybooks/server-kitchen-sink/package.json b/test-storybooks/server-kitchen-sink/package.json index 4e908a34f22e..4987d2b8c86a 100644 --- a/test-storybooks/server-kitchen-sink/package.json +++ b/test-storybooks/server-kitchen-sink/package.json @@ -26,8 +26,6 @@ "@storybook/addon-links": "portal:../../code/addons/links", "@storybook/addon-measure": "portal:../../code/addons/measure", "@storybook/addon-outline": "portal:../../code/addons/outline", - "@storybook/addon-storyshots": "portal:../../code/addons/storyshots-core", - "@storybook/addon-storyshots-puppeteer": "portal:../../code/addons/storyshots-puppeteer", "@storybook/addon-storysource": "portal:../../code/addons/storysource", "@storybook/addon-toolbars": "portal:../../code/addons/toolbars", "@storybook/addon-viewport": "portal:../../code/addons/viewport", diff --git a/test-storybooks/standalone-preview/package.json b/test-storybooks/standalone-preview/package.json index 0ff82a1af4f1..725b0002ab1a 100644 --- a/test-storybooks/standalone-preview/package.json +++ b/test-storybooks/standalone-preview/package.json @@ -19,8 +19,6 @@ "@storybook/addon-links": "portal:../../code/addons/links", "@storybook/addon-measure": "portal:../../code/addons/measure", "@storybook/addon-outline": "portal:../../code/addons/outline", - "@storybook/addon-storyshots": "portal:../../code/addons/storyshots-core", - "@storybook/addon-storyshots-puppeteer": "portal:../../code/addons/storyshots-puppeteer", "@storybook/addon-storysource": "portal:../../code/addons/storysource", "@storybook/addon-toolbars": "portal:../../code/addons/toolbars", "@storybook/addon-viewport": "portal:../../code/addons/viewport", From b911c4d16a98bf6218a3c186ea0f00727e251bfa Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 14 Sep 2023 15:24:20 +0200 Subject: [PATCH 003/105] migrate first 2 stories by hand --- CODEOWNERS | 2 -- code/ui/manager/src/utils/status.test.ts | 5 +++-- code/ui/manager/src/utils/tree.test.js | 1 + 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index de427497aba2..14bd82cdc8c6 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -26,8 +26,6 @@ /code/addons/links/ @yannbf @JReinhold /code/addons/measure/ @yannbf @valentinpalkovic /code/addons/outline/ @yannbf @valentinpalkovic -/code/addons/storyshots-core/ @ndelangen -/code/addons/storyshots-puppeteer/ @ndelangen /code/addons/storysource/ @ndelangen /code/addons/toolbars/ @ndelangen @JReinhold /code/addons/viewport/ @yannbf @ndelangen diff --git a/code/ui/manager/src/utils/status.test.ts b/code/ui/manager/src/utils/status.test.ts index 294e23caea6d..682589cbd5db 100644 --- a/code/ui/manager/src/utils/status.test.ts +++ b/code/ui/manager/src/utils/status.test.ts @@ -1,3 +1,4 @@ +import { describe, test, expect } from 'vitest'; import { getHighestStatus, getGroupStatus } from './status'; import { mockDataset } from '../components/sidebar/mockdata'; @@ -22,7 +23,7 @@ describe('getGroupStatus', () => { 'group-1--child-b1': { a: { status: 'warn', description: '', title: '' } }, }) ).toMatchInlineSnapshot(` - Object { + { "group-1": "warn", "root-1-child-a1": "unknown", "root-1-child-a2": "unknown", @@ -39,7 +40,7 @@ describe('getGroupStatus', () => { }, }) ).toMatchInlineSnapshot(` - Object { + { "group-1": "error", "root-1-child-a1": "unknown", "root-1-child-a2": "unknown", diff --git a/code/ui/manager/src/utils/tree.test.js b/code/ui/manager/src/utils/tree.test.js index 3481e21f6c29..88f60b4a7747 100644 --- a/code/ui/manager/src/utils/tree.test.js +++ b/code/ui/manager/src/utils/tree.test.js @@ -1,3 +1,4 @@ +import { describe, test, expect } from 'vitest'; import { mockDataset, mockExpanded, mockSelected } from '../components/sidebar/mockdata'; import * as utils from './tree'; From ed23b2ea2d36a6e0895fe5d15be7ae5c953c6581 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 14 Sep 2023 15:27:30 +0200 Subject: [PATCH 004/105] run tests only once --- code/vitest.workspace.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/code/vitest.workspace.ts b/code/vitest.workspace.ts index b19384d0184b..6a74414e6d1a 100644 --- a/code/vitest.workspace.ts +++ b/code/vitest.workspace.ts @@ -1,12 +1,12 @@ import { defineWorkspace } from 'vitest/config'; export default defineWorkspace([ - 'addons/*', - 'frameworks/*', - 'lib/*', - 'deprecated/*', - 'builders/*', - 'ui/*', - 'presets/*', - 'renderers/*', + 'addons/*/vitest.config.ts', + 'frameworks/*/vitest.config.ts', + 'lib/*/vitest.config.ts', + 'deprecated/*/vitest.config.ts', + 'builders/*/vitest.config.ts', + 'ui/*/vitest.config.ts', + 'presets/*/vitest.config.ts', + 'renderers/*/vitest.config.ts', ]); From aacc4ac622ebff34f97ddc109b2e23bee4dc5e25 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 14 Sep 2023 16:14:23 +0200 Subject: [PATCH 005/105] migrate some things by hand --- code/.eslintignore | 1 - code/.eslintrc.js | 17 +----- code/addons/a11y/jest.config.js | 7 --- code/addons/a11y/src/a11yRunner.test.ts | 6 +- .../a11y/src/components/A11YPanel.test.tsx | 4 +- .../a11y/src/components/A11yContext.test.tsx | 4 +- code/addons/a11y/src/manager.test.tsx | 6 +- code/addons/a11y/tsconfig.json | 1 - code/addons/actions/jest.config.js | 7 --- .../src/runtime/__tests__/action.test.js | 2 +- .../src/runtime/__tests__/actions.test.js | 2 +- code/addons/backgrounds/jest.config.js | 7 --- code/addons/controls/jest.config.js | 7 --- code/addons/docs/jest.config.js | 7 --- code/addons/essentials/jest.config.js | 7 --- code/addons/gfm/jest.config.js | 7 --- code/addons/highlight/jest.config.js | 7 --- code/addons/interactions/jest.config.js | 7 --- code/addons/interactions/tsconfig.json | 1 - code/addons/jest/jest.config.js | 7 --- code/addons/links/jest.config.js | 7 --- .../links/src/react/components/link.test.tsx | 6 +- code/addons/links/src/utils.test.ts | 6 +- code/addons/links/tsconfig.json | 3 +- code/addons/measure/jest.config.js | 7 --- code/addons/outline/jest.config.js | 7 --- code/addons/storysource/jest.config.js | 7 --- code/addons/themes/jest.config.js | 7 --- code/addons/toolbars/jest.config.js | 7 --- code/addons/viewport/jest.config.js | 7 --- code/builders/builder-manager/jest.config.js | 7 --- code/builders/builder-vite/jest.config.js | 7 --- .../builder-vite/src/vite-config.test.ts | 4 +- code/builders/builder-webpack5/jest.config.js | 7 --- .../channel-postmessage/jest.config.js | 7 --- .../channel-websocket/jest.config.js | 7 --- .../builders/start-storybook/index.spec.ts | 2 +- .../src/builders/utils/run-compodoc.spec.ts | 2 +- .../angular-beta/RendererFactory.test.ts | 2 +- code/frameworks/ember/jest.config.js | 7 --- code/frameworks/html-webpack5/jest.config.js | 7 --- code/frameworks/nextjs/jest.config.js | 7 --- code/frameworks/preact-vite/jest.config.js | 7 --- .../frameworks/preact-webpack5/jest.config.js | 7 --- code/frameworks/react-vite/jest.config.js | 7 --- code/frameworks/react-webpack5/jest.config.js | 7 --- .../frameworks/server-webpack5/jest.config.js | 7 --- code/frameworks/svelte-vite/jest.config.js | 7 --- .../frameworks/svelte-webpack5/jest.config.js | 7 --- code/frameworks/sveltekit/jest.config.js | 7 --- code/frameworks/vue-vite/jest.config.js | 7 --- code/frameworks/vue-webpack5/jest.config.js | 7 --- code/frameworks/vue3-vite/jest.config.js | 7 --- code/frameworks/vue3-webpack5/jest.config.js | 7 --- .../web-components-vite/jest.config.js | 7 --- .../web-components-webpack5/jest.config.js | 7 --- code/lib/channels/jest.config.js | 7 --- code/lib/cli-storybook/jest.config.js | 7 --- code/lib/cli/jest.config.js | 7 --- .../angular-builders-multiproject.test.ts | 10 ++-- .../fixes/angular-builders.test.ts | 10 ++-- .../fixes/bare-mdx-stories-glob.test.ts | 2 +- .../automigrate/fixes/eslint-plugin.test.ts | 2 +- .../fixes/incompatible-addons.test.ts | 2 +- .../src/automigrate/fixes/mdx-1-to-2.test.ts | 2 +- .../cli/src/automigrate/fixes/mdx-gfm.test.ts | 2 +- .../automigrate/fixes/missing-babelrc.test.ts | 4 +- .../automigrate/fixes/new-frameworks.test.ts | 4 +- .../fixes/nodejs-requirement.test.ts | 4 +- .../fixes/remove-global-client-apis.test.ts | 6 +- .../automigrate/fixes/wrap-require.test.ts | 2 +- .../helpers/checkWebpack5Builder.test.ts | 6 +- .../helpers/getMigrationSummary.test.ts | 2 +- .../helpers/new-frameworks-utils.test.ts | 2 +- .../automigrate/helpers/testing-helpers.ts | 4 +- code/lib/cli/src/detect.test.ts | 16 ++--- code/lib/cli/src/generators/configure.test.ts | 16 ++--- code/lib/cli/src/helpers.test.ts | 20 +++---- .../JsPackageManagerFactory.test.ts | 8 +-- .../src/js-package-manager/NPMProxy.test.ts | 2 +- code/lib/cli/src/warn.test.ts | 8 +-- code/lib/cli/tsconfig.json | 2 +- code/lib/client-logger/jest.config.js | 7 --- code/lib/client-logger/src/index.test.ts | 2 +- code/lib/client-logger/tsconfig.json | 2 +- code/lib/codemod/jest.config.js | 9 --- .../transforms/__tests__/mdx-to-csf.test.ts | 4 +- .../transforms/__tests__/transforms.tests.js | 2 +- code/lib/core-common/jest.config.js | 7 --- code/lib/core-common/src/presets.test.ts | 6 +- .../utils/__tests__/normalize-stories.test.ts | 2 +- .../src/utils/__tests__/paths.test.ts | 4 +- code/lib/core-events/jest.config.js | 7 --- code/lib/core-server/jest.config.js | 7 --- .../core-server/src/presets/favicon.test.ts | 8 +-- .../StoryIndexGenerator.deprecated.test.ts | 22 +++---- .../src/utils/StoryIndexGenerator.test.ts | 20 +++---- .../utils/__tests__/index-extraction.test.ts | 4 +- .../utils/__tests__/server-address.test.ts | 4 +- .../src/utils/server-address.test.ts | 8 +-- .../src/utils/stories-json.test.ts | 12 ++-- .../src/utils/watch-story-specifiers.test.ts | 2 +- .../lib/core-server/src/withTelemetry.test.ts | 60 +++++++++---------- code/lib/core-webpack/jest.config.js | 7 --- code/lib/csf-plugin/jest.config.js | 7 --- code/lib/csf-tools/jest.config.js | 7 --- code/lib/csf-tools/src/ConfigFile.test.ts | 2 +- code/lib/csf-tools/src/CsfFile.test.ts | 2 +- code/lib/csf-tools/src/enrichCsf.test.ts | 2 +- code/lib/docs-tools/jest.config.js | 7 --- code/lib/instrumenter/jest.config.js | 7 --- .../lib/instrumenter/src/instrumenter.test.ts | 4 +- code/lib/manager-api/jest.config.js | 7 --- code/lib/manager-api/src/tests/events.test.ts | 2 +- .../lib/manager-api/src/tests/globals.test.ts | 4 +- code/lib/manager-api/src/tests/refs.test.ts | 4 +- code/lib/manager-api/src/tests/store.test.js | 2 +- .../lib/manager-api/src/tests/stories.test.ts | 12 ++-- code/lib/manager-api/src/tests/url.test.js | 2 +- .../manager-api/src/tests/versions.test.js | 8 +-- code/lib/node-logger/jest.config.js | 7 --- code/lib/node-logger/src/index.test.ts | 2 +- code/lib/postinstall/jest.config.js | 7 --- code/lib/postinstall/src/codemods.test.ts | 2 +- code/lib/preview-api/jest.config.js | 7 --- .../src/modules/core-client/start.test.ts | 12 ++-- .../PreviewWeb.integration.test.ts | 18 +++--- .../preview-web/PreviewWeb.mockdata.ts | 6 +- .../modules/preview-web/PreviewWeb.test.ts | 19 +++--- .../src/modules/preview-web/UrlStore.test.ts | 2 +- .../preview-web/parseArgsParam.test.ts | 2 +- .../src/modules/store/ArgsStore.test.ts | 2 +- .../src/modules/store/GlobalsStore.test.ts | 2 +- .../src/modules/store/StoryIndexStore.test.ts | 2 +- .../src/modules/store/StoryStore.test.ts | 6 +- .../src/modules/store/args.test.ts | 2 +- .../modules/store/csf/composeConfigs.test.ts | 2 +- .../modules/store/csf/prepareStory.test.ts | 4 +- .../src/modules/store/hooks.test.ts | 2 +- .../src/modules/store/inferArgTypes.test.ts | 8 +-- code/lib/preview/jest.config.js | 7 --- code/lib/react-dom-shim/tsconfig.json | 2 +- code/lib/router/jest.config.js | 7 --- code/lib/router/src/utils.test.ts | 2 +- code/lib/source-loader/jest.config.js | 7 --- code/lib/telemetry/jest.config.js | 7 --- .../telemetry/src/get-framework-info.test.ts | 4 +- .../telemetry/src/get-monorepo-type.test.ts | 4 +- code/lib/telemetry/src/session-id.test.ts | 4 +- .../telemetry/src/storybook-metadata.test.ts | 6 +- code/lib/telemetry/src/telemetry.test.ts | 10 ++-- code/lib/theming/jest.config.js | 7 --- code/lib/theming/src/tests/util.test.js | 2 +- code/lib/types/jest.config.js | 7 --- code/package.json | 11 ---- .../react-webpack/src/cra-config.test.ts | 10 ++-- .../src/framework-preset-react.test.ts | 2 +- code/renderers/html/jest.config.js | 7 --- .../html/src/docs/sourceDecorator.test.ts | 8 +-- code/renderers/preact/jest.config.js | 7 --- code/renderers/react/jest.config.js | 7 --- .../src/__test__/composeStories.test.tsx | 2 +- .../react/src/__test__/internals.test.tsx | 2 +- .../react/src/docs/jsxDecorator.test.tsx | 8 +-- code/renderers/server/jest.config.js | 7 --- code/renderers/svelte/jest.config.js | 7 --- code/renderers/vue/jest.config.js | 7 --- code/renderers/vue3/jest.config.js | 11 ---- code/renderers/web-components/jest.config.js | 7 --- .../src/docs/sourceDecorator.test.ts | 8 +-- .../docs/web-components-properties.test.ts | 4 +- code/tsconfig.json | 3 +- code/ui/blocks/jest.config.js | 7 --- .../internal/InternalCanvas.stories.tsx | 2 +- code/ui/blocks/tsconfig.json | 1 - code/ui/components/jest.config.js | 7 --- code/ui/components/tsconfig.json | 2 +- code/ui/manager/jest.config.js | 7 --- code/ui/manager/tsconfig.json | 1 - scripts/package.json | 2 +- .../release/__tests__/is-pr-frozen.test.ts | 4 +- .../release/__tests__/label-patches.test.ts | 16 ++--- scripts/release/__tests__/version.test.ts | 8 +-- .../release/__tests__/write-changelog.test.ts | 2 +- scripts/tsconfig.json | 2 +- 185 files changed, 301 insertions(+), 852 deletions(-) delete mode 100644 code/addons/a11y/jest.config.js delete mode 100644 code/addons/actions/jest.config.js delete mode 100644 code/addons/backgrounds/jest.config.js delete mode 100644 code/addons/controls/jest.config.js delete mode 100644 code/addons/docs/jest.config.js delete mode 100644 code/addons/essentials/jest.config.js delete mode 100644 code/addons/gfm/jest.config.js delete mode 100644 code/addons/highlight/jest.config.js delete mode 100644 code/addons/interactions/jest.config.js delete mode 100644 code/addons/jest/jest.config.js delete mode 100644 code/addons/links/jest.config.js delete mode 100644 code/addons/measure/jest.config.js delete mode 100644 code/addons/outline/jest.config.js delete mode 100644 code/addons/storysource/jest.config.js delete mode 100644 code/addons/themes/jest.config.js delete mode 100644 code/addons/toolbars/jest.config.js delete mode 100644 code/addons/viewport/jest.config.js delete mode 100644 code/builders/builder-manager/jest.config.js delete mode 100644 code/builders/builder-vite/jest.config.js delete mode 100644 code/builders/builder-webpack5/jest.config.js delete mode 100644 code/deprecated/channel-postmessage/jest.config.js delete mode 100644 code/deprecated/channel-websocket/jest.config.js delete mode 100644 code/frameworks/ember/jest.config.js delete mode 100644 code/frameworks/html-webpack5/jest.config.js delete mode 100644 code/frameworks/nextjs/jest.config.js delete mode 100644 code/frameworks/preact-vite/jest.config.js delete mode 100644 code/frameworks/preact-webpack5/jest.config.js delete mode 100644 code/frameworks/react-vite/jest.config.js delete mode 100644 code/frameworks/react-webpack5/jest.config.js delete mode 100644 code/frameworks/server-webpack5/jest.config.js delete mode 100644 code/frameworks/svelte-vite/jest.config.js delete mode 100644 code/frameworks/svelte-webpack5/jest.config.js delete mode 100644 code/frameworks/sveltekit/jest.config.js delete mode 100644 code/frameworks/vue-vite/jest.config.js delete mode 100644 code/frameworks/vue-webpack5/jest.config.js delete mode 100644 code/frameworks/vue3-vite/jest.config.js delete mode 100644 code/frameworks/vue3-webpack5/jest.config.js delete mode 100644 code/frameworks/web-components-vite/jest.config.js delete mode 100644 code/frameworks/web-components-webpack5/jest.config.js delete mode 100644 code/lib/channels/jest.config.js delete mode 100644 code/lib/cli-storybook/jest.config.js delete mode 100644 code/lib/cli/jest.config.js delete mode 100644 code/lib/client-logger/jest.config.js delete mode 100644 code/lib/codemod/jest.config.js delete mode 100644 code/lib/core-common/jest.config.js delete mode 100644 code/lib/core-events/jest.config.js delete mode 100644 code/lib/core-server/jest.config.js delete mode 100644 code/lib/core-webpack/jest.config.js delete mode 100644 code/lib/csf-plugin/jest.config.js delete mode 100644 code/lib/csf-tools/jest.config.js delete mode 100644 code/lib/docs-tools/jest.config.js delete mode 100644 code/lib/instrumenter/jest.config.js delete mode 100644 code/lib/manager-api/jest.config.js delete mode 100644 code/lib/node-logger/jest.config.js delete mode 100644 code/lib/postinstall/jest.config.js delete mode 100644 code/lib/preview-api/jest.config.js delete mode 100644 code/lib/preview/jest.config.js delete mode 100644 code/lib/router/jest.config.js delete mode 100644 code/lib/source-loader/jest.config.js delete mode 100644 code/lib/telemetry/jest.config.js delete mode 100644 code/lib/theming/jest.config.js delete mode 100644 code/lib/types/jest.config.js delete mode 100644 code/renderers/html/jest.config.js delete mode 100644 code/renderers/preact/jest.config.js delete mode 100644 code/renderers/react/jest.config.js delete mode 100644 code/renderers/server/jest.config.js delete mode 100644 code/renderers/svelte/jest.config.js delete mode 100644 code/renderers/vue/jest.config.js delete mode 100644 code/renderers/vue3/jest.config.js delete mode 100644 code/renderers/web-components/jest.config.js delete mode 100644 code/ui/blocks/jest.config.js delete mode 100644 code/ui/components/jest.config.js delete mode 100644 code/ui/manager/jest.config.js diff --git a/code/.eslintignore b/code/.eslintignore index 69b8bfb98ce3..d4623aea1453 100644 --- a/code/.eslintignore +++ b/code/.eslintignore @@ -16,6 +16,5 @@ ember-output !.babelrc.js !.eslintrc.js !.eslintrc-markdown.js -!.jest.config.js !.storybook diff --git a/code/.eslintrc.js b/code/.eslintrc.js index 1df0d85c1437..5b9d6a495e1f 100644 --- a/code/.eslintrc.js +++ b/code/.eslintrc.js @@ -15,7 +15,6 @@ module.exports = { 'eslint-comments/no-unused-disable': 'error', 'react-hooks/rules-of-hooks': 'off', 'import/extensions': 'off', // for mjs, we sometimes need extensions - 'jest/no-done-callback': 'off', '@typescript-eslint/dot-notation': [ 'error', { @@ -40,15 +39,7 @@ module.exports = { }, }, { - files: [ - '*.js', - '*.jsx', - '*.json', - '*.html', - '**/.storybook/*.ts', - '**/.storybook/*.tsx', - 'setup-jest.ts', - ], + files: ['*.js', '*.jsx', '*.json', '*.html', '**/.storybook/*.ts', '**/.storybook/*.tsx'], parserOptions: { project: null, }, @@ -142,12 +133,6 @@ module.exports = { 'spaced-comment': 'off', }, }, - { - files: ['**/e2e-tests/**/*'], - rules: { - 'jest/no-test-callback': 'off', // These aren't jest tests - }, - }, { files: ['**/builder-vite/input/iframe.html'], rules: { diff --git a/code/addons/a11y/jest.config.js b/code/addons/a11y/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/a11y/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/a11y/src/a11yRunner.test.ts b/code/addons/a11y/src/a11yRunner.test.ts index c1662d39369b..48f1dd909e63 100644 --- a/code/addons/a11y/src/a11yRunner.test.ts +++ b/code/addons/a11y/src/a11yRunner.test.ts @@ -1,11 +1,11 @@ import { addons } from '@storybook/preview-api'; import { EVENTS } from './constants'; -jest.mock('@storybook/preview-api'); -const mockedAddons = addons as jest.Mocked; +vi.mock('@storybook/preview-api'); +const mockedAddons = addons as vi.mocked; describe('a11yRunner', () => { - let mockChannel: { on: jest.Mock; emit?: jest.Mock }; + let mockChannel: { on: vi.mock; emit?: vi.mock }; beforeEach(() => { mockedAddons.getChannel.mockReset(); diff --git a/code/addons/a11y/src/components/A11YPanel.test.tsx b/code/addons/a11y/src/components/A11YPanel.test.tsx index cb1be531cad3..41fbe0f1ab18 100644 --- a/code/addons/a11y/src/components/A11YPanel.test.tsx +++ b/code/addons/a11y/src/components/A11YPanel.test.tsx @@ -7,11 +7,11 @@ import * as api from '@storybook/manager-api'; import { A11YPanel } from './A11YPanel'; import { EVENTS } from '../constants'; -jest.mock('@storybook/manager-api'); +vi.mock('@storybook/manager-api'); global.ResizeObserver = require('resize-observer-polyfill'); -const mockedApi = api as jest.Mocked; +const mockedApi = api as vi.mocked; const axeResult = { incomplete: [ diff --git a/code/addons/a11y/src/components/A11yContext.test.tsx b/code/addons/a11y/src/components/A11yContext.test.tsx index 0d7db6e8de46..65fd00c5ada7 100644 --- a/code/addons/a11y/src/components/A11yContext.test.tsx +++ b/code/addons/a11y/src/components/A11yContext.test.tsx @@ -8,8 +8,8 @@ import { HIGHLIGHT } from '@storybook/addon-highlight'; import { A11yContextProvider, useA11yContext } from './A11yContext'; import { EVENTS } from '../constants'; -jest.mock('@storybook/manager-api'); -const mockedApi = api as jest.Mocked; +vi.mock('@storybook/manager-api'); +const mockedApi = api as vi.mocked; const storyId = 'jest'; const axeResult: Partial = { diff --git a/code/addons/a11y/src/manager.test.tsx b/code/addons/a11y/src/manager.test.tsx index f389266ce785..29a79f520c95 100644 --- a/code/addons/a11y/src/manager.test.tsx +++ b/code/addons/a11y/src/manager.test.tsx @@ -3,10 +3,10 @@ import type { Addon_BaseType } from '@storybook/types'; import { PANEL_ID } from './constants'; import './manager'; -jest.mock('@storybook/manager-api'); -const mockedApi = api as unknown as jest.Mocked; +vi.mock('@storybook/manager-api'); +const mockedApi = api as unknown as vi.mocked; mockedApi.useAddonState = jest.fn(); -const mockedAddons = api.addons as jest.Mocked; +const mockedAddons = api.addons as vi.mocked; const registrationImpl = mockedAddons.register.mock.calls[0][1]; const isPanel = (input: Parameters[1]): input is Addon_BaseType => diff --git a/code/addons/a11y/tsconfig.json b/code/addons/a11y/tsconfig.json index 2713b9288c15..1dc5a72190bd 100644 --- a/code/addons/a11y/tsconfig.json +++ b/code/addons/a11y/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "types": ["jest", "@testing-library/jest-dom"], "skipLibCheck": true, "strict": true }, diff --git a/code/addons/actions/jest.config.js b/code/addons/actions/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/actions/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/actions/src/runtime/__tests__/action.test.js b/code/addons/actions/src/runtime/__tests__/action.test.js index 4f8f86761065..c64a2409a9b9 100644 --- a/code/addons/actions/src/runtime/__tests__/action.test.js +++ b/code/addons/actions/src/runtime/__tests__/action.test.js @@ -1,7 +1,7 @@ import { addons } from '@storybook/preview-api'; import { action, configureActions } from '../..'; -jest.mock('@storybook/preview-api'); +vi.mock('@storybook/preview-api'); const createChannel = () => { const channel = { emit: jest.fn() }; diff --git a/code/addons/actions/src/runtime/__tests__/actions.test.js b/code/addons/actions/src/runtime/__tests__/actions.test.js index b3e1ae2779ad..88f85e818ea2 100644 --- a/code/addons/actions/src/runtime/__tests__/actions.test.js +++ b/code/addons/actions/src/runtime/__tests__/actions.test.js @@ -1,7 +1,7 @@ import { addons } from '@storybook/preview-api'; import { actions } from '../..'; -jest.mock('@storybook/preview-api'); +vi.mock('@storybook/preview-api'); const createChannel = () => { const channel = { emit: jest.fn() }; diff --git a/code/addons/backgrounds/jest.config.js b/code/addons/backgrounds/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/backgrounds/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/controls/jest.config.js b/code/addons/controls/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/controls/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/docs/jest.config.js b/code/addons/docs/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/docs/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/essentials/jest.config.js b/code/addons/essentials/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/essentials/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/gfm/jest.config.js b/code/addons/gfm/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/gfm/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/highlight/jest.config.js b/code/addons/highlight/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/highlight/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/interactions/jest.config.js b/code/addons/interactions/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/interactions/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/interactions/tsconfig.json b/code/addons/interactions/tsconfig.json index 4bc2c0bffe1f..a6f65038a17b 100644 --- a/code/addons/interactions/tsconfig.json +++ b/code/addons/interactions/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "types": ["testing-library__jest-dom"], "skipLibCheck": true, "strict": false }, diff --git a/code/addons/jest/jest.config.js b/code/addons/jest/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/jest/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/links/jest.config.js b/code/addons/links/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/links/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/links/src/react/components/link.test.tsx b/code/addons/links/src/react/components/link.test.tsx index dd19a2eab69f..30c8dd546fec 100644 --- a/code/addons/links/src/react/components/link.test.tsx +++ b/code/addons/links/src/react/components/link.test.tsx @@ -5,8 +5,8 @@ import userEvent from '@testing-library/user-event'; import { SELECT_STORY } from '@storybook/core-events'; import LinkTo from './link'; -jest.mock('@storybook/preview-api'); -jest.mock('@storybook/global', () => ({ +vi.mock('@storybook/preview-api'); +vi.mock('@storybook/global', () => ({ global: { document: { location: { @@ -29,7 +29,7 @@ const mockChannel = () => { once: jest.fn(), }; }; -const mockAddons = addons as unknown as jest.Mocked; +const mockAddons = addons as unknown as vi.mocked; describe('LinkTo', () => { describe('render', () => { diff --git a/code/addons/links/src/utils.test.ts b/code/addons/links/src/utils.test.ts index f2dd2871501c..5597cd0a0066 100644 --- a/code/addons/links/src/utils.test.ts +++ b/code/addons/links/src/utils.test.ts @@ -3,15 +3,15 @@ import { SELECT_STORY } from '@storybook/core-events'; import { linkTo, hrefTo } from './utils'; -jest.mock('@storybook/preview-api'); -jest.mock('@storybook/global', () => ({ +vi.mock('@storybook/preview-api'); +vi.mock('@storybook/global', () => ({ global: { document: global.document, window: global, }, })); -const mockAddons = addons as unknown as jest.Mocked; +const mockAddons = addons as unknown as vi.mocked; describe('preview', () => { const channel = { emit: jest.fn() }; diff --git a/code/addons/links/tsconfig.json b/code/addons/links/tsconfig.json index a774dc60331e..5b3f3a56a68d 100644 --- a/code/addons/links/tsconfig.json +++ b/code/addons/links/tsconfig.json @@ -2,8 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "strict": true, - "skipLibCheck": true, - "types": ["testing-library__jest-dom"] + "skipLibCheck": true }, "include": ["src/**/*"] } diff --git a/code/addons/measure/jest.config.js b/code/addons/measure/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/measure/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/outline/jest.config.js b/code/addons/outline/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/outline/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/storysource/jest.config.js b/code/addons/storysource/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/storysource/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/themes/jest.config.js b/code/addons/themes/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/themes/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/toolbars/jest.config.js b/code/addons/toolbars/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/toolbars/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/addons/viewport/jest.config.js b/code/addons/viewport/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/addons/viewport/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/builders/builder-manager/jest.config.js b/code/builders/builder-manager/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/builders/builder-manager/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/builders/builder-vite/jest.config.js b/code/builders/builder-vite/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/builders/builder-vite/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/builders/builder-vite/src/vite-config.test.ts b/code/builders/builder-vite/src/vite-config.test.ts index c4f2f212be48..d849831165a8 100644 --- a/code/builders/builder-vite/src/vite-config.test.ts +++ b/code/builders/builder-vite/src/vite-config.test.ts @@ -2,11 +2,11 @@ import type { Options, Presets } from '@storybook/types'; import { loadConfigFromFile } from 'vite'; import { commonConfig } from './vite-config'; -jest.mock('vite', () => ({ +vi.mock('vite', () => ({ ...jest.requireActual('vite'), loadConfigFromFile: jest.fn(async () => ({})), })); -const loadConfigFromFileMock = jest.mocked(loadConfigFromFile); +const loadConfigFromFileMock = vi.mocked(loadConfigFromFile); const dummyOptions: Options = { configType: 'DEVELOPMENT', diff --git a/code/builders/builder-webpack5/jest.config.js b/code/builders/builder-webpack5/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/builders/builder-webpack5/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/deprecated/channel-postmessage/jest.config.js b/code/deprecated/channel-postmessage/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/deprecated/channel-postmessage/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/deprecated/channel-websocket/jest.config.js b/code/deprecated/channel-websocket/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/deprecated/channel-websocket/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/angular/src/builders/start-storybook/index.spec.ts b/code/frameworks/angular/src/builders/start-storybook/index.spec.ts index 9ef597063ca1..b96d25289add 100644 --- a/code/frameworks/angular/src/builders/start-storybook/index.spec.ts +++ b/code/frameworks/angular/src/builders/start-storybook/index.spec.ts @@ -19,7 +19,7 @@ jest.doMock('find-up', () => ({ sync: () => './storybook/tsconfig.ts' })); const mockRunScript = jest.fn(); -jest.mock('@storybook/cli', () => ({ +vi.mock('@storybook/cli', () => ({ getEnvConfig: (options: any) => options, versions: { storybook: 'x.x.x', diff --git a/code/frameworks/angular/src/builders/utils/run-compodoc.spec.ts b/code/frameworks/angular/src/builders/utils/run-compodoc.spec.ts index c8cbbf2133f6..e772cd76833c 100644 --- a/code/frameworks/angular/src/builders/utils/run-compodoc.spec.ts +++ b/code/frameworks/angular/src/builders/utils/run-compodoc.spec.ts @@ -5,7 +5,7 @@ const { runCompodoc } = require('./run-compodoc'); const mockRunScript = jest.fn(); -jest.mock('@storybook/cli', () => ({ +vi.mock('@storybook/cli', () => ({ JsPackageManagerFactory: { getPackageManager: () => ({ runPackageCommandSync: mockRunScript, diff --git a/code/frameworks/angular/src/client/angular-beta/RendererFactory.test.ts b/code/frameworks/angular/src/client/angular-beta/RendererFactory.test.ts index 0dc51d15eb6c..8dc35d2c5cf1 100644 --- a/code/frameworks/angular/src/client/angular-beta/RendererFactory.test.ts +++ b/code/frameworks/angular/src/client/angular-beta/RendererFactory.test.ts @@ -6,7 +6,7 @@ import { CanvasRenderer } from './CanvasRenderer'; import { RendererFactory } from './RendererFactory'; import { DocsRenderer } from './DocsRenderer'; -jest.mock('@angular/platform-browser-dynamic'); +vi.mock('@angular/platform-browser-dynamic'); declare const document: Document; describe('RendererFactory', () => { diff --git a/code/frameworks/ember/jest.config.js b/code/frameworks/ember/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/ember/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/html-webpack5/jest.config.js b/code/frameworks/html-webpack5/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/html-webpack5/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/nextjs/jest.config.js b/code/frameworks/nextjs/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/nextjs/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/preact-vite/jest.config.js b/code/frameworks/preact-vite/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/preact-vite/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/preact-webpack5/jest.config.js b/code/frameworks/preact-webpack5/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/preact-webpack5/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/react-vite/jest.config.js b/code/frameworks/react-vite/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/react-vite/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/react-webpack5/jest.config.js b/code/frameworks/react-webpack5/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/react-webpack5/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/server-webpack5/jest.config.js b/code/frameworks/server-webpack5/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/server-webpack5/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/svelte-vite/jest.config.js b/code/frameworks/svelte-vite/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/svelte-vite/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/svelte-webpack5/jest.config.js b/code/frameworks/svelte-webpack5/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/svelte-webpack5/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/sveltekit/jest.config.js b/code/frameworks/sveltekit/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/sveltekit/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/vue-vite/jest.config.js b/code/frameworks/vue-vite/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/vue-vite/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/vue-webpack5/jest.config.js b/code/frameworks/vue-webpack5/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/vue-webpack5/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/vue3-vite/jest.config.js b/code/frameworks/vue3-vite/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/vue3-vite/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/vue3-webpack5/jest.config.js b/code/frameworks/vue3-webpack5/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/vue3-webpack5/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/web-components-vite/jest.config.js b/code/frameworks/web-components-vite/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/web-components-vite/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/frameworks/web-components-webpack5/jest.config.js b/code/frameworks/web-components-webpack5/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/frameworks/web-components-webpack5/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/channels/jest.config.js b/code/lib/channels/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/channels/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/cli-storybook/jest.config.js b/code/lib/cli-storybook/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/cli-storybook/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/cli/jest.config.js b/code/lib/cli/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/cli/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/cli/src/automigrate/fixes/angular-builders-multiproject.test.ts b/code/lib/cli/src/automigrate/fixes/angular-builders-multiproject.test.ts index b9066b9c48f2..c7d6a93cd9c6 100644 --- a/code/lib/cli/src/automigrate/fixes/angular-builders-multiproject.test.ts +++ b/code/lib/cli/src/automigrate/fixes/angular-builders-multiproject.test.ts @@ -18,12 +18,12 @@ const checkAngularBuilders = async ({ }); }; -jest.mock('../../helpers', () => ({ +vi.mock('../../helpers', () => ({ ...jest.requireActual('../../helpers'), isNxProject: jest.fn(), })); -jest.mock('../../generators/ANGULAR/helpers', () => ({ +vi.mock('../../generators/ANGULAR/helpers', () => ({ ...jest.requireActual('../../generators/ANGULAR/helpers'), AngularJSON: jest.fn(), })); @@ -96,7 +96,7 @@ describe('is not Nx project', () => { describe('has one Storybook builder defined', () => { beforeEach(() => { // Mock AngularJSON.constructor - (angularHelpers.AngularJSON as jest.Mock).mockImplementation(() => ({ + (angularHelpers.AngularJSON as vi.mock).mockImplementation(() => ({ hasStorybookBuilder: true, })); }); @@ -114,7 +114,7 @@ describe('is not Nx project', () => { describe('has one project', () => { beforeEach(() => { // Mock AngularJSON.constructor - (angularHelpers.AngularJSON as jest.Mock).mockImplementation(() => ({ + (angularHelpers.AngularJSON as vi.mock).mockImplementation(() => ({ hasStorybookBuilder: false, projects: { project1: { root: 'project1', architect: {} }, @@ -136,7 +136,7 @@ describe('is not Nx project', () => { describe('has multiple projects without root project defined', () => { beforeEach(() => { // Mock AngularJSON.constructor - (angularHelpers.AngularJSON as jest.Mock).mockImplementation(() => ({ + (angularHelpers.AngularJSON as vi.mock).mockImplementation(() => ({ hasStorybookBuilder: false, projects: { project1: { root: 'project1', architect: {} }, diff --git a/code/lib/cli/src/automigrate/fixes/angular-builders.test.ts b/code/lib/cli/src/automigrate/fixes/angular-builders.test.ts index 8f1f0650deb6..020d7d415609 100644 --- a/code/lib/cli/src/automigrate/fixes/angular-builders.test.ts +++ b/code/lib/cli/src/automigrate/fixes/angular-builders.test.ts @@ -20,12 +20,12 @@ const checkAngularBuilders = async ({ }); }; -jest.mock('../../helpers', () => ({ +vi.mock('../../helpers', () => ({ ...jest.requireActual('../../helpers'), isNxProject: jest.fn(), })); -jest.mock('../../generators/ANGULAR/helpers', () => ({ +vi.mock('../../generators/ANGULAR/helpers', () => ({ ...jest.requireActual('../../generators/ANGULAR/helpers'), AngularJSON: jest.fn(), })); @@ -100,7 +100,7 @@ describe('is not Nx project', () => { describe('has one Storybook builder defined', () => { beforeEach(() => { // Mock AngularJSON.constructor - (angularHelpers.AngularJSON as jest.Mock).mockImplementation(() => ({ + (angularHelpers.AngularJSON as vi.mock).mockImplementation(() => ({ hasStorybookBuilder: true, })); }); @@ -118,7 +118,7 @@ describe('is not Nx project', () => { describe('has multiple projects without root project defined', () => { beforeEach(() => { // Mock AngularJSON.constructor - (angularHelpers.AngularJSON as jest.Mock).mockImplementation(() => ({ + (angularHelpers.AngularJSON as vi.mock).mockImplementation(() => ({ hasStorybookBuilder: false, projects: { project1: { root: 'project1', architect: {} }, @@ -141,7 +141,7 @@ describe('is not Nx project', () => { describe('has one project', () => { beforeEach(() => { // Mock AngularJSON.constructor - (angularHelpers.AngularJSON as jest.Mock).mockImplementation(() => ({ + (angularHelpers.AngularJSON as vi.mock).mockImplementation(() => ({ hasStorybookBuilder: false, projects: { project1: { root: 'project1', architect: {} }, diff --git a/code/lib/cli/src/automigrate/fixes/bare-mdx-stories-glob.test.ts b/code/lib/cli/src/automigrate/fixes/bare-mdx-stories-glob.test.ts index 7354fca3c4a9..f9cfaa3662ce 100644 --- a/code/lib/cli/src/automigrate/fixes/bare-mdx-stories-glob.test.ts +++ b/code/lib/cli/src/automigrate/fixes/bare-mdx-stories-glob.test.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import type { PackageJson } from '../../js-package-manager'; diff --git a/code/lib/cli/src/automigrate/fixes/eslint-plugin.test.ts b/code/lib/cli/src/automigrate/fixes/eslint-plugin.test.ts index 54a527848ae6..af4e35d77e66 100644 --- a/code/lib/cli/src/automigrate/fixes/eslint-plugin.test.ts +++ b/code/lib/cli/src/automigrate/fixes/eslint-plugin.test.ts @@ -5,7 +5,7 @@ import { eslintPlugin } from './eslint-plugin'; import { makePackageManager } from '../helpers/testing-helpers'; // eslint-disable-next-line global-require, jest/no-mocks-import -jest.mock('fs-extra', () => require('../../../../../__mocks__/fs-extra')); +vi.mock('fs-extra', () => require('../../../../../__mocks__/fs-extra')); const checkEslint = async ({ packageJson, diff --git a/code/lib/cli/src/automigrate/fixes/incompatible-addons.test.ts b/code/lib/cli/src/automigrate/fixes/incompatible-addons.test.ts index 46978eba8396..5d4423a76b31 100644 --- a/code/lib/cli/src/automigrate/fixes/incompatible-addons.test.ts +++ b/code/lib/cli/src/automigrate/fixes/incompatible-addons.test.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import { incompatibleAddons } from './incompatible-addons'; diff --git a/code/lib/cli/src/automigrate/fixes/mdx-1-to-2.test.ts b/code/lib/cli/src/automigrate/fixes/mdx-1-to-2.test.ts index d3f1556f42b9..e5c61f91eba0 100644 --- a/code/lib/cli/src/automigrate/fixes/mdx-1-to-2.test.ts +++ b/code/lib/cli/src/automigrate/fixes/mdx-1-to-2.test.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; import { dedent } from 'ts-dedent'; import { fixMdxStyleTags, fixMdxComments } from './mdx-1-to-2'; diff --git a/code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts b/code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts index 45d6704c86ea..c1c3022782d9 100644 --- a/code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts +++ b/code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts @@ -1,7 +1,7 @@ import type { StorybookConfig } from '@storybook/types'; import { mdxgfm } from './mdx-gfm'; -jest.mock('globby', () => ({ +vi.mock('globby', () => ({ __esModule: true, default: jest.fn().mockResolvedValue(['a/fake/file.mdx']), })); diff --git a/code/lib/cli/src/automigrate/fixes/missing-babelrc.test.ts b/code/lib/cli/src/automigrate/fixes/missing-babelrc.test.ts index f5306d9b0363..9dddb876080e 100644 --- a/code/lib/cli/src/automigrate/fixes/missing-babelrc.test.ts +++ b/code/lib/cli/src/automigrate/fixes/missing-babelrc.test.ts @@ -1,12 +1,12 @@ /* eslint-disable no-underscore-dangle */ -/// ; +import { describe, test, it, expect } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import { missingBabelRc } from './missing-babelrc'; import type { JsPackageManager } from '../../js-package-manager'; // eslint-disable-next-line global-require, jest/no-mocks-import -jest.mock('fs-extra', () => require('../../../../../__mocks__/fs-extra')); +vi.mock('fs-extra', () => require('../../../../../__mocks__/fs-extra')); const babelContent = JSON.stringify({ sourceType: 'unambiguous', diff --git a/code/lib/cli/src/automigrate/fixes/new-frameworks.test.ts b/code/lib/cli/src/automigrate/fixes/new-frameworks.test.ts index 441af07c311f..4f74b87140b2 100644 --- a/code/lib/cli/src/automigrate/fixes/new-frameworks.test.ts +++ b/code/lib/cli/src/automigrate/fixes/new-frameworks.test.ts @@ -4,8 +4,8 @@ import * as rendererHelpers from '../helpers/detectRenderer'; import { newFrameworks } from './new-frameworks'; import type { JsPackageManager } from '../../js-package-manager'; -jest.mock('find-up'); -jest.mock('../helpers/detectRenderer', () => ({ +vi.mock('find-up'); +vi.mock('../helpers/detectRenderer', () => ({ detectRenderer: jest.fn(jest.requireActual('../helpers/detectRenderer').detectRenderer), })); diff --git a/code/lib/cli/src/automigrate/fixes/nodejs-requirement.test.ts b/code/lib/cli/src/automigrate/fixes/nodejs-requirement.test.ts index d86b266b6081..6be35b06c1b0 100644 --- a/code/lib/cli/src/automigrate/fixes/nodejs-requirement.test.ts +++ b/code/lib/cli/src/automigrate/fixes/nodejs-requirement.test.ts @@ -1,9 +1,9 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; import { nodeJsRequirement } from './nodejs-requirement'; // eslint-disable-next-line global-require, jest/no-mocks-import -jest.mock('fs-extra', () => require('../../../../../__mocks__/fs-extra')); +vi.mock('fs-extra', () => require('../../../../../__mocks__/fs-extra')); const check = async ({ storybookVersion = '7.0.0' }) => { return nodeJsRequirement.check({ diff --git a/code/lib/cli/src/automigrate/fixes/remove-global-client-apis.test.ts b/code/lib/cli/src/automigrate/fixes/remove-global-client-apis.test.ts index 27d6fe065f3f..0dc35a2a887f 100644 --- a/code/lib/cli/src/automigrate/fixes/remove-global-client-apis.test.ts +++ b/code/lib/cli/src/automigrate/fixes/remove-global-client-apis.test.ts @@ -1,12 +1,12 @@ -/// ; - /* eslint-disable no-underscore-dangle */ +import { describe, it, expect, vi } from 'vitest'; + import path from 'path'; import type { JsPackageManager } from '../../js-package-manager'; import { RemovedAPIs, removedGlobalClientAPIs as migration } from './remove-global-client-apis'; // eslint-disable-next-line global-require, jest/no-mocks-import -jest.mock('fs-extra', () => require('../../../../../__mocks__/fs-extra')); +vi.mock('fs-extra', () => require('../../../../../__mocks__/fs-extra')); const check = async ({ contents, previewConfigPath }: any) => { if (contents) { diff --git a/code/lib/cli/src/automigrate/fixes/wrap-require.test.ts b/code/lib/cli/src/automigrate/fixes/wrap-require.test.ts index e040eb6e29f7..fb917deda7b4 100644 --- a/code/lib/cli/src/automigrate/fixes/wrap-require.test.ts +++ b/code/lib/cli/src/automigrate/fixes/wrap-require.test.ts @@ -1,7 +1,7 @@ import { wrapRequire } from './wrap-require'; import * as detect from '../../detect'; -jest.mock('../../detect', () => ({ +vi.mock('../../detect', () => ({ ...jest.requireActual('../../detect'), detectPnp: jest.fn(), })); diff --git a/code/lib/cli/src/automigrate/helpers/checkWebpack5Builder.test.ts b/code/lib/cli/src/automigrate/helpers/checkWebpack5Builder.test.ts index 51cb622baf42..a68f5fd0c130 100644 --- a/code/lib/cli/src/automigrate/helpers/checkWebpack5Builder.test.ts +++ b/code/lib/cli/src/automigrate/helpers/checkWebpack5Builder.test.ts @@ -8,7 +8,7 @@ const mockMainConfig: StorybookConfig = { stories: [], }; -jest.mock('./mainConfigFile'); +vi.mock('./mainConfigFile'); describe('checkWebpack5Builder', () => { let loggerWarnSpy: jest.SpyInstance; @@ -52,7 +52,7 @@ describe('checkWebpack5Builder', () => { }); it('should return null and log an info message if builderPackageName is found but not "webpack4"', async () => { - jest.mocked(getBuilderPackageName).mockReturnValueOnce('webpack5'); + vi.mocked(getBuilderPackageName).mockReturnValueOnce('webpack5'); const result = await checkWebpack5Builder({ mainConfig: mockMainConfig, @@ -64,7 +64,7 @@ describe('checkWebpack5Builder', () => { }); it('should return { storybookVersion } if all checks pass', async () => { - jest.mocked(getBuilderPackageName).mockReturnValueOnce('webpack4'); + vi.mocked(getBuilderPackageName).mockReturnValueOnce('webpack4'); const result = await checkWebpack5Builder({ mainConfig: mockMainConfig, diff --git a/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts b/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts index f5569ae2f49d..e3d23ebfb853 100644 --- a/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts +++ b/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts @@ -2,7 +2,7 @@ import { getMigrationSummary } from './getMigrationSummary'; import { FixStatus } from '../types'; import type { InstallationMetadata } from '../../js-package-manager/types'; -jest.mock('boxen', () => +vi.mock('boxen', () => // eslint-disable-next-line no-control-regex jest.fn((str, { title = '' }) => `${title}\n\n${str.replace(/\x1b\[[0-9;]*[mG]/g, '')}`) ); diff --git a/code/lib/cli/src/automigrate/helpers/new-frameworks-utils.test.ts b/code/lib/cli/src/automigrate/helpers/new-frameworks-utils.test.ts index a112619717b3..3c5e0a8ecbfa 100644 --- a/code/lib/cli/src/automigrate/helpers/new-frameworks-utils.test.ts +++ b/code/lib/cli/src/automigrate/helpers/new-frameworks-utils.test.ts @@ -5,7 +5,7 @@ import { } from './new-frameworks-utils'; import type { JsPackageManager } from '../../js-package-manager'; -jest.mock('find-up'); +vi.mock('find-up'); type GetBuilderInfoParams = Parameters[0]['mainConfig']; diff --git a/code/lib/cli/src/automigrate/helpers/testing-helpers.ts b/code/lib/cli/src/automigrate/helpers/testing-helpers.ts index f7b206ccb004..ee473277fe48 100644 --- a/code/lib/cli/src/automigrate/helpers/testing-helpers.ts +++ b/code/lib/cli/src/automigrate/helpers/testing-helpers.ts @@ -1,11 +1,11 @@ import type { JsPackageManager, PackageJson } from '../../js-package-manager'; -jest.mock('./mainConfigFile', () => ({ +vi.mock('./mainConfigFile', () => ({ ...jest.requireActual('./mainConfigFile'), getStorybookData: jest.fn(), })); -jest.mock('@storybook/core-common', () => ({ +vi.mock('@storybook/core-common', () => ({ ...jest.requireActual('@storybook/core-common'), loadMainConfig: jest.fn(), })); diff --git a/code/lib/cli/src/detect.test.ts b/code/lib/cli/src/detect.test.ts index 7a78fa8fa536..e656c4255416 100644 --- a/code/lib/cli/src/detect.test.ts +++ b/code/lib/cli/src/detect.test.ts @@ -4,27 +4,27 @@ import { detect, detectFrameworkPreset, detectLanguage } from './detect'; import { ProjectType, SupportedLanguage } from './project_types'; import type { JsPackageManager, PackageJsonWithMaybeDeps } from './js-package-manager'; -jest.mock('./helpers', () => ({ +vi.mock('./helpers', () => ({ isNxProject: jest.fn(), })); -jest.mock('fs', () => ({ +vi.mock('fs', () => ({ existsSync: jest.fn(), stat: jest.fn(), lstat: jest.fn(), access: jest.fn(), })); -jest.mock('fs-extra', () => ({ +vi.mock('fs-extra', () => ({ pathExistsSync: jest.fn(() => true), })); -jest.mock('path', () => ({ +vi.mock('path', () => ({ // make it return just the second path, for easier testing join: jest.fn((_, p) => p), })); -jest.mock('@storybook/node-logger'); +vi.mock('@storybook/node-logger'); const MOCK_FRAMEWORK_FILES: { name: string; @@ -244,7 +244,7 @@ describe('Detect', () => { }); it(`should return language javascript if the TS dependency is present but less than minimum supported`, async () => { - (logger.warn as jest.MockedFunction).mockClear(); + (logger.warn as vi.mockedFunction).mockClear(); const packageManager = { retrievePackageJson: () => @@ -438,7 +438,7 @@ describe('Detect', () => { MOCK_FRAMEWORK_FILES.forEach((structure) => { it(`${structure.name}`, () => { - (fs.existsSync as jest.Mock).mockImplementation((filePath) => { + (fs.existsSync as vi.mock).mockImplementation((filePath) => { return Object.keys(structure.files).includes(filePath); }); @@ -471,7 +471,7 @@ describe('Detect', () => { '/node_modules/.bin/react-scripts': 'file content', }; - (fs.existsSync as jest.Mock).mockImplementation((filePath) => { + (fs.existsSync as vi.mock).mockImplementation((filePath) => { return Object.keys(forkedReactScriptsConfig).includes(filePath); }); diff --git a/code/lib/cli/src/generators/configure.test.ts b/code/lib/cli/src/generators/configure.test.ts index c79eea9a253c..981b38f63c8d 100644 --- a/code/lib/cli/src/generators/configure.test.ts +++ b/code/lib/cli/src/generators/configure.test.ts @@ -3,7 +3,7 @@ import dedent from 'ts-dedent'; import { SupportedLanguage } from '../project_types'; import { configureMain, configurePreview } from './configure'; -jest.mock('fs-extra'); +vi.mock('fs-extra'); describe('configureMain', () => { beforeAll(() => { @@ -21,7 +21,7 @@ describe('configureMain', () => { }, }); - const { calls } = (fse.writeFile as unknown as jest.Mock).mock; + const { calls } = (fse.writeFile as unknown as vi.mock).mock; const [mainConfigPath, mainConfigContent] = calls[0]; expect(mainConfigPath).toEqual('./.storybook/main.js'); @@ -50,7 +50,7 @@ describe('configureMain', () => { }, }); - const { calls } = (fse.writeFile as unknown as jest.Mock).mock; + const { calls } = (fse.writeFile as unknown as vi.mock).mock; const [mainConfigPath, mainConfigContent] = calls[0]; expect(mainConfigPath).toEqual('./.storybook/main.ts'); @@ -85,7 +85,7 @@ describe('configureMain', () => { }, }); - const { calls } = (fse.writeFile as unknown as jest.Mock).mock; + const { calls } = (fse.writeFile as unknown as vi.mock).mock; const [mainConfigPath, mainConfigContent] = calls[0]; expect(mainConfigPath).toEqual('./.storybook/main.js'); @@ -119,7 +119,7 @@ describe('configurePreview', () => { rendererId: 'react', }); - const { calls } = (fse.writeFile as unknown as jest.Mock).mock; + const { calls } = (fse.writeFile as unknown as vi.mock).mock; const [previewConfigPath, previewConfigContent] = calls[0]; expect(previewConfigPath).toEqual('./.storybook/preview.js'); @@ -149,7 +149,7 @@ describe('configurePreview', () => { rendererId: 'react', }); - const { calls } = (fse.writeFile as unknown as jest.Mock).mock; + const { calls } = (fse.writeFile as unknown as vi.mock).mock; const [previewConfigPath, previewConfigContent] = calls[0]; expect(previewConfigPath).toEqual('./.storybook/preview.ts'); @@ -174,7 +174,7 @@ describe('configurePreview', () => { }); test('should not do anything if the framework template already included a preview', async () => { - (fse.pathExists as unknown as jest.Mock).mockReturnValueOnce(true); + (fse.pathExists as unknown as vi.mock).mockReturnValueOnce(true); await configurePreview({ language: SupportedLanguage.TYPESCRIPT_4_9, storybookConfigFolder: '.storybook', @@ -197,7 +197,7 @@ describe('configurePreview', () => { }, }); - const { calls } = (fse.writeFile as unknown as jest.Mock).mock; + const { calls } = (fse.writeFile as unknown as vi.mock).mock; const [previewConfigPath, previewConfigContent] = calls[0]; expect(previewConfigPath).toEqual('./.storybook/preview.ts'); diff --git a/code/lib/cli/src/helpers.test.ts b/code/lib/cli/src/helpers.test.ts index 01897444db11..5ebc2f385e39 100644 --- a/code/lib/cli/src/helpers.test.ts +++ b/code/lib/cli/src/helpers.test.ts @@ -6,15 +6,15 @@ import type { JsPackageManager } from './js-package-manager'; import type { SupportedRenderers } from './project_types'; import { SupportedLanguage } from './project_types'; -jest.mock('fs', () => ({ +vi.mock('fs', () => ({ existsSync: jest.fn(), })); -jest.mock('./dirs', () => ({ +vi.mock('./dirs', () => ({ getRendererDir: (_: JsPackageManager, renderer: string) => `@storybook/${renderer}`, getCliDir: () => '@storybook/cli', })); -jest.mock('fs-extra', () => ({ +vi.mock('fs-extra', () => ({ copySync: jest.fn(() => ({})), copy: jest.fn(() => ({})), ensureDir: jest.fn(() => {}), @@ -24,11 +24,11 @@ jest.mock('fs-extra', () => ({ writeFile: jest.fn(), })); -jest.mock('find-up', () => ({ +vi.mock('find-up', () => ({ sync: jest.fn(), })); -jest.mock('path', () => { +vi.mock('path', () => { const path = jest.requireActual('path'); return { // make it return just the second path, for easier testing @@ -50,7 +50,7 @@ describe('Helpers', () => { describe('copyTemplate', () => { it(`should copy template files when directory is present`, () => { const csfDirectory = `template-csf/`; - (fs.existsSync as jest.Mock).mockImplementation((filePath) => { + (fs.existsSync as vi.mock).mockImplementation((filePath) => { return true; }); helpers.copyTemplate(''); @@ -60,7 +60,7 @@ describe('Helpers', () => { }); it(`should throw an error if template directory cannot be found`, () => { - (fs.existsSync as jest.Mock).mockImplementation((filePath) => { + (fs.existsSync as vi.mock).mockImplementation((filePath) => { return false; }); @@ -86,7 +86,7 @@ describe('Helpers', () => { const componentsDirectory = exists.map( (folder: string) => `@storybook/react/template/cli/${folder}` ); - (fse.pathExists as jest.Mock).mockImplementation( + (fse.pathExists as vi.mock).mockImplementation( (filePath) => componentsDirectory.includes(filePath) || filePath === '@storybook/react/template/cli' ); @@ -110,7 +110,7 @@ describe('Helpers', () => { ); it(`should copy to src folder when exists`, async () => { - (fse.pathExists as jest.Mock).mockImplementation((filePath) => { + (fse.pathExists as vi.mock).mockImplementation((filePath) => { return filePath === '@storybook/react/template/cli' || filePath === './src'; }); await helpers.copyTemplateFiles({ @@ -122,7 +122,7 @@ describe('Helpers', () => { }); it(`should copy to root folder when src doesn't exist`, async () => { - (fse.pathExists as jest.Mock).mockImplementation((filePath) => { + (fse.pathExists as vi.mock).mockImplementation((filePath) => { return filePath === '@storybook/react/template/cli'; }); await helpers.copyTemplateFiles({ diff --git a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts index 4567987488ef..8bd9ffa218c1 100644 --- a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts +++ b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts @@ -7,11 +7,11 @@ import { PNPMProxy } from './PNPMProxy'; import { Yarn1Proxy } from './Yarn1Proxy'; import { Yarn2Proxy } from './Yarn2Proxy'; -jest.mock('cross-spawn'); -const spawnSyncMock = spawnSync as jest.Mock; +vi.mock('cross-spawn'); +const spawnSyncMock = spawnSync as vi.mock; -jest.mock('find-up'); -const findUpSyncMock = findUpSync as unknown as jest.Mock; +vi.mock('find-up'); +const findUpSyncMock = findUpSync as unknown as vi.mock; describe('JsPackageManagerFactory', () => { beforeEach(() => { diff --git a/code/lib/cli/src/js-package-manager/NPMProxy.test.ts b/code/lib/cli/src/js-package-manager/NPMProxy.test.ts index 60ba9e3e9a4a..c96d458d0d5c 100644 --- a/code/lib/cli/src/js-package-manager/NPMProxy.test.ts +++ b/code/lib/cli/src/js-package-manager/NPMProxy.test.ts @@ -1,7 +1,7 @@ import { NPMProxy } from './NPMProxy'; // mock createLogStream -jest.mock('../utils', () => ({ +vi.mock('../utils', () => ({ createLogStream: jest.fn(() => ({ logStream: '', readLogFile: jest.fn(), diff --git a/code/lib/cli/src/warn.test.ts b/code/lib/cli/src/warn.test.ts index 7ce18679f218..42a439101d5f 100644 --- a/code/lib/cli/src/warn.test.ts +++ b/code/lib/cli/src/warn.test.ts @@ -2,8 +2,8 @@ import globby from 'globby'; import { logger } from '@storybook/node-logger'; import { warn } from './warn'; -jest.mock('@storybook/node-logger'); -jest.mock('globby'); +vi.mock('@storybook/node-logger'); +vi.mock('globby'); describe('warn', () => { beforeEach(() => { @@ -21,7 +21,7 @@ describe('warn', () => { describe('when TypeScript is not installed as a dependency', () => { it('should not warn if `.tsx?` files are not found', () => { - (globby.sync as jest.Mock).mockReturnValueOnce([]); + (globby.sync as vi.mock).mockReturnValueOnce([]); warn({ hasTSDependency: false, }); @@ -29,7 +29,7 @@ describe('warn', () => { }); it('should warn if `.tsx?` files are found', () => { - (globby.sync as jest.Mock).mockReturnValueOnce(['a.ts']); + (globby.sync as vi.mock).mockReturnValueOnce(['a.ts']); warn({ hasTSDependency: false, }); diff --git a/code/lib/cli/tsconfig.json b/code/lib/cli/tsconfig.json index b0f65014db55..6bec4755416e 100644 --- a/code/lib/cli/tsconfig.json +++ b/code/lib/cli/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "types": ["node", "jest"], + "types": ["node"], "strict": false, "skipLibCheck": true, "strictNullChecks": false, diff --git a/code/lib/client-logger/jest.config.js b/code/lib/client-logger/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/lib/client-logger/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/client-logger/src/index.test.ts b/code/lib/client-logger/src/index.test.ts index be6b3f74b3e2..7776673a96a5 100644 --- a/code/lib/client-logger/src/index.test.ts +++ b/code/lib/client-logger/src/index.test.ts @@ -1,6 +1,6 @@ import { logger } from '.'; -jest.mock('@storybook/global', () => ({ global: { ...global, LOGLEVEL: 'debug' } })); +vi.mock('@storybook/global', () => ({ global: { ...global, LOGLEVEL: 'debug' } })); describe('client-logger default LOGLEVEL', () => { const initialConsole = { ...global.console }; diff --git a/code/lib/client-logger/tsconfig.json b/code/lib/client-logger/tsconfig.json index 2d2342b88992..7378641b0d33 100644 --- a/code/lib/client-logger/tsconfig.json +++ b/code/lib/client-logger/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "strict": true, - "types": ["node", "jest"] + "types": ["node"] }, "include": ["src/**/*"] } diff --git a/code/lib/codemod/jest.config.js b/code/lib/codemod/jest.config.js deleted file mode 100644 index 04479f97b1d5..000000000000 --- a/code/lib/codemod/jest.config.js +++ /dev/null @@ -1,9 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -/** @type {import('jest').Config} */ -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), - resetMocks: true, -}; diff --git a/code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts b/code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts index dc3ad2b654c7..a982dcf7f12a 100644 --- a/code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts +++ b/code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts @@ -8,8 +8,8 @@ expect.addSnapshotSerializer({ test: () => true, }); -jest.mock('node:fs'); -const fs = fs_ as jest.Mocked; +vi.mock('node:fs'); +const fs = fs_ as vi.mocked; beforeEach(() => { fs.existsSync.mockImplementation(() => false); diff --git a/code/lib/codemod/src/transforms/__tests__/transforms.tests.js b/code/lib/codemod/src/transforms/__tests__/transforms.tests.js index 840fa7a87304..79d98e2a77ed 100644 --- a/code/lib/codemod/src/transforms/__tests__/transforms.tests.js +++ b/code/lib/codemod/src/transforms/__tests__/transforms.tests.js @@ -3,7 +3,7 @@ import fs from 'fs'; import 'jest-specific-snapshot'; import { applyTransform } from 'jscodeshift/dist/testUtils'; -jest.mock('@storybook/node-logger'); +vi.mock('@storybook/node-logger'); const inputRegExp = /\.input\.js$/; diff --git a/code/lib/core-common/jest.config.js b/code/lib/core-common/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/core-common/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/core-common/src/presets.test.ts b/code/lib/core-common/src/presets.test.ts index 92b27dbdcd22..1fe603f92972 100644 --- a/code/lib/core-common/src/presets.test.ts +++ b/code/lib/core-common/src/presets.test.ts @@ -10,10 +10,10 @@ function wrapPreset(basePresets: any): { babel: Function; webpack: Function } { } function mockPreset(name: string, mockPresetObject: any) { - jest.mock(name, () => mockPresetObject, { virtual: true }); + vi.mock(name, () => mockPresetObject, { virtual: true }); } -jest.mock('@storybook/node-logger', () => ({ +vi.mock('@storybook/node-logger', () => ({ logger: { info: jest.fn(), warn: jest.fn(), @@ -21,7 +21,7 @@ jest.mock('@storybook/node-logger', () => ({ }, })); -jest.mock('./utils/safeResolve', () => { +vi.mock('./utils/safeResolve', () => { const KNOWN_FILES = [ '@storybook/react', '@storybook/addon-actions/manager', diff --git a/code/lib/core-common/src/utils/__tests__/normalize-stories.test.ts b/code/lib/core-common/src/utils/__tests__/normalize-stories.test.ts index 0b857b7a57c1..73acdc1b7c89 100644 --- a/code/lib/core-common/src/utils/__tests__/normalize-stories.test.ts +++ b/code/lib/core-common/src/utils/__tests__/normalize-stories.test.ts @@ -32,7 +32,7 @@ expect.extend({ }, }); -jest.mock('fs', () => { +vi.mock('fs', () => { const mockStat = ( path: string, options: Record, diff --git a/code/lib/core-common/src/utils/__tests__/paths.test.ts b/code/lib/core-common/src/utils/__tests__/paths.test.ts index 317c9cf1c2c5..33bd5d2ef585 100644 --- a/code/lib/core-common/src/utils/__tests__/paths.test.ts +++ b/code/lib/core-common/src/utils/__tests__/paths.test.ts @@ -3,7 +3,7 @@ import findUp from 'find-up'; import slash from 'slash'; import { normalizeStoryPath, getProjectRoot } from '../paths'; -jest.mock('find-up'); +vi.mock('find-up'); describe('paths - normalizeStoryPath()', () => { it('returns a path starting with "./" unchanged', () => { @@ -43,7 +43,7 @@ describe('paths - normalizeStoryPath()', () => { }); describe('getProjectRoot', () => { - const mockedFindUp = findUp as jest.Mocked; + const mockedFindUp = findUp as vi.mocked; it('should return the root directory containing a .git directory', () => { mockedFindUp.sync.mockImplementation((name) => diff --git a/code/lib/core-events/jest.config.js b/code/lib/core-events/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/core-events/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/core-server/jest.config.js b/code/lib/core-server/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/core-server/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/core-server/src/presets/favicon.test.ts b/code/lib/core-server/src/presets/favicon.test.ts index 3deaa8736113..8fad6ce8db96 100644 --- a/code/lib/core-server/src/presets/favicon.test.ts +++ b/code/lib/core-server/src/presets/favicon.test.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; import { join } from 'path'; import * as fs from 'fs-extra'; @@ -24,7 +24,7 @@ const createOptions = (locations: string[]): Parameters[1] => }, }); -jest.mock('fs-extra', () => { +vi.mock('fs-extra', () => { return { pathExists: jest.fn((p: string) => { return false; @@ -35,7 +35,7 @@ jest.mock('fs-extra', () => { }; }); -jest.mock('@storybook/node-logger', () => { +vi.mock('@storybook/node-logger', () => { return { logger: { warn: jest.fn(() => {}), @@ -43,7 +43,7 @@ jest.mock('@storybook/node-logger', () => { }; }); -const pathExists = fs.pathExists as jest.Mock; +const pathExists = fs.pathExists as vi.mock; test('with no staticDirs favicon should return default', async () => { const options = createOptions([]); diff --git a/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts b/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts index 60d700bad62e..5df0ace6f746 100644 --- a/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts +++ b/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-shadow */ -/// ; +import { describe, test, it, expect } from 'vitest'; /** * @jest-environment node @@ -16,8 +16,8 @@ import { logger, once } from '@storybook/node-logger'; import type { StoryIndexGeneratorOptions } from './StoryIndexGenerator'; import { StoryIndexGenerator } from './StoryIndexGenerator'; -jest.mock('@storybook/csf-tools'); -jest.mock('@storybook/csf', () => { +vi.mock('@storybook/csf-tools'); +vi.mock('@storybook/csf', () => { const csf = jest.requireActual('@storybook/csf'); return { ...csf, @@ -25,11 +25,11 @@ jest.mock('@storybook/csf', () => { }; }); -jest.mock('@storybook/node-logger'); +vi.mock('@storybook/node-logger'); -const toIdMock = toId as jest.Mock>; -const loadCsfMock = loadCsf as jest.Mock>; -const getStorySortParameterMock = getStorySortParameter as jest.Mock< +const toIdMock = toId as vi.mock>; +const loadCsfMock = loadCsf as vi.mock>; +const getStorySortParameterMock = getStorySortParameter as vi.mock< ReturnType >; @@ -62,8 +62,8 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { beforeEach(() => { const actual = jest.requireActual('@storybook/csf-tools'); loadCsfMock.mockImplementation(actual.loadCsf); - jest.mocked(logger.warn).mockClear(); - jest.mocked(once.warn).mockClear(); + vi.mocked(logger.warn).mockClear(); + vi.mocked(once.warn).mockClear(); }); describe('extraction', () => { const storiesSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry( @@ -1049,7 +1049,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.getIndex(); expect(once.warn).toHaveBeenCalledTimes(1); - const logMessage = jest.mocked(once.warn).mock.calls[0][0]; + const logMessage = vi.mocked(once.warn).mock.calls[0][0]; expect(logMessage).toContain(`No story files found for the specified pattern`); }); }); @@ -1211,7 +1211,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { const generator = new StoryIndexGenerator([docsSpecifier, storiesSpecifier], options); await generator.initialize(); - (getStorySortParameter as jest.Mock).mockReturnValueOnce({ + (getStorySortParameter as vi.mock).mockReturnValueOnce({ order: ['docs2', 'D', 'B', 'nested', 'A', 'second-nested', 'first-nested/deeply'], }); diff --git a/code/lib/core-server/src/utils/StoryIndexGenerator.test.ts b/code/lib/core-server/src/utils/StoryIndexGenerator.test.ts index fad7090789fe..c8f7c62578d5 100644 --- a/code/lib/core-server/src/utils/StoryIndexGenerator.test.ts +++ b/code/lib/core-server/src/utils/StoryIndexGenerator.test.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-shadow */ -/// ; +import { describe, test, it, expect } from 'vitest'; /** * @jest-environment node @@ -18,7 +18,7 @@ import type { StoryIndexGeneratorOptions } from './StoryIndexGenerator'; import { StoryIndexGenerator } from './StoryIndexGenerator'; import { csfIndexer } from '../presets/common-preset'; -jest.mock('@storybook/csf', () => { +vi.mock('@storybook/csf', () => { const csf = jest.requireActual('@storybook/csf'); return { ...csf, @@ -26,10 +26,10 @@ jest.mock('@storybook/csf', () => { }; }); -jest.mock('@storybook/node-logger'); +vi.mock('@storybook/node-logger'); -const toIdMock = toId as jest.Mock>; -jest.mock('@storybook/csf-tools', () => { +const toIdMock = toId as vi.mock>; +vi.mock('@storybook/csf-tools', () => { const csfTools = jest.requireActual('@storybook/csf-tools'); return { ...csfTools, @@ -38,8 +38,8 @@ jest.mock('@storybook/csf-tools', () => { }; }); -const readCsfMock = readCsf as jest.Mock>; -const getStorySortParameterMock = getStorySortParameter as jest.Mock< +const readCsfMock = readCsf as vi.mock>; +const getStorySortParameterMock = getStorySortParameter as vi.mock< ReturnType >; @@ -55,8 +55,8 @@ const options: StoryIndexGeneratorOptions = { describe('StoryIndexGenerator', () => { beforeEach(() => { - jest.mocked(logger.warn).mockClear(); - jest.mocked(once.warn).mockClear(); + vi.mocked(logger.warn).mockClear(); + vi.mocked(once.warn).mockClear(); }); describe('extraction', () => { const storiesSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry( @@ -1190,7 +1190,7 @@ describe('StoryIndexGenerator', () => { await generator.getIndex(); expect(once.warn).toHaveBeenCalledTimes(1); - const logMessage = jest.mocked(once.warn).mock.calls[0][0]; + const logMessage = vi.mocked(once.warn).mock.calls[0][0]; expect(logMessage).toContain(`No story files found for the specified pattern`); }); }); diff --git a/code/lib/core-server/src/utils/__tests__/index-extraction.test.ts b/code/lib/core-server/src/utils/__tests__/index-extraction.test.ts index 39820b3e2c17..cc826c7ccfc3 100644 --- a/code/lib/core-server/src/utils/__tests__/index-extraction.test.ts +++ b/code/lib/core-server/src/utils/__tests__/index-extraction.test.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; /** * @jest-environment node @@ -11,7 +11,7 @@ import type { NormalizedStoriesSpecifier } from '@storybook/types'; import type { StoryIndexGeneratorOptions } from '../StoryIndexGenerator'; import { AUTODOCS_TAG, STORIES_MDX_TAG, StoryIndexGenerator } from '../StoryIndexGenerator'; -jest.mock('@storybook/node-logger'); +vi.mock('@storybook/node-logger'); const options: StoryIndexGeneratorOptions = { configDir: path.join(__dirname, '..', '__mockdata__'), diff --git a/code/lib/core-server/src/utils/__tests__/server-address.test.ts b/code/lib/core-server/src/utils/__tests__/server-address.test.ts index 351061347db9..4c4ba898d1b8 100644 --- a/code/lib/core-server/src/utils/__tests__/server-address.test.ts +++ b/code/lib/core-server/src/utils/__tests__/server-address.test.ts @@ -1,8 +1,8 @@ import ip from 'ip'; import { getServerAddresses } from '../server-address'; -jest.mock('ip'); -const mockedIp = ip as jest.Mocked; +vi.mock('ip'); +const mockedIp = ip as vi.mocked; describe('getServerAddresses', () => { beforeEach(() => { diff --git a/code/lib/core-server/src/utils/server-address.test.ts b/code/lib/core-server/src/utils/server-address.test.ts index bf7dbd194fcf..0b3a5b637f29 100644 --- a/code/lib/core-server/src/utils/server-address.test.ts +++ b/code/lib/core-server/src/utils/server-address.test.ts @@ -1,9 +1,9 @@ import detectPort from 'detect-port'; import { getServerAddresses, getServerPort, getServerChannelUrl } from './server-address'; -jest.mock('ip'); -jest.mock('detect-port'); -jest.mock('@storybook/node-logger'); +vi.mock('ip'); +vi.mock('detect-port'); +vi.mock('@storybook/node-logger'); describe('getServerAddresses', () => { const port = 3000; @@ -51,7 +51,7 @@ describe('getServerPort', () => { it('should resolve with a free port', async () => { const expectedFreePort = 4000; - (detectPort as jest.Mock).mockResolvedValue(expectedFreePort); + (detectPort as vi.mock).mockResolvedValue(expectedFreePort); const result = await getServerPort(port); diff --git a/code/lib/core-server/src/utils/stories-json.test.ts b/code/lib/core-server/src/utils/stories-json.test.ts index e1f0b1f6d613..c671256a1798 100644 --- a/code/lib/core-server/src/utils/stories-json.test.ts +++ b/code/lib/core-server/src/utils/stories-json.test.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, it, expect, vi } from 'vitest'; import type { Router, Request, Response } from 'express'; import Watchpack from 'watchpack'; @@ -16,9 +16,9 @@ import type { StoryIndexGeneratorOptions } from './StoryIndexGenerator'; import { StoryIndexGenerator } from './StoryIndexGenerator'; import { csfIndexer } from '../presets/common-preset'; -jest.mock('watchpack'); -jest.mock('lodash/debounce'); -jest.mock('@storybook/node-logger'); +vi.mock('watchpack'); +vi.mock('lodash/debounce'); +vi.mock('@storybook/node-logger'); const workingDir = path.join(__dirname, '__mockdata__'); const normalizedStories = [ @@ -80,7 +80,7 @@ describe('useStoriesJson', () => { use.mockClear(); send.mockClear(); write.mockClear(); - (debounce as jest.Mock).mockImplementation((cb) => cb); + (debounce as vi.mock).mockImplementation((cb) => cb); }); const request: Request = { @@ -981,7 +981,7 @@ describe('useStoriesJson', () => { }); it('debounces invalidation events', async () => { - (debounce as jest.Mock).mockImplementation(jest.requireActual('lodash/debounce.js') as any); + (debounce as vi.mock).mockImplementation(jest.requireActual('lodash/debounce.js') as any); const mockServerChannel = { emit: jest.fn() } as any as ServerChannel; useStoriesJson({ diff --git a/code/lib/core-server/src/utils/watch-story-specifiers.test.ts b/code/lib/core-server/src/utils/watch-story-specifiers.test.ts index 53eb81dad074..f515fea7907c 100644 --- a/code/lib/core-server/src/utils/watch-story-specifiers.test.ts +++ b/code/lib/core-server/src/utils/watch-story-specifiers.test.ts @@ -4,7 +4,7 @@ import Watchpack from 'watchpack'; import { watchStorySpecifiers } from './watch-story-specifiers'; -jest.mock('watchpack'); +vi.mock('watchpack'); describe('watchStorySpecifiers', () => { const workingDir = path.join(__dirname, '__mockdata__'); diff --git a/code/lib/core-server/src/withTelemetry.test.ts b/code/lib/core-server/src/withTelemetry.test.ts index edcf7ddde90c..e2b3ab1588d1 100644 --- a/code/lib/core-server/src/withTelemetry.test.ts +++ b/code/lib/core-server/src/withTelemetry.test.ts @@ -1,5 +1,5 @@ /* eslint-disable local-rules/no-uncategorized-errors */ -/// ; +import { describe, test, it, expect } from 'vitest'; import prompts from 'prompts'; import { loadAllPresets, cache } from '@storybook/core-common'; @@ -7,9 +7,9 @@ import { telemetry, oneWayHash } from '@storybook/telemetry'; import { getErrorLevel, sendTelemetryError, withTelemetry } from './withTelemetry'; -jest.mock('prompts'); -jest.mock('@storybook/core-common'); -jest.mock('@storybook/telemetry'); +vi.mock('prompts'); +vi.mock('@storybook/core-common'); +vi.mock('@storybook/telemetry'); const cliOptions = {}; @@ -80,7 +80,7 @@ describe('withTelemetry', () => { }); it('does not send full error message when crash reports are disabled', async () => { - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({ enableCrashReports: false } as any), }); await expect(async () => @@ -100,7 +100,7 @@ describe('withTelemetry', () => { }); it('does send error message when crash reports are enabled', async () => { - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({ enableCrashReports: true } as any), }); @@ -121,7 +121,7 @@ describe('withTelemetry', () => { }); it('does not send any error message when telemetry is disabled', async () => { - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({ disableTelemetry: true } as any), }); @@ -142,7 +142,7 @@ describe('withTelemetry', () => { }); it('does send error messages when telemetry is disabled, but crash reports are enabled', async () => { - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({ disableTelemetry: true, enableCrashReports: true } as any), }); @@ -163,10 +163,10 @@ describe('withTelemetry', () => { }); it('does not send full error messages when disabled crash reports are cached', async () => { - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({} as any), }); - jest.mocked(cache.get).mockResolvedValueOnce(false); + vi.mocked(cache.get).mockResolvedValueOnce(false); await expect(async () => withTelemetry( @@ -185,10 +185,10 @@ describe('withTelemetry', () => { }); it('does send error messages when enabled crash reports are cached', async () => { - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({} as any), }); - jest.mocked(cache.get).mockResolvedValueOnce(true); + vi.mocked(cache.get).mockResolvedValueOnce(true); await expect(async () => withTelemetry( @@ -207,11 +207,11 @@ describe('withTelemetry', () => { }); it('does not send full error messages when disabled crash reports are prompted', async () => { - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({} as any), }); - jest.mocked(cache.get).mockResolvedValueOnce(undefined); - jest.mocked(prompts).mockResolvedValueOnce({ enableCrashReports: false }); + vi.mocked(cache.get).mockResolvedValueOnce(undefined); + vi.mocked(prompts).mockResolvedValueOnce({ enableCrashReports: false }); await expect(async () => withTelemetry( @@ -230,11 +230,11 @@ describe('withTelemetry', () => { }); it('does send error messages when enabled crash reports are prompted', async () => { - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({} as any), }); - jest.mocked(cache.get).mockResolvedValueOnce(undefined); - jest.mocked(prompts).mockResolvedValueOnce({ enableCrashReports: true }); + vi.mocked(cache.get).mockResolvedValueOnce(undefined); + vi.mocked(prompts).mockResolvedValueOnce({ enableCrashReports: true }); await expect(async () => withTelemetry( @@ -255,7 +255,7 @@ describe('withTelemetry', () => { // if main.js has errors, we have no way to tell if they've disabled error reporting, // so we assume they have. it('does not send full error messages when presets fail to evaluate', async () => { - jest.mocked(loadAllPresets).mockRejectedValueOnce(error); + vi.mocked(loadAllPresets).mockRejectedValueOnce(error); await expect(async () => withTelemetry( @@ -284,7 +284,7 @@ describe('sendTelemetryError', () => { const mockError = new Error('Test error'); const eventType: any = 'testEventType'; - jest.mocked(oneWayHash).mockReturnValueOnce('some-hash'); + vi.mocked(oneWayHash).mockReturnValueOnce('some-hash'); await sendTelemetryError(mockError, eventType, options); @@ -387,10 +387,10 @@ describe('getErrorLevel', () => { skipPrompt: false, }; - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({ enableCrashReports: true } as any), }); - jest.mocked(cache.get).mockResolvedValueOnce(false); + vi.mocked(cache.get).mockResolvedValueOnce(false); const errorLevel = await getErrorLevel(options); @@ -406,10 +406,10 @@ describe('getErrorLevel', () => { skipPrompt: false, }; - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({ enableCrashReports: false } as any), }); - jest.mocked(cache.get).mockResolvedValueOnce(false); + vi.mocked(cache.get).mockResolvedValueOnce(false); const errorLevel = await getErrorLevel(options); @@ -425,10 +425,10 @@ describe('getErrorLevel', () => { skipPrompt: false, }; - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({ disableTelemetry: true } as any), }); - jest.mocked(cache.get).mockResolvedValueOnce(false); + vi.mocked(cache.get).mockResolvedValueOnce(false); const errorLevel = await getErrorLevel(options); @@ -444,8 +444,8 @@ describe('getErrorLevel', () => { skipPrompt: false, }; - jest.mocked(cache.get).mockResolvedValueOnce(true); - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(cache.get).mockResolvedValueOnce(true); + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({} as any), }); @@ -463,10 +463,10 @@ describe('getErrorLevel', () => { skipPrompt: true, }; - jest.mocked(loadAllPresets).mockResolvedValueOnce({ + vi.mocked(loadAllPresets).mockResolvedValueOnce({ apply: async () => ({} as any), }); - jest.mocked(cache.get).mockResolvedValueOnce(undefined); + vi.mocked(cache.get).mockResolvedValueOnce(undefined); const errorLevel = await getErrorLevel(options); diff --git a/code/lib/core-webpack/jest.config.js b/code/lib/core-webpack/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/core-webpack/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/csf-plugin/jest.config.js b/code/lib/csf-plugin/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/lib/csf-plugin/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/csf-tools/jest.config.js b/code/lib/csf-tools/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/csf-tools/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/csf-tools/src/ConfigFile.test.ts b/code/lib/csf-tools/src/ConfigFile.test.ts index 10b2c5e8d025..93016db8b8ae 100644 --- a/code/lib/csf-tools/src/ConfigFile.test.ts +++ b/code/lib/csf-tools/src/ConfigFile.test.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; import { dedent } from 'ts-dedent'; import { loadConfig, printConfig } from './ConfigFile'; diff --git a/code/lib/csf-tools/src/CsfFile.test.ts b/code/lib/csf-tools/src/CsfFile.test.ts index c57859e3fee5..5cdf8a265de0 100644 --- a/code/lib/csf-tools/src/CsfFile.test.ts +++ b/code/lib/csf-tools/src/CsfFile.test.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; /* eslint-disable no-underscore-dangle */ import { dedent } from 'ts-dedent'; diff --git a/code/lib/csf-tools/src/enrichCsf.test.ts b/code/lib/csf-tools/src/enrichCsf.test.ts index a8f5f3aaa09c..9aa89ca9a616 100644 --- a/code/lib/csf-tools/src/enrichCsf.test.ts +++ b/code/lib/csf-tools/src/enrichCsf.test.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; /* eslint-disable no-underscore-dangle */ import { dedent } from 'ts-dedent'; diff --git a/code/lib/docs-tools/jest.config.js b/code/lib/docs-tools/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/docs-tools/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/instrumenter/jest.config.js b/code/lib/instrumenter/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/lib/instrumenter/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/instrumenter/src/instrumenter.test.ts b/code/lib/instrumenter/src/instrumenter.test.ts index eadb1f7d5c84..0f8728faf9b5 100644 --- a/code/lib/instrumenter/src/instrumenter.test.ts +++ b/code/lib/instrumenter/src/instrumenter.test.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; /* eslint-disable no-underscore-dangle */ import { addons, mockChannel } from '@storybook/preview-api'; @@ -13,7 +13,7 @@ import { global } from '@storybook/global'; import { EVENTS, Instrumenter } from './instrumenter'; import type { Options } from './types'; -jest.mock('@storybook/client-logger'); +vi.mock('@storybook/client-logger'); const callSpy = jest.fn(); const syncSpy = jest.fn(); diff --git a/code/lib/manager-api/jest.config.js b/code/lib/manager-api/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/manager-api/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/manager-api/src/tests/events.test.ts b/code/lib/manager-api/src/tests/events.test.ts index ee1c354c2f66..c380a107c7d4 100644 --- a/code/lib/manager-api/src/tests/events.test.ts +++ b/code/lib/manager-api/src/tests/events.test.ts @@ -1,7 +1,7 @@ import { getEventMetadata } from '../lib/events'; import type { API } from '../index'; -jest.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', () => ({ global: { location: { origin: 'http://localhost:6006', pathname: '/' }, }, diff --git a/code/lib/manager-api/src/tests/globals.test.ts b/code/lib/manager-api/src/tests/globals.test.ts index 1f51a113935a..b6db27711f37 100644 --- a/code/lib/manager-api/src/tests/globals.test.ts +++ b/code/lib/manager-api/src/tests/globals.test.ts @@ -9,8 +9,8 @@ import type { ModuleArgs } from '../lib/types'; const { logger } = require('@storybook/client-logger'); const { getEventMetadata } = require('../lib/events'); -jest.mock('@storybook/client-logger'); -jest.mock('../lib/events'); +vi.mock('@storybook/client-logger'); +vi.mock('../lib/events'); beforeEach(() => { getEventMetadata.mockReset().mockReturnValue({ sourceType: 'local' }); }); diff --git a/code/lib/manager-api/src/tests/refs.test.ts b/code/lib/manager-api/src/tests/refs.test.ts index f0556d560ba3..1f987f1e047d 100644 --- a/code/lib/manager-api/src/tests/refs.test.ts +++ b/code/lib/manager-api/src/tests/refs.test.ts @@ -3,9 +3,9 @@ import { getSourceType, init as initRefs } from '../modules/refs'; const { fetch } = global; -const fetchMock = jest.mocked(fetch); +const fetchMock = vi.mocked(fetch); -jest.mock('@storybook/global', () => { +vi.mock('@storybook/global', () => { const globalMock = { fetch: jest.fn(() => Promise.resolve({})), REFS: { diff --git a/code/lib/manager-api/src/tests/store.test.js b/code/lib/manager-api/src/tests/store.test.js index 4d555d74f9f0..2403c373a27c 100644 --- a/code/lib/manager-api/src/tests/store.test.js +++ b/code/lib/manager-api/src/tests/store.test.js @@ -3,7 +3,7 @@ import flushPromises from 'flush-promises'; import Store, { STORAGE_KEY } from '../store'; -jest.mock('store2', () => ({ +vi.mock('store2', () => ({ local: { set: jest.fn(), get: jest.fn(), diff --git a/code/lib/manager-api/src/tests/stories.test.ts b/code/lib/manager-api/src/tests/stories.test.ts index a93cd1df9a99..22127d3aa931 100644 --- a/code/lib/manager-api/src/tests/stories.test.ts +++ b/code/lib/manager-api/src/tests/stories.test.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; import { STORY_ARGS_UPDATED, UPDATE_STORY_ARGS, @@ -26,17 +26,17 @@ import { mockEntries, docsEntries, preparedEntries, navigationEntries } from './ import type { ModuleArgs } from '../lib/types'; const mockGetEntries = jest.fn(); -const fetch = global.fetch as jest.Mock>; -const getEventMetadata = getEventMetadataOriginal as unknown as jest.Mock< +const fetch = global.fetch as vi.mock>; +const getEventMetadata = getEventMetadataOriginal as unknown as vi.mock< ReturnType >; const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); -jest.mock('../lib/events', () => ({ +vi.mock('../lib/events', () => ({ getEventMetadata: jest.fn(() => ({ sourceType: 'local' })), })); -jest.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', () => ({ global: { ...globalThis, fetch: jest.fn(() => ({ json: () => ({ v: 4, entries: mockGetEntries() }) })), @@ -65,7 +65,7 @@ function createMockModuleArgs({ fullAPI = {}, initialState = {}, }: { - fullAPI?: Partial>; + fullAPI?: Partial>; initialState?: Partial; }) { const navigate = jest.fn(); diff --git a/code/lib/manager-api/src/tests/url.test.js b/code/lib/manager-api/src/tests/url.test.js index 33cf4a1872c1..a236314db5eb 100644 --- a/code/lib/manager-api/src/tests/url.test.js +++ b/code/lib/manager-api/src/tests/url.test.js @@ -5,7 +5,7 @@ import { SET_CURRENT_STORY, GLOBALS_UPDATED, UPDATE_QUERY_PARAMS } from '@storyb import EventEmitter from 'events'; import { init as initURL } from '../modules/url'; -jest.mock('@storybook/client-logger'); +vi.mock('@storybook/client-logger'); jest.useFakeTimers(); describe('initial state', () => { diff --git a/code/lib/manager-api/src/tests/versions.test.js b/code/lib/manager-api/src/tests/versions.test.js index 004221a3d076..1d5c4cdc9c66 100644 --- a/code/lib/manager-api/src/tests/versions.test.js +++ b/code/lib/manager-api/src/tests/versions.test.js @@ -1,10 +1,10 @@ import { init as initVersions } from '../modules/versions'; -jest.mock('../version', () => ({ +vi.mock('../version', () => ({ version: '3.0.0', })); -jest.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', () => ({ global: { VERSIONCHECK: JSON.stringify({ success: true, @@ -21,7 +21,7 @@ jest.mock('@storybook/global', () => ({ }, })); -jest.mock('@storybook/client-logger'); +vi.mock('@storybook/client-logger'); function createMockStore() { let state = { @@ -42,7 +42,7 @@ function createMockStore() { }; } -jest.mock('@storybook/client-logger'); +vi.mock('@storybook/client-logger'); describe('versions API', () => { it('sets initial state with current version', async () => { diff --git a/code/lib/node-logger/jest.config.js b/code/lib/node-logger/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/node-logger/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/node-logger/src/index.test.ts b/code/lib/node-logger/src/index.test.ts index 3cda41501ed0..6ffb9658040c 100644 --- a/code/lib/node-logger/src/index.test.ts +++ b/code/lib/node-logger/src/index.test.ts @@ -3,7 +3,7 @@ import { logger } from '.'; globalThis.console = { log: jest.fn() } as any; -jest.mock('npmlog', () => ({ +vi.mock('npmlog', () => ({ info: jest.fn(), warn: jest.fn(), error: jest.fn(), diff --git a/code/lib/postinstall/jest.config.js b/code/lib/postinstall/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/postinstall/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/postinstall/src/codemods.test.ts b/code/lib/postinstall/src/codemods.test.ts index cc7489df0b0e..6c8e56a16275 100644 --- a/code/lib/postinstall/src/codemods.test.ts +++ b/code/lib/postinstall/src/codemods.test.ts @@ -4,7 +4,7 @@ import 'jest-specific-snapshot'; // @ts-expect-error (broken types) import { applyTransform } from 'jscodeshift/dist/testUtils'; -jest.mock('@storybook/node-logger'); +vi.mock('@storybook/node-logger'); const inputRegExp = /\.input\.js$/; diff --git a/code/lib/preview-api/jest.config.js b/code/lib/preview-api/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/preview-api/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/preview-api/src/modules/core-client/start.test.ts b/code/lib/preview-api/src/modules/core-client/start.test.ts index b114e640f50a..fc0957874343 100644 --- a/code/lib/preview-api/src/modules/core-client/start.test.ts +++ b/code/lib/preview-api/src/modules/core-client/start.test.ts @@ -20,7 +20,7 @@ import { import { start as realStart } from './start'; import type { Loadable } from './executeLoadable'; -jest.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', () => ({ global: { ...globalThis, window: globalThis, @@ -37,14 +37,14 @@ jest.mock('@storybook/global', () => ({ // console.log(global); -jest.mock('@storybook/channels', () => ({ +vi.mock('@storybook/channels', () => ({ createBrowserChannel: () => mockChannel, })); -jest.mock('@storybook/client-logger'); -jest.mock('react-dom'); +vi.mock('@storybook/client-logger'); +vi.mock('react-dom'); // for the auto-title test -jest.mock('../../store', () => { +vi.mock('../../store', () => { const actualStore = jest.requireActual('../../store'); return { ...actualStore, @@ -53,7 +53,7 @@ jest.mock('../../store', () => { }; }); -jest.mock('../../preview-web', () => { +vi.mock('../../preview-web', () => { const actualPreviewWeb = jest.requireActual('../../preview-web'); class OverloadPreviewWeb extends actualPreviewWeb.PreviewWeb { diff --git a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.integration.test.ts b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.integration.test.ts index 805c5e7cb1b6..4ca470a67a94 100644 --- a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.integration.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.integration.test.ts @@ -24,16 +24,16 @@ import { // - ie. from`renderToCanvas()` (stories) or`ReactDOM.render()` (docs) in. // This file lets them rip. -jest.mock('@storybook/channels', () => ({ +vi.mock('@storybook/channels', () => ({ ...jest.requireActual('@storybook/channels'), createBrowserChannel: () => mockChannel, })); -jest.mock('@storybook/client-logger'); +vi.mock('@storybook/client-logger'); -jest.mock('./WebView'); +vi.mock('./WebView'); const { document } = global; -jest.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', () => ({ global: { ...globalThis, history: { replaceState: jest.fn() }, @@ -69,8 +69,8 @@ beforeEach(() => { addons.setChannel(mockChannel as any); addons.setServerChannel(createMockChannel()); - jest.mocked(WebView.prototype).prepareForDocs.mockReturnValue('docs-element' as any); - jest.mocked(WebView.prototype).prepareForStory.mockReturnValue('story-element' as any); + vi.mocked(WebView.prototype).prepareForDocs.mockReturnValue('docs-element' as any); + vi.mocked(WebView.prototype).prepareForStory.mockReturnValue('story-element' as any); }); describe('PreviewWeb', () => { @@ -100,7 +100,7 @@ describe('PreviewWeb', () => { const docsRoot = document.createElement('div'); ( - preview.view.prepareForDocs as any as jest.Mock + preview.view.prepareForDocs as any as vi.mock ).mockReturnValue(docsRoot as any); componentOneExports.default.parameters.docs.container.mockImplementationOnce(() => React.createElement('div', {}, 'INSIDE') @@ -127,14 +127,14 @@ describe('PreviewWeb', () => { const docsRoot = document.createElement('div'); ( - preview.view.prepareForDocs as any as jest.Mock + preview.view.prepareForDocs as any as vi.mock ).mockReturnValue(docsRoot as any); componentOneExports.default.parameters.docs.container.mockImplementationOnce(() => { throw new Error('Docs rendering error'); }); ( - preview.view.showErrorDisplay as any as jest.Mock + preview.view.showErrorDisplay as any as vi.mock ).mockClear(); await preview.initialize({ importFn, getProjectAnnotations }); await waitForRender(); diff --git a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.mockdata.ts b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.mockdata.ts index e136fc63b260..57c3ca18a241 100644 --- a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.mockdata.ts +++ b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.mockdata.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; import { EventEmitter } from 'events'; import { @@ -48,7 +48,7 @@ export const extraComponentOneExports = { }, e: {}, }; -export const importFn: jest.Mocked = jest.fn( +export const importFn: vi.mocked = jest.fn( async (path: string) => ({ './src/ComponentOne.stories.js': componentOneExports, @@ -63,7 +63,7 @@ export const docsRenderer = { render: jest.fn().mockImplementation((context, parameters, element) => Promise.resolve()), unmount: jest.fn(), }; -export const teardownrenderToCanvas: jest.Mock = jest.fn(); +export const teardownrenderToCanvas: vi.mock = jest.fn(); export const projectAnnotations = { globals: { a: 'b' }, globalTypes: {}, diff --git a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts index 41e735ebfddb..1abd3cffccda 100644 --- a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts @@ -59,7 +59,7 @@ const { history, document } = global; const mockStoryIndex = jest.fn(() => storyIndex); let mockFetchResult: any; -jest.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', () => ({ global: { ...(jest.requireActual('@storybook/global') as any), history: { replaceState: jest.fn() }, @@ -77,9 +77,9 @@ jest.mock('@storybook/global', () => ({ }, })); -jest.mock('@storybook/client-logger'); -jest.mock('react-dom'); -jest.mock('./WebView'); +vi.mock('@storybook/client-logger'); +vi.mock('react-dom'); +vi.mock('./WebView'); const serializeError = (error: Error) => { const { name = 'Error', message = String(error), stack } = error; @@ -131,15 +131,15 @@ beforeEach(() => { projectAnnotations.render.mockClear(); projectAnnotations.decorators[0].mockClear(); docsRenderer.render.mockClear(); - (logger.warn as jest.Mock).mockClear(); + (logger.warn as vi.mock).mockClear(); mockStoryIndex.mockReset().mockReturnValue(storyIndex); addons.setChannel(mockChannel as any); addons.setServerChannel(createMockChannel()); mockFetchResult = { status: 200, json: mockStoryIndex, text: () => 'error text' }; - jest.mocked(WebView.prototype).prepareForDocs.mockReturnValue('docs-element' as any); - jest.mocked(WebView.prototype).prepareForStory.mockReturnValue('story-element' as any); + vi.mocked(WebView.prototype).prepareForDocs.mockReturnValue('docs-element' as any); + vi.mocked(WebView.prototype).prepareForStory.mockReturnValue('story-element' as any); }); describe('PreviewWeb', () => { @@ -530,8 +530,7 @@ describe('PreviewWeb', () => { await expect(preview.initialize({ importFn, getProjectAnnotations })).rejects.toThrow(); expect(preview.view.showErrorDisplay).toHaveBeenCalled(); - expect((preview.view.showErrorDisplay as jest.Mock).mock.calls[0][0]) - .toMatchInlineSnapshot(` + expect((preview.view.showErrorDisplay as vi.mock).mock.calls[0][0]).toMatchInlineSnapshot(` [Error: Expected your framework's preset to export a \`renderToCanvas\` field. Perhaps it needs to be upgraded for Storybook 6.4? @@ -3109,7 +3108,7 @@ describe('PreviewWeb', () => { document.location.search = '?id=component-one--a'; const preview = await createAndRenderPreview(); - (preview.view.showMain as jest.Mock).mockClear(); + (preview.view.showMain as vi.mock).mockClear(); mockChannel.emit.mockClear(); preview.onStoriesChanged({ importFn: newImportFn }); await waitForEvents([STORY_UNCHANGED]); diff --git a/code/lib/preview-api/src/modules/preview-web/UrlStore.test.ts b/code/lib/preview-api/src/modules/preview-web/UrlStore.test.ts index 58784329913c..3a4d7f184a5b 100644 --- a/code/lib/preview-api/src/modules/preview-web/UrlStore.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/UrlStore.test.ts @@ -4,7 +4,7 @@ import { pathToId, setPath, getSelectionSpecifierFromPath } from './UrlStore'; const { history, document } = global; -jest.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', () => ({ global: { history: { replaceState: jest.fn() }, document: { diff --git a/code/lib/preview-api/src/modules/preview-web/parseArgsParam.test.ts b/code/lib/preview-api/src/modules/preview-web/parseArgsParam.test.ts index 246c3c2cba35..477fdc284e70 100644 --- a/code/lib/preview-api/src/modules/preview-web/parseArgsParam.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/parseArgsParam.test.ts @@ -1,6 +1,6 @@ import { parseArgsParam } from './parseArgsParam'; -jest.mock('@storybook/client-logger', () => ({ +vi.mock('@storybook/client-logger', () => ({ once: { warn: jest.fn() }, })); diff --git a/code/lib/preview-api/src/modules/store/ArgsStore.test.ts b/code/lib/preview-api/src/modules/store/ArgsStore.test.ts index d4656ef71f3b..46277efc6ffd 100644 --- a/code/lib/preview-api/src/modules/store/ArgsStore.test.ts +++ b/code/lib/preview-api/src/modules/store/ArgsStore.test.ts @@ -2,7 +2,7 @@ import { expect } from '@jest/globals'; import { ArgsStore } from './ArgsStore'; -jest.mock('@storybook/client-logger'); +vi.mock('@storybook/client-logger'); const stringType = { type: { name: 'string' } }; const booleanType = { type: { name: 'boolean' } }; diff --git a/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts b/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts index a2991f925cb8..22066932a570 100644 --- a/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts +++ b/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts @@ -1,7 +1,7 @@ import { expect } from '@jest/globals'; import { GlobalsStore } from './GlobalsStore'; -jest.mock('@storybook/client-logger', () => ({ +vi.mock('@storybook/client-logger', () => ({ logger: { warn: jest.fn(), }, diff --git a/code/lib/preview-api/src/modules/store/StoryIndexStore.test.ts b/code/lib/preview-api/src/modules/store/StoryIndexStore.test.ts index c906d7a21a75..d2d56721a617 100644 --- a/code/lib/preview-api/src/modules/store/StoryIndexStore.test.ts +++ b/code/lib/preview-api/src/modules/store/StoryIndexStore.test.ts @@ -3,7 +3,7 @@ import { expect } from '@jest/globals'; import type { StoryIndex } from '@storybook/types'; import { StoryIndexStore } from './StoryIndexStore'; -jest.mock('@storybook/channel-websocket', () => () => ({ on: jest.fn() })); +vi.mock('@storybook/channel-websocket', () => () => ({ on: jest.fn() })); const storyIndex: StoryIndex = { v: 4, diff --git a/code/lib/preview-api/src/modules/store/StoryStore.test.ts b/code/lib/preview-api/src/modules/store/StoryStore.test.ts index 75eac2a04c8e..48ed0a2b71d6 100644 --- a/code/lib/preview-api/src/modules/store/StoryStore.test.ts +++ b/code/lib/preview-api/src/modules/store/StoryStore.test.ts @@ -7,15 +7,15 @@ import { StoryStore } from './StoryStore'; import type { HooksContext } from './hooks'; // Spy on prepareStory/processCSFFile -jest.mock('./csf/prepareStory', () => ({ +vi.mock('./csf/prepareStory', () => ({ ...jest.requireActual('./csf/prepareStory'), prepareStory: jest.fn(jest.requireActual('./csf/prepareStory').prepareStory), })); -jest.mock('./csf/processCSFFile', () => ({ +vi.mock('./csf/processCSFFile', () => ({ processCSFFile: jest.fn(jest.requireActual('./csf/processCSFFile').processCSFFile), })); -jest.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', () => ({ global: { ...(jest.requireActual('@storybook/global') as any), }, diff --git a/code/lib/preview-api/src/modules/store/args.test.ts b/code/lib/preview-api/src/modules/store/args.test.ts index f567d54cbe5e..062a4dd1d0ed 100644 --- a/code/lib/preview-api/src/modules/store/args.test.ts +++ b/code/lib/preview-api/src/modules/store/args.test.ts @@ -18,7 +18,7 @@ const functionType: SBType = { name: 'function' }; const numArrayType: SBType = { name: 'array', value: numberType }; const boolObjectType: SBType = { name: 'object', value: { bool: booleanType } }; -jest.mock('@storybook/client-logger'); +vi.mock('@storybook/client-logger'); enum ArgsMapTestEnumWithoutInitializer { EnumValue, diff --git a/code/lib/preview-api/src/modules/store/csf/composeConfigs.test.ts b/code/lib/preview-api/src/modules/store/csf/composeConfigs.test.ts index f3c8391a0ea5..62b71222a8c0 100644 --- a/code/lib/preview-api/src/modules/store/csf/composeConfigs.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/composeConfigs.test.ts @@ -3,7 +3,7 @@ import { global } from '@storybook/global'; import { composeConfigs } from './composeConfigs'; -jest.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', () => ({ global: { FEATURES: {}, }, diff --git a/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts b/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts index a7cb1d971e6d..d1d5bf1ac0fe 100644 --- a/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; import { global } from '@storybook/global'; import { expect } from '@jest/globals'; @@ -8,7 +8,7 @@ import { addons, HooksContext } from '../../addons'; import { UNTARGETED } from '../args'; import { prepareStory, prepareMeta, prepareContext } from './prepareStory'; -jest.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', () => ({ global: { ...(jest.requireActual('@storybook/global') as any), }, diff --git a/code/lib/preview-api/src/modules/store/hooks.test.ts b/code/lib/preview-api/src/modules/store/hooks.test.ts index 655a41249b4f..45f574c063a3 100644 --- a/code/lib/preview-api/src/modules/store/hooks.test.ts +++ b/code/lib/preview-api/src/modules/store/hooks.test.ts @@ -26,7 +26,7 @@ import { import { defaultDecorateStory } from './decorators'; -jest.mock('@storybook/client-logger', () => ({ +vi.mock('@storybook/client-logger', () => ({ logger: { warn: jest.fn(), log: jest.fn() }, })); diff --git a/code/lib/preview-api/src/modules/store/inferArgTypes.test.ts b/code/lib/preview-api/src/modules/store/inferArgTypes.test.ts index e2a51d347b2e..57160d08ee2d 100644 --- a/code/lib/preview-api/src/modules/store/inferArgTypes.test.ts +++ b/code/lib/preview-api/src/modules/store/inferArgTypes.test.ts @@ -3,7 +3,7 @@ import { expect } from '@jest/globals'; import { inferArgTypes } from './inferArgTypes'; -jest.mock('@storybook/client-logger'); +vi.mock('@storybook/client-logger'); describe('inferArgTypes', () => { it('infers scalar types', () => { @@ -83,7 +83,7 @@ describe('inferArgTypes', () => { const cyclic: any = {}; cyclic.foo = cyclic; - (logger.warn as jest.MockedFunction).mockClear(); + (logger.warn as vi.mockedFunction).mockClear(); expect( inferArgTypes({ initialArgs: { @@ -100,7 +100,7 @@ describe('inferArgTypes', () => { }); it('ensures names', () => { - (logger.warn as jest.MockedFunction).mockClear(); + (logger.warn as vi.mockedFunction).mockClear(); expect( inferArgTypes({ initialArgs: { @@ -124,7 +124,7 @@ describe('inferArgTypes', () => { }); it('ensures names even with no arg', () => { - (logger.warn as jest.MockedFunction).mockClear(); + (logger.warn as vi.mockedFunction).mockClear(); expect( inferArgTypes({ argTypes: { diff --git a/code/lib/preview/jest.config.js b/code/lib/preview/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/preview/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/react-dom-shim/tsconfig.json b/code/lib/react-dom-shim/tsconfig.json index 2d2342b88992..7378641b0d33 100644 --- a/code/lib/react-dom-shim/tsconfig.json +++ b/code/lib/react-dom-shim/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "strict": true, - "types": ["node", "jest"] + "types": ["node"] }, "include": ["src/**/*"] } diff --git a/code/lib/router/jest.config.js b/code/lib/router/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/router/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/router/src/utils.test.ts b/code/lib/router/src/utils.test.ts index 924eea33fd34..d6ddf6f69b31 100644 --- a/code/lib/router/src/utils.test.ts +++ b/code/lib/router/src/utils.test.ts @@ -1,6 +1,6 @@ import { buildArgsParam, deepDiff, DEEPLY_EQUAL, getMatch, parsePath } from './utils'; -jest.mock('@storybook/client-logger', () => ({ +vi.mock('@storybook/client-logger', () => ({ once: { warn: jest.fn() }, })); diff --git a/code/lib/source-loader/jest.config.js b/code/lib/source-loader/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/source-loader/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/telemetry/jest.config.js b/code/lib/telemetry/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/telemetry/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/telemetry/src/get-framework-info.test.ts b/code/lib/telemetry/src/get-framework-info.test.ts index 4120aaf92879..f5b8e22df596 100644 --- a/code/lib/telemetry/src/get-framework-info.test.ts +++ b/code/lib/telemetry/src/get-framework-info.test.ts @@ -3,7 +3,7 @@ import path from 'path'; import { getFrameworkInfo } from './get-framework-info'; import { getActualPackageJson } from './package-json'; -jest.mock('./package-json', () => ({ +vi.mock('./package-json', () => ({ getActualPackageJson: jest.fn(), })); @@ -36,7 +36,7 @@ describe('getFrameworkInfo', () => { }, }; - (getActualPackageJson as jest.Mock).mockResolvedValueOnce(frameworkPackageJson); + (getActualPackageJson as vi.mock).mockResolvedValueOnce(frameworkPackageJson); const result = await getFrameworkInfo({ framework } as StorybookConfig); diff --git a/code/lib/telemetry/src/get-monorepo-type.test.ts b/code/lib/telemetry/src/get-monorepo-type.test.ts index 634a8ad5729d..896996828954 100644 --- a/code/lib/telemetry/src/get-monorepo-type.test.ts +++ b/code/lib/telemetry/src/get-monorepo-type.test.ts @@ -4,9 +4,9 @@ import path from 'path'; import { getMonorepoType, monorepoConfigs } from './get-monorepo-type'; // eslint-disable-next-line global-require, jest/no-mocks-import -jest.mock('fs-extra', () => require('../../../__mocks__/fs-extra')); +vi.mock('fs-extra', () => require('../../../__mocks__/fs-extra')); -jest.mock('@storybook/core-common', () => { +vi.mock('@storybook/core-common', () => { const coreCommon = jest.requireActual('@storybook/core-common'); return { ...coreCommon, diff --git a/code/lib/telemetry/src/session-id.test.ts b/code/lib/telemetry/src/session-id.test.ts index cfdb784feff7..919245d8d3db 100644 --- a/code/lib/telemetry/src/session-id.test.ts +++ b/code/lib/telemetry/src/session-id.test.ts @@ -2,7 +2,7 @@ import { nanoid } from 'nanoid'; import { cache } from '@storybook/core-common'; import { resetSessionIdForTest, getSessionId, SESSION_TIMEOUT } from './session-id'; -jest.mock('@storybook/core-common', () => { +vi.mock('@storybook/core-common', () => { const actual = jest.requireActual('@storybook/core-common'); return { ...actual, @@ -12,7 +12,7 @@ jest.mock('@storybook/core-common', () => { }, }; }); -jest.mock('nanoid'); +vi.mock('nanoid'); const spy = (x: any) => x as jest.SpyInstance; diff --git a/code/lib/telemetry/src/storybook-metadata.test.ts b/code/lib/telemetry/src/storybook-metadata.test.ts index 83a206a92761..a3d1b6c85fb0 100644 --- a/code/lib/telemetry/src/storybook-metadata.test.ts +++ b/code/lib/telemetry/src/storybook-metadata.test.ts @@ -12,7 +12,7 @@ const mainJsMock: StorybookConfig = { stories: [], }; -jest.mock('./package-json', () => { +vi.mock('./package-json', () => { const getActualPackageVersion = jest.fn((name) => Promise.resolve({ name, @@ -38,11 +38,11 @@ jest.mock('./package-json', () => { }; }); -jest.mock('./get-monorepo-type', () => ({ +vi.mock('./get-monorepo-type', () => ({ getMonorepoType: () => 'Nx', })); -jest.mock('detect-package-manager', () => ({ +vi.mock('detect-package-manager', () => ({ detect: () => 'Yarn', getNpmVersion: () => '3.1.1', })); diff --git a/code/lib/telemetry/src/telemetry.test.ts b/code/lib/telemetry/src/telemetry.test.ts index 3c58187785df..ba88abc1ee4a 100644 --- a/code/lib/telemetry/src/telemetry.test.ts +++ b/code/lib/telemetry/src/telemetry.test.ts @@ -1,15 +1,15 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; import fetch from 'node-fetch'; import { sendTelemetry } from './telemetry'; -jest.mock('node-fetch'); -jest.mock('./event-cache', () => { +vi.mock('node-fetch'); +vi.mock('./event-cache', () => { return { set: jest.fn() }; }); -jest.mock('./session-id', () => { +vi.mock('./session-id', () => { return { getSessionId: async () => { return 'session-id'; @@ -17,7 +17,7 @@ jest.mock('./session-id', () => { }; }); -const fetchMock = fetch as jest.Mock; +const fetchMock = fetch as vi.mock; beforeEach(() => { fetchMock.mockResolvedValue({ status: 200 }); diff --git a/code/lib/theming/jest.config.js b/code/lib/theming/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/lib/theming/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/lib/theming/src/tests/util.test.js b/code/lib/theming/src/tests/util.test.js index 6580f7458fbf..024fcaf14201 100644 --- a/code/lib/theming/src/tests/util.test.js +++ b/code/lib/theming/src/tests/util.test.js @@ -80,7 +80,7 @@ describe('utils', () => { describe('getPreferredColorScheme', () => { it('should return "light" if "window" is unavailable', () => { - jest.mock('@storybook/global', () => ({ global: { window: undefined } })); + vi.mock('@storybook/global', () => ({ global: { window: undefined } })); const colorScheme = getPreferredColorScheme(); expect(colorScheme).toBe('light'); diff --git a/code/lib/types/jest.config.js b/code/lib/types/jest.config.js deleted file mode 100644 index 343e4c7a7f32..000000000000 --- a/code/lib/types/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.node'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/package.json b/code/package.json index 67ac084c3a4a..2ff642c3638b 100644 --- a/code/package.json +++ b/code/package.json @@ -97,8 +97,6 @@ "@babel/preset-react": "^7.22.5", "@babel/preset-typescript": "^7.22.5", "@babel/runtime": "^7.22.6", - "@emotion/jest": "^11.10.0", - "@jest/globals": "^29.3.1", "@nx/workspace": "16.2.1", "@playwright/test": "1.36.0", "@storybook/addon-a11y": "workspace:*", @@ -195,9 +193,7 @@ "@storybook/web-components-vite": "workspace:*", "@storybook/web-components-webpack5": "workspace:*", "@swc/core": "1.3.82", - "@swc/jest": "^0.2.26", "@testing-library/dom": "^7.29.4", - "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.2", "@testing-library/user-event": "^13.2.1", "@types/express": "^4.17.11", @@ -232,13 +228,6 @@ "glob": "^10.0.0", "http-server": "^14.1.1", "husky": "^4.3.7", - "jest": "^29.5.0", - "jest-environment-jsdom": "^29.5.0", - "jest-image-snapshot": "^6.0.0", - "jest-junit": "^16.0.0", - "jest-os-detection": "^1.3.1", - "jest-serializer-html": "^7.1.0", - "jest-watch-typeahead": "^2.2.1", "lerna": "^6.4.0", "lint-staged": "^13.2.2", "lodash": "^4.17.21", diff --git a/code/presets/react-webpack/src/cra-config.test.ts b/code/presets/react-webpack/src/cra-config.test.ts index 290da39d501d..bef1eab4ebf7 100644 --- a/code/presets/react-webpack/src/cra-config.test.ts +++ b/code/presets/react-webpack/src/cra-config.test.ts @@ -2,7 +2,7 @@ import fs from 'fs'; import path from 'path'; import { getReactScriptsPath } from './cra-config'; -jest.mock('fs', () => ({ +vi.mock('fs', () => ({ realpathSync: jest.fn(() => '/test-project'), readFileSync: jest.fn(), existsSync: jest.fn(() => true), @@ -13,7 +13,7 @@ const SCRIPT_PATH = path.join('.bin', 'react-scripts'); describe('cra-config', () => { describe('when used with the default react-scripts package', () => { beforeEach(() => { - (fs.realpathSync as unknown as jest.Mock).mockImplementationOnce((filePath) => + (fs.realpathSync as unknown as vi.mock).mockImplementationOnce((filePath) => filePath.replace(SCRIPT_PATH, `react-scripts/${SCRIPT_PATH}`) ); }); @@ -27,7 +27,7 @@ describe('cra-config', () => { describe('when used with a custom react-scripts package', () => { beforeEach(() => { - (fs.realpathSync as unknown as jest.Mock).mockImplementationOnce((filePath) => + (fs.realpathSync as unknown as vi.mock).mockImplementationOnce((filePath) => filePath.replace(SCRIPT_PATH, `custom-react-scripts/${SCRIPT_PATH}`) ); }); @@ -43,9 +43,9 @@ describe('cra-config', () => { beforeEach(() => { // In case of .bin/react-scripts is not symlink (like it happens on Windows), // realpathSync() method does not translate the path. - (fs.realpathSync as unknown as jest.Mock).mockImplementationOnce((filePath) => filePath); + (fs.realpathSync as unknown as vi.mock).mockImplementationOnce((filePath) => filePath); - (fs.readFileSync as unknown as jest.Mock).mockImplementationOnce( + (fs.readFileSync as unknown as vi.mock).mockImplementationOnce( () => `#!/bin/sh basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") diff --git a/code/presets/react-webpack/src/framework-preset-react.test.ts b/code/presets/react-webpack/src/framework-preset-react.test.ts index e28b72c90819..a9898ad9b91b 100644 --- a/code/presets/react-webpack/src/framework-preset-react.test.ts +++ b/code/presets/react-webpack/src/framework-preset-react.test.ts @@ -4,7 +4,7 @@ import type { Options } from '@storybook/core-webpack'; import * as preset from './framework-preset-react'; const mockApply = jest.fn(); -jest.mock('@pmmmwh/react-refresh-webpack-plugin', () => { +vi.mock('@pmmmwh/react-refresh-webpack-plugin', () => { return jest.fn().mockImplementation(() => { return { apply: mockApply }; }); diff --git a/code/renderers/html/jest.config.js b/code/renderers/html/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/renderers/html/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/renderers/html/src/docs/sourceDecorator.test.ts b/code/renderers/html/src/docs/sourceDecorator.test.ts index 22550ab8050f..effc416a0a40 100644 --- a/code/renderers/html/src/docs/sourceDecorator.test.ts +++ b/code/renderers/html/src/docs/sourceDecorator.test.ts @@ -3,9 +3,9 @@ import { addons, useEffect } from '@storybook/preview-api'; import { sourceDecorator } from './sourceDecorator'; import type { StoryContext } from '../types'; -jest.mock('@storybook/preview-api'); -const mockedAddons = addons as jest.Mocked; -const mockedUseEffect = useEffect as jest.Mocked; +vi.mock('@storybook/preview-api'); +const mockedAddons = addons as vi.mocked; +const mockedUseEffect = useEffect as vi.mocked; expect.addSnapshotSerializer({ print: (val: any) => val, @@ -34,7 +34,7 @@ const makeContext = (name: string, parameters: any, args: any, extra?: object): } as StoryContext); describe('sourceDecorator', () => { - let mockChannel: { on: jest.Mock; emit?: jest.Mock }; + let mockChannel: { on: vi.mock; emit?: vi.mock }; beforeEach(() => { mockedAddons.getChannel.mockReset(); // @ts-expect-error (Converted from ts-ignore) diff --git a/code/renderers/preact/jest.config.js b/code/renderers/preact/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/renderers/preact/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/renderers/react/jest.config.js b/code/renderers/react/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/renderers/react/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/renderers/react/src/__test__/composeStories.test.tsx b/code/renderers/react/src/__test__/composeStories.test.tsx index 8c97d906ab22..ef706b79ce81 100644 --- a/code/renderers/react/src/__test__/composeStories.test.tsx +++ b/code/renderers/react/src/__test__/composeStories.test.tsx @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; import React from 'react'; import { render, screen } from '@testing-library/react'; diff --git a/code/renderers/react/src/__test__/internals.test.tsx b/code/renderers/react/src/__test__/internals.test.tsx index 6550e03dddbb..d3e23b0a9c37 100644 --- a/code/renderers/react/src/__test__/internals.test.tsx +++ b/code/renderers/react/src/__test__/internals.test.tsx @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; /* eslint-disable @typescript-eslint/no-non-null-assertion */ import React from 'react'; import { addons } from '@storybook/preview-api'; diff --git a/code/renderers/react/src/docs/jsxDecorator.test.tsx b/code/renderers/react/src/docs/jsxDecorator.test.tsx index 63fe5fb217b5..cb561e12ecc4 100644 --- a/code/renderers/react/src/docs/jsxDecorator.test.tsx +++ b/code/renderers/react/src/docs/jsxDecorator.test.tsx @@ -6,9 +6,9 @@ import { addons, useEffect } from '@storybook/preview-api'; import { SNIPPET_RENDERED } from '@storybook/docs-tools'; import { renderJsx, jsxDecorator } from './jsxDecorator'; -jest.mock('@storybook/preview-api'); -const mockedAddons = addons as jest.Mocked; -const mockedUseEffect = useEffect as jest.Mocked; +vi.mock('@storybook/preview-api'); +const mockedAddons = addons as vi.mocked; +const mockedUseEffect = useEffect as vi.mocked; expect.addSnapshotSerializer({ print: (val: any) => val, @@ -189,7 +189,7 @@ const makeContext = (name: string, parameters: any, args: any, extra?: object): }); describe('jsxDecorator', () => { - let mockChannel: { on: jest.Mock; emit?: jest.Mock }; + let mockChannel: { on: vi.mock; emit?: vi.mock }; beforeEach(() => { mockedAddons.getChannel.mockReset(); // @ts-expect-error (Converted from ts-ignore) diff --git a/code/renderers/server/jest.config.js b/code/renderers/server/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/renderers/server/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/renderers/svelte/jest.config.js b/code/renderers/svelte/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/renderers/svelte/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/renderers/vue/jest.config.js b/code/renderers/vue/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/renderers/vue/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/renderers/vue3/jest.config.js b/code/renderers/vue3/jest.config.js deleted file mode 100644 index 47b606e09fc4..000000000000 --- a/code/renderers/vue3/jest.config.js +++ /dev/null @@ -1,11 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), - transform: { - ...baseConfig.transform, - '^.+\\.vue$': '@vue/vue3-jest', - }, -}; diff --git a/code/renderers/web-components/jest.config.js b/code/renderers/web-components/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/renderers/web-components/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/renderers/web-components/src/docs/sourceDecorator.test.ts b/code/renderers/web-components/src/docs/sourceDecorator.test.ts index d09a4136c7f5..784396b9b100 100644 --- a/code/renderers/web-components/src/docs/sourceDecorator.test.ts +++ b/code/renderers/web-components/src/docs/sourceDecorator.test.ts @@ -5,9 +5,9 @@ import { SNIPPET_RENDERED } from '@storybook/docs-tools'; import type { StoryContext } from '../types'; import { sourceDecorator } from './sourceDecorator'; -jest.mock('@storybook/preview-api'); -const mockedAddons = addons as jest.Mocked; -const mockedUseEffect = useEffect as jest.Mock; +vi.mock('@storybook/preview-api'); +const mockedAddons = addons as vi.mocked; +const mockedUseEffect = useEffect as vi.mock; expect.addSnapshotSerializer({ print: (val: any) => val, @@ -30,7 +30,7 @@ const makeContext = (name: string, parameters: any, args: any, extra?: Partial { - let mockChannel: { on: jest.Mock; emit?: jest.Mock }; + let mockChannel: { on: vi.mock; emit?: vi.mock }; beforeEach(() => { mockedAddons.getChannel.mockReset(); mockedUseEffect.mockImplementation((cb) => setTimeout(() => cb(), 0)); diff --git a/code/renderers/web-components/src/docs/web-components-properties.test.ts b/code/renderers/web-components/src/docs/web-components-properties.test.ts index 1e4e90915ce3..70b8c3e6f449 100644 --- a/code/renderers/web-components/src/docs/web-components-properties.test.ts +++ b/code/renderers/web-components/src/docs/web-components-properties.test.ts @@ -32,8 +32,8 @@ describe('web-components component properties', () => { // we need to mock lit and dynamically require custom-elements // because lit is distributed as ESM not CJS // https://github.com/Polymer/lit-html/issues/516 - jest.mock('lit', () => {}); - jest.mock('lit/directive-helpers.js', () => {}); + vi.mock('lit', () => {}); + vi.mock('lit/directive-helpers.js', () => {}); // eslint-disable-next-line global-require const { extractArgTypesFromElements } = require('./custom-elements'); diff --git a/code/tsconfig.json b/code/tsconfig.json index 26de1b5ba684..d26e5efa6de8 100644 --- a/code/tsconfig.json +++ b/code/tsconfig.json @@ -17,10 +17,9 @@ "strictBindCallApply": true, "lib": ["dom", "dom.iterable", "esnext"], "noUnusedLocals": true, - "types": ["jest"], "strict": true }, - "exclude": ["dist", "**/dist", "node_modules", "**/node_modules", "**/setup-jest.ts"], + "exclude": ["dist", "**/dist", "node_modules", "**/node_modules"], "ts-node": { "transpileOnly": true, "files": true, diff --git a/code/ui/blocks/jest.config.js b/code/ui/blocks/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/ui/blocks/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/ui/blocks/src/blocks/internal/InternalCanvas.stories.tsx b/code/ui/blocks/src/blocks/internal/InternalCanvas.stories.tsx index fb0f444720c3..4c1460b42749 100644 --- a/code/ui/blocks/src/blocks/internal/InternalCanvas.stories.tsx +++ b/code/ui/blocks/src/blocks/internal/InternalCanvas.stories.tsx @@ -1,4 +1,4 @@ -/// ; +import { describe, test, it, expect } from 'vitest'; /// ; import React from 'react'; import type { Meta, StoryObj } from '@storybook/react'; diff --git a/code/ui/blocks/tsconfig.json b/code/ui/blocks/tsconfig.json index fcad33be23fa..061b6a531157 100644 --- a/code/ui/blocks/tsconfig.json +++ b/code/ui/blocks/tsconfig.json @@ -4,7 +4,6 @@ "module": "esnext", "skipLibCheck": true, "rootDir": "./src", - "types": ["jest"], "strict": false }, "include": ["src/**/*"] diff --git a/code/ui/components/jest.config.js b/code/ui/components/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/ui/components/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/ui/components/tsconfig.json b/code/ui/components/tsconfig.json index a2bea817d943..bbe2d66fb72a 100644 --- a/code/ui/components/tsconfig.json +++ b/code/ui/components/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "types": ["react-syntax-highlighter", "jest", "testing-library__jest-dom"], + "types": ["react-syntax-highlighter"], "skipLibCheck": true, "strict": false }, diff --git a/code/ui/manager/jest.config.js b/code/ui/manager/jest.config.js deleted file mode 100644 index 4396fbc7010d..000000000000 --- a/code/ui/manager/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -const path = require('path'); -const baseConfig = require('../../jest.config.browser'); - -module.exports = { - ...baseConfig, - displayName: __dirname.split(path.sep).slice(-2).join(path.posix.sep), -}; diff --git a/code/ui/manager/tsconfig.json b/code/ui/manager/tsconfig.json index 4bc2c0bffe1f..a6f65038a17b 100644 --- a/code/ui/manager/tsconfig.json +++ b/code/ui/manager/tsconfig.json @@ -1,7 +1,6 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "types": ["testing-library__jest-dom"], "skipLibCheck": true, "strict": false }, diff --git a/scripts/package.json b/scripts/package.json index c7ee5504b1fa..83e36c43e5d2 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -28,7 +28,7 @@ "release:write-changelog": "ts-node --swc ./release/write-changelog.ts", "strict-ts": "node --require esbuild-register ./strict-ts.ts", "task": "ts-node --swc ./task.ts", - "test": "jest --config ./jest.config.js", + "test": "vitest", "upgrade": "ts-node --swc ./task.ts", "upload-bench": "ts-node ./upload-bench.ts" }, diff --git a/scripts/release/__tests__/is-pr-frozen.test.ts b/scripts/release/__tests__/is-pr-frozen.test.ts index 63747a863ddf..0b9187e01dd4 100644 --- a/scripts/release/__tests__/is-pr-frozen.test.ts +++ b/scripts/release/__tests__/is-pr-frozen.test.ts @@ -4,8 +4,8 @@ import path from 'path'; import { run as isPrFrozen } from '../is-pr-frozen'; // eslint-disable-next-line jest/no-mocks-import -jest.mock('fs-extra', () => require('../../../code/__mocks__/fs-extra')); -jest.mock('../utils/get-github-info'); +vi.mock('fs-extra', () => require('../../../code/__mocks__/fs-extra')); +vi.mock('../utils/get-github-info'); const fsExtra = require('fs-extra'); const simpleGit = require('simple-git'); diff --git a/scripts/release/__tests__/label-patches.test.ts b/scripts/release/__tests__/label-patches.test.ts index d98abc7eb763..65ec494c33e6 100644 --- a/scripts/release/__tests__/label-patches.test.ts +++ b/scripts/release/__tests__/label-patches.test.ts @@ -5,14 +5,14 @@ import * as gitClient_ from '../utils/git-client'; import * as githubInfo_ from '../utils/get-github-info'; import * as github_ from '../utils/github-client'; -jest.mock('uuid'); -jest.mock('../utils/get-github-info'); -jest.mock('../utils/github-client'); -jest.mock('../utils/git-client', () => jest.requireActual('jest-mock-extended').mockDeep()); - -const gitClient = jest.mocked(gitClient_); -const github = jest.mocked(github_); -const githubInfo = jest.mocked(githubInfo_); +vi.mock('uuid'); +vi.mock('../utils/get-github-info'); +vi.mock('../utils/github-client'); +vi.mock('../utils/git-client', () => jest.requireActual('jest-mock-extended').mockDeep()); + +const gitClient = vi.mocked(gitClient_); +const github = vi.mocked(github_); +const githubInfo = vi.mocked(githubInfo_); const remoteMock = [ { diff --git a/scripts/release/__tests__/version.test.ts b/scripts/release/__tests__/version.test.ts index 98069ffaba74..297752184cb9 100644 --- a/scripts/release/__tests__/version.test.ts +++ b/scripts/release/__tests__/version.test.ts @@ -4,17 +4,17 @@ import path from 'path'; import { run as version } from '../version'; // eslint-disable-next-line jest/no-mocks-import -jest.mock('fs-extra', () => require('../../../code/__mocks__/fs-extra')); +vi.mock('fs-extra', () => require('../../../code/__mocks__/fs-extra')); const fsExtra = require('fs-extra'); -jest.mock('../../../code/lib/cli/src/versions', () => ({ +vi.mock('../../../code/lib/cli/src/versions', () => ({ '@storybook/addon-a11y': '7.1.0-alpha.29', })); -jest.mock('../../utils/exec'); +vi.mock('../../utils/exec'); const { execaCommand } = require('../../utils/exec'); -jest.mock('../../utils/workspace', () => ({ +vi.mock('../../utils/workspace', () => ({ getWorkspaces: jest.fn().mockResolvedValue([ { name: '@storybook/addon-a11y', diff --git a/scripts/release/__tests__/write-changelog.test.ts b/scripts/release/__tests__/write-changelog.test.ts index 7431222f975a..a17a5a4bb189 100644 --- a/scripts/release/__tests__/write-changelog.test.ts +++ b/scripts/release/__tests__/write-changelog.test.ts @@ -6,7 +6,7 @@ import { run as writeChangelog } from '../write-changelog'; import * as changesUtils from '../utils/get-changes'; // eslint-disable-next-line jest/no-mocks-import -jest.mock('fs-extra', () => require('../../../code/__mocks__/fs-extra')); +vi.mock('fs-extra', () => require('../../../code/__mocks__/fs-extra')); const fsExtra = require('fs-extra'); const getChangesMock = jest.spyOn(changesUtils, 'getChanges'); diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json index c82e14a95108..4fdeb6aa864b 100644 --- a/scripts/tsconfig.json +++ b/scripts/tsconfig.json @@ -14,7 +14,7 @@ "isolatedModules": true, "strictBindCallApply": true, "lib": ["dom", "esnext"], - "types": ["node", "jest"], + "types": ["node"], "strict": true, "strictNullChecks": false, "forceConsistentCasingInFileNames": true, From 93db551f3f11a0d14d747d75221c9b30b0a628b1 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 14 Sep 2023 16:16:50 +0200 Subject: [PATCH 006/105] more manual migrations --- code/lib/codemod/src/transforms/__tests__/csf-2-to-3.test.ts | 2 +- code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts | 2 +- .../src/transforms/__tests__/upgrade-deprecated-types.test.ts | 2 +- code/lib/preview-api/src/modules/core-client/start.test.ts | 2 +- code/lib/preview-api/src/modules/store/ArgsStore.test.ts | 2 +- code/lib/preview-api/src/modules/store/GlobalsStore.test.ts | 2 +- .../lib/preview-api/src/modules/store/StoryIndexStore.test.ts | 2 +- code/lib/preview-api/src/modules/store/StoryStore.test.ts | 2 +- code/lib/preview-api/src/modules/store/args.test.ts | 2 +- code/lib/preview-api/src/modules/store/autoTitle.test.ts | 2 +- .../preview-api/src/modules/store/csf/composeConfigs.test.ts | 2 +- .../src/modules/store/csf/normalizeInputTypes.test.ts | 2 +- .../preview-api/src/modules/store/csf/normalizeStory.test.ts | 2 +- .../preview-api/src/modules/store/csf/prepareStory.test.ts | 1 - .../preview-api/src/modules/store/csf/processCSFFile.test.ts | 2 +- code/lib/preview-api/src/modules/store/decorators.test.ts | 2 +- code/lib/preview-api/src/modules/store/hooks.test.ts | 2 +- code/lib/preview-api/src/modules/store/inferArgTypes.test.ts | 2 +- code/lib/preview-api/src/modules/store/inferControls.test.ts | 2 +- code/lib/preview-api/src/modules/store/parameters.test.ts | 2 +- code/lib/preview-api/src/modules/store/storySort.test.ts | 2 +- code/renderers/react/src/public-types.test.tsx | 2 +- code/renderers/svelte/src/docs/extractArgTypes.test.ts | 2 +- .../svelte/src/docs/extractComponentDescription.test.ts | 2 +- code/renderers/svelte/src/docs/sourceDecorator.test.ts | 2 +- code/renderers/svelte/src/public-types.test.ts | 2 +- code/renderers/vue3/src/docs/sourceDecorator.test.ts | 2 +- scripts/utils/options.test.ts | 2 +- scripts/vitest.config.ts | 4 +++- 29 files changed, 30 insertions(+), 29 deletions(-) diff --git a/code/lib/codemod/src/transforms/__tests__/csf-2-to-3.test.ts b/code/lib/codemod/src/transforms/__tests__/csf-2-to-3.test.ts index 033c4646d16f..5e48d811ca16 100644 --- a/code/lib/codemod/src/transforms/__tests__/csf-2-to-3.test.ts +++ b/code/lib/codemod/src/transforms/__tests__/csf-2-to-3.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect } from '@jest/globals'; +import { describe, it, expect } from 'vitest'; import { dedent } from 'ts-dedent'; import type { API } from 'jscodeshift'; import ansiRegex from 'ansi-regex'; diff --git a/code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts b/code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts index a982dcf7f12a..9fd9cd04e997 100644 --- a/code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts +++ b/code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts @@ -1,5 +1,5 @@ import * as fs_ from 'node:fs'; -import { expect, test } from '@jest/globals'; +import { expect, test } from 'vitest'; import dedent from 'ts-dedent'; import jscodeshift, { nameToValidExport } from '../mdx-to-csf'; diff --git a/code/lib/codemod/src/transforms/__tests__/upgrade-deprecated-types.test.ts b/code/lib/codemod/src/transforms/__tests__/upgrade-deprecated-types.test.ts index 51a7640072c5..f8f38d201107 100644 --- a/code/lib/codemod/src/transforms/__tests__/upgrade-deprecated-types.test.ts +++ b/code/lib/codemod/src/transforms/__tests__/upgrade-deprecated-types.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from '@jest/globals'; +import { describe, expect, it } from 'vitest'; import { dedent } from 'ts-dedent'; import type { API } from 'jscodeshift'; import ansiRegex from 'ansi-regex'; diff --git a/code/lib/preview-api/src/modules/core-client/start.test.ts b/code/lib/preview-api/src/modules/core-client/start.test.ts index fc0957874343..e5a7f5d9997b 100644 --- a/code/lib/preview-api/src/modules/core-client/start.test.ts +++ b/code/lib/preview-api/src/modules/core-client/start.test.ts @@ -3,7 +3,7 @@ * @jest-environment jsdom */ -// import { describe, it, beforeAll, beforeEach, afterAll, afterEach, jest } from '@jest/globals'; +// import { describe, it, beforeAll, beforeEach, afterAll, afterEach, jest } from 'vitest' import { STORY_RENDERED, STORY_UNCHANGED, SET_INDEX, CONFIG_ERROR } from '@storybook/core-events'; import type { ModuleExports, Path } from '@storybook/types'; diff --git a/code/lib/preview-api/src/modules/store/ArgsStore.test.ts b/code/lib/preview-api/src/modules/store/ArgsStore.test.ts index 46277efc6ffd..fb7f9c109444 100644 --- a/code/lib/preview-api/src/modules/store/ArgsStore.test.ts +++ b/code/lib/preview-api/src/modules/store/ArgsStore.test.ts @@ -1,4 +1,4 @@ -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import { ArgsStore } from './ArgsStore'; diff --git a/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts b/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts index 22066932a570..f3f2ae96cad9 100644 --- a/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts +++ b/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts @@ -1,4 +1,4 @@ -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import { GlobalsStore } from './GlobalsStore'; vi.mock('@storybook/client-logger', () => ({ diff --git a/code/lib/preview-api/src/modules/store/StoryIndexStore.test.ts b/code/lib/preview-api/src/modules/store/StoryIndexStore.test.ts index d2d56721a617..2fb61820ec38 100644 --- a/code/lib/preview-api/src/modules/store/StoryIndexStore.test.ts +++ b/code/lib/preview-api/src/modules/store/StoryIndexStore.test.ts @@ -1,4 +1,4 @@ -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import type { StoryIndex } from '@storybook/types'; import { StoryIndexStore } from './StoryIndexStore'; diff --git a/code/lib/preview-api/src/modules/store/StoryStore.test.ts b/code/lib/preview-api/src/modules/store/StoryStore.test.ts index 48ed0a2b71d6..fbbd5bca9d36 100644 --- a/code/lib/preview-api/src/modules/store/StoryStore.test.ts +++ b/code/lib/preview-api/src/modules/store/StoryStore.test.ts @@ -1,5 +1,5 @@ import type { Renderer, ProjectAnnotations, StoryIndex } from '@storybook/types'; -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import { prepareStory } from './csf/prepareStory'; import { processCSFFile } from './csf/processCSFFile'; diff --git a/code/lib/preview-api/src/modules/store/args.test.ts b/code/lib/preview-api/src/modules/store/args.test.ts index 062a4dd1d0ed..d4a742bf18db 100644 --- a/code/lib/preview-api/src/modules/store/args.test.ts +++ b/code/lib/preview-api/src/modules/store/args.test.ts @@ -1,5 +1,5 @@ import { once } from '@storybook/client-logger'; -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import type { SBType } from '@storybook/types'; import { diff --git a/code/lib/preview-api/src/modules/store/autoTitle.test.ts b/code/lib/preview-api/src/modules/store/autoTitle.test.ts index e4c1fe23dbb2..e17c50717796 100644 --- a/code/lib/preview-api/src/modules/store/autoTitle.test.ts +++ b/code/lib/preview-api/src/modules/store/autoTitle.test.ts @@ -1,5 +1,5 @@ import { normalizeStoriesEntry } from '@storybook/core-common'; -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import { userOrAutoTitleFromSpecifier as userOrAuto } from './autoTitle'; diff --git a/code/lib/preview-api/src/modules/store/csf/composeConfigs.test.ts b/code/lib/preview-api/src/modules/store/csf/composeConfigs.test.ts index 62b71222a8c0..e223880b2990 100644 --- a/code/lib/preview-api/src/modules/store/csf/composeConfigs.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/composeConfigs.test.ts @@ -1,4 +1,4 @@ -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import { global } from '@storybook/global'; import { composeConfigs } from './composeConfigs'; diff --git a/code/lib/preview-api/src/modules/store/csf/normalizeInputTypes.test.ts b/code/lib/preview-api/src/modules/store/csf/normalizeInputTypes.test.ts index 5cdb504e94eb..a90e0c82369f 100644 --- a/code/lib/preview-api/src/modules/store/csf/normalizeInputTypes.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/normalizeInputTypes.test.ts @@ -1,4 +1,4 @@ -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import { normalizeInputType, normalizeInputTypes } from './normalizeInputTypes'; diff --git a/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts b/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts index 5a97b4b56359..f086ff5cdf2c 100644 --- a/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts @@ -1,4 +1,4 @@ -import { expect, describe, it } from '@jest/globals'; +import { expect, describe, it } from 'vitest'; import type { Renderer, StoryAnnotationsOrFn } from '@storybook/types'; import { normalizeStory } from './normalizeStory'; diff --git a/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts b/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts index d1d5bf1ac0fe..0198e525e700 100644 --- a/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts @@ -1,7 +1,6 @@ import { describe, test, it, expect } from 'vitest'; import { global } from '@storybook/global'; -import { expect } from '@jest/globals'; import type { Renderer, ArgsEnhancer, PlayFunctionContext, SBScalarType } from '@storybook/types'; import { addons, HooksContext } from '../../addons'; diff --git a/code/lib/preview-api/src/modules/store/csf/processCSFFile.test.ts b/code/lib/preview-api/src/modules/store/csf/processCSFFile.test.ts index 56ce7883a3aa..2895228bb2cf 100644 --- a/code/lib/preview-api/src/modules/store/csf/processCSFFile.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/processCSFFile.test.ts @@ -1,4 +1,4 @@ -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import { processCSFFile } from './processCSFFile'; diff --git a/code/lib/preview-api/src/modules/store/decorators.test.ts b/code/lib/preview-api/src/modules/store/decorators.test.ts index 889b16fff8ae..a24aec1a41e2 100644 --- a/code/lib/preview-api/src/modules/store/decorators.test.ts +++ b/code/lib/preview-api/src/modules/store/decorators.test.ts @@ -1,4 +1,4 @@ -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import type { Renderer, StoryContext } from '@storybook/types'; import { defaultDecorateStory } from './decorators'; diff --git a/code/lib/preview-api/src/modules/store/hooks.test.ts b/code/lib/preview-api/src/modules/store/hooks.test.ts index 45f574c063a3..4e4a8f49efcb 100644 --- a/code/lib/preview-api/src/modules/store/hooks.test.ts +++ b/code/lib/preview-api/src/modules/store/hooks.test.ts @@ -1,4 +1,4 @@ -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import { FORCE_RE_RENDER, STORY_RENDERED, diff --git a/code/lib/preview-api/src/modules/store/inferArgTypes.test.ts b/code/lib/preview-api/src/modules/store/inferArgTypes.test.ts index 57160d08ee2d..b5f520c80e5b 100644 --- a/code/lib/preview-api/src/modules/store/inferArgTypes.test.ts +++ b/code/lib/preview-api/src/modules/store/inferArgTypes.test.ts @@ -1,5 +1,5 @@ import { logger } from '@storybook/client-logger'; -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import { inferArgTypes } from './inferArgTypes'; diff --git a/code/lib/preview-api/src/modules/store/inferControls.test.ts b/code/lib/preview-api/src/modules/store/inferControls.test.ts index 966a2ba7129a..da66bd24adbd 100644 --- a/code/lib/preview-api/src/modules/store/inferControls.test.ts +++ b/code/lib/preview-api/src/modules/store/inferControls.test.ts @@ -1,4 +1,4 @@ -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import { logger } from '@storybook/client-logger'; import type { StoryContextForEnhancers } from '@storybook/types'; diff --git a/code/lib/preview-api/src/modules/store/parameters.test.ts b/code/lib/preview-api/src/modules/store/parameters.test.ts index 29a15b48a503..0669481f602c 100644 --- a/code/lib/preview-api/src/modules/store/parameters.test.ts +++ b/code/lib/preview-api/src/modules/store/parameters.test.ts @@ -1,4 +1,4 @@ -import { expect } from '@jest/globals'; +import { expect } from 'vitest'; import { combineParameters } from './parameters'; describe('client-api.parameters', () => { diff --git a/code/lib/preview-api/src/modules/store/storySort.test.ts b/code/lib/preview-api/src/modules/store/storySort.test.ts index 62d8a9dceaca..2c9041f5b8f1 100644 --- a/code/lib/preview-api/src/modules/store/storySort.test.ts +++ b/code/lib/preview-api/src/modules/store/storySort.test.ts @@ -1,4 +1,4 @@ -import { expect, describe, it } from '@jest/globals'; +import { expect, describe, it } from 'vitest'; import type { StoryId, StoryIndexEntry } from '@storybook/types'; import { storySort } from './storySort'; diff --git a/code/renderers/react/src/public-types.test.tsx b/code/renderers/react/src/public-types.test.tsx index 1fc3fd15d10c..0b129c2cbc01 100644 --- a/code/renderers/react/src/public-types.test.tsx +++ b/code/renderers/react/src/public-types.test.tsx @@ -1,4 +1,4 @@ -import { describe, test } from '@jest/globals'; +import { describe, test } from 'vitest'; import { satisfies } from '@storybook/core-common'; import type { Args, StoryAnnotations, StrictArgs } from '@storybook/types'; diff --git a/code/renderers/svelte/src/docs/extractArgTypes.test.ts b/code/renderers/svelte/src/docs/extractArgTypes.test.ts index dcde4dddcce6..827f7ba98fc4 100644 --- a/code/renderers/svelte/src/docs/extractArgTypes.test.ts +++ b/code/renderers/svelte/src/docs/extractArgTypes.test.ts @@ -1,4 +1,4 @@ -import { describe, expect } from '@jest/globals'; +import { describe, expect } from 'vitest'; import svelteDoc from 'sveltedoc-parser'; import * as fs from 'fs'; import { createArgTypes } from './extractArgTypes'; diff --git a/code/renderers/svelte/src/docs/extractComponentDescription.test.ts b/code/renderers/svelte/src/docs/extractComponentDescription.test.ts index f2e7866f6394..c7638ad3c534 100644 --- a/code/renderers/svelte/src/docs/extractComponentDescription.test.ts +++ b/code/renderers/svelte/src/docs/extractComponentDescription.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, test } from '@jest/globals'; +import { describe, expect, test } from 'vitest'; import { extractComponentDescription } from './extractComponentDescription'; describe('extractComponentDescription', () => { diff --git a/code/renderers/svelte/src/docs/sourceDecorator.test.ts b/code/renderers/svelte/src/docs/sourceDecorator.test.ts index 6123b45d8b94..4f03ad93df0c 100644 --- a/code/renderers/svelte/src/docs/sourceDecorator.test.ts +++ b/code/renderers/svelte/src/docs/sourceDecorator.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, test } from '@jest/globals'; +import { describe, expect, test } from 'vitest'; import type { Args } from '@storybook/types'; import { generateSvelteSource } from './sourceDecorator'; diff --git a/code/renderers/svelte/src/public-types.test.ts b/code/renderers/svelte/src/public-types.test.ts index 9459fe91e41b..a1011b4f60e6 100644 --- a/code/renderers/svelte/src/public-types.test.ts +++ b/code/renderers/svelte/src/public-types.test.ts @@ -1,4 +1,4 @@ -import { describe, test } from '@jest/globals'; +import { describe, test } from 'vitest'; import { satisfies } from '@storybook/core-common'; import type { ComponentAnnotations, StoryAnnotations } from '@storybook/types'; import { expectTypeOf } from 'expect-type'; diff --git a/code/renderers/vue3/src/docs/sourceDecorator.test.ts b/code/renderers/vue3/src/docs/sourceDecorator.test.ts index ec59ae61c9b3..d5393a65e5bc 100644 --- a/code/renderers/vue3/src/docs/sourceDecorator.test.ts +++ b/code/renderers/vue3/src/docs/sourceDecorator.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, test } from '@jest/globals'; +import { describe, expect, test } from 'vitest'; import { mapAttributesAndDirectives, diff --git a/scripts/utils/options.test.ts b/scripts/utils/options.test.ts index c183db207f2c..8693c557130f 100644 --- a/scripts/utils/options.test.ts +++ b/scripts/utils/options.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from '@jest/globals'; +import { describe, expect, it } from 'vitest'; import { createCommand } from 'commander'; import { areOptionsSatisfied, createOptions, getCommand, getOptions } from './options'; diff --git a/scripts/vitest.config.ts b/scripts/vitest.config.ts index f053ebf7976e..94ede10e225a 100644 --- a/scripts/vitest.config.ts +++ b/scripts/vitest.config.ts @@ -1 +1,3 @@ -module.exports = {}; +import { defineConfig } from 'vitest/config'; + +export default defineConfig({}); From fd0386f071014acc4e97e8cdbc0036b4189c9d47 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 14 Sep 2023 16:42:06 +0200 Subject: [PATCH 007/105] making progress on migrating to vitest --- code/addons/a11y/vitest.config.ts | 22 ++++++++++--------- code/addons/actions/vitest.config.ts | 22 ++++++++++--------- code/addons/backgrounds/vitest.config.ts | 22 ++++++++++--------- code/addons/controls/vitest.config.ts | 22 ++++++++++--------- code/addons/docs/vitest.config.ts | 22 ++++++++++--------- code/addons/essentials/vitest.config.ts | 22 ++++++++++--------- code/addons/gfm/vitest.config.ts | 22 ++++++++++--------- code/addons/highlight/vitest.config.ts | 22 ++++++++++--------- code/addons/interactions/vitest.config.ts | 22 ++++++++++--------- code/addons/jest/vitest.config.ts | 22 ++++++++++--------- code/addons/links/vitest.config.ts | 22 ++++++++++--------- code/addons/measure/vitest.config.ts | 22 ++++++++++--------- code/addons/outline/vitest.config.ts | 22 ++++++++++--------- code/addons/storysource/vitest.config.ts | 22 ++++++++++--------- code/addons/themes/vitest.config.ts | 22 ++++++++++--------- code/addons/toolbars/vitest.config.ts | 22 ++++++++++--------- code/addons/viewport/vitest.config.ts | 22 ++++++++++--------- .../builders/builder-manager/vitest.config.ts | 21 +++++++++--------- code/builders/builder-vite/vitest.config.ts | 21 +++++++++--------- .../builder-webpack5/vitest.config.ts | 21 +++++++++--------- .../channel-postmessage/vitest.config.ts | 22 ++++++++++--------- .../channel-websocket/vitest.config.ts | 22 ++++++++++--------- code/frameworks/ember/vitest.config.ts | 21 +++++++++--------- .../frameworks/html-webpack5/vitest.config.ts | 21 +++++++++--------- code/frameworks/nextjs/vitest.config.ts | 21 +++++++++--------- code/frameworks/preact-vite/vitest.config.ts | 21 +++++++++--------- .../preact-webpack5/vitest.config.ts | 21 +++++++++--------- code/frameworks/react-vite/vitest.config.ts | 21 +++++++++--------- .../react-webpack5/vitest.config.ts | 21 +++++++++--------- .../server-webpack5/vitest.config.ts | 21 +++++++++--------- code/frameworks/svelte-vite/vitest.config.ts | 21 +++++++++--------- .../svelte-webpack5/vitest.config.ts | 21 +++++++++--------- code/frameworks/sveltekit/vitest.config.ts | 21 +++++++++--------- code/frameworks/vue-vite/vitest.config.ts | 21 +++++++++--------- code/frameworks/vue-webpack5/vitest.config.ts | 21 +++++++++--------- code/frameworks/vue3-vite/vitest.config.ts | 21 +++++++++--------- .../frameworks/vue3-webpack5/vitest.config.ts | 21 +++++++++--------- .../web-components-vite/vitest.config.ts | 21 +++++++++--------- .../web-components-webpack5/vitest.config.ts | 21 +++++++++--------- code/lib/channels/vitest.config.ts | 21 +++++++++--------- code/lib/cli-sb/vitest.config.ts | 21 +++++++++--------- code/lib/cli-storybook/vitest.config.ts | 21 +++++++++--------- code/lib/cli/vitest.config.ts | 21 +++++++++--------- code/lib/client-logger/vitest.config.ts | 22 ++++++++++--------- code/lib/codemod/vitest.config.ts | 21 +++++++++--------- code/lib/core-common/vitest.config.ts | 21 +++++++++--------- code/lib/core-events/vitest.config.ts | 21 +++++++++--------- code/lib/core-server/vitest.config.ts | 21 +++++++++--------- code/lib/core-webpack/vitest.config.ts | 21 +++++++++--------- code/lib/csf-plugin/vitest.config.ts | 22 ++++++++++--------- code/lib/csf-tools/vitest.config.ts | 21 +++++++++--------- code/lib/docs-tools/vitest.config.ts | 21 +++++++++--------- code/lib/instrumenter/vitest.config.ts | 22 ++++++++++--------- code/lib/manager-api/vitest.config.ts | 21 +++++++++--------- code/lib/node-logger/vitest.config.ts | 21 +++++++++--------- code/lib/postinstall/vitest.config.ts | 21 +++++++++--------- code/lib/preview-api/vitest.config.ts | 21 +++++++++--------- code/lib/preview/vitest.config.ts | 21 +++++++++--------- code/lib/router/vitest.config.ts | 21 +++++++++--------- code/lib/source-loader/vitest.config.ts | 21 +++++++++--------- code/lib/telemetry/vitest.config.ts | 21 +++++++++--------- code/lib/theming/vitest.config.ts | 22 ++++++++++--------- code/lib/types/vitest.config.ts | 21 +++++++++--------- code/renderers/html/vitest.config.ts | 22 ++++++++++--------- code/renderers/preact/vitest.config.ts | 22 ++++++++++--------- .../__snapshots__/internals.test.tsx.snap | 2 +- code/renderers/react/vitest.config.ts | 22 ++++++++++--------- code/renderers/server/vitest.config.ts | 22 ++++++++++--------- code/renderers/svelte/vitest.config.ts | 22 ++++++++++--------- code/renderers/vue/vitest.config.ts | 22 ++++++++++--------- code/renderers/vue3/vitest.config.ts | 22 ++++++++++--------- .../renderers/web-components/vitest.config.ts | 22 ++++++++++--------- code/ui/blocks/vitest.config.ts | 22 ++++++++++--------- code/ui/components/vitest.config.ts | 22 ++++++++++--------- code/ui/manager/vitest.config.ts | 22 ++++++++++--------- code/vitest.workspace.ts | 8 ++++++- .../release/__tests__/is-pr-frozen.test.ts | 5 +---- 77 files changed, 857 insertions(+), 746 deletions(-) diff --git a/code/addons/a11y/vitest.config.ts b/code/addons/a11y/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/a11y/vitest.config.ts +++ b/code/addons/a11y/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/actions/vitest.config.ts b/code/addons/actions/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/actions/vitest.config.ts +++ b/code/addons/actions/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/backgrounds/vitest.config.ts b/code/addons/backgrounds/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/backgrounds/vitest.config.ts +++ b/code/addons/backgrounds/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/controls/vitest.config.ts b/code/addons/controls/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/controls/vitest.config.ts +++ b/code/addons/controls/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/docs/vitest.config.ts b/code/addons/docs/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/docs/vitest.config.ts +++ b/code/addons/docs/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/essentials/vitest.config.ts b/code/addons/essentials/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/essentials/vitest.config.ts +++ b/code/addons/essentials/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/gfm/vitest.config.ts b/code/addons/gfm/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/gfm/vitest.config.ts +++ b/code/addons/gfm/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/highlight/vitest.config.ts b/code/addons/highlight/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/highlight/vitest.config.ts +++ b/code/addons/highlight/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/interactions/vitest.config.ts b/code/addons/interactions/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/interactions/vitest.config.ts +++ b/code/addons/interactions/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/jest/vitest.config.ts b/code/addons/jest/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/jest/vitest.config.ts +++ b/code/addons/jest/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/links/vitest.config.ts b/code/addons/links/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/links/vitest.config.ts +++ b/code/addons/links/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/measure/vitest.config.ts b/code/addons/measure/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/measure/vitest.config.ts +++ b/code/addons/measure/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/outline/vitest.config.ts b/code/addons/outline/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/outline/vitest.config.ts +++ b/code/addons/outline/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/storysource/vitest.config.ts b/code/addons/storysource/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/storysource/vitest.config.ts +++ b/code/addons/storysource/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/themes/vitest.config.ts b/code/addons/themes/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/themes/vitest.config.ts +++ b/code/addons/themes/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/toolbars/vitest.config.ts b/code/addons/toolbars/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/toolbars/vitest.config.ts +++ b/code/addons/toolbars/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/addons/viewport/vitest.config.ts b/code/addons/viewport/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/addons/viewport/vitest.config.ts +++ b/code/addons/viewport/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/builders/builder-manager/vitest.config.ts b/code/builders/builder-manager/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/builders/builder-manager/vitest.config.ts +++ b/code/builders/builder-manager/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/builders/builder-vite/vitest.config.ts b/code/builders/builder-vite/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/builders/builder-vite/vitest.config.ts +++ b/code/builders/builder-vite/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/builders/builder-webpack5/vitest.config.ts b/code/builders/builder-webpack5/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/builders/builder-webpack5/vitest.config.ts +++ b/code/builders/builder-webpack5/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/deprecated/channel-postmessage/vitest.config.ts b/code/deprecated/channel-postmessage/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/deprecated/channel-postmessage/vitest.config.ts +++ b/code/deprecated/channel-postmessage/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/deprecated/channel-websocket/vitest.config.ts b/code/deprecated/channel-websocket/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/deprecated/channel-websocket/vitest.config.ts +++ b/code/deprecated/channel-websocket/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/ember/vitest.config.ts b/code/frameworks/ember/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/ember/vitest.config.ts +++ b/code/frameworks/ember/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/html-webpack5/vitest.config.ts b/code/frameworks/html-webpack5/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/html-webpack5/vitest.config.ts +++ b/code/frameworks/html-webpack5/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/nextjs/vitest.config.ts b/code/frameworks/nextjs/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/nextjs/vitest.config.ts +++ b/code/frameworks/nextjs/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/preact-vite/vitest.config.ts b/code/frameworks/preact-vite/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/preact-vite/vitest.config.ts +++ b/code/frameworks/preact-vite/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/preact-webpack5/vitest.config.ts b/code/frameworks/preact-webpack5/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/preact-webpack5/vitest.config.ts +++ b/code/frameworks/preact-webpack5/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/react-vite/vitest.config.ts b/code/frameworks/react-vite/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/react-vite/vitest.config.ts +++ b/code/frameworks/react-vite/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/react-webpack5/vitest.config.ts b/code/frameworks/react-webpack5/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/react-webpack5/vitest.config.ts +++ b/code/frameworks/react-webpack5/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/server-webpack5/vitest.config.ts b/code/frameworks/server-webpack5/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/server-webpack5/vitest.config.ts +++ b/code/frameworks/server-webpack5/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/svelte-vite/vitest.config.ts b/code/frameworks/svelte-vite/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/svelte-vite/vitest.config.ts +++ b/code/frameworks/svelte-vite/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/svelte-webpack5/vitest.config.ts b/code/frameworks/svelte-webpack5/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/svelte-webpack5/vitest.config.ts +++ b/code/frameworks/svelte-webpack5/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/sveltekit/vitest.config.ts b/code/frameworks/sveltekit/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/sveltekit/vitest.config.ts +++ b/code/frameworks/sveltekit/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/vue-vite/vitest.config.ts b/code/frameworks/vue-vite/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/vue-vite/vitest.config.ts +++ b/code/frameworks/vue-vite/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/vue-webpack5/vitest.config.ts b/code/frameworks/vue-webpack5/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/vue-webpack5/vitest.config.ts +++ b/code/frameworks/vue-webpack5/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/vue3-vite/vitest.config.ts b/code/frameworks/vue3-vite/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/vue3-vite/vitest.config.ts +++ b/code/frameworks/vue3-vite/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/vue3-webpack5/vitest.config.ts b/code/frameworks/vue3-webpack5/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/vue3-webpack5/vitest.config.ts +++ b/code/frameworks/vue3-webpack5/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/web-components-vite/vitest.config.ts b/code/frameworks/web-components-vite/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/web-components-vite/vitest.config.ts +++ b/code/frameworks/web-components-vite/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/frameworks/web-components-webpack5/vitest.config.ts b/code/frameworks/web-components-webpack5/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/frameworks/web-components-webpack5/vitest.config.ts +++ b/code/frameworks/web-components-webpack5/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/channels/vitest.config.ts b/code/lib/channels/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/channels/vitest.config.ts +++ b/code/lib/channels/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/cli-sb/vitest.config.ts b/code/lib/cli-sb/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/cli-sb/vitest.config.ts +++ b/code/lib/cli-sb/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/cli-storybook/vitest.config.ts b/code/lib/cli-storybook/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/cli-storybook/vitest.config.ts +++ b/code/lib/cli-storybook/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/cli/vitest.config.ts b/code/lib/cli/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/cli/vitest.config.ts +++ b/code/lib/cli/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/client-logger/vitest.config.ts b/code/lib/client-logger/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/lib/client-logger/vitest.config.ts +++ b/code/lib/client-logger/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/codemod/vitest.config.ts b/code/lib/codemod/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/codemod/vitest.config.ts +++ b/code/lib/codemod/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/core-common/vitest.config.ts b/code/lib/core-common/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/core-common/vitest.config.ts +++ b/code/lib/core-common/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/core-events/vitest.config.ts b/code/lib/core-events/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/core-events/vitest.config.ts +++ b/code/lib/core-events/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/core-server/vitest.config.ts b/code/lib/core-server/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/core-server/vitest.config.ts +++ b/code/lib/core-server/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/core-webpack/vitest.config.ts b/code/lib/core-webpack/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/core-webpack/vitest.config.ts +++ b/code/lib/core-webpack/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/csf-plugin/vitest.config.ts b/code/lib/csf-plugin/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/lib/csf-plugin/vitest.config.ts +++ b/code/lib/csf-plugin/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/csf-tools/vitest.config.ts b/code/lib/csf-tools/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/csf-tools/vitest.config.ts +++ b/code/lib/csf-tools/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/docs-tools/vitest.config.ts b/code/lib/docs-tools/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/docs-tools/vitest.config.ts +++ b/code/lib/docs-tools/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/instrumenter/vitest.config.ts b/code/lib/instrumenter/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/lib/instrumenter/vitest.config.ts +++ b/code/lib/instrumenter/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/manager-api/vitest.config.ts b/code/lib/manager-api/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/manager-api/vitest.config.ts +++ b/code/lib/manager-api/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/node-logger/vitest.config.ts b/code/lib/node-logger/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/node-logger/vitest.config.ts +++ b/code/lib/node-logger/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/postinstall/vitest.config.ts b/code/lib/postinstall/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/postinstall/vitest.config.ts +++ b/code/lib/postinstall/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/preview-api/vitest.config.ts b/code/lib/preview-api/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/preview-api/vitest.config.ts +++ b/code/lib/preview-api/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/preview/vitest.config.ts b/code/lib/preview/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/preview/vitest.config.ts +++ b/code/lib/preview/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/router/vitest.config.ts b/code/lib/router/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/router/vitest.config.ts +++ b/code/lib/router/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/source-loader/vitest.config.ts b/code/lib/source-loader/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/source-loader/vitest.config.ts +++ b/code/lib/source-loader/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/telemetry/vitest.config.ts b/code/lib/telemetry/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/telemetry/vitest.config.ts +++ b/code/lib/telemetry/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/theming/vitest.config.ts b/code/lib/theming/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/lib/theming/vitest.config.ts +++ b/code/lib/theming/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/lib/types/vitest.config.ts b/code/lib/types/vitest.config.ts index aa50537cbd84..ddec70e554d4 100644 --- a/code/lib/types/vitest.config.ts +++ b/code/lib/types/vitest.config.ts @@ -1,12 +1,13 @@ -import { defineProject } from 'vitest/config'; +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'node', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'node', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/renderers/html/vitest.config.ts b/code/renderers/html/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/renderers/html/vitest.config.ts +++ b/code/renderers/html/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/renderers/preact/vitest.config.ts b/code/renderers/preact/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/renderers/preact/vitest.config.ts +++ b/code/renderers/preact/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/renderers/react/src/__test__/__snapshots__/internals.test.tsx.snap b/code/renderers/react/src/__test__/__snapshots__/internals.test.tsx.snap index 4507f513248b..2b92b1d68424 100644 --- a/code/renderers/react/src/__test__/__snapshots__/internals.test.tsx.snap +++ b/code/renderers/react/src/__test__/__snapshots__/internals.test.tsx.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`Renders CSF2Secondary story 1`] = ` diff --git a/code/renderers/react/vitest.config.ts b/code/renderers/react/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/renderers/react/vitest.config.ts +++ b/code/renderers/react/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/renderers/server/vitest.config.ts b/code/renderers/server/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/renderers/server/vitest.config.ts +++ b/code/renderers/server/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/renderers/svelte/vitest.config.ts b/code/renderers/svelte/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/renderers/svelte/vitest.config.ts +++ b/code/renderers/svelte/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/renderers/vue/vitest.config.ts b/code/renderers/vue/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/renderers/vue/vitest.config.ts +++ b/code/renderers/vue/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/renderers/vue3/vitest.config.ts b/code/renderers/vue3/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/renderers/vue3/vitest.config.ts +++ b/code/renderers/vue3/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/renderers/web-components/vitest.config.ts b/code/renderers/web-components/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/renderers/web-components/vitest.config.ts +++ b/code/renderers/web-components/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/ui/blocks/vitest.config.ts b/code/ui/blocks/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/ui/blocks/vitest.config.ts +++ b/code/ui/blocks/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/ui/components/vitest.config.ts b/code/ui/components/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/ui/components/vitest.config.ts +++ b/code/ui/components/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/ui/manager/vitest.config.ts b/code/ui/manager/vitest.config.ts index 4aaad5122170..0432e7483834 100644 --- a/code/ui/manager/vitest.config.ts +++ b/code/ui/manager/vitest.config.ts @@ -1,12 +1,14 @@ -import { defineProject } from 'vitest/config'; +/* eslint-disable import/no-extraneous-dependencies */ +import { defineConfig, mergeConfig } from 'vitest/config'; import { sep, posix } from 'path'; -// import { fileURLToPath } from 'url'; +import { vitestCommonConfig } from '../../vitest.workspace'; -// const __dirname = dirname(fileURLToPath(import.meta.url)); - -export default defineProject({ - test: { - environment: 'jsdom', - name: __dirname.split(sep).slice(-2).join(posix.sep), - }, -}); +export default mergeConfig( + vitestCommonConfig, + defineConfig({ + test: { + environment: 'jsdom', + name: __dirname.split(sep).slice(-2).join(posix.sep), + }, + }) +); diff --git a/code/vitest.workspace.ts b/code/vitest.workspace.ts index 6a74414e6d1a..c063a58ec30b 100644 --- a/code/vitest.workspace.ts +++ b/code/vitest.workspace.ts @@ -1,4 +1,4 @@ -import { defineWorkspace } from 'vitest/config'; +import { defineConfig, defineWorkspace } from 'vitest/config'; export default defineWorkspace([ 'addons/*/vitest.config.ts', @@ -10,3 +10,9 @@ export default defineWorkspace([ 'presets/*/vitest.config.ts', 'renderers/*/vitest.config.ts', ]); + +export const vitestCommonConfig = defineConfig({ + test: { + clearMocks: true, + }, +}); diff --git a/scripts/release/__tests__/is-pr-frozen.test.ts b/scripts/release/__tests__/is-pr-frozen.test.ts index 0b9187e01dd4..717d9de7c15a 100644 --- a/scripts/release/__tests__/is-pr-frozen.test.ts +++ b/scripts/release/__tests__/is-pr-frozen.test.ts @@ -1,6 +1,7 @@ /* eslint-disable no-underscore-dangle */ /* eslint-disable global-require */ import path from 'path'; +import { vi, describe, expect, it } from 'vitest'; import { run as isPrFrozen } from '../is-pr-frozen'; // eslint-disable-next-line jest/no-mocks-import @@ -19,10 +20,6 @@ fsExtra.__setMockFiles({ }); describe('isPrFrozen', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - it('should return true when PR is frozen', async () => { getPullInfoFromCommit.mockResolvedValue({ labels: ['freeze'], From 1dfe6870b77eceb1aaf1122dd9aa5617d4b1b48c Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Thu, 14 Sep 2023 16:50:40 +0200 Subject: [PATCH 008/105] migrate all jest references to vitest --- code/__mocks__/fs-extra.js | 5 +- code/__mocks__/fs.js | 3 +- code/addons/a11y/src/a11yRunner.test.ts | 8 +- .../a11y/src/components/A11YPanel.test.tsx | 8 +- .../a11y/src/components/A11yContext.test.tsx | 14 +- .../Report/HighlightToggle.test.tsx | 9 +- .../src/components/VisionSimulator.test.tsx | 1 + code/addons/a11y/src/manager.test.tsx | 8 +- .../addons/actions/src/addArgsHelpers.test.ts | 1 + .../src/runtime/__tests__/action.test.js | 3 +- .../src/runtime/__tests__/actions.test.js | 3 +- .../__tests__/configureActions.test.js | 1 + code/addons/interactions/src/Panel.test.ts | 1 + code/addons/jest/src/shared.test.ts | 1 + .../links/src/react/components/link.test.tsx | 16 +- code/addons/links/src/utils.test.ts | 6 +- .../builder-vite/src/vite-config.test.ts | 7 +- .../builders/build-storybook/index.spec.ts | 17 +- .../builders/start-storybook/index.spec.ts | 15 +- .../src/builders/utils/run-compodoc.spec.ts | 17 +- .../angular-beta/RendererFactory.test.ts | 5 +- .../utils/PropertyExtractor.test.ts | 3 +- .../angular/src/client/decorators.test.ts | 3 +- code/lib/channels/src/index.test.ts | 35 ++-- .../src/automigrate/fixes/add-react.test.ts | 1 + .../angular-builders-multiproject.test.ts | 28 ++-- .../fixes/angular-builders.test.ts | 30 ++-- .../automigrate/fixes/autodocs-true.test.ts | 3 +- .../fixes/bare-mdx-stories-glob.test.ts | 4 +- .../automigrate/fixes/builder-vite.test.ts | 3 +- .../cli/src/automigrate/fixes/cra5.test.ts | 7 +- .../automigrate/fixes/eslint-plugin.test.ts | 3 +- .../fixes/incompatible-addons.test.ts | 4 +- .../src/automigrate/fixes/mdx-1-to-2.test.ts | 2 +- .../cli/src/automigrate/fixes/mdx-gfm.test.ts | 3 +- .../automigrate/fixes/missing-babelrc.test.ts | 4 +- .../automigrate/fixes/new-frameworks.test.ts | 25 +-- .../fixes/nodejs-requirement.test.ts | 4 +- .../src/automigrate/fixes/sb-binary.test.ts | 1 + .../src/automigrate/fixes/sb-scripts.test.ts | 3 +- .../cli/src/automigrate/fixes/vue3.test.ts | 3 +- .../src/automigrate/fixes/webpack5.test.ts | 3 +- .../automigrate/fixes/wrap-require.test.ts | 16 +- .../helpers/checkWebpack5Builder.test.ts | 9 +- .../helpers/getMigrationSummary.test.ts | 3 +- .../helpers/mainConfigFile.test.ts | 1 + .../helpers/new-frameworks-utils.test.ts | 13 +- .../automigrate/helpers/testing-helpers.ts | 13 +- code/lib/cli/src/detect.test.ts | 24 +-- code/lib/cli/src/generators/configure.test.ts | 18 +- code/lib/cli/src/helpers.test.ts | 42 ++--- .../JsPackageManagerFactory.test.ts | 14 +- .../src/js-package-manager/NPMProxy.test.ts | 55 +++--- .../src/js-package-manager/PNPMProxy.test.ts | 39 ++--- .../src/js-package-manager/Yarn1Proxy.test.ts | 35 ++-- .../src/js-package-manager/Yarn2Proxy.test.ts | 35 ++-- code/lib/cli/src/project_types.test.ts | 1 + code/lib/cli/src/upgrade.test.ts | 1 + code/lib/cli/src/utils.test.ts | 1 + code/lib/cli/src/warn.test.ts | 8 +- code/lib/cli/test/default/cli.test.js | 1 + code/lib/client-logger/src/index.test.ts | 13 +- code/lib/codemod/src/lib/utils.test.js | 1 + .../transforms/__tests__/mdx-to-csf.test.ts | 5 +- .../transforms/__tests__/transforms.tests.js | 1 + code/lib/core-common/src/config.test.ts | 1 + code/lib/core-common/src/presets.test.ts | 67 ++++---- code/lib/core-common/src/test-typings.d.ts | 4 +- .../utils/__tests__/check-addon-order.test.ts | 3 +- .../utils/__tests__/interpret-files.test.ts | 1 + .../utils/__tests__/normalize-stories.test.ts | 1 + .../src/utils/__tests__/paths.test.ts | 4 +- .../src/utils/__tests__/template.test.ts | 1 + .../utils/get-storybook-configuration.test.ts | 1 + .../src/utils/validate-config.test.ts | 7 +- .../src/errors/server-errors.test.ts | 1 + .../src/errors/storybook-error.test.ts | 1 + code/lib/core-events/src/index.test.ts | 1 + .../core-server/src/presets/favicon.test.ts | 11 +- .../StoryIndexGenerator.deprecated.test.ts | 30 ++-- .../src/utils/StoryIndexGenerator.test.ts | 31 ++-- .../src/utils/__tests__/IndexingError.test.ts | 1 + .../src/utils/__tests__/autoName.test.ts | 1 + .../utils/__tests__/index-extraction.test.ts | 5 +- .../utils/__tests__/server-address.test.ts | 4 +- .../utils/__tests__/server-channel.test.ts | 13 +- .../utils/__tests__/server-statics.test.ts | 5 +- .../src/utils/server-address.test.ts | 4 +- .../src/utils/stories-json.test.ts | 49 +++--- .../src/utils/summarizeIndex.test.ts | 1 + .../src/utils/watch-story-specifiers.test.ts | 9 +- .../lib/core-server/src/withTelemetry.test.ts | 39 ++--- .../core-webpack/src/importPipeline.test.ts | 9 +- .../src/merge-webpack-config.test.ts | 1 + code/lib/core-webpack/src/to-importFn.test.ts | 1 + .../src/to-require-context.test.ts | 1 + code/lib/csf-tools/src/ConfigFile.test.ts | 5 +- code/lib/csf-tools/src/CsfFile.test.ts | 8 +- code/lib/csf-tools/src/enrichCsf.test.ts | 5 +- .../src/getStorySortParameter.test.ts | 1 + .../src/argTypes/convert/convert.test.ts | 1 + .../docgen/extractDocgenProps.test.ts | 1 + .../docgen/flow/createPropDef.test.ts | 1 + .../docgen/typeScript/createPropDef.test.ts | 1 + .../src/argTypes/enhanceArgTypes.test.ts | 1 + .../src/argTypes/jsdocParser.test.ts | 1 + .../lib/docs-tools/src/argTypes/utils.test.ts | 1 + .../lib/instrumenter/src/instrumenter.test.ts | 39 ++--- code/lib/manager-api/src/lib/stories.test.ts | 1 + code/lib/manager-api/src/tests/addons.test.js | 11 +- code/lib/manager-api/src/tests/events.test.ts | 3 +- .../lib/manager-api/src/tests/globals.test.ts | 15 +- code/lib/manager-api/src/tests/layout.test.js | 5 +- .../src/tests/notifications.test.js | 5 +- code/lib/manager-api/src/tests/refs.test.ts | 11 +- .../manager-api/src/tests/shortcut.test.js | 3 +- .../manager-api/src/tests/shortcuts.test.js | 5 +- code/lib/manager-api/src/tests/store.test.js | 29 ++-- .../lib/manager-api/src/tests/stories.test.ts | 69 ++++---- code/lib/manager-api/src/tests/url.test.js | 27 +-- .../manager-api/src/tests/versions.test.js | 5 +- code/lib/node-logger/src/index.test.ts | 9 +- code/lib/postinstall/src/codemods.test.ts | 1 + code/lib/postinstall/src/frameworks.test.ts | 1 + .../src/modules/addons/hooks.test.js | 1 + .../src/modules/addons/make-decorator.test.ts | 41 ++--- .../src/modules/client-api/ClientApi.test.ts | 13 +- .../src/modules/core-client/start.test.ts | 157 +++++++++--------- .../PreviewWeb.integration.test.ts | 18 +- .../preview-web/PreviewWeb.mockdata.ts | 36 ++-- .../modules/preview-web/PreviewWeb.test.ts | 88 +++++----- .../src/modules/preview-web/UrlStore.test.ts | 3 +- .../docs-context/DocsContext.test.ts | 7 +- .../preview-web/parseArgsParam.test.ts | 3 +- .../preview-web/render/CsfDocsRender.test.ts | 5 +- .../preview-web/render/MdxDocsRender.test.ts | 7 +- .../preview-web/render/StoryRender.test.ts | 27 +-- .../preview-web/simulate-pageload.test.ts | 3 +- .../src/modules/store/ArgsStore.test.ts | 2 +- .../src/modules/store/GlobalsStore.test.ts | 4 +- .../src/modules/store/StoryIndexStore.test.ts | 4 +- .../src/modules/store/StoryStore.test.ts | 32 ++-- .../src/modules/store/args.test.ts | 1 + .../src/modules/store/autoTitle.test.ts | 1 + .../modules/store/csf/composeConfigs.test.ts | 4 +- .../store/csf/normalizeInputTypes.test.ts | 2 +- .../modules/store/csf/normalizeStory.test.ts | 14 +- .../modules/store/csf/prepareStory.test.ts | 71 ++++---- .../modules/store/csf/processCSFFile.test.ts | 2 +- .../src/modules/store/csf/stepRunners.test.ts | 9 +- .../store/csf/testing-utils/index.test.ts | 5 +- .../src/modules/store/decorators.test.ts | 2 +- .../src/modules/store/hooks.test.ts | 58 +++---- .../src/modules/store/inferArgTypes.test.ts | 9 +- .../src/modules/store/inferControls.test.ts | 7 +- .../src/modules/store/parameters.test.ts | 2 +- code/lib/router/src/utils.test.ts | 3 +- .../inject-decorator.csf.test.js | 1 + .../inject-decorator.test.js | 1 + code/lib/telemetry/src/anonymous-id.test.ts | 1 + code/lib/telemetry/src/event-cache.test.ts | 1 + .../src/get-chromatic-version.test.ts | 1 + .../telemetry/src/get-framework-info.test.ts | 6 +- .../telemetry/src/get-monorepo-type.test.ts | 5 +- code/lib/telemetry/src/sanitize.test.ts | 7 +- code/lib/telemetry/src/session-id.test.ts | 16 +- .../telemetry/src/storybook-metadata.test.ts | 18 +- code/lib/telemetry/src/telemetry.test.ts | 10 +- code/lib/theming/src/tests/convert.test.js | 1 + code/lib/theming/src/tests/create.test.js | 1 + code/lib/theming/src/tests/util.test.js | 5 +- .../react-webpack/src/cra-config.test.ts | 16 +- .../src/framework-preset-react-docs.test.ts | 1 + .../src/framework-preset-react.test.ts | 5 +- .../html/src/docs/sourceDecorator.test.ts | 10 +- .../src/__test__/composeStories.test.tsx | 4 +- .../react/src/__test__/internals.test.tsx | 1 - .../react/src/docs/jsxDecorator.test.tsx | 12 +- code/renderers/react/src/public-api.test.ts | 3 +- code/renderers/vue/src/public-types.test.ts | 1 + code/renderers/vue3/src/render.test.ts | 1 + .../vue3/template/cli/ts-4-9/Page.stories.ts | 2 - .../src/docs/sourceDecorator.test.ts | 10 +- .../docs/web-components-properties.test.ts | 1 + .../internal/InternalCanvas.stories.tsx | 2 +- .../components/typography/link/link.test.tsx | 15 +- scripts/__mocks__/simple-git.js | 9 +- scripts/__mocks__/uuid.ts | 2 +- .../__tests__/generate-pr-description.test.ts | 1 + .../release/__tests__/is-pr-frozen.test.ts | 6 +- .../release/__tests__/label-patches.test.ts | 11 +- scripts/release/__tests__/version.test.ts | 11 +- .../release/__tests__/write-changelog.test.ts | 11 +- 193 files changed, 1135 insertions(+), 958 deletions(-) diff --git a/code/__mocks__/fs-extra.js b/code/__mocks__/fs-extra.js index 7e18c3ead80d..eb34ac9f19d8 100644 --- a/code/__mocks__/fs-extra.js +++ b/code/__mocks__/fs-extra.js @@ -1,4 +1,5 @@ -const fs = jest.createMockFromModule('fs-extra'); +import { vi } from 'vitest'; +const fs = vi.createMockFromModule('fs-extra'); // This is a custom function that our tests can use during setup to specify // what the files on the "mock" filesystem should look like when any of the @@ -20,7 +21,7 @@ const readJsonSync = (filePath = '') => JSON.parse(mockFiles[filePath]); const lstatSync = (filePath) => ({ isFile: () => !!mockFiles[filePath], }); -const writeJson = jest.fn((filePath, json, { spaces } = {}) => { +const writeJson = vi.fn((filePath, json, { spaces } = {}) => { mockFiles[filePath] = JSON.stringify(json, null, spaces); }); diff --git a/code/__mocks__/fs.js b/code/__mocks__/fs.js index 18710b4986d5..07956c1eaf4a 100644 --- a/code/__mocks__/fs.js +++ b/code/__mocks__/fs.js @@ -1,4 +1,5 @@ -const fs = jest.createMockFromModule('fs'); +import { vi } from 'vitest'; +const fs = vi.createMockFromModule('fs'); // This is a custom function that our tests can use during setup to specify // what the files on the "mock" filesystem should look like when any of the diff --git a/code/addons/a11y/src/a11yRunner.test.ts b/code/addons/a11y/src/a11yRunner.test.ts index 48f1dd909e63..e2e46408b6b3 100644 --- a/code/addons/a11y/src/a11yRunner.test.ts +++ b/code/addons/a11y/src/a11yRunner.test.ts @@ -1,16 +1,18 @@ +import type { Mock, Mocked } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import { addons } from '@storybook/preview-api'; import { EVENTS } from './constants'; vi.mock('@storybook/preview-api'); -const mockedAddons = addons as vi.mocked; +const mockedAddons = addons as Mocked; describe('a11yRunner', () => { - let mockChannel: { on: vi.mock; emit?: vi.mock }; + let mockChannel: { on: Mock; emit?: Mock }; beforeEach(() => { mockedAddons.getChannel.mockReset(); - mockChannel = { on: jest.fn(), emit: jest.fn() }; + mockChannel = { on: vi.fn(), emit: vi.fn() }; mockedAddons.getChannel.mockReturnValue(mockChannel as any); }); diff --git a/code/addons/a11y/src/components/A11YPanel.test.tsx b/code/addons/a11y/src/components/A11YPanel.test.tsx index 41fbe0f1ab18..2b93ae4a047e 100644 --- a/code/addons/a11y/src/components/A11YPanel.test.tsx +++ b/code/addons/a11y/src/components/A11YPanel.test.tsx @@ -1,3 +1,5 @@ +import type { Mocked } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import React from 'react'; import { render, waitFor, fireEvent, act } from '@testing-library/react'; @@ -11,7 +13,7 @@ vi.mock('@storybook/manager-api'); global.ResizeObserver = require('resize-observer-polyfill'); -const mockedApi = api as vi.mocked; +const mockedApi = api as Mocked; const axeResult = { incomplete: [ @@ -67,7 +69,7 @@ describe('A11YPanel', () => { mockedApi.useAddonState.mockReset(); mockedApi.useAddonState.mockImplementation((_, defaultState) => React.useState(defaultState)); - mockedApi.useChannel.mockReturnValue(jest.fn()); + mockedApi.useChannel.mockReturnValue(vi.fn()); mockedApi.useParameter.mockReturnValue({ manual: false }); const state: Partial = { storyId: 'jest' }; // Lazy to mock entire state @@ -104,7 +106,7 @@ describe('A11YPanel', () => { }); it('should handle "running" status', async () => { - const emit = jest.fn(); + const emit = vi.fn(); mockedApi.useChannel.mockReturnValue(emit); mockedApi.useParameter.mockReturnValue({ manual: true }); const { getByRole, getByText } = render(); diff --git a/code/addons/a11y/src/components/A11yContext.test.tsx b/code/addons/a11y/src/components/A11yContext.test.tsx index 65fd00c5ada7..01118bda905f 100644 --- a/code/addons/a11y/src/components/A11yContext.test.tsx +++ b/code/addons/a11y/src/components/A11yContext.test.tsx @@ -1,3 +1,5 @@ +import type { Mocked } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import * as React from 'react'; import type { AxeResults } from 'axe-core'; import { render, act } from '@testing-library/react'; @@ -9,7 +11,7 @@ import { A11yContextProvider, useA11yContext } from './A11yContext'; import { EVENTS } from '../constants'; vi.mock('@storybook/manager-api'); -const mockedApi = api as vi.mocked; +const mockedApi = api as Mocked; const storyId = 'jest'; const axeResult: Partial = { @@ -51,14 +53,14 @@ const axeResult: Partial = { }; describe('A11YPanel', () => { - const getCurrentStoryData = jest.fn(); + const getCurrentStoryData = vi.fn(); beforeEach(() => { mockedApi.useChannel.mockReset(); mockedApi.useStorybookApi.mockReset(); mockedApi.useAddonState.mockReset(); mockedApi.useAddonState.mockImplementation((_, defaultState) => React.useState(defaultState)); - mockedApi.useChannel.mockReturnValue(jest.fn()); + mockedApi.useChannel.mockReturnValue(vi.fn()); getCurrentStoryData.mockReset().mockReturnValue({ id: storyId, type: 'story' }); mockedApi.useStorybookApi.mockReturnValue({ getCurrentStoryData } as any); }); @@ -73,7 +75,7 @@ describe('A11YPanel', () => { }); it('should not render when inactive', () => { - const emit = jest.fn(); + const emit = vi.fn(); mockedApi.useChannel.mockReturnValue(emit); const { queryByTestId } = render( @@ -85,7 +87,7 @@ describe('A11YPanel', () => { }); it('should emit request when moving from inactive to active', () => { - const emit = jest.fn(); + const emit = vi.fn(); mockedApi.useChannel.mockReturnValue(emit); const { rerender } = render(); rerender(); @@ -93,7 +95,7 @@ describe('A11YPanel', () => { }); it('should emit highlight with no values when inactive', () => { - const emit = jest.fn(); + const emit = vi.fn(); mockedApi.useChannel.mockReturnValue(emit); const { rerender } = render(); rerender(); diff --git a/code/addons/a11y/src/components/Report/HighlightToggle.test.tsx b/code/addons/a11y/src/components/Report/HighlightToggle.test.tsx index 9bda14726da1..eed785fabe4c 100644 --- a/code/addons/a11y/src/components/Report/HighlightToggle.test.tsx +++ b/code/addons/a11y/src/components/Report/HighlightToggle.test.tsx @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import React from 'react'; import { render, fireEvent } from '@testing-library/react'; import type { NodeResult } from 'axe-core'; @@ -18,12 +19,12 @@ const defaultProviderValue = { incomplete: [], violations: [], }, - setResults: jest.fn(), + setResults: vi.fn(), highlighted: [], - toggleHighlight: jest.fn(), - clearHighlights: jest.fn(), + toggleHighlight: vi.fn(), + clearHighlights: vi.fn(), tab: 0, - setTab: jest.fn(), + setTab: vi.fn(), }; describe('', () => { diff --git a/code/addons/a11y/src/components/VisionSimulator.test.tsx b/code/addons/a11y/src/components/VisionSimulator.test.tsx index 7c66fb762b64..c3aef6f123e0 100644 --- a/code/addons/a11y/src/components/VisionSimulator.test.tsx +++ b/code/addons/a11y/src/components/VisionSimulator.test.tsx @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import React from 'react'; import { render, fireEvent, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; diff --git a/code/addons/a11y/src/manager.test.tsx b/code/addons/a11y/src/manager.test.tsx index 29a79f520c95..61511c6435e5 100644 --- a/code/addons/a11y/src/manager.test.tsx +++ b/code/addons/a11y/src/manager.test.tsx @@ -1,12 +1,14 @@ +import type { Mocked } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import * as api from '@storybook/manager-api'; import type { Addon_BaseType } from '@storybook/types'; import { PANEL_ID } from './constants'; import './manager'; vi.mock('@storybook/manager-api'); -const mockedApi = api as unknown as vi.mocked; -mockedApi.useAddonState = jest.fn(); -const mockedAddons = api.addons as vi.mocked; +const mockedApi = api as unknown as Mocked; +mockedApi.useAddonState = vi.fn(); +const mockedAddons = api.addons as Mocked; const registrationImpl = mockedAddons.register.mock.calls[0][1]; const isPanel = (input: Parameters[1]): input is Addon_BaseType => diff --git a/code/addons/actions/src/addArgsHelpers.test.ts b/code/addons/actions/src/addArgsHelpers.test.ts index 46318534b132..d03b9ea55d9b 100644 --- a/code/addons/actions/src/addArgsHelpers.test.ts +++ b/code/addons/actions/src/addArgsHelpers.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import type { StoryContext } from '@storybook/types'; import { inferActionsFromArgTypesRegex, addActionsFromArgTypes } from './addArgsHelpers'; diff --git a/code/addons/actions/src/runtime/__tests__/action.test.js b/code/addons/actions/src/runtime/__tests__/action.test.js index c64a2409a9b9..e0a2af63597c 100644 --- a/code/addons/actions/src/runtime/__tests__/action.test.js +++ b/code/addons/actions/src/runtime/__tests__/action.test.js @@ -1,10 +1,11 @@ +import { describe, it, expect, vi } from 'vitest'; import { addons } from '@storybook/preview-api'; import { action, configureActions } from '../..'; vi.mock('@storybook/preview-api'); const createChannel = () => { - const channel = { emit: jest.fn() }; + const channel = { emit: vi.fn() }; addons.getChannel.mockReturnValue(channel); return channel; }; diff --git a/code/addons/actions/src/runtime/__tests__/actions.test.js b/code/addons/actions/src/runtime/__tests__/actions.test.js index 88f85e818ea2..de2f9adc0352 100644 --- a/code/addons/actions/src/runtime/__tests__/actions.test.js +++ b/code/addons/actions/src/runtime/__tests__/actions.test.js @@ -1,10 +1,11 @@ +import { describe, it, expect, vi } from 'vitest'; import { addons } from '@storybook/preview-api'; import { actions } from '../..'; vi.mock('@storybook/preview-api'); const createChannel = () => { - const channel = { emit: jest.fn() }; + const channel = { emit: vi.fn() }; addons.getChannel.mockReturnValue(channel); return channel; }; diff --git a/code/addons/actions/src/runtime/__tests__/configureActions.test.js b/code/addons/actions/src/runtime/__tests__/configureActions.test.js index 7bebbe8a2524..7034904a2a5c 100644 --- a/code/addons/actions/src/runtime/__tests__/configureActions.test.js +++ b/code/addons/actions/src/runtime/__tests__/configureActions.test.js @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { config } from '../configureActions'; import { configureActions } from '../..'; diff --git a/code/addons/interactions/src/Panel.test.ts b/code/addons/interactions/src/Panel.test.ts index 869b64b8bb0d..e8cc77fcfa78 100644 --- a/code/addons/interactions/src/Panel.test.ts +++ b/code/addons/interactions/src/Panel.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { type Call, CallStates, type LogItem } from '@storybook/instrumenter'; import { getInteractions } from './Panel'; diff --git a/code/addons/jest/src/shared.test.ts b/code/addons/jest/src/shared.test.ts index ddc3a0c71b17..fd73321bf3b9 100644 --- a/code/addons/jest/src/shared.test.ts +++ b/code/addons/jest/src/shared.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, vi } from 'vitest'; import { defineJestParameter } from './shared'; describe('defineJestParameter', () => { diff --git a/code/addons/links/src/react/components/link.test.tsx b/code/addons/links/src/react/components/link.test.tsx index 30c8dd546fec..214fe24def05 100644 --- a/code/addons/links/src/react/components/link.test.tsx +++ b/code/addons/links/src/react/components/link.test.tsx @@ -1,3 +1,5 @@ +import type { Mocked } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import React from 'react'; import { addons } from '@storybook/preview-api'; import { render, screen, waitFor } from '@testing-library/react'; @@ -17,19 +19,19 @@ vi.mock('@storybook/global', () => ({ }, window: global, __STORYBOOK_STORY_STORE__: { - fromId: jest.fn(() => ({})), + fromId: vi.fn(() => ({})), }, }, })); const mockChannel = () => { return { - emit: jest.fn(), - on: jest.fn(), - once: jest.fn(), + emit: vi.fn(), + on: vi.fn(), + once: vi.fn(), }; }; -const mockAddons = addons as unknown as vi.mocked; +const mockAddons = addons as unknown as Mocked; describe('LinkTo', () => { describe('render', () => { @@ -63,8 +65,8 @@ describe('LinkTo', () => { describe('events', () => { it('should select the kind and story on click', () => { const channel = { - emit: jest.fn(), - on: jest.fn(), + emit: vi.fn(), + on: vi.fn(), } as any; mockAddons.getChannel.mockReturnValue(channel); diff --git a/code/addons/links/src/utils.test.ts b/code/addons/links/src/utils.test.ts index 5597cd0a0066..2876cc6a0ff1 100644 --- a/code/addons/links/src/utils.test.ts +++ b/code/addons/links/src/utils.test.ts @@ -1,3 +1,5 @@ +import type { Mocked } from 'vitest'; +import { describe, beforeAll, beforeEach, it, expect, vi } from 'vitest'; import { addons } from '@storybook/preview-api'; import { SELECT_STORY } from '@storybook/core-events'; @@ -11,10 +13,10 @@ vi.mock('@storybook/global', () => ({ }, })); -const mockAddons = addons as unknown as vi.mocked; +const mockAddons = addons as unknown as Mocked; describe('preview', () => { - const channel = { emit: jest.fn() }; + const channel = { emit: vi.fn() }; beforeAll(() => { mockAddons.getChannel.mockReturnValue(channel as any); }); diff --git a/code/builders/builder-vite/src/vite-config.test.ts b/code/builders/builder-vite/src/vite-config.test.ts index d849831165a8..560d5d797374 100644 --- a/code/builders/builder-vite/src/vite-config.test.ts +++ b/code/builders/builder-vite/src/vite-config.test.ts @@ -1,10 +1,11 @@ +import { describe, it, expect, vi } from 'vitest'; import type { Options, Presets } from '@storybook/types'; import { loadConfigFromFile } from 'vite'; import { commonConfig } from './vite-config'; -vi.mock('vite', () => ({ - ...jest.requireActual('vite'), - loadConfigFromFile: jest.fn(async () => ({})), +vi.mock('vite', async () => ({ + ...(await vi.importActual('vite')), + loadConfigFromFile: vi.fn(async () => ({})), })); const loadConfigFromFileMock = vi.mocked(loadConfigFromFile); diff --git a/code/frameworks/angular/src/builders/build-storybook/index.spec.ts b/code/frameworks/angular/src/builders/build-storybook/index.spec.ts index 52b328aede7b..96514d45c0cb 100644 --- a/code/frameworks/angular/src/builders/build-storybook/index.spec.ts +++ b/code/frameworks/angular/src/builders/build-storybook/index.spec.ts @@ -1,14 +1,15 @@ /* - * @jest-environment node + * @vitest-environment node */ +import { vi, describe, beforeEach, expect } from 'vitest'; import { Architect, createBuilder } from '@angular-devkit/architect'; import { TestingArchitectHost } from '@angular-devkit/architect/testing'; import { schema } from '@angular-devkit/core'; import * as path from 'path'; -const buildDevStandaloneMock = jest.fn(); -const buildStaticStandaloneMock = jest.fn(); +const buildDevStandaloneMock = vi.fn(); +const buildStaticStandaloneMock = vi.fn(); const buildMock = { buildDevStandalone: buildDevStandaloneMock, @@ -16,8 +17,8 @@ const buildMock = { withTelemetry: (name: string, options: any, fn: any) => fn(), }; -jest.doMock('@storybook/core-server', () => buildMock); -jest.doMock('@storybook/cli', () => ({ +vi.doMock('@storybook/core-server', () => buildMock); +vi.doMock('@storybook/cli', () => ({ JsPackageManagerFactory: { getPackageManager: () => ({ runPackageCommand: mockRunScript, @@ -28,9 +29,9 @@ jest.doMock('@storybook/cli', () => ({ storybook: 'x.x.x', }, })); -jest.doMock('find-up', () => ({ sync: () => './storybook/tsconfig.ts' })); +vi.doMock('find-up', () => ({ sync: () => './storybook/tsconfig.ts' })); -const mockRunScript = jest.fn(); +const mockRunScript = vi.fn(); // Randomly fails on CI. TODO: investigate why // eslint-disable-next-line jest/no-disabled-tests @@ -76,7 +77,7 @@ describe.skip('Build Storybook Builder', () => { }); afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); it('should start storybook with angularBrowserTarget', async () => { diff --git a/code/frameworks/angular/src/builders/start-storybook/index.spec.ts b/code/frameworks/angular/src/builders/start-storybook/index.spec.ts index b96d25289add..75263713ef91 100644 --- a/code/frameworks/angular/src/builders/start-storybook/index.spec.ts +++ b/code/frameworks/angular/src/builders/start-storybook/index.spec.ts @@ -1,23 +1,24 @@ /* - * @jest-environment node + * @vitest-environment node */ +import { vi, describe, expect, it, beforeEach } from 'vitest'; import { Architect, createBuilder } from '@angular-devkit/architect'; import { TestingArchitectHost } from '@angular-devkit/architect/testing'; import { schema } from '@angular-devkit/core'; import * as path from 'path'; -const buildDevStandaloneMock = jest.fn(); -const buildStaticStandaloneMock = jest.fn(); +const buildDevStandaloneMock = vi.fn(); +const buildStaticStandaloneMock = vi.fn(); const buildMock = { buildDevStandalone: buildDevStandaloneMock, buildStaticStandalone: buildStaticStandaloneMock, withTelemetry: (_: string, __: any, fn: any) => fn(), }; -jest.doMock('@storybook/core-server', () => buildMock); -jest.doMock('find-up', () => ({ sync: () => './storybook/tsconfig.ts' })); +vi.doMock('@storybook/core-server', () => buildMock); +vi.doMock('find-up', () => ({ sync: () => './storybook/tsconfig.ts' })); -const mockRunScript = jest.fn(); +const mockRunScript = vi.fn(); vi.mock('@storybook/cli', () => ({ getEnvConfig: (options: any) => options, @@ -74,7 +75,7 @@ describe.skip('Start Storybook Builder', () => { }); afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); it('should start storybook with angularBrowserTarget', async () => { diff --git a/code/frameworks/angular/src/builders/utils/run-compodoc.spec.ts b/code/frameworks/angular/src/builders/utils/run-compodoc.spec.ts index e772cd76833c..4fb842440548 100644 --- a/code/frameworks/angular/src/builders/utils/run-compodoc.spec.ts +++ b/code/frameworks/angular/src/builders/utils/run-compodoc.spec.ts @@ -1,9 +1,10 @@ +import { vi, describe, afterEach, it, expect } from 'vitest'; import { LoggerApi } from '@angular-devkit/core/src/logger'; import { take } from 'rxjs/operators'; const { runCompodoc } = require('./run-compodoc'); -const mockRunScript = jest.fn(); +const mockRunScript = vi.fn(); vi.mock('@storybook/cli', () => ({ JsPackageManagerFactory: { @@ -14,13 +15,13 @@ vi.mock('@storybook/cli', () => ({ })); const builderContextLoggerMock: LoggerApi = { - createChild: jest.fn(), - log: jest.fn(), - debug: jest.fn(), - info: jest.fn(), - warn: jest.fn(), - error: jest.fn(), - fatal: jest.fn(), + createChild: vi.fn(), + log: vi.fn(), + debug: vi.fn(), + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + fatal: vi.fn(), }; describe('runCompodoc', () => { diff --git a/code/frameworks/angular/src/client/angular-beta/RendererFactory.test.ts b/code/frameworks/angular/src/client/angular-beta/RendererFactory.test.ts index 8dc35d2c5cf1..5f5c30ad8423 100644 --- a/code/frameworks/angular/src/client/angular-beta/RendererFactory.test.ts +++ b/code/frameworks/angular/src/client/angular-beta/RendererFactory.test.ts @@ -1,3 +1,4 @@ +import { vi, describe, it, expect, beforeEach } from 'vitest'; import { Component, ɵresetJitOptions } from '@angular/core'; import { platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; @@ -21,11 +22,11 @@ describe('RendererFactory', () => { rootTargetDOMNode = global.document.getElementById('storybook-root'); rootDocstargetDOMNode = global.document.getElementById('root-docs'); (platformBrowserDynamic as any).mockImplementation(platformBrowserDynamicTesting); - jest.spyOn(console, 'log').mockImplementation(() => {}); + vi.spyOn(console, 'log').mockImplementation(() => {}); }); afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); // Necessary to avoid this error "Provided value for `preserveWhitespaces` can not be changed once it has been set." : // Source: https://github.com/angular/angular/commit/e342ffd855ffeb8af7067b42307ffa320d82177e#diff-92b125e532cc22977b46a91f068d6d7ea81fd61b772842a4a0212f1cfd875be6R28 diff --git a/code/frameworks/angular/src/client/angular-beta/utils/PropertyExtractor.test.ts b/code/frameworks/angular/src/client/angular-beta/utils/PropertyExtractor.test.ts index 45d2fb73e62f..7583f7252170 100644 --- a/code/frameworks/angular/src/client/angular-beta/utils/PropertyExtractor.test.ts +++ b/code/frameworks/angular/src/client/angular-beta/utils/PropertyExtractor.test.ts @@ -1,3 +1,4 @@ +import { vi, describe, it, expect } from 'vitest'; import { CommonModule } from '@angular/common'; import { Component, Directive, Injectable, InjectionToken, NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; @@ -45,7 +46,7 @@ const extractApplicationProviders = (metadata: NgModuleMetadata, component?: any }; describe('PropertyExtractor', () => { - jest.spyOn(console, 'warn').mockImplementation(() => {}); + vi.spyOn(console, 'warn').mockImplementation(() => {}); describe('analyzeMetadata', () => { it('should remove BrowserModule', () => { diff --git a/code/frameworks/angular/src/client/decorators.test.ts b/code/frameworks/angular/src/client/decorators.test.ts index a1fc71efe581..72a6f6836713 100644 --- a/code/frameworks/angular/src/client/decorators.test.ts +++ b/code/frameworks/angular/src/client/decorators.test.ts @@ -1,5 +1,6 @@ import { Addon_StoryContext } from '@storybook/types'; +import { vi, expect, describe, it } from 'vitest'; import { Component } from '@angular/core'; import { moduleMetadata, applicationConfig } from './decorators'; import { AngularRenderer } from './types'; @@ -19,7 +20,7 @@ const defaultContext: Addon_StoryContext = { globals: {}, hooks: {}, loaded: {}, - originalStoryFn: jest.fn(), + originalStoryFn: vi.fn(), viewMode: 'story', abortSignal: undefined, canvasElement: undefined, diff --git a/code/lib/channels/src/index.test.ts b/code/lib/channels/src/index.test.ts index 8eb319f927fc..e7fae34768c6 100644 --- a/code/lib/channels/src/index.test.ts +++ b/code/lib/channels/src/index.test.ts @@ -1,14 +1,15 @@ +import { describe, beforeEach, it, expect, vi } from 'vitest'; import type { ChannelTransport, Listener } from '.'; import { Channel } from '.'; -jest.useFakeTimers(); +vi.useFakeTimers(); describe('Channel', () => { let transport: ChannelTransport; let channel: Channel; beforeEach(() => { - transport = { setHandler: jest.fn(), send: jest.fn() }; + transport = { setHandler: vi.fn(), send: vi.fn() }; channel = new Channel({ transport }); }); @@ -43,7 +44,7 @@ describe('Channel', () => { it('should create one listener', () => { const eventName = 'event1'; - channel.addListener(eventName, jest.fn()); + channel.addListener(eventName, vi.fn()); expect(channel.listeners(eventName)?.length).toBe(1); }); }); @@ -52,7 +53,7 @@ describe('Channel', () => { it('should do the same as addListener', () => { const eventName = 'event1'; - channel.on(eventName, jest.fn()); + channel.on(eventName, vi.fn()); expect(channel.listeners(eventName)?.length).toBe(1); }); }); @@ -60,7 +61,7 @@ describe('Channel', () => { describe('method:off', () => { it('should remove listeners', () => { const eventName = 'event1'; - const fn = jest.fn(); + const fn = vi.fn(); channel.on(eventName, fn); expect(channel.listeners(eventName)?.length).toBe(1); @@ -103,7 +104,7 @@ describe('Channel', () => { channel.addListener(eventName, (...data) => { listenerOutputData = data; }); - const sendSpy = jest.fn(); + const sendSpy = vi.fn(); // @ts-expect-error (access private property for testing purposes) channel.transports.forEach((t) => { // eslint-disable-next-line no-param-reassign @@ -116,14 +117,14 @@ describe('Channel', () => { it('should use setImmediate if async is true', () => { channel = new Channel({ async: true, transport }); - channel.addListener('event1', jest.fn()); + channel.addListener('event1', vi.fn()); }); }); describe('method:eventNames', () => { it('should return a list of all registered events', () => { const eventNames = ['event1', 'event2', 'event3']; - eventNames.forEach((eventName) => channel.addListener(eventName, jest.fn())); + eventNames.forEach((eventName) => channel.addListener(eventName, vi.fn())); expect(channel.eventNames()).toEqual(eventNames); }); @@ -132,8 +133,8 @@ describe('Channel', () => { describe('method:listenerCount', () => { it('should return a list of all registered events', () => { const events = [ - { eventName: 'event1', listeners: [jest.fn(), jest.fn(), jest.fn()], listenerCount: 0 }, - { eventName: 'event2', listeners: [jest.fn()], listenerCount: 0 }, + { eventName: 'event1', listeners: [vi.fn(), vi.fn(), vi.fn()], listenerCount: 0 }, + { eventName: 'event2', listeners: [vi.fn()], listenerCount: 0 }, ]; events.forEach((event) => { event.listeners.forEach((listener) => { @@ -152,7 +153,7 @@ describe('Channel', () => { describe('method:once', () => { it('should execute a listener once and remove it afterwards', () => { const eventName = 'event1'; - channel.once(eventName, jest.fn()); + channel.once(eventName, vi.fn()); channel.emit(eventName); expect(channel.listenerCount(eventName)).toBe(0); @@ -174,7 +175,7 @@ describe('Channel', () => { it('should be removable', () => { const eventName = 'event1'; - const listenerToBeRemoved = jest.fn(); + const listenerToBeRemoved = vi.fn(); channel.once(eventName, listenerToBeRemoved); channel.removeListener(eventName, listenerToBeRemoved); @@ -185,8 +186,8 @@ describe('Channel', () => { it('should remove all listeners', () => { const eventName1 = 'event1'; const eventName2 = 'event2'; - const listeners1 = [jest.fn(), jest.fn(), jest.fn()]; - const listeners2 = [jest.fn()]; + const listeners1 = [vi.fn(), vi.fn(), vi.fn()]; + const listeners2 = [vi.fn()]; listeners1.forEach((fn) => channel.addListener(eventName1, fn)); listeners2.forEach((fn) => channel.addListener(eventName2, fn)); @@ -198,7 +199,7 @@ describe('Channel', () => { it('should remove all listeners of a certain event', () => { const eventName = 'event1'; - const listeners = [jest.fn(), jest.fn(), jest.fn()]; + const listeners = [vi.fn(), vi.fn(), vi.fn()]; listeners.forEach((fn) => channel.addListener(eventName, fn)); expect(channel.listenerCount(eventName)).toBe(listeners.length); @@ -211,8 +212,8 @@ describe('Channel', () => { describe('method:removeListener', () => { it('should remove one listener', () => { const eventName = 'event1'; - const listenerToBeRemoved = jest.fn(); - const listeners = [jest.fn(), jest.fn()]; + const listenerToBeRemoved = vi.fn(); + const listeners = [vi.fn(), vi.fn()]; const findListener = (listener: Listener) => channel.listeners(eventName)?.find((_listener) => _listener === listener); diff --git a/code/lib/cli/src/automigrate/fixes/add-react.test.ts b/code/lib/cli/src/automigrate/fixes/add-react.test.ts index 4602a30d3ecd..0a7fba10f887 100644 --- a/code/lib/cli/src/automigrate/fixes/add-react.test.ts +++ b/code/lib/cli/src/automigrate/fixes/add-react.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import type { JsPackageManager, PackageJson } from '../../js-package-manager'; import { addReact } from './add-react'; diff --git a/code/lib/cli/src/automigrate/fixes/angular-builders-multiproject.test.ts b/code/lib/cli/src/automigrate/fixes/angular-builders-multiproject.test.ts index c7d6a93cd9c6..983926cbacc2 100644 --- a/code/lib/cli/src/automigrate/fixes/angular-builders-multiproject.test.ts +++ b/code/lib/cli/src/automigrate/fixes/angular-builders-multiproject.test.ts @@ -1,3 +1,5 @@ +import type { Mock, SpyInstance } from 'vitest'; +import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import type { JsPackageManager } from '../../js-package-manager'; import { angularBuildersMultiproject } from './angular-builders-multiproject'; @@ -18,14 +20,14 @@ const checkAngularBuilders = async ({ }); }; -vi.mock('../../helpers', () => ({ - ...jest.requireActual('../../helpers'), - isNxProject: jest.fn(), +vi.mock('../../helpers', async () => ({ + ...(await vi.importActual('../../helpers')), + isNxProject: vi.fn(), })); -vi.mock('../../generators/ANGULAR/helpers', () => ({ - ...jest.requireActual('../../generators/ANGULAR/helpers'), - AngularJSON: jest.fn(), +vi.mock('../../generators/ANGULAR/helpers', async () => ({ + ...(await vi.importActual('../../generators/ANGULAR/helpers')), + AngularJSON: vi.fn(), })); describe('is Nx project', () => { @@ -36,7 +38,7 @@ describe('is Nx project', () => { } as Partial; beforeEach(() => { - (helpers.isNxProject as any as jest.SpyInstance).mockResolvedValue(true); + (helpers.isNxProject as any as SpyInstance).mockResolvedValue(true); }); it('should return null', async () => { @@ -46,15 +48,15 @@ describe('is Nx project', () => { describe('is not Nx project', () => { beforeEach(() => { - (helpers.isNxProject as any as jest.SpyInstance).mockResolvedValue(false); + (helpers.isNxProject as any as SpyInstance).mockResolvedValue(false); }); describe('angular builders', () => { - afterEach(jest.restoreAllMocks); + afterEach(vi.restoreAllMocks); describe('Angular not found', () => { const packageManager = { - getPackageVersion: jest.fn().mockResolvedValue(null), + getPackageVersion: vi.fn().mockResolvedValue(null), } as Partial; it('should return null', async () => { @@ -96,7 +98,7 @@ describe('is not Nx project', () => { describe('has one Storybook builder defined', () => { beforeEach(() => { // Mock AngularJSON.constructor - (angularHelpers.AngularJSON as vi.mock).mockImplementation(() => ({ + (angularHelpers.AngularJSON as Mock).mockImplementation(() => ({ hasStorybookBuilder: true, })); }); @@ -114,7 +116,7 @@ describe('is not Nx project', () => { describe('has one project', () => { beforeEach(() => { // Mock AngularJSON.constructor - (angularHelpers.AngularJSON as vi.mock).mockImplementation(() => ({ + (angularHelpers.AngularJSON as Mock).mockImplementation(() => ({ hasStorybookBuilder: false, projects: { project1: { root: 'project1', architect: {} }, @@ -136,7 +138,7 @@ describe('is not Nx project', () => { describe('has multiple projects without root project defined', () => { beforeEach(() => { // Mock AngularJSON.constructor - (angularHelpers.AngularJSON as vi.mock).mockImplementation(() => ({ + (angularHelpers.AngularJSON as Mock).mockImplementation(() => ({ hasStorybookBuilder: false, projects: { project1: { root: 'project1', architect: {} }, diff --git a/code/lib/cli/src/automigrate/fixes/angular-builders.test.ts b/code/lib/cli/src/automigrate/fixes/angular-builders.test.ts index 020d7d415609..613398abc06c 100644 --- a/code/lib/cli/src/automigrate/fixes/angular-builders.test.ts +++ b/code/lib/cli/src/automigrate/fixes/angular-builders.test.ts @@ -1,3 +1,5 @@ +import type { Mock, SpyInstance } from 'vitest'; +import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import { angularBuilders } from './angular-builders'; import * as helpers from '../../helpers'; @@ -20,23 +22,23 @@ const checkAngularBuilders = async ({ }); }; -vi.mock('../../helpers', () => ({ - ...jest.requireActual('../../helpers'), - isNxProject: jest.fn(), +vi.mock('../../helpers', async () => ({ + ...(await vi.importActual('../../helpers')), + isNxProject: vi.fn(), })); -vi.mock('../../generators/ANGULAR/helpers', () => ({ - ...jest.requireActual('../../generators/ANGULAR/helpers'), - AngularJSON: jest.fn(), +vi.mock('../../generators/ANGULAR/helpers', async () => ({ + ...(await vi.importActual('../../generators/ANGULAR/helpers')), + AngularJSON: vi.fn(), })); describe('is Nx project', () => { beforeEach(() => { - (helpers.isNxProject as any as jest.SpyInstance).mockResolvedValue(true); + (helpers.isNxProject as any as SpyInstance).mockResolvedValue(true); }); const packageManager = { - getPackageVersion: jest.fn().mockImplementation((packageName) => { + getPackageVersion: vi.fn().mockImplementation((packageName) => { if (packageName === '@angular/core') { return '12.0.0'; } @@ -52,15 +54,15 @@ describe('is Nx project', () => { describe('is not Nx project', () => { beforeEach(() => { - (helpers.isNxProject as any as jest.SpyInstance).mockResolvedValue(false); + (helpers.isNxProject as any as SpyInstance).mockResolvedValue(false); }); describe('angular builders', () => { - afterEach(jest.restoreAllMocks); + afterEach(vi.restoreAllMocks); describe('Angular not found', () => { const packageManager = { - getPackageVersion: jest.fn().mockReturnValue(null), + getPackageVersion: vi.fn().mockReturnValue(null), } as Partial; it('should return null', async () => { @@ -100,7 +102,7 @@ describe('is not Nx project', () => { describe('has one Storybook builder defined', () => { beforeEach(() => { // Mock AngularJSON.constructor - (angularHelpers.AngularJSON as vi.mock).mockImplementation(() => ({ + (angularHelpers.AngularJSON as Mock).mockImplementation(() => ({ hasStorybookBuilder: true, })); }); @@ -118,7 +120,7 @@ describe('is not Nx project', () => { describe('has multiple projects without root project defined', () => { beforeEach(() => { // Mock AngularJSON.constructor - (angularHelpers.AngularJSON as vi.mock).mockImplementation(() => ({ + (angularHelpers.AngularJSON as Mock).mockImplementation(() => ({ hasStorybookBuilder: false, projects: { project1: { root: 'project1', architect: {} }, @@ -141,7 +143,7 @@ describe('is not Nx project', () => { describe('has one project', () => { beforeEach(() => { // Mock AngularJSON.constructor - (angularHelpers.AngularJSON as vi.mock).mockImplementation(() => ({ + (angularHelpers.AngularJSON as Mock).mockImplementation(() => ({ hasStorybookBuilder: false, projects: { project1: { root: 'project1', architect: {} }, diff --git a/code/lib/cli/src/automigrate/fixes/autodocs-true.test.ts b/code/lib/cli/src/automigrate/fixes/autodocs-true.test.ts index c21de1bd9727..131e7b82c25e 100644 --- a/code/lib/cli/src/automigrate/fixes/autodocs-true.test.ts +++ b/code/lib/cli/src/automigrate/fixes/autodocs-true.test.ts @@ -1,3 +1,4 @@ +import { describe, afterEach, it, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import type { PackageJson } from '../../js-package-manager'; import { makePackageManager } from '../helpers/testing-helpers'; @@ -18,7 +19,7 @@ const checkAutodocs = async ({ }; describe('autodocs-true fix', () => { - afterEach(jest.restoreAllMocks); + afterEach(vi.restoreAllMocks); it('should skip when docs.autodocs is already defined', async () => { await expect(checkAutodocs({ main: { docs: { autodocs: 'tag' } } })).resolves.toBeFalsy(); diff --git a/code/lib/cli/src/automigrate/fixes/bare-mdx-stories-glob.test.ts b/code/lib/cli/src/automigrate/fixes/bare-mdx-stories-glob.test.ts index f9cfaa3662ce..705e8a7c1d1c 100644 --- a/code/lib/cli/src/automigrate/fixes/bare-mdx-stories-glob.test.ts +++ b/code/lib/cli/src/automigrate/fixes/bare-mdx-stories-glob.test.ts @@ -1,4 +1,4 @@ -import { describe, test, it, expect } from 'vitest'; +import { describe, afterEach, it, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import type { PackageJson } from '../../js-package-manager'; @@ -24,7 +24,7 @@ const checkBareMdxStoriesGlob = async ({ }; describe('bare-mdx fix', () => { - afterEach(jest.restoreAllMocks); + afterEach(vi.restoreAllMocks); describe('should no-op', () => { it('in SB < v7.0.0', async () => { diff --git a/code/lib/cli/src/automigrate/fixes/builder-vite.test.ts b/code/lib/cli/src/automigrate/fixes/builder-vite.test.ts index 20b8f935c0e7..75c43984ab9b 100644 --- a/code/lib/cli/src/automigrate/fixes/builder-vite.test.ts +++ b/code/lib/cli/src/automigrate/fixes/builder-vite.test.ts @@ -1,3 +1,4 @@ +import { describe, afterEach, it, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import { makePackageManager } from '../helpers/testing-helpers'; import type { PackageJson } from '../../js-package-manager'; @@ -18,7 +19,7 @@ const checkBuilderVite = async ({ }; describe('builder-vite fix', () => { - afterEach(jest.restoreAllMocks); + afterEach(vi.restoreAllMocks); describe('storybook-builder-vite', () => { it('using storybook-builder-vite', async () => { diff --git a/code/lib/cli/src/automigrate/fixes/cra5.test.ts b/code/lib/cli/src/automigrate/fixes/cra5.test.ts index 15ef6485851d..30970c55a721 100644 --- a/code/lib/cli/src/automigrate/fixes/cra5.test.ts +++ b/code/lib/cli/src/automigrate/fixes/cra5.test.ts @@ -1,3 +1,4 @@ +import { describe, afterEach, it, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import type { JsPackageManager } from '../../js-package-manager'; import { cra5 } from './cra5'; @@ -19,12 +20,12 @@ const checkCra5 = async ({ }; describe('cra5 fix', () => { - afterEach(jest.restoreAllMocks); + afterEach(vi.restoreAllMocks); describe('sb < 6.3', () => { describe('cra5 dependency', () => { const packageManager = { - getPackageVersion: jest.fn().mockResolvedValue('5.0.0'), + getPackageVersion: vi.fn().mockResolvedValue('5.0.0'), } as Partial; it('should fail', async () => { @@ -38,7 +39,7 @@ describe('cra5 fix', () => { }); describe('no cra5 dependency', () => { const packageManager = { - getPackageVersion: jest.fn().mockResolvedValue(null), + getPackageVersion: vi.fn().mockResolvedValue(null), } as Partial; it('should no-op', async () => { diff --git a/code/lib/cli/src/automigrate/fixes/eslint-plugin.test.ts b/code/lib/cli/src/automigrate/fixes/eslint-plugin.test.ts index af4e35d77e66..cc4b7b2588c3 100644 --- a/code/lib/cli/src/automigrate/fixes/eslint-plugin.test.ts +++ b/code/lib/cli/src/automigrate/fixes/eslint-plugin.test.ts @@ -1,4 +1,5 @@ /* eslint-disable no-underscore-dangle */ +import { describe, it, expect, vi } from 'vitest'; import { dedent } from 'ts-dedent'; import type { PackageJson } from '../../js-package-manager'; import { eslintPlugin } from './eslint-plugin'; @@ -75,7 +76,7 @@ describe('eslint-plugin fix', () => { describe('should no-op and warn when', () => { it('.eslintrc is not found', async () => { - const loggerSpy = jest.spyOn(console, 'warn').mockImplementationOnce(jest.fn); + const loggerSpy = vi.spyOn(console, 'warn').mockImplementationOnce(vi.fn); const result = await checkEslint({ packageJson, hasEslint: false, diff --git a/code/lib/cli/src/automigrate/fixes/incompatible-addons.test.ts b/code/lib/cli/src/automigrate/fixes/incompatible-addons.test.ts index 5d4423a76b31..a50724876e4f 100644 --- a/code/lib/cli/src/automigrate/fixes/incompatible-addons.test.ts +++ b/code/lib/cli/src/automigrate/fixes/incompatible-addons.test.ts @@ -1,4 +1,4 @@ -import { describe, test, it, expect } from 'vitest'; +import { describe, afterEach, it, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import { incompatibleAddons } from './incompatible-addons'; @@ -22,7 +22,7 @@ const check = async ({ }; describe('incompatible-addons fix', () => { - afterEach(jest.restoreAllMocks); + afterEach(vi.restoreAllMocks); it('should show incompatible addons', async () => { await expect( diff --git a/code/lib/cli/src/automigrate/fixes/mdx-1-to-2.test.ts b/code/lib/cli/src/automigrate/fixes/mdx-1-to-2.test.ts index e5c61f91eba0..9560a570d391 100644 --- a/code/lib/cli/src/automigrate/fixes/mdx-1-to-2.test.ts +++ b/code/lib/cli/src/automigrate/fixes/mdx-1-to-2.test.ts @@ -1,4 +1,4 @@ -import { describe, test, it, expect } from 'vitest'; +import { it, expect } from 'vitest'; import { dedent } from 'ts-dedent'; import { fixMdxStyleTags, fixMdxComments } from './mdx-1-to-2'; diff --git a/code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts b/code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts index c1c3022782d9..52020fc4f793 100644 --- a/code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts +++ b/code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts @@ -1,9 +1,10 @@ +import { describe, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import { mdxgfm } from './mdx-gfm'; vi.mock('globby', () => ({ __esModule: true, - default: jest.fn().mockResolvedValue(['a/fake/file.mdx']), + default: vi.fn().mockResolvedValue(['a/fake/file.mdx']), })); const check = async ({ diff --git a/code/lib/cli/src/automigrate/fixes/missing-babelrc.test.ts b/code/lib/cli/src/automigrate/fixes/missing-babelrc.test.ts index 9dddb876080e..af05fba06138 100644 --- a/code/lib/cli/src/automigrate/fixes/missing-babelrc.test.ts +++ b/code/lib/cli/src/automigrate/fixes/missing-babelrc.test.ts @@ -1,5 +1,5 @@ /* eslint-disable no-underscore-dangle */ -import { describe, test, it, expect } from 'vitest'; +import { describe, afterEach, it, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import { missingBabelRc } from './missing-babelrc'; @@ -66,7 +66,7 @@ const packageManagerWithBabelField = { } as Partial; describe('missing-babelrc fix', () => { - afterEach(jest.restoreAllMocks); + afterEach(vi.restoreAllMocks); it('skips when storybook version < 7.0.0', async () => { await expect(check({ storybookVersion: '6.3.2' })).resolves.toBeNull(); diff --git a/code/lib/cli/src/automigrate/fixes/new-frameworks.test.ts b/code/lib/cli/src/automigrate/fixes/new-frameworks.test.ts index 4f74b87140b2..5a918f01fdc2 100644 --- a/code/lib/cli/src/automigrate/fixes/new-frameworks.test.ts +++ b/code/lib/cli/src/automigrate/fixes/new-frameworks.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import * as findUp from 'find-up'; import * as rendererHelpers from '../helpers/detectRenderer'; @@ -5,8 +6,8 @@ import { newFrameworks } from './new-frameworks'; import type { JsPackageManager } from '../../js-package-manager'; vi.mock('find-up'); -vi.mock('../helpers/detectRenderer', () => ({ - detectRenderer: jest.fn(jest.requireActual('../helpers/detectRenderer').detectRenderer), +vi.mock('../helpers/detectRenderer', async () => ({ + detectRenderer: vi.fn((await vi.importActual('../helpers/detectRenderer')).detectRenderer), })); const checkNewFrameworks = async ({ @@ -323,7 +324,7 @@ describe('new-frameworks fix', () => { it('should prompt when there are multiple renderer packages', async () => { // there should be a prompt, which we mock the response - const detectRendererSpy = jest.spyOn(rendererHelpers, 'detectRenderer'); + const detectRendererSpy = vi.spyOn(rendererHelpers, 'detectRenderer'); detectRendererSpy.mockReturnValueOnce(Promise.resolve('@storybook/react')); const packageManager = getPackageManager({ @@ -357,7 +358,7 @@ describe('new-frameworks fix', () => { }); // project contains vite.config.js - jest.spyOn(findUp, 'default').mockReturnValueOnce(Promise.resolve('vite.config.js')); + vi.spyOn(findUp, 'default').mockReturnValueOnce(Promise.resolve('vite.config.js')); await expect( checkNewFrameworks({ packageManager, @@ -372,9 +373,9 @@ describe('new-frameworks fix', () => { }); it('should migrate to @storybook/web-components-webpack5 in a monorepo that contains the vite builder, but main.js has webpack5 in builder field', async () => { - jest - .spyOn(rendererHelpers, 'detectRenderer') - .mockReturnValueOnce(Promise.resolve('@storybook/web-components')); + vi.spyOn(rendererHelpers, 'detectRenderer').mockReturnValueOnce( + Promise.resolve('@storybook/web-components') + ); const packageManager = getPackageManager({ '@storybook/addon-essentials': '7.0.0-beta.48', @@ -430,7 +431,7 @@ describe('new-frameworks fix', () => { }); it('skips if project already has @storybook/nextjs set up', async () => { - jest.spyOn(findUp, 'default').mockReturnValueOnce(Promise.resolve('next.config.js')); + vi.spyOn(findUp, 'default').mockReturnValueOnce(Promise.resolve('next.config.js')); const packageManager = getPackageManager({ '@storybook/react': '7.0.0', @@ -452,7 +453,7 @@ describe('new-frameworks fix', () => { next: '12.0.0', }); - jest.spyOn(findUp, 'default').mockReturnValueOnce(Promise.resolve('next.config.js')); + vi.spyOn(findUp, 'default').mockReturnValueOnce(Promise.resolve('next.config.js')); await expect( checkNewFrameworks({ packageManager, @@ -470,7 +471,7 @@ describe('new-frameworks fix', () => { }); it('should remove legacy addons', async () => { - jest.spyOn(findUp, 'default').mockReturnValueOnce(Promise.resolve('next.config.js')); + vi.spyOn(findUp, 'default').mockReturnValueOnce(Promise.resolve('next.config.js')); const packageManager = getPackageManager({ '@storybook/react': '7.0.0-alpha.0', '@storybook/react-webpack5': '7.0.0-alpha.0', @@ -500,7 +501,7 @@ describe('new-frameworks fix', () => { }); it('should move storybook-addon-next options and reactOptions to frameworkOptions', async () => { - jest.spyOn(findUp, 'default').mockReturnValueOnce(Promise.resolve('next.config.js')); + vi.spyOn(findUp, 'default').mockReturnValueOnce(Promise.resolve('next.config.js')); const packageManager = getPackageManager({ '@storybook/react': '7.0.0-alpha.0', @@ -549,7 +550,7 @@ describe('new-frameworks fix', () => { }); it('should migrate to @storybook/react-vite in Next.js project that uses vite builder', async () => { - jest.spyOn(findUp, 'default').mockReturnValueOnce(Promise.resolve('next.config.js')); + vi.spyOn(findUp, 'default').mockReturnValueOnce(Promise.resolve('next.config.js')); const packageManager = getPackageManager({ '@storybook/react': '7.0.0-alpha.0', diff --git a/code/lib/cli/src/automigrate/fixes/nodejs-requirement.test.ts b/code/lib/cli/src/automigrate/fixes/nodejs-requirement.test.ts index 6be35b06c1b0..366d1fe3986c 100644 --- a/code/lib/cli/src/automigrate/fixes/nodejs-requirement.test.ts +++ b/code/lib/cli/src/automigrate/fixes/nodejs-requirement.test.ts @@ -1,4 +1,4 @@ -import { describe, test, it, expect } from 'vitest'; +import { describe, afterAll, it, expect, vi } from 'vitest'; import { nodeJsRequirement } from './nodejs-requirement'; @@ -25,7 +25,7 @@ const mockNodeVersion = (version: string) => { describe('nodejs-requirement fix', () => { afterAll(() => { mockNodeVersion(originalNodeVersion); - jest.restoreAllMocks(); + vi.restoreAllMocks(); }); it('skips when sb <= 7.0.0', async () => { diff --git a/code/lib/cli/src/automigrate/fixes/sb-binary.test.ts b/code/lib/cli/src/automigrate/fixes/sb-binary.test.ts index c0326a9620fe..c709e448b746 100644 --- a/code/lib/cli/src/automigrate/fixes/sb-binary.test.ts +++ b/code/lib/cli/src/automigrate/fixes/sb-binary.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import type { JsPackageManager } from '../../js-package-manager'; import { sbBinary } from './sb-binary'; diff --git a/code/lib/cli/src/automigrate/fixes/sb-scripts.test.ts b/code/lib/cli/src/automigrate/fixes/sb-scripts.test.ts index 036cb18ba098..e5208b397211 100644 --- a/code/lib/cli/src/automigrate/fixes/sb-scripts.test.ts +++ b/code/lib/cli/src/automigrate/fixes/sb-scripts.test.ts @@ -1,3 +1,4 @@ +import { describe, afterEach, it, expect, vi } from 'vitest'; import type { JsPackageManager } from '../../js-package-manager'; import { getStorybookScripts, sbScripts } from './sb-scripts'; @@ -16,7 +17,7 @@ const checkSbScripts = async ({ }; describe('getStorybookScripts', () => { - afterEach(jest.restoreAllMocks); + afterEach(vi.restoreAllMocks); it('detects default storybook scripts', () => { expect( getStorybookScripts({ diff --git a/code/lib/cli/src/automigrate/fixes/vue3.test.ts b/code/lib/cli/src/automigrate/fixes/vue3.test.ts index 6d7f61d77186..790a02f64803 100644 --- a/code/lib/cli/src/automigrate/fixes/vue3.test.ts +++ b/code/lib/cli/src/automigrate/fixes/vue3.test.ts @@ -1,3 +1,4 @@ +import { describe, afterEach, it, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import type { JsPackageManager } from '../../js-package-manager'; import { vue3 } from './vue3'; @@ -20,7 +21,7 @@ const checkVue3 = async ({ }; describe('vue3 fix', () => { - afterEach(jest.restoreAllMocks); + afterEach(vi.restoreAllMocks); describe('sb < 6.3', () => { describe('vue3 dependency', () => { diff --git a/code/lib/cli/src/automigrate/fixes/webpack5.test.ts b/code/lib/cli/src/automigrate/fixes/webpack5.test.ts index db03eeb57a08..9cd2bbd20677 100644 --- a/code/lib/cli/src/automigrate/fixes/webpack5.test.ts +++ b/code/lib/cli/src/automigrate/fixes/webpack5.test.ts @@ -1,3 +1,4 @@ +import { describe, afterEach, it, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import type { JsPackageManager } from '../../js-package-manager'; import { webpack5 } from './webpack5'; @@ -21,7 +22,7 @@ const checkWebpack5 = async ({ }; describe('webpack5 fix', () => { - afterEach(jest.restoreAllMocks); + afterEach(vi.restoreAllMocks); describe('sb < 6.3', () => { describe('webpack5 dependency', () => { diff --git a/code/lib/cli/src/automigrate/fixes/wrap-require.test.ts b/code/lib/cli/src/automigrate/fixes/wrap-require.test.ts index fb917deda7b4..092ef9386105 100644 --- a/code/lib/cli/src/automigrate/fixes/wrap-require.test.ts +++ b/code/lib/cli/src/automigrate/fixes/wrap-require.test.ts @@ -1,15 +1,17 @@ +import type { SpyInstance } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import { wrapRequire } from './wrap-require'; import * as detect from '../../detect'; -vi.mock('../../detect', () => ({ - ...jest.requireActual('../../detect'), - detectPnp: jest.fn(), +vi.mock('../../detect', async () => ({ + ...(await vi.importActual('../../detect')), + detectPnp: vi.fn(), })); describe('wrapRequire', () => { describe('check', () => { it('should return null if not in a monorepo and pnp is not enabled', async () => { - (detect.detectPnp as any as jest.SpyInstance).mockResolvedValue(false); + (detect.detectPnp as any as SpyInstance).mockResolvedValue(false); const check = wrapRequire.check({ packageManager: { @@ -23,7 +25,7 @@ describe('wrapRequire', () => { }); it('should return the configuration object if in a pnp environment', async () => { - (detect.detectPnp as any as jest.SpyInstance).mockResolvedValue(true); + (detect.detectPnp as any as SpyInstance).mockResolvedValue(true); const check = wrapRequire.check({ packageManager: { @@ -42,7 +44,7 @@ describe('wrapRequire', () => { }); it('should return the configuration object if in a monorepo environment', async () => { - (detect.detectPnp as any as jest.SpyInstance).mockResolvedValue(false); + (detect.detectPnp as any as SpyInstance).mockResolvedValue(false); const check = wrapRequire.check({ packageManager: { @@ -61,7 +63,7 @@ describe('wrapRequire', () => { }); it('should return null, if all fields have the require wrapper', async () => { - (detect.detectPnp as any as jest.SpyInstance).mockResolvedValue(true); + (detect.detectPnp as any as SpyInstance).mockResolvedValue(true); const check = wrapRequire.check({ packageManager: { diff --git a/code/lib/cli/src/automigrate/helpers/checkWebpack5Builder.test.ts b/code/lib/cli/src/automigrate/helpers/checkWebpack5Builder.test.ts index a68f5fd0c130..b0066044e0af 100644 --- a/code/lib/cli/src/automigrate/helpers/checkWebpack5Builder.test.ts +++ b/code/lib/cli/src/automigrate/helpers/checkWebpack5Builder.test.ts @@ -1,3 +1,4 @@ +import { describe, beforeEach, afterEach, it, expect, vi, SpyInstance } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import { checkWebpack5Builder } from './checkWebpack5Builder'; import { getBuilderPackageName } from './mainConfigFile'; @@ -11,12 +12,12 @@ const mockMainConfig: StorybookConfig = { vi.mock('./mainConfigFile'); describe('checkWebpack5Builder', () => { - let loggerWarnSpy: jest.SpyInstance; - let loggerInfoSpy: jest.SpyInstance; + let loggerWarnSpy: SpyInstance; + let loggerInfoSpy: SpyInstance; beforeEach(() => { - loggerWarnSpy = jest.spyOn(console, 'warn').mockImplementation(); - loggerInfoSpy = jest.spyOn(console, 'info').mockImplementation(); + loggerWarnSpy = vi.spyOn(console, 'warn').mockImplementation(); + loggerInfoSpy = vi.spyOn(console, 'info').mockImplementation(); }); afterEach(() => { diff --git a/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts b/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts index e3d23ebfb853..ec07cc7af35a 100644 --- a/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts +++ b/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts @@ -1,10 +1,11 @@ +import { describe, expect, vi } from 'vitest'; import { getMigrationSummary } from './getMigrationSummary'; import { FixStatus } from '../types'; import type { InstallationMetadata } from '../../js-package-manager/types'; vi.mock('boxen', () => // eslint-disable-next-line no-control-regex - jest.fn((str, { title = '' }) => `${title}\n\n${str.replace(/\x1b\[[0-9;]*[mG]/g, '')}`) + vi.fn((str, { title = '' }) => `${title}\n\n${str.replace(/\x1b\[[0-9;]*[mG]/g, '')}`) ); describe('getMigrationSummary', () => { diff --git a/code/lib/cli/src/automigrate/helpers/mainConfigFile.test.ts b/code/lib/cli/src/automigrate/helpers/mainConfigFile.test.ts index f31ca41f0a0f..7fd8f7d0a845 100644 --- a/code/lib/cli/src/automigrate/helpers/mainConfigFile.test.ts +++ b/code/lib/cli/src/automigrate/helpers/mainConfigFile.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { getBuilderPackageName, getFrameworkPackageName, diff --git a/code/lib/cli/src/automigrate/helpers/new-frameworks-utils.test.ts b/code/lib/cli/src/automigrate/helpers/new-frameworks-utils.test.ts index 3c5e0a8ecbfa..d4395cee5c0f 100644 --- a/code/lib/cli/src/automigrate/helpers/new-frameworks-utils.test.ts +++ b/code/lib/cli/src/automigrate/helpers/new-frameworks-utils.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import * as findUp from 'find-up'; import { detectBuilderInfo as _getBuilderInfo, @@ -166,7 +167,7 @@ describe('getBuilderInfo', () => { }); it('when main.js has legacy renderer as framework, it should infer vite info from vite config file', async () => { - const findUpSpy = jest + const findUpSpy = vi .spyOn(findUp, 'default') .mockReturnValueOnce(Promise.resolve('vite.config.js')); await expect(getBuilderInfo({ mainConfig: { framework: 'react' } })).resolves.toEqual({ @@ -177,7 +178,7 @@ describe('getBuilderInfo', () => { }); it('when main.js has legacy renderer as framework, it should infer webpack info from webpack config file', async () => { - const findUpSpy = jest + const findUpSpy = vi .spyOn(findUp, 'default') .mockReturnValueOnce(Promise.resolve(undefined)) .mockReturnValueOnce(Promise.resolve('webpack.config.js')); @@ -189,7 +190,7 @@ describe('getBuilderInfo', () => { }); it('when main.js has no builder or framework, it should infer vite info from vite config file', async () => { - const findUpSpy = jest + const findUpSpy = vi .spyOn(findUp, 'default') .mockReturnValueOnce(Promise.resolve('vite.config.js')); await expect(getBuilderInfo({ mainConfig: {} })).resolves.toEqual({ @@ -200,7 +201,7 @@ describe('getBuilderInfo', () => { }); it('when main.js has no builder or framework, it should infer webpack info from webpack config file', async () => { - const findUpSpy = jest + const findUpSpy = vi .spyOn(findUp, 'default') .mockReturnValueOnce(Promise.resolve(undefined)) .mockReturnValueOnce(Promise.resolve('webpack.config.js')); @@ -212,7 +213,7 @@ describe('getBuilderInfo', () => { }); it('when main.js has no builder or framework, and there is no vite or webpack config, infer vite from dependencies', async () => { - const findUpSpy = jest.spyOn(findUp, 'default').mockReturnValue(Promise.resolve(undefined)); + const findUpSpy = vi.spyOn(findUp, 'default').mockReturnValue(Promise.resolve(undefined)); await expect( getBuilderInfo({ mainConfig: {}, @@ -233,7 +234,7 @@ describe('getBuilderInfo', () => { }); it('when main.js has no builder or framework, and there is no vite or webpack config, infer webpack from dependencies', async () => { - const findUpSpy = jest.spyOn(findUp, 'default').mockReturnValue(Promise.resolve(undefined)); + const findUpSpy = vi.spyOn(findUp, 'default').mockReturnValue(Promise.resolve(undefined)); await expect( getBuilderInfo({ mainConfig: {}, diff --git a/code/lib/cli/src/automigrate/helpers/testing-helpers.ts b/code/lib/cli/src/automigrate/helpers/testing-helpers.ts index ee473277fe48..e6bc83bb09a4 100644 --- a/code/lib/cli/src/automigrate/helpers/testing-helpers.ts +++ b/code/lib/cli/src/automigrate/helpers/testing-helpers.ts @@ -1,13 +1,14 @@ +import { vi } from 'vitest'; import type { JsPackageManager, PackageJson } from '../../js-package-manager'; -vi.mock('./mainConfigFile', () => ({ - ...jest.requireActual('./mainConfigFile'), - getStorybookData: jest.fn(), +vi.mock('./mainConfigFile', async () => ({ + ...(await vi.importActual('./mainConfigFile')), + getStorybookData: vi.fn(), })); -vi.mock('@storybook/core-common', () => ({ - ...jest.requireActual('@storybook/core-common'), - loadMainConfig: jest.fn(), +vi.mock('@storybook/core-common', async () => ({ + ...(await vi.importActual('@storybook/core-common')), + loadMainConfig: vi.fn(), })); export const makePackageManager = (packageJson: PackageJson) => { diff --git a/code/lib/cli/src/detect.test.ts b/code/lib/cli/src/detect.test.ts index e656c4255416..6c822e4e0aaa 100644 --- a/code/lib/cli/src/detect.test.ts +++ b/code/lib/cli/src/detect.test.ts @@ -1,3 +1,5 @@ +import type { Mock } from 'vitest'; +import { describe, afterEach, it, expect, vi } from 'vitest'; import * as fs from 'fs'; import { logger } from '@storybook/node-logger'; import { detect, detectFrameworkPreset, detectLanguage } from './detect'; @@ -5,23 +7,23 @@ import { ProjectType, SupportedLanguage } from './project_types'; import type { JsPackageManager, PackageJsonWithMaybeDeps } from './js-package-manager'; vi.mock('./helpers', () => ({ - isNxProject: jest.fn(), + isNxProject: vi.fn(), })); vi.mock('fs', () => ({ - existsSync: jest.fn(), - stat: jest.fn(), - lstat: jest.fn(), - access: jest.fn(), + existsSync: vi.fn(), + stat: vi.fn(), + lstat: vi.fn(), + access: vi.fn(), })); vi.mock('fs-extra', () => ({ - pathExistsSync: jest.fn(() => true), + pathExistsSync: vi.fn(() => true), })); vi.mock('path', () => ({ // make it return just the second path, for easier testing - join: jest.fn((_, p) => p), + join: vi.fn((_, p) => p), })); vi.mock('@storybook/node-logger'); @@ -244,7 +246,7 @@ describe('Detect', () => { }); it(`should return language javascript if the TS dependency is present but less than minimum supported`, async () => { - (logger.warn as vi.mockedFunction).mockClear(); + (logger.warn as Mock).mockClear(); const packageManager = { retrievePackageJson: () => @@ -433,12 +435,12 @@ describe('Detect', () => { describe('detectFrameworkPreset should return', () => { afterEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); MOCK_FRAMEWORK_FILES.forEach((structure) => { it(`${structure.name}`, () => { - (fs.existsSync as vi.mock).mockImplementation((filePath) => { + (fs.existsSync as Mock).mockImplementation((filePath) => { return Object.keys(structure.files).includes(filePath); }); @@ -471,7 +473,7 @@ describe('Detect', () => { '/node_modules/.bin/react-scripts': 'file content', }; - (fs.existsSync as vi.mock).mockImplementation((filePath) => { + (fs.existsSync as Mock).mockImplementation((filePath) => { return Object.keys(forkedReactScriptsConfig).includes(filePath); }); diff --git a/code/lib/cli/src/generators/configure.test.ts b/code/lib/cli/src/generators/configure.test.ts index 981b38f63c8d..5b591255109a 100644 --- a/code/lib/cli/src/generators/configure.test.ts +++ b/code/lib/cli/src/generators/configure.test.ts @@ -1,3 +1,5 @@ +import type { Mock } from 'vitest'; +import { describe, beforeAll, expect, vi } from 'vitest'; import fse from 'fs-extra'; import dedent from 'ts-dedent'; import { SupportedLanguage } from '../project_types'; @@ -7,7 +9,7 @@ vi.mock('fs-extra'); describe('configureMain', () => { beforeAll(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); test('should generate main.js', async () => { @@ -21,7 +23,7 @@ describe('configureMain', () => { }, }); - const { calls } = (fse.writeFile as unknown as vi.mock).mock; + const { calls } = (fse.writeFile as unknown as Mock).mock; const [mainConfigPath, mainConfigContent] = calls[0]; expect(mainConfigPath).toEqual('./.storybook/main.js'); @@ -50,7 +52,7 @@ describe('configureMain', () => { }, }); - const { calls } = (fse.writeFile as unknown as vi.mock).mock; + const { calls } = (fse.writeFile as unknown as Mock).mock; const [mainConfigPath, mainConfigContent] = calls[0]; expect(mainConfigPath).toEqual('./.storybook/main.ts'); @@ -85,7 +87,7 @@ describe('configureMain', () => { }, }); - const { calls } = (fse.writeFile as unknown as vi.mock).mock; + const { calls } = (fse.writeFile as unknown as Mock).mock; const [mainConfigPath, mainConfigContent] = calls[0]; expect(mainConfigPath).toEqual('./.storybook/main.js'); @@ -119,7 +121,7 @@ describe('configurePreview', () => { rendererId: 'react', }); - const { calls } = (fse.writeFile as unknown as vi.mock).mock; + const { calls } = (fse.writeFile as unknown as Mock).mock; const [previewConfigPath, previewConfigContent] = calls[0]; expect(previewConfigPath).toEqual('./.storybook/preview.js'); @@ -149,7 +151,7 @@ describe('configurePreview', () => { rendererId: 'react', }); - const { calls } = (fse.writeFile as unknown as vi.mock).mock; + const { calls } = (fse.writeFile as unknown as Mock).mock; const [previewConfigPath, previewConfigContent] = calls[0]; expect(previewConfigPath).toEqual('./.storybook/preview.ts'); @@ -174,7 +176,7 @@ describe('configurePreview', () => { }); test('should not do anything if the framework template already included a preview', async () => { - (fse.pathExists as unknown as vi.mock).mockReturnValueOnce(true); + (fse.pathExists as unknown as Mock).mockReturnValueOnce(true); await configurePreview({ language: SupportedLanguage.TYPESCRIPT_4_9, storybookConfigFolder: '.storybook', @@ -197,7 +199,7 @@ describe('configurePreview', () => { }, }); - const { calls } = (fse.writeFile as unknown as vi.mock).mock; + const { calls } = (fse.writeFile as unknown as Mock).mock; const [previewConfigPath, previewConfigContent] = calls[0]; expect(previewConfigPath).toEqual('./.storybook/preview.ts'); diff --git a/code/lib/cli/src/helpers.test.ts b/code/lib/cli/src/helpers.test.ts index 5ebc2f385e39..0f77cb619a6c 100644 --- a/code/lib/cli/src/helpers.test.ts +++ b/code/lib/cli/src/helpers.test.ts @@ -1,3 +1,5 @@ +import type { Mock } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import fs from 'fs'; import fse from 'fs-extra'; @@ -7,7 +9,7 @@ import type { SupportedRenderers } from './project_types'; import { SupportedLanguage } from './project_types'; vi.mock('fs', () => ({ - existsSync: jest.fn(), + existsSync: vi.fn(), })); vi.mock('./dirs', () => ({ getRendererDir: (_: JsPackageManager, renderer: string) => `@storybook/${renderer}`, @@ -15,24 +17,24 @@ vi.mock('./dirs', () => ({ })); vi.mock('fs-extra', () => ({ - copySync: jest.fn(() => ({})), - copy: jest.fn(() => ({})), - ensureDir: jest.fn(() => {}), - existsSync: jest.fn(), - pathExists: jest.fn(), - readFile: jest.fn(() => ''), - writeFile: jest.fn(), + copySync: vi.fn(() => ({})), + copy: vi.fn(() => ({})), + ensureDir: vi.fn(() => {}), + existsSync: vi.fn(), + pathExists: vi.fn(), + readFile: vi.fn(() => ''), + writeFile: vi.fn(), })); vi.mock('find-up', () => ({ - sync: jest.fn(), + sync: vi.fn(), })); -vi.mock('path', () => { - const path = jest.requireActual('path'); +vi.mock('path', async () => { + const path = await vi.importActual('path'); return { // make it return just the second path, for easier testing - resolve: jest.fn((_, p) => p), + resolve: vi.fn((_, p) => p), dirname: path.dirname, join: path.join, }; @@ -44,23 +46,23 @@ const packageManagerMock = { describe('Helpers', () => { beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe('copyTemplate', () => { it(`should copy template files when directory is present`, () => { const csfDirectory = `template-csf/`; - (fs.existsSync as vi.mock).mockImplementation((filePath) => { + (fs.existsSync as Mock).mockImplementation((filePath) => { return true; }); helpers.copyTemplate(''); - const copySyncSpy = jest.spyOn(fse, 'copySync'); + const copySyncSpy = vi.spyOn(fse, 'copySync'); expect(copySyncSpy).toHaveBeenCalledWith(csfDirectory, expect.anything(), expect.anything()); }); it(`should throw an error if template directory cannot be found`, () => { - (fs.existsSync as vi.mock).mockImplementation((filePath) => { + (fs.existsSync as Mock).mockImplementation((filePath) => { return false; }); @@ -86,7 +88,7 @@ describe('Helpers', () => { const componentsDirectory = exists.map( (folder: string) => `@storybook/react/template/cli/${folder}` ); - (fse.pathExists as vi.mock).mockImplementation( + (fse.pathExists as Mock).mockImplementation( (filePath) => componentsDirectory.includes(filePath) || filePath === '@storybook/react/template/cli' ); @@ -96,7 +98,7 @@ describe('Helpers', () => { packageManager: packageManagerMock, }); - const copySpy = jest.spyOn(fse, 'copy'); + const copySpy = vi.spyOn(fse, 'copy'); expect(copySpy).toHaveBeenNthCalledWith( 1, '@storybook/cli/rendererAssets/common', @@ -110,7 +112,7 @@ describe('Helpers', () => { ); it(`should copy to src folder when exists`, async () => { - (fse.pathExists as vi.mock).mockImplementation((filePath) => { + (fse.pathExists as Mock).mockImplementation((filePath) => { return filePath === '@storybook/react/template/cli' || filePath === './src'; }); await helpers.copyTemplateFiles({ @@ -122,7 +124,7 @@ describe('Helpers', () => { }); it(`should copy to root folder when src doesn't exist`, async () => { - (fse.pathExists as vi.mock).mockImplementation((filePath) => { + (fse.pathExists as Mock).mockImplementation((filePath) => { return filePath === '@storybook/react/template/cli'; }); await helpers.copyTemplateFiles({ diff --git a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts index 8bd9ffa218c1..c0e6b6f93ad9 100644 --- a/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts +++ b/code/lib/cli/src/js-package-manager/JsPackageManagerFactory.test.ts @@ -1,3 +1,5 @@ +import type { Mock } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import { sync as spawnSync } from 'cross-spawn'; import { sync as findUpSync } from 'find-up'; import path from 'path'; @@ -8,10 +10,10 @@ import { Yarn1Proxy } from './Yarn1Proxy'; import { Yarn2Proxy } from './Yarn2Proxy'; vi.mock('cross-spawn'); -const spawnSyncMock = spawnSync as vi.mock; +const spawnSyncMock = spawnSync as Mock; vi.mock('find-up'); -const findUpSyncMock = findUpSync as unknown as vi.mock; +const findUpSyncMock = findUpSync as unknown as Mock; describe('JsPackageManagerFactory', () => { beforeEach(() => { @@ -104,9 +106,9 @@ describe('JsPackageManagerFactory', () => { expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(PNPMProxy); }); - it('when a pnpm-lock.yaml file is closer than a yarn.lock', () => { + it('when a pnpm-lock.yaml file is closer than a yarn.lock', async () => { // Allow find-up to work as normal, we'll set the cwd to our fixture package - findUpSyncMock.mockImplementation(jest.requireActual('find-up').sync); + findUpSyncMock.mockImplementation((await vi.importActual('find-up')).sync); spawnSyncMock.mockImplementation((command) => { // Yarn is ok @@ -215,9 +217,9 @@ describe('JsPackageManagerFactory', () => { expect(JsPackageManagerFactory.getPackageManager()).toBeInstanceOf(Yarn1Proxy); }); - it('when multiple lockfiles are in a project, prefers yarn', () => { + it('when multiple lockfiles are in a project, prefers yarn', async () => { // Allow find-up to work as normal, we'll set the cwd to our fixture package - findUpSyncMock.mockImplementation(jest.requireActual('find-up').sync); + findUpSyncMock.mockImplementation((await vi.importActual('find-up')).sync); spawnSyncMock.mockImplementation((command) => { // Yarn is ok diff --git a/code/lib/cli/src/js-package-manager/NPMProxy.test.ts b/code/lib/cli/src/js-package-manager/NPMProxy.test.ts index c96d458d0d5c..b320bd355b35 100644 --- a/code/lib/cli/src/js-package-manager/NPMProxy.test.ts +++ b/code/lib/cli/src/js-package-manager/NPMProxy.test.ts @@ -1,12 +1,13 @@ +import { describe, beforeEach, it, expect, vi } from 'vitest'; import { NPMProxy } from './NPMProxy'; // mock createLogStream vi.mock('../utils', () => ({ - createLogStream: jest.fn(() => ({ + createLogStream: vi.fn(() => ({ logStream: '', - readLogFile: jest.fn(), - moveLogFile: jest.fn(), - removeLogFile: jest.fn(), + readLogFile: vi.fn(), + moveLogFile: vi.fn(), + removeLogFile: vi.fn(), })), })); @@ -23,7 +24,7 @@ describe('NPM Proxy', () => { describe('initPackageJson', () => { it('should run `npm init -y`', async () => { - const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(npmProxy, 'executeCommand').mockResolvedValueOnce(''); await npmProxy.initPackageJson(); @@ -35,7 +36,7 @@ describe('NPM Proxy', () => { describe('setRegistryUrl', () => { it('should run `npm config set registry https://foo.bar`', async () => { - const executeCommandSpy = jest.spyOn(npmProxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(npmProxy, 'executeCommand').mockResolvedValueOnce(''); await npmProxy.setRegistryURL('https://foo.bar'); @@ -51,7 +52,7 @@ describe('NPM Proxy', () => { describe('installDependencies', () => { describe('npm6', () => { it('should run `npm install`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce('6.0.0'); @@ -64,7 +65,7 @@ describe('NPM Proxy', () => { }); describe('npm7', () => { it('should run `npm install`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce('7.1.0'); @@ -80,7 +81,7 @@ describe('NPM Proxy', () => { describe('runScript', () => { describe('npm6', () => { it('should execute script `npm exec -- compodoc -e json -d .`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce('6.0.0'); @@ -96,7 +97,7 @@ describe('NPM Proxy', () => { }); describe('npm7', () => { it('should execute script `npm run compodoc -- -e json -d .`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce('7.1.0'); @@ -115,7 +116,7 @@ describe('NPM Proxy', () => { describe('addDependencies', () => { describe('npm6', () => { it('with devDep it should run `npm install -D @storybook/preview-api`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce('6.0.0'); @@ -133,7 +134,7 @@ describe('NPM Proxy', () => { }); describe('npm7', () => { it('with devDep it should run `npm install -D @storybook/preview-api`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce('7.0.0'); @@ -154,7 +155,7 @@ describe('NPM Proxy', () => { describe('removeDependencies', () => { describe('npm6', () => { it('with devDep it should run `npm uninstall @storybook/preview-api`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce('6.0.0'); @@ -167,7 +168,7 @@ describe('NPM Proxy', () => { }); describe('npm7', () => { it('with devDep it should run `npm uninstall @storybook/preview-api`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce('7.0.0'); @@ -180,12 +181,10 @@ describe('NPM Proxy', () => { }); describe('skipInstall', () => { it('should only change package.json without running install', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce('7.0.0'); - const writePackageSpy = jest - .spyOn(npmProxy, 'writePackageJson') - .mockImplementation(jest.fn()); + const writePackageSpy = vi.spyOn(npmProxy, 'writePackageJson').mockImplementation(vi.fn()); await npmProxy.removeDependencies( { @@ -212,7 +211,7 @@ describe('NPM Proxy', () => { describe('latestVersion', () => { it('without constraint it returns the latest version', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce('"5.3.19"'); @@ -228,7 +227,7 @@ describe('NPM Proxy', () => { }); it('with constraint it returns the latest version satisfying the constraint', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce('["4.25.3","5.3.19","6.0.0-beta.23"]'); @@ -244,7 +243,7 @@ describe('NPM Proxy', () => { }); it('throws an error if command output is not a valid JSON', async () => { - jest.spyOn(npmProxy, 'executeCommand').mockResolvedValueOnce('NOT A JSON'); + vi.spyOn(npmProxy, 'executeCommand').mockResolvedValueOnce('NOT A JSON'); await expect(npmProxy.latestVersion('@storybook/preview-api')).rejects.toThrow(); }); @@ -254,7 +253,7 @@ describe('NPM Proxy', () => { it('with a Storybook package listed in versions.json it returns the version', async () => { // eslint-disable-next-line global-require const storybookAngularVersion = require('../versions').default['@storybook/angular']; - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce('"5.3.19"'); @@ -271,7 +270,7 @@ describe('NPM Proxy', () => { it('with a Storybook package not listed in versions.json it returns the latest version', async () => { const packageVersion = '5.3.19'; - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(npmProxy, 'executeCommand') .mockResolvedValueOnce(`"${packageVersion}"`); @@ -289,12 +288,10 @@ describe('NPM Proxy', () => { describe('addPackageResolutions', () => { it('adds resolutions to package.json and account for existing resolutions', async () => { - const writePackageSpy = jest - .spyOn(npmProxy, 'writePackageJson') - .mockImplementation(jest.fn()); + const writePackageSpy = vi.spyOn(npmProxy, 'writePackageJson').mockImplementation(vi.fn()); - jest.spyOn(npmProxy, 'retrievePackageJson').mockImplementation( - jest.fn(async () => ({ + vi.spyOn(npmProxy, 'retrievePackageJson').mockImplementation( + vi.fn(async () => ({ dependencies: {}, devDependencies: {}, overrides: { @@ -322,7 +319,7 @@ describe('NPM Proxy', () => { describe('mapDependencies', () => { it('should display duplicated dependencies based on npm output', async () => { // npm ls --depth 10 --json - jest.spyOn(npmProxy, 'executeCommand').mockResolvedValueOnce(` + vi.spyOn(npmProxy, 'executeCommand').mockResolvedValueOnce(` { "dependencies": { "unrelated-and-should-be-filtered": { diff --git a/code/lib/cli/src/js-package-manager/PNPMProxy.test.ts b/code/lib/cli/src/js-package-manager/PNPMProxy.test.ts index 94ba1d1e7ed7..1cd761729c22 100644 --- a/code/lib/cli/src/js-package-manager/PNPMProxy.test.ts +++ b/code/lib/cli/src/js-package-manager/PNPMProxy.test.ts @@ -1,3 +1,4 @@ +import { describe, beforeEach, it, expect, vi } from 'vitest'; import { PNPMProxy } from './PNPMProxy'; describe('PNPM Proxy', () => { @@ -13,7 +14,7 @@ describe('PNPM Proxy', () => { describe('initPackageJson', () => { it('should run `pnpm init`', async () => { - const executeCommandSpy = jest.spyOn(pnpmProxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(pnpmProxy, 'executeCommand').mockResolvedValueOnce(''); await pnpmProxy.initPackageJson(); @@ -25,7 +26,7 @@ describe('PNPM Proxy', () => { describe('setRegistryUrl', () => { it('should run `npm config set registry https://foo.bar`', async () => { - const executeCommandSpy = jest.spyOn(pnpmProxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(pnpmProxy, 'executeCommand').mockResolvedValueOnce(''); await pnpmProxy.setRegistryURL('https://foo.bar'); @@ -40,7 +41,7 @@ describe('PNPM Proxy', () => { describe('installDependencies', () => { it('should run `pnpm install`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(pnpmProxy, 'executeCommand') .mockResolvedValueOnce('7.1.0'); @@ -54,7 +55,7 @@ describe('PNPM Proxy', () => { describe('runScript', () => { it('should execute script `pnpm exec compodoc -- -e json -d .`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(pnpmProxy, 'executeCommand') .mockResolvedValueOnce('7.1.0'); @@ -71,7 +72,7 @@ describe('PNPM Proxy', () => { describe('addDependencies', () => { it('with devDep it should run `pnpm add -D @storybook/preview-api`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(pnpmProxy, 'executeCommand') .mockResolvedValueOnce('6.0.0'); @@ -87,7 +88,7 @@ describe('PNPM Proxy', () => { describe('removeDependencies', () => { it('with devDep it should run `npm uninstall @storybook/preview-api`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(pnpmProxy, 'executeCommand') .mockResolvedValueOnce('6.0.0'); @@ -100,12 +101,10 @@ describe('PNPM Proxy', () => { describe('skipInstall', () => { it('should only change package.json without running install', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(pnpmProxy, 'executeCommand') .mockResolvedValueOnce('7.0.0'); - const writePackageSpy = jest - .spyOn(pnpmProxy, 'writePackageJson') - .mockImplementation(jest.fn()); + const writePackageSpy = vi.spyOn(pnpmProxy, 'writePackageJson').mockImplementation(vi.fn()); await pnpmProxy.removeDependencies( { @@ -132,7 +131,7 @@ describe('PNPM Proxy', () => { describe('latestVersion', () => { it('without constraint it returns the latest version', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(pnpmProxy, 'executeCommand') .mockResolvedValueOnce('"5.3.19"'); @@ -148,7 +147,7 @@ describe('PNPM Proxy', () => { }); it('with constraint it returns the latest version satisfying the constraint', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(pnpmProxy, 'executeCommand') .mockResolvedValueOnce('["4.25.3","5.3.19","6.0.0-beta.23"]'); @@ -164,7 +163,7 @@ describe('PNPM Proxy', () => { }); it('throws an error if command output is not a valid JSON', async () => { - jest.spyOn(pnpmProxy, 'executeCommand').mockResolvedValueOnce('NOT A JSON'); + vi.spyOn(pnpmProxy, 'executeCommand').mockResolvedValueOnce('NOT A JSON'); await expect(pnpmProxy.latestVersion('@storybook/preview-api')).rejects.toThrow(); }); @@ -174,7 +173,7 @@ describe('PNPM Proxy', () => { it('with a Storybook package listed in versions.json it returns the version', async () => { // eslint-disable-next-line global-require const storybookAngularVersion = require('../versions').default['@storybook/angular']; - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(pnpmProxy, 'executeCommand') .mockResolvedValueOnce('"5.3.19"'); @@ -191,7 +190,7 @@ describe('PNPM Proxy', () => { it('with a Storybook package not listed in versions.json it returns the latest version', async () => { const packageVersion = '5.3.19'; - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(pnpmProxy, 'executeCommand') .mockResolvedValueOnce(`"${packageVersion}"`); @@ -209,13 +208,11 @@ describe('PNPM Proxy', () => { describe('addPackageResolutions', () => { it('adds resolutions to package.json and account for existing resolutions', async () => { - const writePackageSpy = jest - .spyOn(pnpmProxy, 'writePackageJson') - .mockImplementation(jest.fn()); + const writePackageSpy = vi.spyOn(pnpmProxy, 'writePackageJson').mockImplementation(vi.fn()); - jest.spyOn(pnpmProxy, 'retrievePackageJson').mockImplementation( + vi.spyOn(pnpmProxy, 'retrievePackageJson').mockImplementation( // @ts-expect-error (not strict) - jest.fn(() => ({ + vi.fn(() => ({ overrides: { bar: 'x.x.x', }, @@ -239,7 +236,7 @@ describe('PNPM Proxy', () => { describe('mapDependencies', () => { it('should display duplicated dependencies based on pnpm output', async () => { // pnpm list "@storybook/*" "storybook" --depth 10 --json - jest.spyOn(pnpmProxy, 'executeCommand').mockResolvedValueOnce(` + vi.spyOn(pnpmProxy, 'executeCommand').mockResolvedValueOnce(` [ { "peerDependencies": { diff --git a/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts b/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts index 799fe8fb55cd..87bd0f7b66da 100644 --- a/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts +++ b/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts @@ -1,3 +1,4 @@ +import { describe, beforeEach, it, expect, vi } from 'vitest'; import dedent from 'ts-dedent'; import { Yarn1Proxy } from './Yarn1Proxy'; @@ -14,7 +15,7 @@ describe('Yarn 1 Proxy', () => { describe('initPackageJson', () => { it('should run `yarn init -y`', async () => { - const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce(''); await yarn1Proxy.initPackageJson(); @@ -26,7 +27,7 @@ describe('Yarn 1 Proxy', () => { describe('setRegistryUrl', () => { it('should run `yarn config set npmRegistryServer https://foo.bar`', async () => { - const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce(''); await yarn1Proxy.setRegistryURL('https://foo.bar'); @@ -41,7 +42,7 @@ describe('Yarn 1 Proxy', () => { describe('installDependencies', () => { it('should run `yarn`', async () => { - const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce(''); await yarn1Proxy.installDependencies(); @@ -56,7 +57,7 @@ describe('Yarn 1 Proxy', () => { describe('runScript', () => { it('should execute script `yarn compodoc -- -e json -d .`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(yarn1Proxy, 'executeCommand') .mockResolvedValueOnce('7.1.0'); @@ -70,7 +71,7 @@ describe('Yarn 1 Proxy', () => { describe('addDependencies', () => { it('with devDep it should run `yarn install -D --ignore-workspace-root-check @storybook/preview-api`', async () => { - const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce(''); await yarn1Proxy.addDependencies({ installAsDevDependencies: true }, [ '@storybook/preview-api', @@ -87,7 +88,7 @@ describe('Yarn 1 Proxy', () => { describe('removeDependencies', () => { it('should run `yarn remove --ignore-workspace-root-check @storybook/preview-api`', async () => { - const executeCommandSpy = jest.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce(''); yarn1Proxy.removeDependencies({}, ['@storybook/preview-api']); @@ -100,12 +101,10 @@ describe('Yarn 1 Proxy', () => { }); it('skipInstall should only change package.json without running install', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(yarn1Proxy, 'executeCommand') .mockResolvedValueOnce('7.0.0'); - const writePackageSpy = jest - .spyOn(yarn1Proxy, 'writePackageJson') - .mockImplementation(jest.fn()); + const writePackageSpy = vi.spyOn(yarn1Proxy, 'writePackageJson').mockImplementation(vi.fn()); await yarn1Proxy.removeDependencies( { @@ -131,7 +130,7 @@ describe('Yarn 1 Proxy', () => { describe('latestVersion', () => { it('without constraint it returns the latest version', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(yarn1Proxy, 'executeCommand') .mockResolvedValueOnce('{"type":"inspect","data":"5.3.19"}'); @@ -147,7 +146,7 @@ describe('Yarn 1 Proxy', () => { }); it('with constraint it returns the latest version satisfying the constraint', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(yarn1Proxy, 'executeCommand') .mockResolvedValueOnce('{"type":"inspect","data":["4.25.3","5.3.19","6.0.0-beta.23"]}'); @@ -163,7 +162,7 @@ describe('Yarn 1 Proxy', () => { }); it('throws an error if command output is not a valid JSON', async () => { - jest.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce('NOT A JSON'); + vi.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce('NOT A JSON'); await expect(yarn1Proxy.latestVersion('@storybook/preview-api')).rejects.toThrow(); }); @@ -171,12 +170,10 @@ describe('Yarn 1 Proxy', () => { describe('addPackageResolutions', () => { it('adds resolutions to package.json and account for existing resolutions', async () => { - const writePackageSpy = jest - .spyOn(yarn1Proxy, 'writePackageJson') - .mockImplementation(jest.fn()); + const writePackageSpy = vi.spyOn(yarn1Proxy, 'writePackageJson').mockImplementation(vi.fn()); - jest.spyOn(yarn1Proxy, 'retrievePackageJson').mockImplementation( - jest.fn(async () => ({ + vi.spyOn(yarn1Proxy, 'retrievePackageJson').mockImplementation( + vi.fn(async () => ({ dependencies: {}, devDependencies: {}, resolutions: { @@ -204,7 +201,7 @@ describe('Yarn 1 Proxy', () => { describe('mapDependencies', () => { it('should display duplicated dependencies based on yarn output', async () => { // yarn list --pattern "@storybook/*" "@storybook/react" --recursive --json - jest.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce(` + vi.spyOn(yarn1Proxy, 'executeCommand').mockResolvedValueOnce(` { "type": "tree", "data": { diff --git a/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts b/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts index 0e1bb1276a30..3ef5389287df 100644 --- a/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts +++ b/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts @@ -1,3 +1,4 @@ +import { describe, beforeEach, it, expect, vi } from 'vitest'; import dedent from 'ts-dedent'; import { Yarn2Proxy } from './Yarn2Proxy'; @@ -14,7 +15,7 @@ describe('Yarn 2 Proxy', () => { describe('initPackageJson', () => { it('should run `yarn init`', async () => { - const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce(''); await yarn2Proxy.initPackageJson(); @@ -26,7 +27,7 @@ describe('Yarn 2 Proxy', () => { describe('installDependencies', () => { it('should run `yarn`', async () => { - const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce(''); await yarn2Proxy.installDependencies(); @@ -38,7 +39,7 @@ describe('Yarn 2 Proxy', () => { describe('runScript', () => { it('should execute script `yarn compodoc -- -e json -d .`', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(yarn2Proxy, 'executeCommand') .mockResolvedValueOnce('7.1.0'); @@ -55,7 +56,7 @@ describe('Yarn 2 Proxy', () => { describe('setRegistryUrl', () => { it('should run `yarn config set npmRegistryServer https://foo.bar`', async () => { - const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce(''); await yarn2Proxy.setRegistryURL('https://foo.bar'); @@ -70,7 +71,7 @@ describe('Yarn 2 Proxy', () => { describe('addDependencies', () => { it('with devDep it should run `yarn install -D @storybook/preview-api`', async () => { - const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce(''); await yarn2Proxy.addDependencies({ installAsDevDependencies: true }, [ '@storybook/preview-api', @@ -84,7 +85,7 @@ describe('Yarn 2 Proxy', () => { describe('removeDependencies', () => { it('should run `yarn remove @storybook/preview-api`', async () => { - const executeCommandSpy = jest.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce(''); + const executeCommandSpy = vi.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce(''); await yarn2Proxy.removeDependencies({}, ['@storybook/preview-api']); @@ -97,12 +98,10 @@ describe('Yarn 2 Proxy', () => { }); it('skipInstall should only change package.json without running install', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(yarn2Proxy, 'executeCommand') .mockResolvedValueOnce('7.0.0'); - const writePackageSpy = jest - .spyOn(yarn2Proxy, 'writePackageJson') - .mockImplementation(jest.fn()); + const writePackageSpy = vi.spyOn(yarn2Proxy, 'writePackageJson').mockImplementation(vi.fn()); await yarn2Proxy.removeDependencies( { @@ -128,7 +127,7 @@ describe('Yarn 2 Proxy', () => { describe('latestVersion', () => { it('without constraint it returns the latest version', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(yarn2Proxy, 'executeCommand') .mockResolvedValueOnce('{"name":"@storybook/preview-api","version":"5.3.19"}'); @@ -144,7 +143,7 @@ describe('Yarn 2 Proxy', () => { }); it('with constraint it returns the latest version satisfying the constraint', async () => { - const executeCommandSpy = jest + const executeCommandSpy = vi .spyOn(yarn2Proxy, 'executeCommand') .mockResolvedValueOnce( '{"name":"@storybook/preview-api","versions":["4.25.3","5.3.19","6.0.0-beta.23"]}' @@ -162,7 +161,7 @@ describe('Yarn 2 Proxy', () => { }); it('throws an error if command output is not a valid JSON', async () => { - jest.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce('NOT A JSON'); + vi.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce('NOT A JSON'); await expect(yarn2Proxy.latestVersion('@storybook/preview-api')).rejects.toThrow(); }); @@ -170,12 +169,10 @@ describe('Yarn 2 Proxy', () => { describe('addPackageResolutions', () => { it('adds resolutions to package.json and account for existing resolutions', async () => { - const writePackageSpy = jest - .spyOn(yarn2Proxy, 'writePackageJson') - .mockImplementation(jest.fn()); + const writePackageSpy = vi.spyOn(yarn2Proxy, 'writePackageJson').mockImplementation(vi.fn()); - jest.spyOn(yarn2Proxy, 'retrievePackageJson').mockImplementation( - jest.fn(async () => ({ + vi.spyOn(yarn2Proxy, 'retrievePackageJson').mockImplementation( + vi.fn(async () => ({ dependencies: {}, devDependencies: {}, resolutions: { @@ -204,7 +201,7 @@ describe('Yarn 2 Proxy', () => { describe('mapDependencies', () => { it('should display duplicated dependencies based on yarn2 output', async () => { // yarn info --name-only --recursive "@storybook/*" "storybook" - jest.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce(` + vi.spyOn(yarn2Proxy, 'executeCommand').mockResolvedValueOnce(` "unrelated-and-should-be-filtered@npm:1.0.0" "@storybook/global@npm:5.0.0" "@storybook/instrumenter@npm:7.0.0-beta.12" diff --git a/code/lib/cli/src/project_types.test.ts b/code/lib/cli/src/project_types.test.ts index b27beac01366..95bca595dfc7 100644 --- a/code/lib/cli/src/project_types.test.ts +++ b/code/lib/cli/src/project_types.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { installableProjectTypes, SUPPORTED_RENDERERS } from './project_types'; describe('installableProjectTypes should have an entry for the supported framework', () => { diff --git a/code/lib/cli/src/upgrade.test.ts b/code/lib/cli/src/upgrade.test.ts index 1110946e0b2b..3acb5fd92a0d 100644 --- a/code/lib/cli/src/upgrade.test.ts +++ b/code/lib/cli/src/upgrade.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { addExtraFlags, addNxPackagesToReject, getStorybookVersion } from './upgrade'; describe.each([ diff --git a/code/lib/cli/src/utils.test.ts b/code/lib/cli/src/utils.test.ts index 6d7dd9fe9eae..41f65a83a7f1 100644 --- a/code/lib/cli/src/utils.test.ts +++ b/code/lib/cli/src/utils.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { isCorePackage } from './utils'; describe('UTILS', () => { diff --git a/code/lib/cli/src/warn.test.ts b/code/lib/cli/src/warn.test.ts index 42a439101d5f..457078de9dea 100644 --- a/code/lib/cli/src/warn.test.ts +++ b/code/lib/cli/src/warn.test.ts @@ -1,3 +1,5 @@ +import type { Mock } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import globby from 'globby'; import { logger } from '@storybook/node-logger'; import { warn } from './warn'; @@ -7,7 +9,7 @@ vi.mock('globby'); describe('warn', () => { beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe('when TypeScript is installed as a dependency', () => { @@ -21,7 +23,7 @@ describe('warn', () => { describe('when TypeScript is not installed as a dependency', () => { it('should not warn if `.tsx?` files are not found', () => { - (globby.sync as vi.mock).mockReturnValueOnce([]); + (globby.sync as Mock).mockReturnValueOnce([]); warn({ hasTSDependency: false, }); @@ -29,7 +31,7 @@ describe('warn', () => { }); it('should warn if `.tsx?` files are found', () => { - (globby.sync as vi.mock).mockReturnValueOnce(['a.ts']); + (globby.sync as Mock).mockReturnValueOnce(['a.ts']); warn({ hasTSDependency: false, }); diff --git a/code/lib/cli/test/default/cli.test.js b/code/lib/cli/test/default/cli.test.js index b7ead3851c9e..05fa2be9f436 100755 --- a/code/lib/cli/test/default/cli.test.js +++ b/code/lib/cli/test/default/cli.test.js @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; const run = require('../helpers'); describe('Default behavior', () => { diff --git a/code/lib/client-logger/src/index.test.ts b/code/lib/client-logger/src/index.test.ts index 7776673a96a5..8574cef5066d 100644 --- a/code/lib/client-logger/src/index.test.ts +++ b/code/lib/client-logger/src/index.test.ts @@ -1,3 +1,4 @@ +import { describe, beforeEach, afterAll, it, expect, vi } from 'vitest'; import { logger } from '.'; vi.mock('@storybook/global', () => ({ global: { ...global, LOGLEVEL: 'debug' } })); @@ -5,12 +6,12 @@ vi.mock('@storybook/global', () => ({ global: { ...global, LOGLEVEL: 'debug' } } describe('client-logger default LOGLEVEL', () => { const initialConsole = { ...global.console }; beforeEach(() => { - global.console.trace = jest.fn(); - global.console.debug = jest.fn(); - global.console.log = jest.fn(); - global.console.info = jest.fn(); - global.console.warn = jest.fn(); - global.console.error = jest.fn(); + global.console.trace = vi.fn(); + global.console.debug = vi.fn(); + global.console.log = vi.fn(); + global.console.info = vi.fn(); + global.console.warn = vi.fn(); + global.console.error = vi.fn(); }); afterAll(() => { global.console = initialConsole; diff --git a/code/lib/codemod/src/lib/utils.test.js b/code/lib/codemod/src/lib/utils.test.js index 588ed7f3ad45..edce155064cc 100644 --- a/code/lib/codemod/src/lib/utils.test.js +++ b/code/lib/codemod/src/lib/utils.test.js @@ -1,3 +1,4 @@ +import { it, expect } from 'vitest'; import { sanitizeName } from './utils'; it('should sanitize names', () => { diff --git a/code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts b/code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts index 9fd9cd04e997..66295f9751ff 100644 --- a/code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts +++ b/code/lib/codemod/src/transforms/__tests__/mdx-to-csf.test.ts @@ -1,5 +1,6 @@ +import type { Mocked } from 'vitest'; +import { beforeEach, expect, vi } from 'vitest'; import * as fs_ from 'node:fs'; -import { expect, test } from 'vitest'; import dedent from 'ts-dedent'; import jscodeshift, { nameToValidExport } from '../mdx-to-csf'; @@ -9,7 +10,7 @@ expect.addSnapshotSerializer({ }); vi.mock('node:fs'); -const fs = fs_ as vi.mocked; +const fs = fs_ as Mocked; beforeEach(() => { fs.existsSync.mockImplementation(() => false); diff --git a/code/lib/codemod/src/transforms/__tests__/transforms.tests.js b/code/lib/codemod/src/transforms/__tests__/transforms.tests.js index 79d98e2a77ed..083db8987c35 100644 --- a/code/lib/codemod/src/transforms/__tests__/transforms.tests.js +++ b/code/lib/codemod/src/transforms/__tests__/transforms.tests.js @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import path from 'path'; import fs from 'fs'; import 'jest-specific-snapshot'; diff --git a/code/lib/core-common/src/config.test.ts b/code/lib/core-common/src/config.test.ts index ae9b2929e0fd..3e75aeb0396f 100644 --- a/code/lib/core-common/src/config.test.ts +++ b/code/lib/core-common/src/config.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { filterPresetsConfig } from './presets'; describe('filterPresetsConfig', () => { diff --git a/code/lib/core-common/src/presets.test.ts b/code/lib/core-common/src/presets.test.ts index 1fe603f92972..612f8b01b81e 100644 --- a/code/lib/core-common/src/presets.test.ts +++ b/code/lib/core-common/src/presets.test.ts @@ -1,3 +1,4 @@ +import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; import path from 'path'; import { logger } from '@storybook/node-logger'; import './presets'; @@ -15,9 +16,9 @@ function mockPreset(name: string, mockPresetObject: any) { vi.mock('@storybook/node-logger', () => ({ logger: { - info: jest.fn(), - warn: jest.fn(), - error: jest.fn(), + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), }, })); @@ -47,13 +48,13 @@ vi.mock('./utils/safeResolve', () => { ]; return { - safeResolveFrom: jest.fn((l: any, name: string) => { + safeResolveFrom: vi.fn((l: any, name: string) => { if (KNOWN_FILES.includes(name)) { return name; } return undefined; }), - safeResolve: jest.fn((name: string) => { + safeResolve: vi.fn((name: string) => { if (KNOWN_FILES.includes(name)) { return name; } @@ -64,7 +65,7 @@ vi.mock('./utils/safeResolve', () => { describe('presets', () => { it('does not throw when there is no preset file', async () => { - const { getPresets } = jest.requireActual('./presets'); + const { getPresets } = await vi.importActual('./presets'); let presets; async function testPresets() { @@ -79,7 +80,7 @@ describe('presets', () => { }); it('does not throw when presets are empty', async () => { - const { getPresets } = jest.requireActual('./presets'); + const { getPresets } = await vi.importActual('./presets'); const presets = wrapPreset(await getPresets([])); async function testPresets() { @@ -91,7 +92,7 @@ describe('presets', () => { }); it('does not throw when preset can not be loaded', async () => { - const { getPresets } = jest.requireActual('./presets'); + const { getPresets } = await vi.importActual('./presets'); const presets = wrapPreset(await getPresets(['preset-foo'])); async function testPresets() { @@ -124,7 +125,7 @@ describe('presets', () => { foo: (exec: string[], options: any) => exec.concat(`valar ${options.custom}`), }); - const { getPresets } = jest.requireActual('./presets'); + const { getPresets } = await vi.importActual('./presets'); const presets = await getPresets(['preset-foo', 'preset-got', 'preset-bar'], {}); const result = await presets.apply('foo', []); @@ -133,8 +134,8 @@ describe('presets', () => { }); it('loads and applies presets when they are declared as a string', async () => { - const mockPresetFooExtendWebpack = jest.fn(); - const mockPresetBarExtendBabel = jest.fn(); + const mockPresetFooExtendWebpack = vi.fn(); + const mockPresetBarExtendBabel = vi.fn(); mockPreset('preset-foo', { webpack: mockPresetFooExtendWebpack, @@ -144,7 +145,7 @@ describe('presets', () => { babel: mockPresetBarExtendBabel, }); - const { getPresets } = jest.requireActual('./presets'); + const { getPresets } = await vi.importActual('./presets'); const presets = wrapPreset(await getPresets(['preset-foo', 'preset-bar'], {})); async function testPresets() { @@ -159,8 +160,8 @@ describe('presets', () => { }); it('loads and applies presets when they are declared as an object without props', async () => { - const mockPresetFooExtendWebpack = jest.fn(); - const mockPresetBarExtendBabel = jest.fn(); + const mockPresetFooExtendWebpack = vi.fn(); + const mockPresetBarExtendBabel = vi.fn(); mockPreset('preset-foo', { webpack: mockPresetFooExtendWebpack, @@ -170,7 +171,7 @@ describe('presets', () => { babel: mockPresetBarExtendBabel, }); - const { getPresets } = jest.requireActual('./presets'); + const { getPresets } = await vi.importActual('./presets'); const presets = wrapPreset( await getPresets([{ name: 'preset-foo' }, { name: 'preset-bar' }], {}) ); @@ -187,8 +188,8 @@ describe('presets', () => { }); it('loads and applies presets when they are declared as an object with props', async () => { - const mockPresetFooExtendWebpack = jest.fn(); - const mockPresetBarExtendBabel = jest.fn(); + const mockPresetFooExtendWebpack = vi.fn(); + const mockPresetBarExtendBabel = vi.fn(); mockPreset('preset-foo', { webpack: mockPresetFooExtendWebpack, @@ -198,7 +199,7 @@ describe('presets', () => { babel: mockPresetBarExtendBabel, }); - const { getPresets } = jest.requireActual('./presets'); + const { getPresets } = await vi.importActual('./presets'); const presets = wrapPreset( await getPresets( [ @@ -229,8 +230,8 @@ describe('presets', () => { }); it('loads and applies presets when they are declared as a string and as an object', async () => { - const mockPresetFooExtendWebpack = jest.fn(); - const mockPresetBarExtendBabel = jest.fn(); + const mockPresetFooExtendWebpack = vi.fn(); + const mockPresetBarExtendBabel = vi.fn(); mockPreset('preset-foo', { webpack: mockPresetFooExtendWebpack, @@ -240,7 +241,7 @@ describe('presets', () => { babel: mockPresetBarExtendBabel, }); - const { getPresets } = jest.requireActual('./presets'); + const { getPresets } = await vi.importActual('./presets'); const presets = wrapPreset( await getPresets( [ @@ -275,8 +276,8 @@ describe('presets', () => { }); it('applies presets in chain', async () => { - const mockPresetFooExtendWebpack = jest.fn((...args: any[]) => ({})); - const mockPresetBarExtendWebpack = jest.fn((...args: any[]) => ({})); + const mockPresetFooExtendWebpack = vi.fn((...args: any[]) => ({})); + const mockPresetBarExtendWebpack = vi.fn((...args: any[]) => ({})); mockPreset('preset-foo', { webpack: mockPresetFooExtendWebpack, @@ -286,7 +287,7 @@ describe('presets', () => { webpack: mockPresetBarExtendWebpack, }); - const { getPresets } = jest.requireActual('./presets'); + const { getPresets } = await vi.importActual('./presets'); const presets = wrapPreset( await getPresets( [ @@ -326,9 +327,9 @@ describe('presets', () => { }); it('allows for presets to export presets array', async () => { - const { getPresets } = jest.requireActual('./presets'); + const { getPresets } = await vi.importActual('./presets'); const input = {}; - const mockPresetBar = jest.fn((...args: any[]) => input); + const mockPresetBar = vi.fn((...args: any[]) => input); mockPreset('preset-foo', { presets: ['preset-bar'], @@ -348,12 +349,12 @@ describe('presets', () => { }); it('allows for presets to export presets fn', async () => { - const { getPresets } = jest.requireActual('./presets'); + const { getPresets } = await vi.importActual('./presets'); const input = {}; const storybookOptions = { a: 1 }; const presetOptions = { b: 2 }; - const mockPresetBar = jest.fn((...args: any[]) => input); - const mockPresetFoo = jest.fn((...args: any[]) => ['preset-bar']); + const mockPresetBar = vi.fn((...args: any[]) => input); + const mockPresetFoo = vi.fn((...args: any[]) => ['preset-bar']); mockPreset('preset-foo', { presets: mockPresetFoo, @@ -374,12 +375,12 @@ describe('presets', () => { }); afterEach(() => { - jest.resetModules(); + vi.resetModules(); }); }); describe('resolveAddonName', () => { - const { resolveAddonName } = jest.requireActual('./presets'); + const { resolveAddonName } = vi.importActual('./presets'); it('should resolve packages with metadata (relative path)', () => { mockPreset('./local/preset', { @@ -458,10 +459,10 @@ describe('loadPreset', () => { mockPreset('addon-baz/register.js', {}); mockPreset('@storybook/addon-notes/register-panel', {}); - const { loadPreset } = jest.requireActual('./presets'); + const { loadPreset } = await vi.importActual('./presets'); beforeEach(() => { - jest.spyOn(logger, 'warn'); + vi.spyOn(logger, 'warn'); }); it('should prepend framework field to list of presets', async () => { diff --git a/code/lib/core-common/src/test-typings.d.ts b/code/lib/core-common/src/test-typings.d.ts index e45372e66b12..2eb86e036ffd 100644 --- a/code/lib/core-common/src/test-typings.d.ts +++ b/code/lib/core-common/src/test-typings.d.ts @@ -1,4 +1,6 @@ -declare namespace jest { +import { vi } from 'vitest'; +// TODO Check this +declare namespace vi { interface Matchers { toMatchPaths(paths: string[]): R; } diff --git a/code/lib/core-common/src/utils/__tests__/check-addon-order.test.ts b/code/lib/core-common/src/utils/__tests__/check-addon-order.test.ts index 03de5b1efbf0..efee96614ab5 100644 --- a/code/lib/core-common/src/utils/__tests__/check-addon-order.test.ts +++ b/code/lib/core-common/src/utils/__tests__/check-addon-order.test.ts @@ -1,3 +1,4 @@ +import { afterEach, it, expect, vi } from 'vitest'; import { logger } from '@storybook/node-logger'; import type { CoreCommon_AddonEntry, @@ -33,7 +34,7 @@ const fromName = (name: string): CoreCommon_AddonInfo => ({ const str = (name: unknown) => JSON.stringify(name); -const warn = jest.spyOn(logger, 'warn'); +const warn = vi.spyOn(logger, 'warn'); afterEach(() => warn.mockReset()); describe.each([ diff --git a/code/lib/core-common/src/utils/__tests__/interpret-files.test.ts b/code/lib/core-common/src/utils/__tests__/interpret-files.test.ts index 8fae7250bc11..fff12806dfb1 100644 --- a/code/lib/core-common/src/utils/__tests__/interpret-files.test.ts +++ b/code/lib/core-common/src/utils/__tests__/interpret-files.test.ts @@ -1,3 +1,4 @@ +import { describe, afterEach, it, expect } from 'vitest'; import mock from 'mock-fs'; import { getInterpretedFile } from '../interpret-files'; diff --git a/code/lib/core-common/src/utils/__tests__/normalize-stories.test.ts b/code/lib/core-common/src/utils/__tests__/normalize-stories.test.ts index 73acdc1b7c89..69d83ea95448 100644 --- a/code/lib/core-common/src/utils/__tests__/normalize-stories.test.ts +++ b/code/lib/core-common/src/utils/__tests__/normalize-stories.test.ts @@ -1,5 +1,6 @@ // eslint-disable-next-line @typescript-eslint/triple-slash-reference /// +import { describe, it, expect, vi } from 'vitest'; import { dedent } from 'ts-dedent'; import { sep } from 'path'; diff --git a/code/lib/core-common/src/utils/__tests__/paths.test.ts b/code/lib/core-common/src/utils/__tests__/paths.test.ts index 33bd5d2ef585..e5f1526ea9fb 100644 --- a/code/lib/core-common/src/utils/__tests__/paths.test.ts +++ b/code/lib/core-common/src/utils/__tests__/paths.test.ts @@ -1,3 +1,5 @@ +import type { Mocked } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import path from 'path'; import findUp from 'find-up'; import slash from 'slash'; @@ -43,7 +45,7 @@ describe('paths - normalizeStoryPath()', () => { }); describe('getProjectRoot', () => { - const mockedFindUp = findUp as vi.mocked; + const mockedFindUp = findUp as Mocked; it('should return the root directory containing a .git directory', () => { mockedFindUp.sync.mockImplementation((name) => diff --git a/code/lib/core-common/src/utils/__tests__/template.test.ts b/code/lib/core-common/src/utils/__tests__/template.test.ts index 969e862f6a3c..36f8957e0d07 100644 --- a/code/lib/core-common/src/utils/__tests__/template.test.ts +++ b/code/lib/core-common/src/utils/__tests__/template.test.ts @@ -1,3 +1,4 @@ +import { describe, beforeEach, afterEach, it, expect } from 'vitest'; import mock from 'mock-fs'; import { getPreviewHeadTemplate, getPreviewBodyTemplate } from '../template'; diff --git a/code/lib/core-common/src/utils/get-storybook-configuration.test.ts b/code/lib/core-common/src/utils/get-storybook-configuration.test.ts index e6a460acdf90..aa821e38e594 100644 --- a/code/lib/core-common/src/utils/get-storybook-configuration.test.ts +++ b/code/lib/core-common/src/utils/get-storybook-configuration.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { getStorybookConfiguration } from './get-storybook-configuration'; describe('getStorybookConfiguration', () => { diff --git a/code/lib/core-common/src/utils/validate-config.test.ts b/code/lib/core-common/src/utils/validate-config.test.ts index 42bb0ac96fcf..362fae82061a 100644 --- a/code/lib/core-common/src/utils/validate-config.test.ts +++ b/code/lib/core-common/src/utils/validate-config.test.ts @@ -1,7 +1,8 @@ +import { describe, afterEach, it, expect, vi } from 'vitest'; import { validateFrameworkName } from './validate-config'; describe('validateFrameworkName', () => { - afterEach(jest.resetAllMocks); + afterEach(vi.resetAllMocks); it('should throw if name is undefined', () => { expect(() => validateFrameworkName(undefined)).toThrow(); }); @@ -17,13 +18,13 @@ describe('validateFrameworkName', () => { it('should not throw if framework is unknown (community) but can be resolved', () => { // mock require.resolve to return a value - jest.spyOn(require, 'resolve').mockReturnValue('some-community-framework'); + vi.spyOn(require, 'resolve').mockReturnValue('some-community-framework'); expect(() => validateFrameworkName('some-community-framework')).toThrow(); }); it('should throw if framework is unknown and cannot be resolved', () => { // mock require.resolve to fail - jest.spyOn(require, 'resolve').mockImplementation(() => { + vi.spyOn(require, 'resolve').mockImplementation(() => { throw new Error('Cannot resolve'); }); diff --git a/code/lib/core-events/src/errors/server-errors.test.ts b/code/lib/core-events/src/errors/server-errors.test.ts index 0eb5fa4ad21d..2bae11ce07ff 100644 --- a/code/lib/core-events/src/errors/server-errors.test.ts +++ b/code/lib/core-events/src/errors/server-errors.test.ts @@ -1,4 +1,5 @@ /* eslint-disable local-rules/no-uncategorized-errors */ +import { describe, it, expect } from 'vitest'; import { WebpackCompilationError } from './server-errors'; describe('WebpackCompilationError', () => { diff --git a/code/lib/core-events/src/errors/storybook-error.test.ts b/code/lib/core-events/src/errors/storybook-error.test.ts index dc26a50f9679..e4162b650f96 100644 --- a/code/lib/core-events/src/errors/storybook-error.test.ts +++ b/code/lib/core-events/src/errors/storybook-error.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { StorybookError } from './storybook-error'; describe('StorybookError', () => { diff --git a/code/lib/core-events/src/index.test.ts b/code/lib/core-events/src/index.test.ts index 1ee0a9a7447f..dbc5b12b4542 100644 --- a/code/lib/core-events/src/index.test.ts +++ b/code/lib/core-events/src/index.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import * as EventsPackageExport from './index'; import EventsDefaultExport, { CHANNEL_CREATED } from './index'; diff --git a/code/lib/core-server/src/presets/favicon.test.ts b/code/lib/core-server/src/presets/favicon.test.ts index 8fad6ce8db96..d111f19ed174 100644 --- a/code/lib/core-server/src/presets/favicon.test.ts +++ b/code/lib/core-server/src/presets/favicon.test.ts @@ -1,4 +1,5 @@ -import { describe, test, it, expect } from 'vitest'; +import type { Mock } from 'vitest'; +import { expect, vi } from 'vitest'; import { join } from 'path'; import * as fs from 'fs-extra'; @@ -26,10 +27,10 @@ const createOptions = (locations: string[]): Parameters[1] => vi.mock('fs-extra', () => { return { - pathExists: jest.fn((p: string) => { + pathExists: vi.fn((p: string) => { return false; }), - existsSync: jest.fn((p: string) => { + existsSync: vi.fn((p: string) => { return false; }), }; @@ -38,12 +39,12 @@ vi.mock('fs-extra', () => { vi.mock('@storybook/node-logger', () => { return { logger: { - warn: jest.fn(() => {}), + warn: vi.fn(() => {}), }, }; }); -const pathExists = fs.pathExists as vi.mock; +const pathExists = fs.pathExists as Mock; test('with no staticDirs favicon should return default', async () => { const options = createOptions([]); diff --git a/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts b/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts index 5df0ace6f746..d15507c44029 100644 --- a/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts +++ b/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts @@ -1,9 +1,9 @@ /* eslint-disable @typescript-eslint/no-shadow */ -import { describe, test, it, expect } from 'vitest'; - /** - * @jest-environment node + * @vitest-environment node */ +import type { Mock } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import path from 'path'; import fs from 'fs-extra'; @@ -17,19 +17,19 @@ import type { StoryIndexGeneratorOptions } from './StoryIndexGenerator'; import { StoryIndexGenerator } from './StoryIndexGenerator'; vi.mock('@storybook/csf-tools'); -vi.mock('@storybook/csf', () => { - const csf = jest.requireActual('@storybook/csf'); +vi.mock('@storybook/csf', async () => { + const csf = await vi.importActual('@storybook/csf'); return { ...csf, - toId: jest.fn(csf.toId), + toId: vi.fn(csf.toId), }; }); vi.mock('@storybook/node-logger'); -const toIdMock = toId as vi.mock>; -const loadCsfMock = loadCsf as vi.mock>; -const getStorySortParameterMock = getStorySortParameter as vi.mock< +const toIdMock = toId as Mock>; +const loadCsfMock = loadCsf as Mock>; +const getStorySortParameterMock = getStorySortParameter as Mock< ReturnType >; @@ -59,8 +59,8 @@ const options: StoryIndexGeneratorOptions = { }; describe('StoryIndexGenerator with deprecated indexer API', () => { - beforeEach(() => { - const actual = jest.requireActual('@storybook/csf-tools'); + beforeEach(async () => { + const actual = await vi.importActual('@storybook/csf-tools'); loadCsfMock.mockImplementation(actual.loadCsf); vi.mocked(logger.warn).mockClear(); vi.mocked(once.warn).mockClear(); @@ -1211,7 +1211,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { const generator = new StoryIndexGenerator([docsSpecifier, storiesSpecifier], options); await generator.initialize(); - (getStorySortParameter as vi.mock).mockReturnValueOnce({ + (getStorySortParameter as Mock).mockReturnValueOnce({ order: ['docs2', 'D', 'B', 'nested', 'A', 'second-nested', 'first-nested/deeply'], }); @@ -1279,7 +1279,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { options ); - const sortFn = jest.fn(); + const sortFn = vi.fn(); getStorySortParameterMock.mockReturnValue(sortFn); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); @@ -1362,7 +1362,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { options ); - const sortFn = jest.fn(); + const sortFn = vi.fn(); getStorySortParameterMock.mockReturnValue(sortFn); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); @@ -1403,7 +1403,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { options ); - const sortFn = jest.fn(); + const sortFn = vi.fn(); getStorySortParameterMock.mockReturnValue(sortFn); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); diff --git a/code/lib/core-server/src/utils/StoryIndexGenerator.test.ts b/code/lib/core-server/src/utils/StoryIndexGenerator.test.ts index c8f7c62578d5..61c491549611 100644 --- a/code/lib/core-server/src/utils/StoryIndexGenerator.test.ts +++ b/code/lib/core-server/src/utils/StoryIndexGenerator.test.ts @@ -1,9 +1,10 @@ /* eslint-disable @typescript-eslint/no-shadow */ -import { describe, test, it, expect } from 'vitest'; /** - * @jest-environment node + * @vitest-environment node */ +import type { Mock } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import path from 'path'; // @ts-expect-error -- cannot find declaration file @@ -18,28 +19,28 @@ import type { StoryIndexGeneratorOptions } from './StoryIndexGenerator'; import { StoryIndexGenerator } from './StoryIndexGenerator'; import { csfIndexer } from '../presets/common-preset'; -vi.mock('@storybook/csf', () => { - const csf = jest.requireActual('@storybook/csf'); +vi.mock('@storybook/csf', async () => { + const csf = await vi.importActual('@storybook/csf'); return { ...csf, - toId: jest.fn(csf.toId), + toId: vi.fn(csf.toId), }; }); vi.mock('@storybook/node-logger'); -const toIdMock = toId as vi.mock>; -vi.mock('@storybook/csf-tools', () => { - const csfTools = jest.requireActual('@storybook/csf-tools'); +const toIdMock = toId as Mock>; +vi.mock('@storybook/csf-tools', async () => { + const csfTools = await vi.importActual('@storybook/csf-tools'); return { ...csfTools, - readCsf: jest.fn(csfTools.readCsf), - getStorySortParameter: jest.fn(csfTools.getStorySortParameter), + readCsf: vi.fn(csfTools.readCsf), + getStorySortParameter: vi.fn(csfTools.getStorySortParameter), }; }); -const readCsfMock = readCsf as vi.mock>; -const getStorySortParameterMock = getStorySortParameter as vi.mock< +const readCsfMock = readCsf as Mock>; +const getStorySortParameterMock = getStorySortParameter as Mock< ReturnType >; @@ -1385,7 +1386,7 @@ describe('StoryIndexGenerator', () => { options ); - const sortFn = jest.fn(); + const sortFn = vi.fn(); getStorySortParameterMock.mockReturnValue(sortFn); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); @@ -1468,7 +1469,7 @@ describe('StoryIndexGenerator', () => { options ); - const sortFn = jest.fn(); + const sortFn = vi.fn(); getStorySortParameterMock.mockReturnValue(sortFn); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); @@ -1509,7 +1510,7 @@ describe('StoryIndexGenerator', () => { options ); - const sortFn = jest.fn(); + const sortFn = vi.fn(); getStorySortParameterMock.mockReturnValue(sortFn); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); diff --git a/code/lib/core-server/src/utils/__tests__/IndexingError.test.ts b/code/lib/core-server/src/utils/__tests__/IndexingError.test.ts index a4ffcea34671..20154aa4250b 100644 --- a/code/lib/core-server/src/utils/__tests__/IndexingError.test.ts +++ b/code/lib/core-server/src/utils/__tests__/IndexingError.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { IndexingError, MultipleIndexingError } from '../IndexingError'; it('formats single file errors', () => { diff --git a/code/lib/core-server/src/utils/__tests__/autoName.test.ts b/code/lib/core-server/src/utils/__tests__/autoName.test.ts index d929d259858a..9aefb7ec3eed 100644 --- a/code/lib/core-server/src/utils/__tests__/autoName.test.ts +++ b/code/lib/core-server/src/utils/__tests__/autoName.test.ts @@ -1,3 +1,4 @@ +import { it, expect } from 'vitest'; import { autoName } from '../autoName'; it('pulls name from named MDX files', () => { diff --git a/code/lib/core-server/src/utils/__tests__/index-extraction.test.ts b/code/lib/core-server/src/utils/__tests__/index-extraction.test.ts index cc826c7ccfc3..e536ba236eed 100644 --- a/code/lib/core-server/src/utils/__tests__/index-extraction.test.ts +++ b/code/lib/core-server/src/utils/__tests__/index-extraction.test.ts @@ -1,8 +1,7 @@ -import { describe, test, it, expect } from 'vitest'; - /** - * @jest-environment node + * @vitest-environment node */ +import { describe, it, expect, vi } from 'vitest'; import path from 'path'; import { normalizeStoriesEntry } from '@storybook/core-common'; diff --git a/code/lib/core-server/src/utils/__tests__/server-address.test.ts b/code/lib/core-server/src/utils/__tests__/server-address.test.ts index 4c4ba898d1b8..39b09939008e 100644 --- a/code/lib/core-server/src/utils/__tests__/server-address.test.ts +++ b/code/lib/core-server/src/utils/__tests__/server-address.test.ts @@ -1,8 +1,10 @@ +import type { Mocked } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import ip from 'ip'; import { getServerAddresses } from '../server-address'; vi.mock('ip'); -const mockedIp = ip as vi.mocked; +const mockedIp = ip as Mocked; describe('getServerAddresses', () => { beforeEach(() => { diff --git a/code/lib/core-server/src/utils/__tests__/server-channel.test.ts b/code/lib/core-server/src/utils/__tests__/server-channel.test.ts index 786370be0f99..eb65c611a877 100644 --- a/code/lib/core-server/src/utils/__tests__/server-channel.test.ts +++ b/code/lib/core-server/src/utils/__tests__/server-channel.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, vi } from 'vitest'; import type { Server } from 'http'; import { Channel } from '@storybook/channels'; @@ -7,13 +8,13 @@ import { getServerChannel, ServerChannelTransport } from '../get-server-channel' describe('getServerChannel', () => { test('should return a channel', () => { - const server = { on: jest.fn() } as any as Server; + const server = { on: vi.fn() } as any as Server; const result = getServerChannel(server); expect(result).toBeInstanceOf(Channel); }); test('should attach to the http server', () => { - const server = { on: jest.fn() } as any as Server; + const server = { on: vi.fn() } as any as Server; getServerChannel(server); expect(server.on).toHaveBeenCalledWith('upgrade', expect.any(Function)); }); @@ -24,7 +25,7 @@ describe('ServerChannelTransport', () => { const server = new EventEmitter() as any as Server; const socket = new EventEmitter(); const transport = new ServerChannelTransport(server); - const handler = jest.fn(); + const handler = vi.fn(); transport.setHandler(handler); // @ts-expect-error (an internal API) @@ -37,7 +38,7 @@ describe('ServerChannelTransport', () => { const server = new EventEmitter() as any as Server; const socket = new EventEmitter(); const transport = new ServerChannelTransport(server); - const handler = jest.fn(); + const handler = vi.fn(); transport.setHandler(handler); // @ts-expect-error (an internal API) @@ -50,7 +51,7 @@ describe('ServerChannelTransport', () => { const server = new EventEmitter() as any as Server; const socket = new EventEmitter(); const transport = new ServerChannelTransport(server); - const handler = jest.fn(); + const handler = vi.fn(); transport.setHandler(handler); // @ts-expect-error (an internal API) @@ -71,7 +72,7 @@ describe('ServerChannelTransport', () => { const server = new EventEmitter() as any as Server; const socket = new EventEmitter(); const transport = new ServerChannelTransport(server); - const handler = jest.fn(); + const handler = vi.fn(); transport.setHandler(handler); // @ts-expect-error (an internal API) diff --git a/code/lib/core-server/src/utils/__tests__/server-statics.test.ts b/code/lib/core-server/src/utils/__tests__/server-statics.test.ts index 879747f8eb64..593086e02bc7 100644 --- a/code/lib/core-server/src/utils/__tests__/server-statics.test.ts +++ b/code/lib/core-server/src/utils/__tests__/server-statics.test.ts @@ -1,9 +1,10 @@ +import { describe, it, expect, vi } from 'vitest'; import fs from 'fs-extra'; import path from 'path'; import 'jest-os-detection'; import { parseStaticDir } from '../server-statics'; -fs.pathExists = jest.fn().mockReturnValue(true); +fs.pathExists = vi.fn().mockReturnValue(true); describe('parseStaticDir', () => { it('returns the static dir/path and default target', async () => { @@ -90,7 +91,7 @@ describe('parseStaticDir', () => { }); it('checks that the path exists', async () => { - fs.pathExists = jest.fn().mockReturnValueOnce(false); + fs.pathExists = vi.fn().mockReturnValueOnce(false); await expect(parseStaticDir('nonexistent')).rejects.toThrow(path.resolve('nonexistent')); }); }); diff --git a/code/lib/core-server/src/utils/server-address.test.ts b/code/lib/core-server/src/utils/server-address.test.ts index 0b3a5b637f29..26e83c6e3d79 100644 --- a/code/lib/core-server/src/utils/server-address.test.ts +++ b/code/lib/core-server/src/utils/server-address.test.ts @@ -1,3 +1,5 @@ +import type { Mock } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import detectPort from 'detect-port'; import { getServerAddresses, getServerPort, getServerChannelUrl } from './server-address'; @@ -51,7 +53,7 @@ describe('getServerPort', () => { it('should resolve with a free port', async () => { const expectedFreePort = 4000; - (detectPort as vi.mock).mockResolvedValue(expectedFreePort); + (detectPort as Mock).mockResolvedValue(expectedFreePort); const result = await getServerPort(port); diff --git a/code/lib/core-server/src/utils/stories-json.test.ts b/code/lib/core-server/src/utils/stories-json.test.ts index c671256a1798..700af21cb10d 100644 --- a/code/lib/core-server/src/utils/stories-json.test.ts +++ b/code/lib/core-server/src/utils/stories-json.test.ts @@ -1,4 +1,5 @@ -import { describe, it, expect, vi } from 'vitest'; +import type { Mock } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import type { Router, Request, Response } from 'express'; import Watchpack from 'watchpack'; @@ -60,27 +61,27 @@ const getInitializedStoryIndexGenerator = async ( }; describe('useStoriesJson', () => { - const use = jest.fn(); + const use = vi.fn(); const router: Router = { use } as any; - const send = jest.fn(); - const write = jest.fn(); + const send = vi.fn(); + const write = vi.fn(); const response: Response = { - header: jest.fn(), + header: vi.fn(), send, - status: jest.fn(), - setHeader: jest.fn(), - flushHeaders: jest.fn(), + status: vi.fn(), + setHeader: vi.fn(), + flushHeaders: vi.fn(), write, - flush: jest.fn(), - end: jest.fn(), - on: jest.fn(), + flush: vi.fn(), + end: vi.fn(), + on: vi.fn(), } as any; beforeEach(async () => { use.mockClear(); send.mockClear(); write.mockClear(); - (debounce as vi.mock).mockImplementation((cb) => cb); + (debounce as Mock).mockImplementation((cb) => cb); }); const request: Request = { @@ -89,7 +90,7 @@ describe('useStoriesJson', () => { describe('JSON endpoint', () => { it('scans and extracts index', async () => { - const mockServerChannel = { emit: jest.fn() } as any as ServerChannel; + const mockServerChannel = { emit: vi.fn() } as any as ServerChannel; useStoriesJson({ router, serverChannel: mockServerChannel, @@ -277,7 +278,7 @@ describe('useStoriesJson', () => { }); it('scans and extracts stories v3', async () => { - const mockServerChannel = { emit: jest.fn() } as any as ServerChannel; + const mockServerChannel = { emit: vi.fn() } as any as ServerChannel; useStoriesJson({ router, initializedStoryIndexGenerator: getInitializedStoryIndexGenerator(), @@ -549,7 +550,7 @@ describe('useStoriesJson', () => { }); it('scans and extracts stories v2', async () => { - const mockServerChannel = { emit: jest.fn() } as any as ServerChannel; + const mockServerChannel = { emit: vi.fn() } as any as ServerChannel; useStoriesJson({ router, initializedStoryIndexGenerator: getInitializedStoryIndexGenerator({ @@ -711,7 +712,7 @@ describe('useStoriesJson', () => { }); it('disallows .mdx files without storyStoreV7', async () => { - const mockServerChannel = { emit: jest.fn() } as any as ServerChannel; + const mockServerChannel = { emit: vi.fn() } as any as ServerChannel; useStoriesJson({ router, initializedStoryIndexGenerator: getInitializedStoryIndexGenerator({ @@ -740,7 +741,7 @@ describe('useStoriesJson', () => { }); it('allows disabling storyStoreV7 if no .mdx files are used', async () => { - const mockServerChannel = { emit: jest.fn() } as any as ServerChannel; + const mockServerChannel = { emit: vi.fn() } as any as ServerChannel; useStoriesJson({ router, initializedStoryIndexGenerator: getInitializedStoryIndexGenerator( @@ -886,7 +887,7 @@ describe('useStoriesJson', () => { }); it('can handle simultaneous access', async () => { - const mockServerChannel = { emit: jest.fn() } as any as ServerChannel; + const mockServerChannel = { emit: vi.fn() } as any as ServerChannel; useStoriesJson({ router, @@ -900,7 +901,7 @@ describe('useStoriesJson', () => { const route = use.mock.calls[0][1]; const firstPromise = route(request, response); - const secondResponse = { ...response, send: jest.fn(), status: jest.fn() }; + const secondResponse = { ...response, send: vi.fn(), status: vi.fn() }; const secondPromise = route(request, secondResponse); await Promise.all([firstPromise, secondPromise]); @@ -919,7 +920,7 @@ describe('useStoriesJson', () => { }); it('sends invalidate events', async () => { - const mockServerChannel = { emit: jest.fn() } as any as ServerChannel; + const mockServerChannel = { emit: vi.fn() } as any as ServerChannel; useStoriesJson({ router, serverChannel: mockServerChannel, @@ -948,7 +949,7 @@ describe('useStoriesJson', () => { }); it('only sends one invalidation when multiple event listeners are listening', async () => { - const mockServerChannel = { emit: jest.fn() } as any as ServerChannel; + const mockServerChannel = { emit: vi.fn() } as any as ServerChannel; useStoriesJson({ router, serverChannel: mockServerChannel, @@ -963,7 +964,7 @@ describe('useStoriesJson', () => { // Don't wait for the first request here before starting the second await Promise.all([ route(request, response), - route(request, { ...response, write: jest.fn() }), + route(request, { ...response, write: vi.fn() }), ]); expect(write).not.toHaveBeenCalled(); @@ -981,9 +982,9 @@ describe('useStoriesJson', () => { }); it('debounces invalidation events', async () => { - (debounce as vi.mock).mockImplementation(jest.requireActual('lodash/debounce.js') as any); + (debounce as Mock).mockImplementation((await vi.importActual('lodash/debounce.js')) as any); - const mockServerChannel = { emit: jest.fn() } as any as ServerChannel; + const mockServerChannel = { emit: vi.fn() } as any as ServerChannel; useStoriesJson({ router, serverChannel: mockServerChannel, diff --git a/code/lib/core-server/src/utils/summarizeIndex.test.ts b/code/lib/core-server/src/utils/summarizeIndex.test.ts index 8662b0e45716..1de47dc6e6d7 100644 --- a/code/lib/core-server/src/utils/summarizeIndex.test.ts +++ b/code/lib/core-server/src/utils/summarizeIndex.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { isPageStory, summarizeIndex } from './summarizeIndex'; describe('isPageStory', () => { diff --git a/code/lib/core-server/src/utils/watch-story-specifiers.test.ts b/code/lib/core-server/src/utils/watch-story-specifiers.test.ts index f515fea7907c..22d3e0901de8 100644 --- a/code/lib/core-server/src/utils/watch-story-specifiers.test.ts +++ b/code/lib/core-server/src/utils/watch-story-specifiers.test.ts @@ -1,3 +1,4 @@ +import { describe, afterEach, it, expect, vi } from 'vitest'; import { normalizeStoriesEntry } from '@storybook/core-common'; import path from 'path'; import Watchpack from 'watchpack'; @@ -19,7 +20,7 @@ describe('watchStorySpecifiers', () => { it('watches basic globs', async () => { const specifier = normalizeStoriesEntry('../src/**/*.stories.@(ts|js)', options); - const onInvalidate = jest.fn(); + const onInvalidate = vi.fn(); close = watchStorySpecifiers([specifier], { workingDir }, onInvalidate); expect(Watchpack).toHaveBeenCalledTimes(1); @@ -66,7 +67,7 @@ describe('watchStorySpecifiers', () => { it('scans directories when they are added', async () => { const specifier = normalizeStoriesEntry('../src/**/*.stories.@(ts|js)', options); - const onInvalidate = jest.fn(); + const onInvalidate = vi.fn(); close = watchStorySpecifiers([specifier], { workingDir }, onInvalidate); expect(Watchpack).toHaveBeenCalledTimes(1); @@ -84,7 +85,7 @@ describe('watchStorySpecifiers', () => { it('watches single file globs', async () => { const specifier = normalizeStoriesEntry('../src/nested/Button.stories.mdx', options); - const onInvalidate = jest.fn(); + const onInvalidate = vi.fn(); close = watchStorySpecifiers([specifier], { workingDir }, onInvalidate); expect(Watchpack).toHaveBeenCalledTimes(1); @@ -125,7 +126,7 @@ describe('watchStorySpecifiers', () => { const globSpecifier = normalizeStoriesEntry('../src/**/*.stories.@(ts|js)', options); const fileSpecifier = normalizeStoriesEntry('../src/nested/Button.stories.mdx', options); - const onInvalidate = jest.fn(); + const onInvalidate = vi.fn(); close = watchStorySpecifiers([globSpecifier, fileSpecifier], { workingDir }, onInvalidate); expect(Watchpack).toHaveBeenCalledTimes(1); diff --git a/code/lib/core-server/src/withTelemetry.test.ts b/code/lib/core-server/src/withTelemetry.test.ts index e2b3ab1588d1..1201e21cd894 100644 --- a/code/lib/core-server/src/withTelemetry.test.ts +++ b/code/lib/core-server/src/withTelemetry.test.ts @@ -1,7 +1,8 @@ +/// /* eslint-disable local-rules/no-uncategorized-errors */ -import { describe, test, it, expect } from 'vitest'; - +import { describe, beforeEach, it, expect } from 'vitest'; import prompts from 'prompts'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import { loadAllPresets, cache } from '@storybook/core-common'; import { telemetry, oneWayHash } from '@storybook/telemetry'; @@ -15,7 +16,7 @@ const cliOptions = {}; describe('withTelemetry', () => { it('works in happy path', async () => { - const run = jest.fn(); + const run = vi.fn(); await withTelemetry('dev', { cliOptions }, run); @@ -24,7 +25,7 @@ describe('withTelemetry', () => { }); it('does not send boot when cli option is passed', async () => { - const run = jest.fn(); + const run = vi.fn(); await withTelemetry('dev', { cliOptions: { disableTelemetry: true } }, run); @@ -33,13 +34,13 @@ describe('withTelemetry', () => { describe('when command fails', () => { const error = new Error('An Error!'); - const run = jest.fn(async () => { + const run = vi.fn(async () => { throw error; }); it('sends boot message', async () => { await expect(async () => - withTelemetry('dev', { cliOptions, printError: jest.fn() }, run) + withTelemetry('dev', { cliOptions, printError: vi.fn() }, run) ).rejects.toThrow(error); expect(telemetry).toHaveBeenCalledWith('boot', { eventType: 'dev' }, { stripMetadata: true }); @@ -47,7 +48,7 @@ describe('withTelemetry', () => { it('does not send boot when cli option is passed', async () => { await expect(async () => - withTelemetry('dev', { cliOptions: { disableTelemetry: true }, printError: jest.fn() }, run) + withTelemetry('dev', { cliOptions: { disableTelemetry: true }, printError: vi.fn() }, run) ).rejects.toThrow(error); expect(telemetry).toHaveBeenCalledTimes(0); @@ -55,7 +56,7 @@ describe('withTelemetry', () => { it('sends error message when no options are passed', async () => { await expect(async () => - withTelemetry('dev', { cliOptions, printError: jest.fn() }, run) + withTelemetry('dev', { cliOptions, printError: vi.fn() }, run) ).rejects.toThrow(error); expect(telemetry).toHaveBeenCalledTimes(2); @@ -68,7 +69,7 @@ describe('withTelemetry', () => { it('does not send error message when cli opt out is passed', async () => { await expect(async () => - withTelemetry('dev', { cliOptions: { disableTelemetry: true }, printError: jest.fn() }, run) + withTelemetry('dev', { cliOptions: { disableTelemetry: true }, printError: vi.fn() }, run) ).rejects.toThrow(error); expect(telemetry).toHaveBeenCalledTimes(0); @@ -86,7 +87,7 @@ describe('withTelemetry', () => { await expect(async () => withTelemetry( 'dev', - { cliOptions: {} as any, presetOptions: {} as any, printError: jest.fn() }, + { cliOptions: {} as any, presetOptions: {} as any, printError: vi.fn() }, run ) ).rejects.toThrow(error); @@ -107,7 +108,7 @@ describe('withTelemetry', () => { await expect(async () => withTelemetry( 'dev', - { cliOptions: {} as any, presetOptions: {} as any, printError: jest.fn() }, + { cliOptions: {} as any, presetOptions: {} as any, printError: vi.fn() }, run ) ).rejects.toThrow(error); @@ -128,7 +129,7 @@ describe('withTelemetry', () => { await expect(async () => withTelemetry( 'dev', - { cliOptions: {} as any, presetOptions: {} as any, printError: jest.fn() }, + { cliOptions: {} as any, presetOptions: {} as any, printError: vi.fn() }, run ) ).rejects.toThrow(error); @@ -149,7 +150,7 @@ describe('withTelemetry', () => { await expect(async () => withTelemetry( 'dev', - { cliOptions: {} as any, presetOptions: {} as any, printError: jest.fn() }, + { cliOptions: {} as any, presetOptions: {} as any, printError: vi.fn() }, run ) ).rejects.toThrow(error); @@ -171,7 +172,7 @@ describe('withTelemetry', () => { await expect(async () => withTelemetry( 'dev', - { cliOptions: {} as any, presetOptions: {} as any, printError: jest.fn() }, + { cliOptions: {} as any, presetOptions: {} as any, printError: vi.fn() }, run ) ).rejects.toThrow(error); @@ -193,7 +194,7 @@ describe('withTelemetry', () => { await expect(async () => withTelemetry( 'dev', - { cliOptions: {} as any, presetOptions: {} as any, printError: jest.fn() }, + { cliOptions: {} as any, presetOptions: {} as any, printError: vi.fn() }, run ) ).rejects.toThrow(error); @@ -216,7 +217,7 @@ describe('withTelemetry', () => { await expect(async () => withTelemetry( 'dev', - { cliOptions: {} as any, presetOptions: {} as any, printError: jest.fn() }, + { cliOptions: {} as any, presetOptions: {} as any, printError: vi.fn() }, run ) ).rejects.toThrow(error); @@ -239,7 +240,7 @@ describe('withTelemetry', () => { await expect(async () => withTelemetry( 'dev', - { cliOptions: {} as any, presetOptions: {} as any, printError: jest.fn() }, + { cliOptions: {} as any, presetOptions: {} as any, printError: vi.fn() }, run ) ).rejects.toThrow(error); @@ -260,7 +261,7 @@ describe('withTelemetry', () => { await expect(async () => withTelemetry( 'dev', - { cliOptions: {} as any, presetOptions: {} as any, printError: jest.fn() }, + { cliOptions: {} as any, presetOptions: {} as any, printError: vi.fn() }, run ) ).rejects.toThrow(error); @@ -347,7 +348,7 @@ describe('sendTelemetryError', () => { describe('getErrorLevel', () => { beforeEach(() => { - jest.resetAllMocks(); + vi.resetAllMocks(); }); it('returns "none" when cliOptions.disableTelemetry is true', async () => { diff --git a/code/lib/core-webpack/src/importPipeline.test.ts b/code/lib/core-webpack/src/importPipeline.test.ts index 6c6642121a44..5d9775c8d453 100644 --- a/code/lib/core-webpack/src/importPipeline.test.ts +++ b/code/lib/core-webpack/src/importPipeline.test.ts @@ -1,3 +1,4 @@ +import { it, expect, vi } from 'vitest'; import { importPipeline } from './importPipeline'; const createGate = (): [Promise, (_?: any) => void] => { @@ -10,7 +11,7 @@ const createGate = (): [Promise, (_?: any) => void] => { it('passes through to passed importFn on serial calls', async () => { const pipeline = importPipeline(); - const importFn = jest.fn(); + const importFn = vi.fn(); importFn.mockResolvedValueOnce('r1'); expect(await pipeline(() => importFn('i1'))).toEqual('r1'); @@ -26,7 +27,7 @@ it('passes through to passed importFn on serial calls', async () => { it('blocks on parallel calls', async () => { const pipeline = importPipeline(); const [firstGate, openFirstGate] = createGate(); - const importFn = jest + const importFn = vi .fn() .mockImplementationOnce(() => firstGate) .mockResolvedValueOnce('r2'); @@ -54,7 +55,7 @@ it('blocks on parallel calls', async () => { it('dispatches all queued calls on opening', async () => { const pipeline = importPipeline(); const [firstGate, openFirstGate] = createGate(); - const importFn = jest + const importFn = vi .fn() .mockImplementationOnce(() => firstGate) .mockResolvedValueOnce('r2') @@ -89,7 +90,7 @@ it('blocks sequentially on parallel calls', async () => { const pipeline = importPipeline(); const [firstGate, openFirstGate] = createGate(); const [secondGate, openSecondGate] = createGate(); - const importFn = jest + const importFn = vi .fn() .mockImplementationOnce(() => firstGate) .mockImplementationOnce(() => secondGate) diff --git a/code/lib/core-webpack/src/merge-webpack-config.test.ts b/code/lib/core-webpack/src/merge-webpack-config.test.ts index e41768955455..7b2c026c2338 100644 --- a/code/lib/core-webpack/src/merge-webpack-config.test.ts +++ b/code/lib/core-webpack/src/merge-webpack-config.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import type { Configuration } from 'webpack'; import { mergeConfigs } from './merge-webpack-config'; diff --git a/code/lib/core-webpack/src/to-importFn.test.ts b/code/lib/core-webpack/src/to-importFn.test.ts index 66d9ab63be70..389f10db8dcd 100644 --- a/code/lib/core-webpack/src/to-importFn.test.ts +++ b/code/lib/core-webpack/src/to-importFn.test.ts @@ -1,3 +1,4 @@ +import { describe, expect } from 'vitest'; import { normalizeStoriesEntry } from '@storybook/core-common'; import { webpackIncludeRegexp } from './to-importFn'; diff --git a/code/lib/core-webpack/src/to-require-context.test.ts b/code/lib/core-webpack/src/to-require-context.test.ts index e1e9d616d165..90fab1d15f97 100644 --- a/code/lib/core-webpack/src/to-require-context.test.ts +++ b/code/lib/core-webpack/src/to-require-context.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import path from 'path'; import { normalizeStoriesEntry } from '@storybook/core-common'; diff --git a/code/lib/csf-tools/src/ConfigFile.test.ts b/code/lib/csf-tools/src/ConfigFile.test.ts index 93016db8b8ae..83a4df393e27 100644 --- a/code/lib/csf-tools/src/ConfigFile.test.ts +++ b/code/lib/csf-tools/src/ConfigFile.test.ts @@ -1,6 +1,7 @@ -import { describe, test, it, expect } from 'vitest'; - +/// +import { describe, it, expect } from 'vitest'; import { dedent } from 'ts-dedent'; +import { describe, it, expect } from 'vitest'; import { loadConfig, printConfig } from './ConfigFile'; import { babelPrint } from './babelParse'; diff --git a/code/lib/csf-tools/src/CsfFile.test.ts b/code/lib/csf-tools/src/CsfFile.test.ts index 5cdf8a265de0..922efd0b4e0f 100644 --- a/code/lib/csf-tools/src/CsfFile.test.ts +++ b/code/lib/csf-tools/src/CsfFile.test.ts @@ -1,7 +1,9 @@ -import { describe, test, it, expect } from 'vitest'; - +/// /* eslint-disable no-underscore-dangle */ +import { describe, it, expect } from 'vitest'; + import { dedent } from 'ts-dedent'; +import { describe, it, expect, vi } from 'vitest'; import yaml from 'js-yaml'; import { loadCsf } from './CsfFile'; @@ -813,7 +815,7 @@ describe('CsfFile', () => { }); it('Object export with storyName', () => { - const consoleWarnMock = jest.spyOn(console, 'warn').mockImplementation(); + const consoleWarnMock = vi.spyOn(console, 'warn').mockImplementation(); parse( dedent` diff --git a/code/lib/csf-tools/src/enrichCsf.test.ts b/code/lib/csf-tools/src/enrichCsf.test.ts index 9aa89ca9a616..2dacbbbcc4f3 100644 --- a/code/lib/csf-tools/src/enrichCsf.test.ts +++ b/code/lib/csf-tools/src/enrichCsf.test.ts @@ -1,7 +1,8 @@ -import { describe, test, it, expect } from 'vitest'; +/// /* eslint-disable no-underscore-dangle */ - +import { describe, it, expect } from 'vitest'; import { dedent } from 'ts-dedent'; +import { describe, it, expect } from 'vitest'; import { formatCsf, loadCsf } from './CsfFile'; import type { EnrichCsfOptions } from './enrichCsf'; import { enrichCsf, extractSource } from './enrichCsf'; diff --git a/code/lib/csf-tools/src/getStorySortParameter.test.ts b/code/lib/csf-tools/src/getStorySortParameter.test.ts index d62c21cc9857..78216cb01f9a 100644 --- a/code/lib/csf-tools/src/getStorySortParameter.test.ts +++ b/code/lib/csf-tools/src/getStorySortParameter.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { dedent } from 'ts-dedent'; import { getStorySortParameter } from './getStorySortParameter'; diff --git a/code/lib/docs-tools/src/argTypes/convert/convert.test.ts b/code/lib/docs-tools/src/argTypes/convert/convert.test.ts index 5b7b15ec6c63..2a0237f0bae3 100644 --- a/code/lib/docs-tools/src/argTypes/convert/convert.test.ts +++ b/code/lib/docs-tools/src/argTypes/convert/convert.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import 'jest-specific-snapshot'; import mapValues from 'lodash/mapValues.js'; import { transformSync } from '@babel/core'; diff --git a/code/lib/docs-tools/src/argTypes/docgen/extractDocgenProps.test.ts b/code/lib/docs-tools/src/argTypes/docgen/extractDocgenProps.test.ts index 8e60d01b5ff6..452e85677614 100644 --- a/code/lib/docs-tools/src/argTypes/docgen/extractDocgenProps.test.ts +++ b/code/lib/docs-tools/src/argTypes/docgen/extractDocgenProps.test.ts @@ -1,4 +1,5 @@ /* eslint-disable no-underscore-dangle */ +import { describe, it, expect } from 'vitest'; import type { Component } from '../types'; import { extractComponentProps } from './extractDocgenProps'; diff --git a/code/lib/docs-tools/src/argTypes/docgen/flow/createPropDef.test.ts b/code/lib/docs-tools/src/argTypes/docgen/flow/createPropDef.test.ts index 3a912c98db17..3cfb59931211 100644 --- a/code/lib/docs-tools/src/argTypes/docgen/flow/createPropDef.test.ts +++ b/code/lib/docs-tools/src/argTypes/docgen/flow/createPropDef.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { createFlowPropDef } from './createPropDef'; import type { DocgenInfo } from '../types'; diff --git a/code/lib/docs-tools/src/argTypes/docgen/typeScript/createPropDef.test.ts b/code/lib/docs-tools/src/argTypes/docgen/typeScript/createPropDef.test.ts index 72dfad81c4a4..6be717be881d 100644 --- a/code/lib/docs-tools/src/argTypes/docgen/typeScript/createPropDef.test.ts +++ b/code/lib/docs-tools/src/argTypes/docgen/typeScript/createPropDef.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { createTsPropDef } from './createPropDef'; import type { DocgenInfo } from '../types'; diff --git a/code/lib/docs-tools/src/argTypes/enhanceArgTypes.test.ts b/code/lib/docs-tools/src/argTypes/enhanceArgTypes.test.ts index 7fdedf3db758..5cae300b49e8 100644 --- a/code/lib/docs-tools/src/argTypes/enhanceArgTypes.test.ts +++ b/code/lib/docs-tools/src/argTypes/enhanceArgTypes.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import type { ArgTypes, StrictInputType } from '@storybook/types'; import { enhanceArgTypes } from './enhanceArgTypes'; diff --git a/code/lib/docs-tools/src/argTypes/jsdocParser.test.ts b/code/lib/docs-tools/src/argTypes/jsdocParser.test.ts index 459b7f2c8c93..711074f2acbd 100644 --- a/code/lib/docs-tools/src/argTypes/jsdocParser.test.ts +++ b/code/lib/docs-tools/src/argTypes/jsdocParser.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { parseJsDoc } from './jsdocParser'; describe('parseJsDoc', () => { diff --git a/code/lib/docs-tools/src/argTypes/utils.test.ts b/code/lib/docs-tools/src/argTypes/utils.test.ts index 0cd887200ded..fc0a204a531c 100644 --- a/code/lib/docs-tools/src/argTypes/utils.test.ts +++ b/code/lib/docs-tools/src/argTypes/utils.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { createSummaryValue } from './utils'; describe('createSummaryValue', () => { diff --git a/code/lib/instrumenter/src/instrumenter.test.ts b/code/lib/instrumenter/src/instrumenter.test.ts index 0f8728faf9b5..905c461c28c9 100644 --- a/code/lib/instrumenter/src/instrumenter.test.ts +++ b/code/lib/instrumenter/src/instrumenter.test.ts @@ -1,7 +1,8 @@ -import { describe, test, it, expect } from 'vitest'; +/// /* eslint-disable no-underscore-dangle */ - +import { describe, beforeEach, afterEach, it, expect } from 'vitest'; import { addons, mockChannel } from '@storybook/preview-api'; +import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; import { logger } from '@storybook/client-logger'; import { FORCE_REMOUNT, @@ -15,9 +16,9 @@ import type { Options } from './types'; vi.mock('@storybook/client-logger'); -const callSpy = jest.fn(); -const syncSpy = jest.fn(); -const forceRemountSpy = jest.fn(); +const callSpy = vi.fn(); +const syncSpy = vi.fn(); +const forceRemountSpy = vi.fn(); addons.setChannel(mockChannel()); addons.getChannel().on(EVENTS.CALL, callSpy); addons.getChannel().on(EVENTS.SYNC, syncSpy); @@ -32,7 +33,7 @@ class HTMLElement { // @ts-expect-error (global scope type conflicts) delete global.location; // @ts-expect-error (global scope type conflicts) -global.location = { reload: jest.fn() }; +global.location = { reload: vi.fn() }; // @ts-expect-error (global scope type conflicts) global.HTMLElement = HTMLElement; @@ -51,7 +52,7 @@ const instrument = >(obj: TObj, options: Option const tick = () => new Promise((resolve) => setTimeout(resolve, 0)); beforeEach(() => { - jest.useRealTimers(); + vi.useRealTimers(); callSpy.mockClear(); syncSpy.mockClear(); forceRemountSpy.mockClear(); @@ -113,7 +114,7 @@ describe('Instrumenter', () => { }); it('patched functions call the original function when invoked', () => { - const { fn } = instrument({ fn: jest.fn() }); + const { fn } = instrument({ fn: vi.fn() }); const obj = {}; fn('foo', obj); expect(fn.__originalFn__).toHaveBeenCalledWith('foo', obj); @@ -357,20 +358,20 @@ describe('Instrumenter', () => { it('emits a "sync" event with debounce after a patched function is invoked', () => { const { fn } = instrument({ fn: (...args: any) => {} }, { intercept: true }); - jest.useFakeTimers(); + vi.useFakeTimers(); syncSpy.mockClear(); fn('foo'); fn('bar'); - jest.runAllTimers(); + vi.runAllTimers(); expect(syncSpy).toHaveBeenCalledTimes(1); }); it('sends a folded log with the "sync" event', () => { const { fn } = instrument({ fn: (...args: any) => ({ fn2: () => {} }) }, { intercept: true }); - jest.useFakeTimers(); + vi.useFakeTimers(); fn('foo', fn('bar')).fn2(); fn('baz'); - jest.runAllTimers(); + vi.runAllTimers(); expect(syncSpy).toHaveBeenCalledWith( expect.objectContaining({ logItems: [ @@ -402,7 +403,7 @@ describe('Instrumenter', () => { it('bubbles child exceptions up to parent (in callback)', () => { const { fn1, fn2 } = instrument({ - fn1: jest.fn((callback: Function) => callback()), + fn1: vi.fn((callback: Function) => callback()), fn2: () => { throw new Error('Boom!'); }, @@ -429,7 +430,7 @@ describe('Instrumenter', () => { }); it('does not affect intercepted methods', () => { - const { fn } = instrument({ fn: jest.fn() }, { intercept: true }); + const { fn } = instrument({ fn: vi.fn() }, { intercept: true }); fn('foo'); expect(fn.__originalFn__).toHaveBeenCalledWith('foo'); }); @@ -532,14 +533,14 @@ describe('Instrumenter', () => { }); it('defers calls to intercepted functions', () => { - const { fn } = instrument({ fn: jest.fn() }, { intercept: true }); + const { fn } = instrument({ fn: vi.fn() }, { intercept: true }); addons.getChannel().emit(EVENTS.START, { storyId }); expect(fn()).toEqual(expect.any(Promise)); expect(fn.__originalFn__).not.toHaveBeenCalled(); }); it('does not defer calls to non-intercepted functions', () => { - const { fn } = instrument({ fn: jest.fn(() => 'ok') }); + const { fn } = instrument({ fn: vi.fn(() => 'ok') }); addons.getChannel().emit(EVENTS.START, { storyId }); expect(fn()).toBe('ok'); expect(fn.__originalFn__).toHaveBeenCalled(); @@ -547,7 +548,7 @@ describe('Instrumenter', () => { it('does not defer calls to intercepted functions that are chained upon', () => { const { fn1 } = instrument( - { fn1: jest.fn(() => ({ fn2: jest.fn() as any })) }, + { fn1: vi.fn(() => ({ fn2: vi.fn() as any })) }, { intercept: true } ); fn1().fn2(); @@ -572,10 +573,10 @@ describe('Instrumenter', () => { }); it('steps through each interceptable function on "next"', async () => { - const fn = jest.fn(); + const fn = vi.fn(); const { fn: instrumentedFn } = instrument({ fn }, { intercept: true }); - const mockedInstrumentedFn = jest.fn(instrumentedFn); + const mockedInstrumentedFn = vi.fn(instrumentedFn); const play = async () => { await mockedInstrumentedFn(); await mockedInstrumentedFn(); diff --git a/code/lib/manager-api/src/lib/stories.test.ts b/code/lib/manager-api/src/lib/stories.test.ts index 59912863be9e..af5807ac2d14 100644 --- a/code/lib/manager-api/src/lib/stories.test.ts +++ b/code/lib/manager-api/src/lib/stories.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import type { StoryIndexV2, StoryIndexV3 } from '@storybook/types'; import { transformStoryIndexV2toV3, transformStoryIndexV3toV4 } from './stories'; diff --git a/code/lib/manager-api/src/tests/addons.test.js b/code/lib/manager-api/src/tests/addons.test.js index fd94abde0292..46770d083cc9 100644 --- a/code/lib/manager-api/src/tests/addons.test.js +++ b/code/lib/manager-api/src/tests/addons.test.js @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import { Addon_TypesEnum as types } from '@storybook/types'; import { init as initAddons } from '../modules/addons'; @@ -29,7 +30,7 @@ const store = { getState: () => ({ selectedPanel: '', }), - setState: jest.fn(), + setState: vi.fn(), }; describe('Addons API', () => { @@ -88,7 +89,7 @@ describe('Addons API', () => { storyId, storiesHash, }), - setState: jest.fn(), + setState: vi.fn(), }; const { api } = initAddons({ @@ -115,7 +116,7 @@ describe('Addons API', () => { getState: () => ({ selectedPanel: 'actions', }), - setState: jest.fn(), + setState: vi.fn(), }; const { api } = initAddons({ provider, store: storeWithSelectedPanel }); @@ -132,7 +133,7 @@ describe('Addons API', () => { getState: () => ({ selectedPanel: 'unknown', }), - setState: jest.fn(), + setState: vi.fn(), }; const { api } = initAddons({ provider, store: storeWithSelectedPanel }); @@ -147,7 +148,7 @@ describe('Addons API', () => { describe('#setSelectedPanel', () => { it('should set value inn store', () => { // given - const setState = jest.fn(); + const setState = vi.fn(); const storeWithSelectedPanel = { getState: () => ({ selectedPanel: 'actions', diff --git a/code/lib/manager-api/src/tests/events.test.ts b/code/lib/manager-api/src/tests/events.test.ts index c380a107c7d4..cd0ec857297c 100644 --- a/code/lib/manager-api/src/tests/events.test.ts +++ b/code/lib/manager-api/src/tests/events.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import { getEventMetadata } from '../lib/events'; import type { API } from '../index'; @@ -8,7 +9,7 @@ vi.mock('@storybook/global', () => ({ })); describe('getEventMetadata', () => { - const fullAPIMock = { findRef: jest.fn(), getRefs: jest.fn() }; + const fullAPIMock = { findRef: vi.fn(), getRefs: vi.fn() }; const fullAPI = fullAPIMock as unknown as API; it('returns local if the event source is the same current location', () => { diff --git a/code/lib/manager-api/src/tests/globals.test.ts b/code/lib/manager-api/src/tests/globals.test.ts index b6db27711f37..69f7e46597a3 100644 --- a/code/lib/manager-api/src/tests/globals.test.ts +++ b/code/lib/manager-api/src/tests/globals.test.ts @@ -1,3 +1,4 @@ +import { describe, beforeEach, it, expect, vi } from 'vitest'; import { EventEmitter } from 'events'; import { SET_STORIES, SET_GLOBALS, UPDATE_GLOBALS, GLOBALS_UPDATED } from '@storybook/core-events'; @@ -18,8 +19,8 @@ beforeEach(() => { function createMockStore() { let state = {}; return { - getState: jest.fn().mockImplementation(() => state), - setState: jest.fn().mockImplementation((s) => { + getState: vi.fn().mockImplementation(() => state), + setState: vi.fn().mockImplementation((s) => { state = { ...state, ...s }; }), }; @@ -58,7 +59,7 @@ describe('globals API', () => { it('ignores SET_STORIES from other refs', () => { const channel = new EventEmitter(); - const api = { findRef: jest.fn() }; + const api = { findRef: vi.fn() }; const store = createMockStore(); const { state } = initModule({ store, @@ -73,7 +74,7 @@ describe('globals API', () => { }); it('ignores SET_GLOBALS from other refs', () => { - const api = { findRef: jest.fn() }; + const api = { findRef: vi.fn() }; const channel = new EventEmitter(); const store = createMockStore(); const { state } = initModule({ @@ -93,7 +94,7 @@ describe('globals API', () => { it('updates the state when the preview emits GLOBALS_UPDATED', () => { const channel = new EventEmitter(); - const api = { findRef: jest.fn() }; + const api = { findRef: vi.fn() }; const store = createMockStore(); const { state } = initModule({ store, @@ -115,7 +116,7 @@ describe('globals API', () => { it('ignores GLOBALS_UPDATED from other refs', () => { const channel = new EventEmitter(); - const api = { findRef: jest.fn() }; + const api = { findRef: vi.fn() }; const store = createMockStore(); const { state } = initModule({ store, @@ -135,7 +136,7 @@ describe('globals API', () => { const channel = new EventEmitter(); const fullAPI = {} as unknown as API; const store = createMockStore(); - const listener = jest.fn(); + const listener = vi.fn(); channel.on(UPDATE_GLOBALS, listener); const { api } = initModule({ store, fullAPI, provider: { channel } } as unknown as ModuleArgs); diff --git a/code/lib/manager-api/src/tests/layout.test.js b/code/lib/manager-api/src/tests/layout.test.js index f2032ba1e118..e51556526f46 100644 --- a/code/lib/manager-api/src/tests/layout.test.js +++ b/code/lib/manager-api/src/tests/layout.test.js @@ -1,3 +1,4 @@ +import { describe, beforeEach, it, expect, vi } from 'vitest'; import { themes } from '@storybook/theming'; import { init as initLayout } from '../modules/layout'; @@ -23,14 +24,14 @@ beforeEach(() => { }; store = { getState: () => currentState, - setState: jest.fn((patch) => { + setState: vi.fn((patch) => { currentState = { ...currentState, ...(typeof patch === 'function' ? patch(currentState) : patch), }; }), }; - provider = { getConfig: jest.fn(() => ({})) }; + provider = { getConfig: vi.fn(() => ({})) }; layoutApi = initLayout({ store, provider }).api; }); diff --git a/code/lib/manager-api/src/tests/notifications.test.js b/code/lib/manager-api/src/tests/notifications.test.js index ffa2a1eec86b..51a53be2b1e3 100644 --- a/code/lib/manager-api/src/tests/notifications.test.js +++ b/code/lib/manager-api/src/tests/notifications.test.js @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import { init as initNotifications } from '../modules/notifications'; describe('notifications API', () => { @@ -6,7 +7,7 @@ describe('notifications API', () => { getState: () => ({ notifications: [], }), - setState: jest.fn(), + setState: vi.fn(), }; const { api } = initNotifications({ store }); @@ -22,7 +23,7 @@ describe('notifications API', () => { getState: () => ({ notifications: [{ id: '1' }, { id: '2' }, { id: '3' }], }), - setState: jest.fn(), + setState: vi.fn(), }; const { api } = initNotifications({ store }); diff --git a/code/lib/manager-api/src/tests/refs.test.ts b/code/lib/manager-api/src/tests/refs.test.ts index 1f987f1e047d..95f917ad3dda 100644 --- a/code/lib/manager-api/src/tests/refs.test.ts +++ b/code/lib/manager-api/src/tests/refs.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import { global } from '@storybook/global'; import { getSourceType, init as initRefs } from '../modules/refs'; @@ -7,7 +8,7 @@ const fetchMock = vi.mocked(fetch); vi.mock('@storybook/global', () => { const globalMock = { - fetch: jest.fn(() => Promise.resolve({})), + fetch: vi.fn(() => Promise.resolve({})), REFS: { fake: { id: 'fake', @@ -27,7 +28,7 @@ vi.mock('@storybook/global', () => { Object.defineProperties(globalMock, { location: { get: edgecaseLocations - .reduce((mockFn, location) => mockFn.mockReturnValueOnce(location), jest.fn()) + .reduce((mockFn, location) => mockFn.mockReturnValueOnce(location), vi.fn()) .mockReturnValue(lastLocation), }, }); @@ -35,11 +36,11 @@ vi.mock('@storybook/global', () => { }); const provider = { - getConfig: jest.fn().mockReturnValue({}), + getConfig: vi.fn().mockReturnValue({}), }; const store = { - getState: jest.fn().mockReturnValue({ + getState: vi.fn().mockReturnValue({ refs: { fake: { id: 'fake', @@ -48,7 +49,7 @@ const store = { }, }, }), - setState: jest.fn((a: any) => {}), + setState: vi.fn((a: any) => {}), }; interface ResponseResult { diff --git a/code/lib/manager-api/src/tests/shortcut.test.js b/code/lib/manager-api/src/tests/shortcut.test.js index 9f9d889576c2..068c938640c5 100644 --- a/code/lib/manager-api/src/tests/shortcut.test.js +++ b/code/lib/manager-api/src/tests/shortcut.test.js @@ -1,6 +1,7 @@ /** - * @jest-environment jsdom + * @vitest-environment jsdom */ +import { describe, expect } from 'vitest'; import { global } from '@storybook/global'; import { eventToShortcut, keyToSymbol } from '../lib/shortcut'; diff --git a/code/lib/manager-api/src/tests/shortcuts.test.js b/code/lib/manager-api/src/tests/shortcuts.test.js index 2e9b9126185c..d5604a47f020 100644 --- a/code/lib/manager-api/src/tests/shortcuts.test.js +++ b/code/lib/manager-api/src/tests/shortcuts.test.js @@ -1,10 +1,11 @@ +import { describe, it, expect, vi } from 'vitest'; import { init as initShortcuts } from '../modules/shortcuts'; function createMockStore() { let state = {}; return { - getState: jest.fn().mockImplementation(() => state), - setState: jest.fn().mockImplementation((s) => { + getState: vi.fn().mockImplementation(() => state), + setState: vi.fn().mockImplementation((s) => { state = { ...state, ...s }; }), }; diff --git a/code/lib/manager-api/src/tests/store.test.js b/code/lib/manager-api/src/tests/store.test.js index 2403c373a27c..4543686815d7 100644 --- a/code/lib/manager-api/src/tests/store.test.js +++ b/code/lib/manager-api/src/tests/store.test.js @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import store2 from 'store2'; import flushPromises from 'flush-promises'; @@ -5,12 +6,12 @@ import Store, { STORAGE_KEY } from '../store'; vi.mock('store2', () => ({ local: { - set: jest.fn(), - get: jest.fn(), + set: vi.fn(), + get: vi.fn(), }, session: { - set: jest.fn(), - get: jest.fn(), + set: vi.fn(), + get: vi.fn(), }, _: { fn: () => {} }, })); @@ -30,7 +31,7 @@ describe('store', () => { }); it('passes getState right through', () => { - const getState = jest.fn(); + const getState = vi.fn(); const store = new Store({ getState }); store.getState(); @@ -40,7 +41,7 @@ describe('store', () => { describe('setState', () => { it('sets values in React only by default', async () => { - const setState = jest.fn().mockImplementation((x, cb) => cb()); + const setState = vi.fn().mockImplementation((x, cb) => cb()); const store = new Store({ setState }); await store.setState({ foo: 'bar' }); @@ -51,7 +52,7 @@ describe('store', () => { }); it('sets values in React and sessionStorage if persistence === session', async () => { - const setState = jest.fn().mockImplementation((x, cb) => cb()); + const setState = vi.fn().mockImplementation((x, cb) => cb()); const store = new Store({ setState }); await store.setState({ foo: 'bar' }, { persistence: 'session' }); @@ -62,7 +63,7 @@ describe('store', () => { }); it('sets values in React and sessionStorage if persistence === permanent', async () => { - const setState = jest.fn().mockImplementation((x, cb) => cb()); + const setState = vi.fn().mockImplementation((x, cb) => cb()); const store = new Store({ setState }); await store.setState({ foo: 'bar' }, { persistence: 'permanent' }); @@ -73,7 +74,7 @@ describe('store', () => { }); it('properly patches existing values', async () => { - const setState = jest.fn().mockImplementation((x, cb) => cb()); + const setState = vi.fn().mockImplementation((x, cb) => cb()); store2.session.get.mockReturnValueOnce({ foo: 'baz', another: 'value', @@ -96,7 +97,7 @@ describe('store', () => { it('waits for react to setState', async () => { let cb; - const setState = jest.fn().mockImplementation((x, inputCb) => { + const setState = vi.fn().mockImplementation((x, inputCb) => { cb = inputCb; }); const store = new Store({ setState }); @@ -117,7 +118,7 @@ describe('store', () => { }); it('returns react.setState result', async () => { - const setState = jest.fn().mockImplementation((x, cb) => cb('RESULT')); + const setState = vi.fn().mockImplementation((x, cb) => cb('RESULT')); const store = new Store({ setState }); const result = await store.setState({ foo: 'bar' }); @@ -127,7 +128,7 @@ describe('store', () => { it('allows a callback', async () => new Promise((resolve) => { - const setState = jest.fn().mockImplementation((x, cb) => cb('RESULT')); + const setState = vi.fn().mockImplementation((x, cb) => cb('RESULT')); const store = new Store({ setState }); store.setState({ foo: 'bar' }, (result) => { @@ -137,13 +138,13 @@ describe('store', () => { })); it('allows a patch function and persists its results', async () => { - const setState = jest.fn().mockImplementation((x, cb) => { + const setState = vi.fn().mockImplementation((x, cb) => { x('OLD_STATE'); cb(); }); const store = new Store({ setState }); - const patch = jest.fn().mockReturnValue({ foo: 'bar' }); + const patch = vi.fn().mockReturnValue({ foo: 'bar' }); await store.setState(patch, { persistence: 'session' }); expect(patch).toHaveBeenCalledWith('OLD_STATE'); diff --git a/code/lib/manager-api/src/tests/stories.test.ts b/code/lib/manager-api/src/tests/stories.test.ts index 22127d3aa931..a70783738135 100644 --- a/code/lib/manager-api/src/tests/stories.test.ts +++ b/code/lib/manager-api/src/tests/stories.test.ts @@ -1,4 +1,5 @@ -import { describe, test, it, expect } from 'vitest'; +import type { Mock, Mocked } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import { STORY_ARGS_UPDATED, UPDATE_STORY_ARGS, @@ -25,21 +26,21 @@ import type { API, State } from '..'; import { mockEntries, docsEntries, preparedEntries, navigationEntries } from './mockStoriesEntries'; import type { ModuleArgs } from '../lib/types'; -const mockGetEntries = jest.fn(); -const fetch = global.fetch as vi.mock>; -const getEventMetadata = getEventMetadataOriginal as unknown as vi.mock< +const mockGetEntries = vi.fn(); +const fetch = global.fetch as Mock>; +const getEventMetadata = getEventMetadataOriginal as unknown as Mock< ReturnType >; const wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); vi.mock('../lib/events', () => ({ - getEventMetadata: jest.fn(() => ({ sourceType: 'local' })), + getEventMetadata: vi.fn(() => ({ sourceType: 'local' })), })); vi.mock('@storybook/global', () => ({ global: { ...globalThis, - fetch: jest.fn(() => ({ json: () => ({ v: 4, entries: mockGetEntries() }) })), + fetch: vi.fn(() => ({ json: () => ({ v: 4, entries: mockGetEntries() }) })), FEATURES: { storyStoreV7: true }, CONFIG_TYPE: 'DEVELOPMENT', }, @@ -48,8 +49,8 @@ vi.mock('@storybook/global', () => ({ function createMockStore(initialState: Partial = {}) { let state = initialState; return { - getState: jest.fn(() => state), - setState: jest.fn((s: typeof state) => { + getState: vi.fn(() => state), + setState: vi.fn((s: typeof state) => { state = { ...state, ...s }; return Promise.resolve(state); }), @@ -57,7 +58,7 @@ function createMockStore(initialState: Partial = {}) { } function createMockProvider() { return { - getConfig: jest.fn().mockReturnValue({}), + getConfig: vi.fn().mockReturnValue({}), channel: new EventEmitter(), }; } @@ -65,10 +66,10 @@ function createMockModuleArgs({ fullAPI = {}, initialState = {}, }: { - fullAPI?: Partial>; + fullAPI?: Partial>; initialState?: Partial; }) { - const navigate = jest.fn(); + const navigate = vi.fn(); const store = createMockStore({ filters: {}, status: {}, ...initialState }); const provider = createMockProvider(); @@ -342,7 +343,7 @@ describe('stories API', () => { }); }); it('retains prepared-ness of stories', async () => { - const fullAPI = { setOptions: jest.fn() }; + const fullAPI = { setOptions: vi.fn() }; const moduleArgs = createMockModuleArgs({ fullAPI }); const { api } = initStories(moduleArgs as unknown as ModuleArgs); const { store, provider } = moduleArgs; @@ -410,7 +411,7 @@ describe('stories API', () => { describe('SET_INDEX event', () => { it('calls setIndex w/ the data', () => { - const fullAPI = { setOptions: jest.fn() }; + const fullAPI = { setOptions: vi.fn() }; const moduleArgs = createMockModuleArgs({ fullAPI }); initStories(moduleArgs as unknown as ModuleArgs); const { store, provider } = moduleArgs; @@ -425,14 +426,14 @@ describe('stories API', () => { ); }); it('calls setOptions w/ first story parameter', () => { - const fullAPI = { setOptions: jest.fn() }; + const fullAPI = { setOptions: vi.fn() }; const moduleArgs = createMockModuleArgs({ fullAPI }); const { api } = initStories(moduleArgs as unknown as ModuleArgs); const { provider } = moduleArgs; // HACK api to effectively mock getCurrentParameter Object.assign(api, { - getCurrentParameter: jest.fn().mockReturnValue('options'), + getCurrentParameter: vi.fn().mockReturnValue('options'), }); provider.channel.emit(SET_INDEX, { v: 4, entries: mockEntries }); @@ -585,7 +586,7 @@ describe('stories API', () => { expect(store.getState().previewInitialized).toBe(true); }); it('sets a ref to previewInitialized', async () => { - const fullAPI = { updateRef: jest.fn() }; + const fullAPI = { updateRef: vi.fn() }; const moduleArgs = createMockModuleArgs({ fullAPI }); initStories(moduleArgs as unknown as ModuleArgs); const { provider } = moduleArgs; @@ -609,7 +610,7 @@ describe('stories API', () => { describe('args handling', () => { it('changes args properly, per story when receiving STORY_ARGS_UPDATED', () => { - const fullAPI = { updateRef: jest.fn() }; + const fullAPI = { updateRef: vi.fn() }; const moduleArgs = createMockModuleArgs({ fullAPI }); const { api } = initStories(moduleArgs as unknown as ModuleArgs); const { provider, store } = moduleArgs; @@ -624,7 +625,7 @@ describe('stories API', () => { expect((changedIndex['b--1'] as API_StoryEntry).args).toEqual({ x: 'y' }); }); it('changes reffed args properly, per story when receiving STORY_ARGS_UPDATED', () => { - const fullAPI = { updateRef: jest.fn() }; + const fullAPI = { updateRef: vi.fn() }; const moduleArgs = createMockModuleArgs({ fullAPI }); initStories(moduleArgs as unknown as ModuleArgs); const { provider } = moduleArgs; @@ -643,12 +644,12 @@ describe('stories API', () => { }); }); it('updateStoryArgs emits UPDATE_STORY_ARGS to the local frame and does not change anything', () => { - const fullAPI = { updateRef: jest.fn() }; + const fullAPI = { updateRef: vi.fn() }; const moduleArgs = createMockModuleArgs({ fullAPI }); const { api } = initStories(moduleArgs as unknown as ModuleArgs); const { provider, store } = moduleArgs; - const listener = jest.fn(); + const listener = vi.fn(); provider.channel.on(UPDATE_STORY_ARGS, listener); api.setIndex({ v: 4, entries: preparedEntries }); @@ -667,12 +668,12 @@ describe('stories API', () => { expect((index['b--1'] as API_StoryEntry).args).toEqual({ x: 'y' }); }); it('updateStoryArgs emits UPDATE_STORY_ARGS to the right frame', () => { - const fullAPI = { updateRef: jest.fn() }; + const fullAPI = { updateRef: vi.fn() }; const moduleArgs = createMockModuleArgs({ fullAPI }); const { api } = initStories(moduleArgs as unknown as ModuleArgs); const { provider } = moduleArgs; - const listener = jest.fn(); + const listener = vi.fn(); provider.channel.on(UPDATE_STORY_ARGS, listener); api.setIndex({ v: 4, entries: preparedEntries }); @@ -686,11 +687,11 @@ describe('stories API', () => { }); }); it('refId to the local frame and does not change anything', () => { - const fullAPI = { updateRef: jest.fn() }; + const fullAPI = { updateRef: vi.fn() }; const moduleArgs = createMockModuleArgs({ fullAPI }); const { api } = initStories(moduleArgs as unknown as ModuleArgs); const { provider, store } = moduleArgs; - const listener = jest.fn(); + const listener = vi.fn(); provider.channel.on(RESET_STORY_ARGS, listener); api.setIndex({ v: 4, entries: preparedEntries }); @@ -709,12 +710,12 @@ describe('stories API', () => { expect((index['b--1'] as API_StoryEntry).args).toEqual({ x: 'y' }); }); it('resetStoryArgs emits RESET_STORY_ARGS to the right frame', () => { - const fullAPI = { updateRef: jest.fn() }; + const fullAPI = { updateRef: vi.fn() }; const moduleArgs = createMockModuleArgs({ fullAPI }); const { api } = initStories(moduleArgs as unknown as ModuleArgs); const { provider } = moduleArgs; - const listener = jest.fn(); + const listener = vi.fn(); provider.channel.on(RESET_STORY_ARGS, listener); api.setIndex({ v: 4, entries: preparedEntries }); @@ -1002,7 +1003,7 @@ describe('stories API', () => { }); describe('STORY_PREPARED', () => { it('prepares the story', async () => { - const fullAPI = { setOptions: jest.fn() }; + const fullAPI = { setOptions: vi.fn() }; const initialState = { path: '/story/a--1', storyId: 'a--1', viewMode: 'story' }; const moduleArgs = createMockModuleArgs({ initialState, fullAPI }); const { api } = initStories(moduleArgs as unknown as ModuleArgs); @@ -1028,7 +1029,7 @@ describe('stories API', () => { }); }); it('sets options the first time it is called', async () => { - const fullAPI = { setOptions: jest.fn() }; + const fullAPI = { setOptions: vi.fn() }; const initialState = { path: '/story/a--1', storyId: 'a--1', viewMode: 'story' }; const moduleArgs = createMockModuleArgs({ initialState, fullAPI }); const { api } = initStories(moduleArgs as unknown as ModuleArgs); @@ -1088,7 +1089,7 @@ describe('stories API', () => { expect(previewInitialized).toBe(true); }); it('sets previewInitialized to true, ref', async () => { - const fullAPI = { updateRef: jest.fn() }; + const fullAPI = { updateRef: vi.fn() }; const moduleArgs = createMockModuleArgs({ fullAPI }); const { api } = initStories(moduleArgs as unknown as ModuleArgs); const { provider } = moduleArgs; @@ -1117,7 +1118,7 @@ describe('stories API', () => { expect(previewInitialized).toBe(true); }); it('sets previewInitialized to true, ref', async () => { - const fullAPI = { updateRef: jest.fn() }; + const fullAPI = { updateRef: vi.fn() }; const moduleArgs = createMockModuleArgs({ fullAPI }); initStories(moduleArgs as unknown as ModuleArgs); const { provider } = moduleArgs; @@ -1136,8 +1137,8 @@ describe('stories API', () => { describe('v2 SET_STORIES event', () => { it('normalizes parameters and calls setRef for external stories', () => { const fullAPI = { - findRef: jest.fn(), - setRef: jest.fn(), + findRef: vi.fn(), + setRef: vi.fn(), }; const moduleArgs = createMockModuleArgs({ fullAPI }); initStories(moduleArgs as unknown as ModuleArgs); @@ -1170,8 +1171,8 @@ describe('stories API', () => { describe('legacy (v1) SET_STORIES event', () => { it('calls setRef with stories', () => { const fullAPI = { - findRef: jest.fn(), - setRef: jest.fn(), + findRef: vi.fn(), + setRef: vi.fn(), }; const moduleArgs = createMockModuleArgs({ fullAPI }); initStories(moduleArgs as unknown as ModuleArgs); diff --git a/code/lib/manager-api/src/tests/url.test.js b/code/lib/manager-api/src/tests/url.test.js index a236314db5eb..fcff98e31f80 100644 --- a/code/lib/manager-api/src/tests/url.test.js +++ b/code/lib/manager-api/src/tests/url.test.js @@ -1,3 +1,4 @@ +import { describe, beforeEach, it, expect, vi } from 'vitest'; import qs from 'qs'; import { SET_CURRENT_STORY, GLOBALS_UPDATED, UPDATE_QUERY_PARAMS } from '@storybook/core-events'; @@ -6,14 +7,14 @@ import EventEmitter from 'events'; import { init as initURL } from '../modules/url'; vi.mock('@storybook/client-logger'); -jest.useFakeTimers(); +vi.useFakeTimers(); describe('initial state', () => { const viewMode = 'story'; describe('config query parameters', () => { it('handles full parameter', () => { - const navigate = jest.fn(); + const navigate = vi.fn(); const location = { search: qs.stringify({ full: '1' }) }; const { @@ -24,7 +25,7 @@ describe('initial state', () => { }); it('handles nav parameter', () => { - const navigate = jest.fn(); + const navigate = vi.fn(); const location = { search: qs.stringify({ nav: '0' }) }; const { @@ -35,7 +36,7 @@ describe('initial state', () => { }); it('handles shortcuts parameter', () => { - const navigate = jest.fn(); + const navigate = vi.fn(); const location = { search: qs.stringify({ shortcuts: '0' }) }; const { @@ -46,7 +47,7 @@ describe('initial state', () => { }); it('handles panel parameter, bottom', () => { - const navigate = jest.fn(); + const navigate = vi.fn(); const location = { search: qs.stringify({ panel: 'bottom' }) }; const { @@ -57,7 +58,7 @@ describe('initial state', () => { }); it('handles panel parameter, right', () => { - const navigate = jest.fn(); + const navigate = vi.fn(); const location = { search: qs.stringify({ panel: 'right' }) }; const { @@ -68,7 +69,7 @@ describe('initial state', () => { }); it('handles panel parameter, 0', () => { - const navigate = jest.fn(); + const navigate = vi.fn(); const location = { search: qs.stringify({ panel: '0' }) }; const { @@ -92,12 +93,12 @@ describe('queryParams', () => { const channel = new EventEmitter(); const { api } = initURL({ state: { location: { search: '' } }, - navigate: jest.fn(), + navigate: vi.fn(), store, provider: { channel }, }); - const listener = jest.fn(); + const listener = vi.fn(); channel.on(UPDATE_QUERY_PARAMS, listener); @@ -126,7 +127,7 @@ describe('initModule', () => { }); const fullAPI = { - showReleaseNotesOnLaunch: jest.fn(), + showReleaseNotesOnLaunch: vi.fn(), }; beforeEach(() => { @@ -137,7 +138,7 @@ describe('initModule', () => { it('updates args param on SET_CURRENT_STORY', async () => { store.setState(storyState('test--story')); - const navigate = jest.fn(); + const navigate = vi.fn(); const channel = new EventEmitter(); initURL({ store, @@ -164,7 +165,7 @@ describe('initModule', () => { it('updates globals param on GLOBALS_UPDATED', async () => { store.setState(storyState('test--story')); - const navigate = jest.fn(); + const navigate = vi.fn(); const channel = new EventEmitter(); initURL({ store, provider: { channel }, state: { location: {} }, navigate, fullAPI }); @@ -178,7 +179,7 @@ describe('initModule', () => { it('adds url params alphabetically', async () => { store.setState({ ...storyState('test--story'), customQueryParams: { full: 1 } }); - const navigate = jest.fn(); + const navigate = vi.fn(); const channel = new EventEmitter(); const { api } = initURL({ store, diff --git a/code/lib/manager-api/src/tests/versions.test.js b/code/lib/manager-api/src/tests/versions.test.js index 1d5c4cdc9c66..4f3e1cf93d7f 100644 --- a/code/lib/manager-api/src/tests/versions.test.js +++ b/code/lib/manager-api/src/tests/versions.test.js @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import { init as initVersions } from '../modules/versions'; vi.mock('../version', () => ({ @@ -35,8 +36,8 @@ function createMockStore() { }, }; return { - getState: jest.fn().mockImplementation(() => state), - setState: jest.fn().mockImplementation((s) => { + getState: vi.fn().mockImplementation(() => state), + setState: vi.fn().mockImplementation((s) => { state = { ...state, ...s }; }), }; diff --git a/code/lib/node-logger/src/index.test.ts b/code/lib/node-logger/src/index.test.ts index 6ffb9658040c..4ed4d119f83d 100644 --- a/code/lib/node-logger/src/index.test.ts +++ b/code/lib/node-logger/src/index.test.ts @@ -1,12 +1,13 @@ +import { describe, it, expect, vi } from 'vitest'; import { info, warn } from 'npmlog'; import { logger } from '.'; -globalThis.console = { log: jest.fn() } as any; +globalThis.console = { log: vi.fn() } as any; vi.mock('npmlog', () => ({ - info: jest.fn(), - warn: jest.fn(), - error: jest.fn(), + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), levels: { silly: -Infinity, verbose: 1000, diff --git a/code/lib/postinstall/src/codemods.test.ts b/code/lib/postinstall/src/codemods.test.ts index 6c8e56a16275..8936e007d430 100644 --- a/code/lib/postinstall/src/codemods.test.ts +++ b/code/lib/postinstall/src/codemods.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import path from 'path'; import fs from 'fs'; import 'jest-specific-snapshot'; diff --git a/code/lib/postinstall/src/frameworks.test.ts b/code/lib/postinstall/src/frameworks.test.ts index 6b498477e193..aa736d553c3f 100644 --- a/code/lib/postinstall/src/frameworks.test.ts +++ b/code/lib/postinstall/src/frameworks.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { getFrameworks } from './frameworks'; const REACT = { diff --git a/code/lib/preview-api/src/modules/addons/hooks.test.js b/code/lib/preview-api/src/modules/addons/hooks.test.js index 0eafc46c1e2e..ee5a259ff7f5 100644 --- a/code/lib/preview-api/src/modules/addons/hooks.test.js +++ b/code/lib/preview-api/src/modules/addons/hooks.test.js @@ -1,3 +1,4 @@ +import { describe, beforeEach, afterEach, expect } from 'vitest'; import { useParameter, useStoryContext } from './hooks'; describe('addons/hooks', () => { diff --git a/code/lib/preview-api/src/modules/addons/make-decorator.test.ts b/code/lib/preview-api/src/modules/addons/make-decorator.test.ts index 13f75dec9a0e..73ba5da0293f 100644 --- a/code/lib/preview-api/src/modules/addons/make-decorator.test.ts +++ b/code/lib/preview-api/src/modules/addons/make-decorator.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import type { Addon_StoryContext } from '@storybook/types'; import { makeDecorator } from './make-decorator'; @@ -19,9 +20,9 @@ const baseContext = { describe('makeDecorator', () => { it('returns a decorator that passes parameters on the parameters argument', () => { - const wrapper = jest.fn(); + const wrapper = vi.fn(); const decorator = makeDecorator({ wrapper, name: 'test', parameterName: 'test' }); - const story = jest.fn(); + const story = vi.fn(); const decoratedStory = defaultDecorateStory(story, [decorator]); const context = { kind: '', name: '', parameters: { test: 'test-val' } }; @@ -31,9 +32,9 @@ describe('makeDecorator', () => { }); it('passes options added at decoration time', () => { - const wrapper = jest.fn(); + const wrapper = vi.fn(); const decorator = makeDecorator({ wrapper, name: 'test', parameterName: 'test' }); - const story = jest.fn(); + const story = vi.fn(); const options = 'test-val'; const decoratedStory = defaultDecorateStory(story, [decorator(options)]); @@ -44,9 +45,9 @@ describe('makeDecorator', () => { }); it('passes object options added at decoration time', () => { - const wrapper = jest.fn(); + const wrapper = vi.fn(); const decorator = makeDecorator({ wrapper, name: 'test', parameterName: 'test' }); - const story = jest.fn(); + const story = vi.fn(); const options = { test: 'val' }; const decoratedStory = defaultDecorateStory(story, [decorator(options)]); @@ -59,9 +60,9 @@ describe('makeDecorator', () => { }); it('passes multiple options added at decoration time', () => { - const wrapper = jest.fn(); + const wrapper = vi.fn(); const decorator = makeDecorator({ wrapper, name: 'test', parameterName: 'test' }); - const story = jest.fn(); + const story = vi.fn(); const options = ['test-val', 'test-val2']; const decoratedStory = defaultDecorateStory(story, [decorator(...options)]); @@ -74,9 +75,9 @@ describe('makeDecorator', () => { }); it('passes multiple options including objects added at decoration time', () => { - const wrapper = jest.fn(); + const wrapper = vi.fn(); const decorator = makeDecorator({ wrapper, name: 'test', parameterName: 'test' }); - const story = jest.fn(); + const story = vi.fn(); const options = ['test-val', 'test-val2', { test: 'val' }]; const decoratedStory = defaultDecorateStory(story, [decorator(...options)]); @@ -89,9 +90,9 @@ describe('makeDecorator', () => { }); it('passes both options *and* parameters at the same time', () => { - const wrapper = jest.fn(); + const wrapper = vi.fn(); const decorator = makeDecorator({ wrapper, name: 'test', parameterName: 'test' }); - const story = jest.fn(); + const story = vi.fn(); const options = 'test-val'; const decoratedStory = defaultDecorateStory(story, [decorator(options)]); @@ -105,9 +106,9 @@ describe('makeDecorator', () => { }); it('passes nothing if neither are supplied', () => { - const wrapper = jest.fn(); + const wrapper = vi.fn(); const decorator = makeDecorator({ wrapper, name: 'test', parameterName: 'test' }); - const story = jest.fn(); + const story = vi.fn(); const decoratedStory = defaultDecorateStory(story, [decorator]); const context = { ...baseContext }; @@ -117,14 +118,14 @@ describe('makeDecorator', () => { }); it('calls the story directly if neither options or parameters are supplied and skipIfNoParametersOrOptions is true', () => { - const wrapper = jest.fn(); + const wrapper = vi.fn(); const decorator = makeDecorator({ wrapper, name: 'test', parameterName: 'test', skipIfNoParametersOrOptions: true, }); - const story = jest.fn(); + const story = vi.fn(); const decoratedStory = defaultDecorateStory(story, [decorator]); const context = { ...baseContext }; @@ -135,14 +136,14 @@ describe('makeDecorator', () => { }); it('calls the story directly if the disable parameter is passed to the decorator', () => { - const wrapper = jest.fn(); + const wrapper = vi.fn(); const decorator = makeDecorator({ wrapper, name: 'test', parameterName: 'test', skipIfNoParametersOrOptions: true, }); - const story = jest.fn(); + const story = vi.fn(); const decoratedStory = defaultDecorateStory(story, [decorator]); const context = { ...baseContext, parameters: { test: { disable: true } } }; @@ -153,14 +154,14 @@ describe('makeDecorator', () => { }); it('throws if options are added at storytime, if not allowed', () => { - const wrapper = jest.fn(); + const wrapper = vi.fn(); const decorator = makeDecorator({ wrapper, name: 'test', parameterName: 'test', }); const options = 'test-val'; - const story = jest.fn(); + const story = vi.fn(); expect(() => decorator(options)(story)).toThrow(/not allowed/); }); }); diff --git a/code/lib/preview-api/src/modules/client-api/ClientApi.test.ts b/code/lib/preview-api/src/modules/client-api/ClientApi.test.ts index 65f4d718a9ed..bc93a037ef8d 100644 --- a/code/lib/preview-api/src/modules/client-api/ClientApi.test.ts +++ b/code/lib/preview-api/src/modules/client-api/ClientApi.test.ts @@ -1,3 +1,4 @@ +import { describe, beforeEach, it, expect, vi } from 'vitest'; import { addons, mockChannel } from '../addons'; import { ClientApi } from './ClientApi'; @@ -10,8 +11,8 @@ describe('ClientApi', () => { it('should remember the order that files were added in', async () => { const clientApi = new ClientApi(); const store = { - processCSFFileWithCache: jest.fn(() => ({ meta: { title: 'title' } })), - storyFromCSFFile: jest.fn(({ storyId }) => ({ + processCSFFileWithCache: vi.fn(() => ({ meta: { title: 'title' } })), + storyFromCSFFile: vi.fn(({ storyId }) => ({ id: storyId, parameters: { fileName: storyId.split('-')[0].replace('kind', 'file') }, })), @@ -23,7 +24,7 @@ describe('ClientApi', () => { id: 'file1', hot: { data: {}, - accept: jest.fn(), + accept: vi.fn(), dispose(cb: () => void) { disposeCallback = cb; }, @@ -32,8 +33,8 @@ describe('ClientApi', () => { const module2 = { id: 'file2', }; - clientApi.storiesOf('kind1', module1 as unknown as NodeModule).add('story1', jest.fn()); - clientApi.storiesOf('kind2', module2 as unknown as NodeModule).add('story2', jest.fn()); + clientApi.storiesOf('kind1', module1 as unknown as NodeModule).add('story1', vi.fn()); + clientApi.storiesOf('kind2', module2 as unknown as NodeModule).add('story2', vi.fn()); // This gets called by configure // eslint-disable-next-line no-underscore-dangle clientApi._loadAddedExports(); @@ -44,7 +45,7 @@ describe('ClientApi', () => { ]); disposeCallback(); - clientApi.storiesOf('kind1', module1 as unknown as NodeModule).add('story1', jest.fn()); + clientApi.storiesOf('kind1', module1 as unknown as NodeModule).add('story1', vi.fn()); await new Promise((r) => setTimeout(r, 0)); expect(Object.keys(clientApi.getStoryIndex().entries)).toEqual([ 'kind1--story1', diff --git a/code/lib/preview-api/src/modules/core-client/start.test.ts b/code/lib/preview-api/src/modules/core-client/start.test.ts index e5a7f5d9997b..239f887e17fd 100644 --- a/code/lib/preview-api/src/modules/core-client/start.test.ts +++ b/code/lib/preview-api/src/modules/core-client/start.test.ts @@ -1,9 +1,8 @@ /* eslint-disable no-underscore-dangle */ /** - * @jest-environment jsdom + * @vitest-environment jsdom */ - -// import { describe, it, beforeAll, beforeEach, afterAll, afterEach, jest } from 'vitest' +import { describe, beforeEach, afterEach, afterAll, it, expect, vi } from 'vitest'; import { STORY_RENDERED, STORY_UNCHANGED, SET_INDEX, CONFIG_ERROR } from '@storybook/core-events'; import type { ModuleExports, Path } from '@storybook/types'; @@ -24,7 +23,7 @@ vi.mock('@storybook/global', () => ({ global: { ...globalThis, window: globalThis, - history: { replaceState: jest.fn() }, + history: { replaceState: vi.fn() }, document: { location: { pathname: 'pathname', @@ -44,8 +43,8 @@ vi.mock('@storybook/client-logger'); vi.mock('react-dom'); // for the auto-title test -vi.mock('../../store', () => { - const actualStore = jest.requireActual('../../store'); +vi.mock('../../store', async () => { + const actualStore = await vi.importActual('../../store'); return { ...actualStore, userOrAutoTitle: (importPath: Path, specifier: any, userTitle?: string) => @@ -53,8 +52,8 @@ vi.mock('../../store', () => { }; }); -vi.mock('../../preview-web', () => { - const actualPreviewWeb = jest.requireActual('../../preview-web'); +vi.mock('../../preview-web', async () => { + const actualPreviewWeb = await vi.importActual('../../preview-web'); class OverloadPreviewWeb extends actualPreviewWeb.PreviewWeb { constructor() { @@ -62,10 +61,10 @@ vi.mock('../../preview-web', () => { this.view = { ...Object.fromEntries( - Object.getOwnPropertyNames(this.view.constructor.prototype).map((key) => [key, jest.fn()]) + Object.getOwnPropertyNames(this.view.constructor.prototype).map((key) => [key, vi.fn()]) ), - prepareForDocs: jest.fn().mockReturnValue('docs-root'), - prepareForStory: jest.fn().mockReturnValue('story-root'), + prepareForDocs: vi.fn().mockReturnValue('docs-root'), + prepareForStory: vi.fn().mockReturnValue('story-root'), }; } } @@ -119,19 +118,19 @@ describe('start', () => { }); describe('when configure is called with storiesOf only', () => { it('loads and renders the first story correctly', async () => { - const renderToCanvas = jest.fn(); + const renderToCanvas = vi.fn(); const { configure, clientApi } = start(renderToCanvas); configure('test', () => { clientApi .storiesOf('Component A', { id: 'file1' } as NodeModule) - .add('Story One', jest.fn()) - .add('Story Two', jest.fn()); + .add('Story One', vi.fn()) + .add('Story Two', vi.fn()); clientApi .storiesOf('Component B', { id: 'file2' } as NodeModule) - .add('Story Three', jest.fn()); + .add('Story Three', vi.fn()); }); await waitForRender(); @@ -217,12 +216,12 @@ describe('start', () => { }); it('deals with stories with "default" name', async () => { - const renderToCanvas = jest.fn(); + const renderToCanvas = vi.fn(); const { configure, clientApi } = start(renderToCanvas); configure('test', () => { - clientApi.storiesOf('Component A', { id: 'file1' } as NodeModule).add('default', jest.fn()); + clientApi.storiesOf('Component A', { id: 'file1' } as NodeModule).add('default', vi.fn()); }); await waitForRender(); @@ -231,14 +230,12 @@ describe('start', () => { }); it('deals with stories with camel-cased names', async () => { - const renderToCanvas = jest.fn(); + const renderToCanvas = vi.fn(); const { configure, clientApi } = start(renderToCanvas); configure('test', () => { - clientApi - .storiesOf('Component A', { id: 'file1' } as NodeModule) - .add('storyOne', jest.fn()); + clientApi.storiesOf('Component A', { id: 'file1' } as NodeModule).add('storyOne', vi.fn()); }); await waitForRender(); @@ -247,14 +244,12 @@ describe('start', () => { }); it('deals with stories with spaces in the name', async () => { - const renderToCanvas = jest.fn(); + const renderToCanvas = vi.fn(); const { configure, clientApi } = start(renderToCanvas); configure('test', () => { - clientApi - .storiesOf('Component A', { id: 'file1' } as NodeModule) - .add('Story One', jest.fn()); + clientApi.storiesOf('Component A', { id: 'file1' } as NodeModule).add('Story One', vi.fn()); }); await waitForRender(); @@ -264,12 +259,12 @@ describe('start', () => { // https://github.com/storybookjs/storybook/issues/16303 it('deals with stories with numeric names', async () => { - const renderToCanvas = jest.fn(); + const renderToCanvas = vi.fn(); const { configure, clientApi } = start(renderToCanvas); configure('test', () => { - clientApi.storiesOf('Component A', { id: 'file1' } as NodeModule).add('story0', jest.fn()); + clientApi.storiesOf('Component A', { id: 'file1' } as NodeModule).add('story0', vi.fn()); }); await waitForRender(); @@ -278,14 +273,14 @@ describe('start', () => { }); it('deals with storiesOf from the same file twice', async () => { - const renderToCanvas = jest.fn(); + const renderToCanvas = vi.fn(); const { configure, clientApi } = start(renderToCanvas); configure('test', () => { - clientApi.storiesOf('Component A', { id: 'file1' } as NodeModule).add('default', jest.fn()); - clientApi.storiesOf('Component B', { id: 'file1' } as NodeModule).add('default', jest.fn()); - clientApi.storiesOf('Component C', { id: 'file1' } as NodeModule).add('default', jest.fn()); + clientApi.storiesOf('Component A', { id: 'file1' } as NodeModule).add('default', vi.fn()); + clientApi.storiesOf('Component B', { id: 'file1' } as NodeModule).add('default', vi.fn()); + clientApi.storiesOf('Component C', { id: 'file1' } as NodeModule).add('default', vi.fn()); }); await waitForRender(); @@ -300,7 +295,7 @@ describe('start', () => { }); it('allows setting compomnent/args/argTypes via a parameter', async () => { - const renderToCanvas = jest.fn(({ storyFn }) => storyFn()); + const renderToCanvas = vi.fn(({ storyFn }) => storyFn()); const { configure, clientApi } = start(renderToCanvas); @@ -313,7 +308,7 @@ describe('start', () => { args: { a: 'a' }, argTypes: { a: { type: 'string' } }, }) - .add('default', jest.fn(), { + .add('default', vi.fn(), { args: { b: 'b' }, argTypes: { b: { type: 'string' } }, }); @@ -339,12 +334,12 @@ describe('start', () => { }); it('supports forceRerender()', async () => { - const renderToCanvas = jest.fn(({ storyFn }) => storyFn()); + const renderToCanvas = vi.fn(({ storyFn }) => storyFn()); const { configure, clientApi, forceReRender } = start(renderToCanvas); configure('test', () => { - clientApi.storiesOf('Component A', { id: 'file1' } as NodeModule).add('default', jest.fn()); + clientApi.storiesOf('Component A', { id: 'file1' } as NodeModule).add('default', vi.fn()); }); await waitForRender(); @@ -358,7 +353,7 @@ describe('start', () => { }); it('supports HMR when a story file changes', async () => { - const renderToCanvas = jest.fn(({ storyFn }) => storyFn()); + const renderToCanvas = vi.fn(({ storyFn }) => storyFn()); const { configure, clientApi } = start(renderToCanvas); @@ -366,13 +361,13 @@ describe('start', () => { const module = { id: 'file1', hot: { - accept: jest.fn(), + accept: vi.fn(), dispose(cb: () => void) { disposeCallback = cb; }, }, }; - const firstImplementation = jest.fn(); + const firstImplementation = vi.fn(); configure('test', () => { clientApi.storiesOf('Component A', module as any).add('default', firstImplementation); }); @@ -385,7 +380,7 @@ describe('start', () => { mockChannel.emit.mockClear(); disposeCallback(); - const secondImplementation = jest.fn(); + const secondImplementation = vi.fn(); clientApi.storiesOf('Component A', module as any).add('default', secondImplementation); await waitForRender(); @@ -394,7 +389,7 @@ describe('start', () => { }); it('re-emits SET_INDEX when a story is added', async () => { - const renderToCanvas = jest.fn(({ storyFn }) => storyFn()); + const renderToCanvas = vi.fn(({ storyFn }) => storyFn()); const { configure, clientApi } = start(renderToCanvas); @@ -402,14 +397,14 @@ describe('start', () => { const module = { id: 'file1', hot: { - accept: jest.fn(), + accept: vi.fn(), dispose(cb: () => void) { disposeCallback = cb; }, }, }; configure('test', () => { - clientApi.storiesOf('Component A', module as any).add('default', jest.fn()); + clientApi.storiesOf('Component A', module as any).add('default', vi.fn()); }); await waitForRender(); @@ -418,8 +413,8 @@ describe('start', () => { disposeCallback(); clientApi .storiesOf('Component A', module as any) - .add('default', jest.fn()) - .add('new', jest.fn()); + .add('default', vi.fn()) + .add('new', vi.fn()); await waitForEvents([SET_INDEX]); expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) @@ -473,7 +468,7 @@ describe('start', () => { }); it('re-emits SET_INDEX when a story file is removed', async () => { - const renderToCanvas = jest.fn(({ storyFn }) => storyFn()); + const renderToCanvas = vi.fn(({ storyFn }) => storyFn()); const { configure, clientApi } = start(renderToCanvas); @@ -481,15 +476,15 @@ describe('start', () => { const moduleB = { id: 'file2', hot: { - accept: jest.fn(), + accept: vi.fn(), dispose(cb: () => void) { disposeCallback = cb; }, }, }; configure('test', () => { - clientApi.storiesOf('Component A', { id: 'file1' } as any).add('default', jest.fn()); - clientApi.storiesOf('Component B', moduleB as any).add('default', jest.fn()); + clientApi.storiesOf('Component A', { id: 'file1' } as any).add('default', vi.fn()); + clientApi.storiesOf('Component B', moduleB as any).add('default', vi.fn()); }); await waitForEvents([SET_INDEX]); @@ -582,15 +577,15 @@ describe('start', () => { tags: ['component-tag', 'autodocs'], }, StoryOne: { - render: jest.fn(), + render: vi.fn(), tags: ['story-tag'], }, - StoryTwo: jest.fn(), + StoryTwo: vi.fn(), }; describe('when configure is called with CSF only', () => { it('loads and renders the first story correctly', async () => { - const renderToCanvas = jest.fn(); + const renderToCanvas = vi.fn(); const { configure } = start(renderToCanvas); configure('test', () => [componentCExports]); @@ -656,14 +651,14 @@ describe('start', () => { }); it('supports HMR when a story file changes', async () => { - const renderToCanvas = jest.fn(({ storyFn }) => storyFn()); + const renderToCanvas = vi.fn(({ storyFn }) => storyFn()); let disposeCallback: (data: object) => void = () => {}; const module = { id: 'file1', hot: { data: {}, - accept: jest.fn(), + accept: vi.fn(), dispose(cb: () => void) { disposeCallback = cb; }, @@ -681,7 +676,7 @@ describe('start', () => { mockChannel.emit.mockClear(); disposeCallback(module.hot.data); - const secondImplementation = jest.fn(); + const secondImplementation = vi.fn(); configure( 'test', () => [{ ...componentCExports, StoryOne: secondImplementation }], @@ -694,14 +689,14 @@ describe('start', () => { }); it('re-emits SET_INDEX when a story is added', async () => { - const renderToCanvas = jest.fn(({ storyFn }) => storyFn()); + const renderToCanvas = vi.fn(({ storyFn }) => storyFn()); let disposeCallback: (data: object) => void = () => {}; const module = { id: 'file1', hot: { data: {}, - accept: jest.fn(), + accept: vi.fn(), dispose(cb: () => void) { disposeCallback = cb; }, @@ -714,7 +709,7 @@ describe('start', () => { mockChannel.emit.mockClear(); disposeCallback(module.hot.data); - configure('test', () => [{ ...componentCExports, StoryThree: jest.fn() }], module as any); + configure('test', () => [{ ...componentCExports, StoryThree: vi.fn() }], module as any); await waitForEvents([SET_INDEX]); expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) @@ -787,14 +782,14 @@ describe('start', () => { }); it('re-emits SET_INDEX when a story file is removed', async () => { - const renderToCanvas = jest.fn(({ storyFn }) => storyFn()); + const renderToCanvas = vi.fn(({ storyFn }) => storyFn()); let disposeCallback: (data: object) => void = () => {}; const module = { id: 'file1', hot: { data: {}, - accept: jest.fn(), + accept: vi.fn(), dispose(cb: () => void) { disposeCallback = cb; }, @@ -803,7 +798,7 @@ describe('start', () => { const { configure } = start(renderToCanvas); configure( 'test', - () => [componentCExports, { default: { title: 'Component D' }, StoryFour: jest.fn() }], + () => [componentCExports, { default: { title: 'Component D' }, StoryFour: vi.fn() }], module as any ); @@ -932,19 +927,19 @@ describe('start', () => { }); it('allows you to override the render function in project annotations', async () => { - const renderToCanvas = jest.fn(({ storyFn }) => storyFn()); - const frameworkRender = jest.fn(); + const renderToCanvas = vi.fn(({ storyFn }) => storyFn()); + const frameworkRender = vi.fn(); const { configure } = start(renderToCanvas, { render: frameworkRender }); - const projectRender = jest.fn(); + const projectRender = vi.fn(); setGlobalRender(projectRender); configure('test', () => { return [ { default: { title: 'Component A', - component: jest.fn(), + component: vi.fn(), }, StoryOne: {}, }, @@ -965,7 +960,7 @@ describe('start', () => { // NOTE: MDX files are only ever passed as CSF it('sends over docs only stories as entries', async () => { - const renderToCanvas = jest.fn(); + const renderToCanvas = vi.fn(); const { configure } = start(renderToCanvas); @@ -1010,7 +1005,7 @@ describe('start', () => { }); it('errors on .mdx files', async () => { - const renderToCanvas = jest.fn(); + const renderToCanvas = vi.fn(); const { configure } = start(renderToCanvas); @@ -1041,18 +1036,18 @@ describe('start', () => { describe('when configure is called with a combination', () => { it('loads and renders the first story correctly', async () => { - const renderToCanvas = jest.fn(); + const renderToCanvas = vi.fn(); const { configure, clientApi } = start(renderToCanvas); configure('test', () => { clientApi .storiesOf('Component A', { id: 'file1' } as NodeModule) - .add('Story One', jest.fn()) - .add('Story Two', jest.fn()); + .add('Story One', vi.fn()) + .add('Story Two', vi.fn()); clientApi .storiesOf('Component B', { id: 'file2' } as NodeModule) - .add('Story Three', jest.fn()); + .add('Story Three', vi.fn()); return [componentCExports]; }); @@ -1183,19 +1178,19 @@ describe('start', () => { }); it('adds stories for each component with autodocs tag', async () => { - const renderToCanvas = jest.fn(); + const renderToCanvas = vi.fn(); const { configure, clientApi } = start(renderToCanvas); configure('test', () => { clientApi .storiesOf('Component A', { id: 'file1' } as NodeModule) - .add('Story One', jest.fn()) - .add('Story Two', jest.fn()); + .add('Story One', vi.fn()) + .add('Story Two', vi.fn()); clientApi .storiesOf('Component B', { id: 'file2' } as NodeModule) .addParameters({ tags: ['autodocs'] }) - .add('Story Three', jest.fn()); + .add('Story Three', vi.fn()); return [componentCExports]; }); @@ -1351,22 +1346,22 @@ describe('start', () => { }); it('adds stories for each component with autodocs tag', async () => { - const renderToDOM = jest.fn(); + const renderToDOM = vi.fn(); const { configure, clientApi } = start(renderToDOM); configure('test', () => { (clientApi as any).addParameters({ - docs: { renderer: () => ({ render: jest.fn((_, _2, _3, d) => d()) }) }, + docs: { renderer: () => ({ render: vi.fn((_, _2, _3, d) => d()) }) }, }); clientApi .storiesOf('Component A', { id: 'file1' } as NodeModule) - .add('Story One', jest.fn()) - .add('Story Two', jest.fn()); + .add('Story One', vi.fn()) + .add('Story Two', vi.fn()); clientApi .storiesOf('Component B', { id: 'file2' } as NodeModule) .addParameters({ tags: ['autodocs'] }) - .add('Story Three', jest.fn()); + .add('Story Three', vi.fn()); return [componentCExports]; }); @@ -1394,10 +1389,10 @@ describe('start', () => { default: { component: 'Component D', }, - StoryOne: jest.fn(), + StoryOne: vi.fn(), }; it('loads and renders the first story correctly', async () => { - const renderToCanvas = jest.fn(); + const renderToCanvas = vi.fn(); const { configure } = start(renderToCanvas); configure('test', () => [componentDExports]); diff --git a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.integration.test.ts b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.integration.test.ts index 4ca470a67a94..186082073d5b 100644 --- a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.integration.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.integration.test.ts @@ -1,6 +1,8 @@ /** - * @jest-environment jsdom + * @vitest-environment jsdom */ +import type { Mock } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import React from 'react'; import { global } from '@storybook/global'; @@ -24,8 +26,8 @@ import { // - ie. from`renderToCanvas()` (stories) or`ReactDOM.render()` (docs) in. // This file lets them rip. -vi.mock('@storybook/channels', () => ({ - ...jest.requireActual('@storybook/channels'), +vi.mock('@storybook/channels', async () => ({ + ...(await vi.importActual('@storybook/channels')), createBrowserChannel: () => mockChannel, })); vi.mock('@storybook/client-logger'); @@ -36,7 +38,7 @@ const { document } = global; vi.mock('@storybook/global', () => ({ global: { ...globalThis, - history: { replaceState: jest.fn() }, + history: { replaceState: vi.fn() }, document: { createElement: globalThis.document.createElement.bind(globalThis.document), location: { @@ -100,7 +102,7 @@ describe('PreviewWeb', () => { const docsRoot = document.createElement('div'); ( - preview.view.prepareForDocs as any as vi.mock + preview.view.prepareForDocs as any as Mock ).mockReturnValue(docsRoot as any); componentOneExports.default.parameters.docs.container.mockImplementationOnce(() => React.createElement('div', {}, 'INSIDE') @@ -127,14 +129,14 @@ describe('PreviewWeb', () => { const docsRoot = document.createElement('div'); ( - preview.view.prepareForDocs as any as vi.mock + preview.view.prepareForDocs as any as Mock ).mockReturnValue(docsRoot as any); componentOneExports.default.parameters.docs.container.mockImplementationOnce(() => { throw new Error('Docs rendering error'); }); ( - preview.view.showErrorDisplay as any as vi.mock + preview.view.showErrorDisplay as any as Mock ).mockClear(); await preview.initialize({ importFn, getProjectAnnotations }); await waitForRender(); @@ -144,7 +146,7 @@ describe('PreviewWeb', () => { }); describe('onGetGlobalMeta changed (HMR)', () => { - const newGlobalDecorator = jest.fn((s) => s()); + const newGlobalDecorator = vi.fn((s) => s()); const newGetProjectAnnotations = () => { return { ...projectAnnotations, diff --git a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.mockdata.ts b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.mockdata.ts index 57c3ca18a241..9527464fa4ed 100644 --- a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.mockdata.ts +++ b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.mockdata.ts @@ -1,4 +1,6 @@ -import { describe, test, it, expect } from 'vitest'; +/// ; +import type { Mock, Mocked } from 'vitest'; +import { vi } from 'vitest'; import { EventEmitter } from 'events'; import { @@ -20,35 +22,35 @@ export const componentOneExports = { foo: { type: { name: 'string' } }, one: { name: 'one', type: { name: 'string' }, mapping: { 1: 'mapped-1' } }, }, - loaders: [jest.fn()], + loaders: [vi.fn()], parameters: { - docs: { page: jest.fn(), container: jest.fn() }, + docs: { page: vi.fn(), container: vi.fn() }, }, }, - a: { args: { foo: 'a', one: 1 }, play: jest.fn() }, - b: { args: { foo: 'b', one: 1 }, play: jest.fn() }, + a: { args: { foo: 'a', one: 1 }, play: vi.fn() }, + b: { args: { foo: 'b', one: 1 }, play: vi.fn() }, }; export const componentTwoExports = { default: { title: 'Component Two' }, c: { args: { foo: 'c' } }, }; export const attachedDocsExports = { - default: jest.fn(), + default: vi.fn(), }; export const unattachedDocsExports = { - default: jest.fn(), + default: vi.fn(), }; // If a second file defines stories for componentOne export const extraComponentOneExports = { default: { title: 'Component One', parameters: { - docs: { page: jest.fn() }, + docs: { page: vi.fn() }, }, }, e: {}, }; -export const importFn: vi.mocked = jest.fn( +export const importFn: Mocked = vi.fn( async (path: string) => ({ './src/ComponentOne.stories.js': componentOneExports, @@ -60,19 +62,19 @@ export const importFn: vi.mocked = jest.fn( ); export const docsRenderer = { - render: jest.fn().mockImplementation((context, parameters, element) => Promise.resolve()), - unmount: jest.fn(), + render: vi.fn().mockImplementation((context, parameters, element) => Promise.resolve()), + unmount: vi.fn(), }; -export const teardownrenderToCanvas: vi.mock = jest.fn(); +export const teardownrenderToCanvas: Mock = vi.fn(); export const projectAnnotations = { globals: { a: 'b' }, globalTypes: {}, - decorators: [jest.fn((s) => s())], - render: jest.fn(), - renderToCanvas: jest.fn().mockReturnValue(teardownrenderToCanvas), + decorators: [vi.fn((s) => s())], + render: vi.fn(), + renderToCanvas: vi.fn().mockReturnValue(teardownrenderToCanvas), parameters: { docs: { renderer: () => docsRenderer } }, }; -export const getProjectAnnotations = jest.fn(() => projectAnnotations as any); +export const getProjectAnnotations = vi.fn(() => projectAnnotations as any); export const storyIndex: StoryIndex = { v: 4, @@ -150,7 +152,7 @@ export const mockChannel = { on: emitter.on.bind(emitter), off: emitter.off.bind(emitter), removeListener: emitter.off.bind(emitter), - emit: jest.fn(emitter.emit.bind(emitter)), + emit: vi.fn(emitter.emit.bind(emitter)), // emit: emitter.emit.bind(emitter), }; diff --git a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts index 1abd3cffccda..a67a5c93a240 100644 --- a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts @@ -1,6 +1,8 @@ /** - * @jest-environment jsdom + * @vitest-environment jsdom */ +import type { Mock } from 'vitest'; +import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; import { global } from '@storybook/global'; import merge from 'lodash/merge.js'; @@ -56,13 +58,13 @@ import { WebView } from './WebView'; const { history, document } = global; -const mockStoryIndex = jest.fn(() => storyIndex); +const mockStoryIndex = vi.fn(() => storyIndex); let mockFetchResult: any; -vi.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', async () => ({ global: { - ...(jest.requireActual('@storybook/global') as any), - history: { replaceState: jest.fn() }, + ...((await vi.importActual('@storybook/global')) as any), + history: { replaceState: vi.fn() }, document: { location: { pathname: 'pathname', @@ -98,9 +100,9 @@ const createGate = (): [Promise, (_?: any) => void] => { // a timer, so we need to first setImmediate (to get past the resolution), then run the timers // Probably jest modern timers do this but they aren't working for some bizarre reason. async function waitForSetCurrentStory() { - jest.useFakeTimers({ doNotFake: ['setTimeout'] }); + vi.useFakeTimers({ doNotFake: ['setTimeout'] }); await new Promise((r) => setTimeout(r, 0)); - jest.runAllTimers(); + vi.runAllTimers(); } async function createAndRenderPreview({ @@ -131,7 +133,7 @@ beforeEach(() => { projectAnnotations.render.mockClear(); projectAnnotations.decorators[0].mockClear(); docsRenderer.render.mockClear(); - (logger.warn as vi.mock).mockClear(); + (logger.warn as Mock).mockClear(); mockStoryIndex.mockReset().mockReturnValue(storyIndex); addons.setChannel(mockChannel as any); @@ -192,7 +194,7 @@ describe('PreviewWeb', () => { it('SET_GLOBALS sets globals and types even when undefined', async () => { await createAndRenderPreview({ - getProjectAnnotations: () => ({ renderToCanvas: jest.fn() }), + getProjectAnnotations: () => ({ renderToCanvas: vi.fn() }), }); expect(mockChannel.emit).toHaveBeenCalledWith(SET_GLOBALS, { @@ -317,9 +319,9 @@ describe('PreviewWeb', () => { mockChannel.emit.mockClear(); const newComponentOneExports = merge({}, componentOneExports, { - d: { args: { foo: 'd' }, play: jest.fn() }, + d: { args: { foo: 'd' }, play: vi.fn() }, }); - const newImportFn = jest.fn(async (path) => { + const newImportFn = vi.fn(async (path) => { return path === './src/ComponentOne.stories.js' ? newComponentOneExports : componentTwoExports; @@ -350,10 +352,10 @@ describe('PreviewWeb', () => { describe('after selection changes', () => { beforeEach(() => { - jest.useFakeTimers(); + vi.useFakeTimers(); }); afterEach(() => { - jest.useRealTimers(); + vi.useRealTimers(); }); it('DOES NOT try again if CSF file changes', async () => { @@ -371,9 +373,9 @@ describe('PreviewWeb', () => { await waitForSetCurrentStory(); const newComponentOneExports = merge({}, componentOneExports, { - d: { args: { foo: 'd' }, play: jest.fn() }, + d: { args: { foo: 'd' }, play: vi.fn() }, }); - const newImportFn = jest.fn(async (path) => { + const newImportFn = vi.fn(async (path) => { return path === './src/ComponentOne.stories.js' ? newComponentOneExports : componentTwoExports; @@ -530,7 +532,7 @@ describe('PreviewWeb', () => { await expect(preview.initialize({ importFn, getProjectAnnotations })).rejects.toThrow(); expect(preview.view.showErrorDisplay).toHaveBeenCalled(); - expect((preview.view.showErrorDisplay as vi.mock).mock.calls[0][0]).toMatchInlineSnapshot(` + expect((preview.view.showErrorDisplay as Mock).mock.calls[0][0]).toMatchInlineSnapshot(` [Error: Expected your framework's preset to export a \`renderToCanvas\` field. Perhaps it needs to be upgraded for Storybook 6.4? @@ -1142,7 +1144,7 @@ describe('PreviewWeb', () => { }); describe('when renderStoryToElement was called', () => { - const callbacks = { showMain: jest.fn(), showError: jest.fn(), showException: jest.fn() }; + const callbacks = { showMain: vi.fn(), showError: vi.fn(), showException: vi.fn() }; it('re-renders the story', async () => { document.location.search = '?id=component-one--docs&viewMode=docs'; @@ -1298,7 +1300,7 @@ describe('PreviewWeb', () => { it('resets a single arg', async () => { document.location.search = '?id=component-one--a'; const preview = await createAndRenderPreview(); - const onUpdateArgsSpy = jest.spyOn(preview, 'onUpdateArgs'); + const onUpdateArgsSpy = vi.spyOn(preview, 'onUpdateArgs'); mockChannel.emit.mockClear(); emitter.emit(UPDATE_STORY_ARGS, { @@ -1341,7 +1343,7 @@ describe('PreviewWeb', () => { it('resets all args after one is updated', async () => { document.location.search = '?id=component-one--a'; const preview = await createAndRenderPreview(); - const onUpdateArgsSpy = jest.spyOn(preview, 'onUpdateArgs'); + const onUpdateArgsSpy = vi.spyOn(preview, 'onUpdateArgs'); emitter.emit(UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -1382,7 +1384,7 @@ describe('PreviewWeb', () => { it('resets all args', async () => { document.location.search = '?id=component-one--a'; const preview = await createAndRenderPreview(); - const onUpdateArgsSpy = jest.spyOn(preview, 'onUpdateArgs'); + const onUpdateArgsSpy = vi.spyOn(preview, 'onUpdateArgs'); emitter.emit(UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -1423,7 +1425,7 @@ describe('PreviewWeb', () => { it('resets all args when one arg is undefined', async () => { document.location.search = '?id=component-one--a'; const preview = await createAndRenderPreview(); - const onUpdateArgsSpy = jest.spyOn(preview, 'onUpdateArgs'); + const onUpdateArgsSpy = vi.spyOn(preview, 'onUpdateArgs'); emitter.emit(UPDATE_STORY_ARGS, { storyId: 'component-one--a', @@ -1481,10 +1483,10 @@ describe('PreviewWeb', () => { describe('on FORCE_REMOUNT', () => { beforeEach(() => { - jest.useFakeTimers(); + vi.useFakeTimers(); }); afterEach(() => { - jest.useRealTimers(); + vi.useRealTimers(); }); it('remounts the story with the same args', async () => { @@ -1545,10 +1547,10 @@ describe('PreviewWeb', () => { describe('onSetCurrentStory', () => { beforeEach(() => { - jest.useFakeTimers(); + vi.useFakeTimers(); }); afterEach(() => { - jest.useRealTimers(); + vi.useRealTimers(); }); it('updates URL', async () => { @@ -2164,7 +2166,7 @@ describe('PreviewWeb', () => { beforeEach(() => { originalLocation = window.location; delete (window as Partial).location; - window.location = { ...originalLocation, reload: jest.fn() }; + window.location = { ...originalLocation, reload: vi.fn() }; }); afterEach(() => { @@ -2771,7 +2773,7 @@ describe('PreviewWeb', () => { const newComponentOneExports = merge({}, componentOneExports, { a: { args: { foo: 'edited' } }, }); - const newImportFn = jest.fn(async (path) => { + const newImportFn = vi.fn(async (path) => { return path === './src/ComponentOne.stories.js' ? newComponentOneExports : componentTwoExports; @@ -3013,7 +3015,7 @@ describe('PreviewWeb', () => { }); describe('when the current story changes importPath', () => { - const newImportFn = jest.fn(async (path) => ({ ...componentOneExports })); + const newImportFn = vi.fn(async (path) => ({ ...componentOneExports })); const newStoryIndex = { v: 4, @@ -3042,10 +3044,10 @@ describe('PreviewWeb', () => { describe('if it was previously rendered', () => { beforeEach(() => { - jest.useFakeTimers(); + vi.useFakeTimers(); }); afterEach(() => { - jest.useRealTimers(); + vi.useRealTimers(); }); it('is reloaded when it is re-selected', async () => { document.location.search = '?id=component-one--a'; @@ -3075,7 +3077,7 @@ describe('PreviewWeb', () => { describe('when the current story has not changed', () => { const newComponentTwoExports = { ...componentTwoExports }; - const newImportFn = jest.fn(async (path) => { + const newImportFn = vi.fn(async (path) => { return path === './src/ComponentOne.stories.js' ? componentOneExports : newComponentTwoExports; @@ -3108,7 +3110,7 @@ describe('PreviewWeb', () => { document.location.search = '?id=component-one--a'; const preview = await createAndRenderPreview(); - (preview.view.showMain as vi.mock).mockClear(); + (preview.view.showMain as Mock).mockClear(); mockChannel.emit.mockClear(); preview.onStoriesChanged({ importFn: newImportFn }); await waitForEvents([STORY_UNCHANGED]); @@ -3132,15 +3134,15 @@ describe('PreviewWeb', () => { describe('when another (not current) story changes', () => { beforeEach(() => { - jest.useFakeTimers(); + vi.useFakeTimers(); }); afterEach(() => { - jest.useRealTimers(); + vi.useRealTimers(); }); const newComponentOneExports = merge({}, componentOneExports, { a: { args: { bar: 'edited' }, argTypes: { bar: { type: { name: 'string' } } } }, }); - const newImportFn = jest.fn(async (path) => { + const newImportFn = vi.fn(async (path) => { return path === './src/ComponentOne.stories.js' ? newComponentOneExports : componentTwoExports; @@ -3206,7 +3208,7 @@ describe('PreviewWeb', () => { describe('if the story no longer exists', () => { const { a, ...componentOneExportsWithoutA } = componentOneExports; - const newImportFn = jest.fn(async (path) => { + const newImportFn = vi.fn(async (path) => { return path === './src/ComponentOne.stories.js' ? componentOneExportsWithoutA : componentTwoExports; @@ -3271,9 +3273,9 @@ describe('PreviewWeb', () => { }); describe('when a mdx docs file changes', () => { - const newUnattachedDocsExports = { default: jest.fn() }; + const newUnattachedDocsExports = { default: vi.fn() }; - const newImportFn = jest.fn(async (path: string) => { + const newImportFn = vi.fn(async (path: string) => { return path === './src/Introduction.mdx' ? newUnattachedDocsExports : importFn(path); }); @@ -3398,7 +3400,7 @@ describe('PreviewWeb', () => { expect(mockChannel.emit).toHaveBeenCalledWith(CONFIG_ERROR, err); }); - const newGlobalDecorator = jest.fn((s: any) => s()); + const newGlobalDecorator = vi.fn((s: any) => s()); const newGetProjectAnnotations = () => { return { ...projectAnnotations, @@ -3502,7 +3504,7 @@ describe('PreviewWeb', () => { const preview = await createAndRenderPreview(); preview.onKeydown({ - target: { tagName: 'div', getAttribute: jest.fn().mockReturnValue(null) }, + target: { tagName: 'div', getAttribute: vi.fn().mockReturnValue(null) }, } as any); expect(mockChannel.emit).toHaveBeenCalledWith(PREVIEW_KEYDOWN, expect.objectContaining({})); @@ -3513,7 +3515,7 @@ describe('PreviewWeb', () => { const preview = await createAndRenderPreview(); preview.onKeydown({ - target: { tagName: 'input', getAttribute: jest.fn().mockReturnValue(null) }, + target: { tagName: 'input', getAttribute: vi.fn().mockReturnValue(null) }, } as any); expect(mockChannel.emit).not.toHaveBeenCalledWith( @@ -3532,7 +3534,7 @@ describe('PreviewWeb', () => { await waitForRenderPhase('playing'); await preview.onKeydown({ - target: { tagName: 'div', getAttribute: jest.fn().mockReturnValue(null) }, + target: { tagName: 'div', getAttribute: vi.fn().mockReturnValue(null) }, } as any); expect(mockChannel.emit).not.toHaveBeenCalledWith( @@ -3558,7 +3560,7 @@ describe('PreviewWeb', () => { await waitForRenderPhase('playing'); await preview.onKeydown({ - target: { tagName: 'div', getAttribute: jest.fn().mockReturnValue(null) }, + target: { tagName: 'div', getAttribute: vi.fn().mockReturnValue(null) }, } as any); expect(mockChannel.emit).not.toHaveBeenCalledWith( diff --git a/code/lib/preview-api/src/modules/preview-web/UrlStore.test.ts b/code/lib/preview-api/src/modules/preview-web/UrlStore.test.ts index 3a4d7f184a5b..cc6e57171968 100644 --- a/code/lib/preview-api/src/modules/preview-web/UrlStore.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/UrlStore.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import { global } from '@storybook/global'; import { pathToId, setPath, getSelectionSpecifierFromPath } from './UrlStore'; @@ -6,7 +7,7 @@ const { history, document } = global; vi.mock('@storybook/global', () => ({ global: { - history: { replaceState: jest.fn() }, + history: { replaceState: vi.fn() }, document: { location: { pathname: 'pathname', diff --git a/code/lib/preview-api/src/modules/preview-web/docs-context/DocsContext.test.ts b/code/lib/preview-api/src/modules/preview-web/docs-context/DocsContext.test.ts index a45c15db2751..22a3aacc8a41 100644 --- a/code/lib/preview-api/src/modules/preview-web/docs-context/DocsContext.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/docs-context/DocsContext.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import { Channel } from '@storybook/channels'; import type { CSFFile, Renderer } from '@storybook/types'; import type { StoryStore } from '../../store'; @@ -6,7 +7,7 @@ import { DocsContext } from './DocsContext'; import { csfFileParts } from './test-utils'; const channel = new Channel({}); -const renderStoryToElement = jest.fn(); +const renderStoryToElement = vi.fn(); describe('referenceCSFFile', () => { it('deals with unattached "docsOnly" csf files', () => { @@ -36,7 +37,7 @@ describe('resolveOf', () => { const { story, csfFile, storyExport, metaExport, moduleExports, component } = csfFileParts(); describe('attached', () => { - const projectAnnotations = { render: jest.fn() }; + const projectAnnotations = { render: vi.fn() }; const store = { componentStoriesFromCSFFile: () => [story], preparedMetaFromCSFFile: () => ({ prepareMeta: 'preparedMeta' }), @@ -177,7 +178,7 @@ describe('resolveOf', () => { }); describe('unattached', () => { - const projectAnnotations = { render: jest.fn() }; + const projectAnnotations = { render: vi.fn() }; const store = { componentStoriesFromCSFFile: () => [story], preparedMetaFromCSFFile: () => ({ prepareMeta: 'preparedMeta' }), diff --git a/code/lib/preview-api/src/modules/preview-web/parseArgsParam.test.ts b/code/lib/preview-api/src/modules/preview-web/parseArgsParam.test.ts index 477fdc284e70..0701f781f0da 100644 --- a/code/lib/preview-api/src/modules/preview-web/parseArgsParam.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/parseArgsParam.test.ts @@ -1,7 +1,8 @@ +import { describe, it, expect, vi } from 'vitest'; import { parseArgsParam } from './parseArgsParam'; vi.mock('@storybook/client-logger', () => ({ - once: { warn: jest.fn() }, + once: { warn: vi.fn() }, })); describe('parseArgsParam', () => { diff --git a/code/lib/preview-api/src/modules/preview-web/render/CsfDocsRender.test.ts b/code/lib/preview-api/src/modules/preview-web/render/CsfDocsRender.test.ts index b492a27e6506..0b290bb765d7 100644 --- a/code/lib/preview-api/src/modules/preview-web/render/CsfDocsRender.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/render/CsfDocsRender.test.ts @@ -1,3 +1,4 @@ +import { it, expect, vi } from 'vitest'; import { Channel } from '@storybook/channels'; import type { Renderer, DocsIndexEntry, RenderContextCallbacks } from '@storybook/types'; import type { StoryStore } from '../../store'; @@ -27,7 +28,7 @@ const createGate = (): [Promise, (_?: any) => void] => { it('throws PREPARE_ABORTED if torndown during prepare', async () => { const [importGate, openImportGate] = createGate(); const mockStore = { - loadEntry: jest.fn(async () => { + loadEntry: vi.fn(async () => { await importGate; return {}; }), @@ -70,7 +71,7 @@ it('attached immediately', async () => { ); await render.prepare(); - const context = render.docsContext(jest.fn()); + const context = render.docsContext(vi.fn()); expect(context.storyById()).toEqual(story); }); diff --git a/code/lib/preview-api/src/modules/preview-web/render/MdxDocsRender.test.ts b/code/lib/preview-api/src/modules/preview-web/render/MdxDocsRender.test.ts index d6676ee26a98..1ee260ae32dc 100644 --- a/code/lib/preview-api/src/modules/preview-web/render/MdxDocsRender.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/render/MdxDocsRender.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import { Channel } from '@storybook/channels'; import type { Renderer, DocsIndexEntry, RenderContextCallbacks } from '@storybook/types'; import type { StoryStore } from '../../store'; @@ -26,7 +27,7 @@ const createGate = (): [Promise, (_?: any) => void] => { it('throws PREPARE_ABORTED if torndown during prepare', async () => { const [importGate, openImportGate] = createGate(); const mockStore = { - loadEntry: jest.fn(async () => { + loadEntry: vi.fn(async () => { await importGate; return {}; }), @@ -69,7 +70,7 @@ describe('attaching', () => { ); await render.prepare(); - const context = render.docsContext(jest.fn()); + const context = render.docsContext(vi.fn()); expect(context.storyById).toThrow('No primary story defined'); }); @@ -83,7 +84,7 @@ describe('attaching', () => { ); await render.prepare(); - const context = render.docsContext(jest.fn()); + const context = render.docsContext(vi.fn()); context.referenceMeta(moduleExports, true); expect(context.storyById()).toEqual(story); diff --git a/code/lib/preview-api/src/modules/preview-web/render/StoryRender.test.ts b/code/lib/preview-api/src/modules/preview-web/render/StoryRender.test.ts index 96b0032f2361..73845a00348d 100644 --- a/code/lib/preview-api/src/modules/preview-web/render/StoryRender.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/render/StoryRender.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import { Channel } from '@storybook/channels'; import type { Renderer, StoryIndexEntry } from '@storybook/types'; import type { StoryStore } from '../../store'; @@ -25,17 +26,17 @@ describe('StoryRender', () => { it('throws PREPARE_ABORTED if torndown during prepare', async () => { const [importGate, openImportGate] = createGate(); const mockStore = { - loadStory: jest.fn(async () => { + loadStory: vi.fn(async () => { await importGate; return {}; }), - cleanupStory: jest.fn(), + cleanupStory: vi.fn(), }; const render = new StoryRender( new Channel({}), mockStore as unknown as StoryStore, - jest.fn(), + vi.fn(), {} as any, entry.id, 'story' @@ -56,16 +57,16 @@ describe('StoryRender', () => { title: 'title', name: 'name', tags: [], - applyLoaders: jest.fn(), - unboundStoryFn: jest.fn(), - playFunction: jest.fn(), - prepareContext: jest.fn(), + applyLoaders: vi.fn(), + unboundStoryFn: vi.fn(), + playFunction: vi.fn(), + prepareContext: vi.fn(), }; const render = new StoryRender( new Channel({}), { getStoryContext: () => ({}) } as any, - jest.fn() as any, + vi.fn() as any, {} as any, entry.id, 'story', @@ -83,16 +84,16 @@ describe('StoryRender', () => { title: 'title', name: 'name', tags: [], - applyLoaders: jest.fn(), - unboundStoryFn: jest.fn(), - playFunction: jest.fn(), - prepareContext: jest.fn(), + applyLoaders: vi.fn(), + unboundStoryFn: vi.fn(), + playFunction: vi.fn(), + prepareContext: vi.fn(), }; const render = new StoryRender( new Channel({}), { getStoryContext: () => ({}) } as any, - jest.fn() as any, + vi.fn() as any, {} as any, entry.id, 'story', diff --git a/code/lib/preview-api/src/modules/preview-web/simulate-pageload.test.ts b/code/lib/preview-api/src/modules/preview-web/simulate-pageload.test.ts index ec5f2051958d..94f9a45e8149 100644 --- a/code/lib/preview-api/src/modules/preview-web/simulate-pageload.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/simulate-pageload.test.ts @@ -1,6 +1,7 @@ /** - * @jest-environment jsdom + * @vitest-environment jsdom */ +import { describe, it, expect } from 'vitest'; import { global } from '@storybook/global'; import { simulatePageLoad } from './simulate-pageload'; diff --git a/code/lib/preview-api/src/modules/store/ArgsStore.test.ts b/code/lib/preview-api/src/modules/store/ArgsStore.test.ts index fb7f9c109444..933dfa1a976c 100644 --- a/code/lib/preview-api/src/modules/store/ArgsStore.test.ts +++ b/code/lib/preview-api/src/modules/store/ArgsStore.test.ts @@ -1,4 +1,4 @@ -import { expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import { ArgsStore } from './ArgsStore'; diff --git a/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts b/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts index f3f2ae96cad9..5d67a641b454 100644 --- a/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts +++ b/code/lib/preview-api/src/modules/store/GlobalsStore.test.ts @@ -1,9 +1,9 @@ -import { expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import { GlobalsStore } from './GlobalsStore'; vi.mock('@storybook/client-logger', () => ({ logger: { - warn: jest.fn(), + warn: vi.fn(), }, })); diff --git a/code/lib/preview-api/src/modules/store/StoryIndexStore.test.ts b/code/lib/preview-api/src/modules/store/StoryIndexStore.test.ts index 2fb61820ec38..f9ec0b6102a3 100644 --- a/code/lib/preview-api/src/modules/store/StoryIndexStore.test.ts +++ b/code/lib/preview-api/src/modules/store/StoryIndexStore.test.ts @@ -1,9 +1,9 @@ -import { expect } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import type { StoryIndex } from '@storybook/types'; import { StoryIndexStore } from './StoryIndexStore'; -vi.mock('@storybook/channel-websocket', () => () => ({ on: jest.fn() })); +vi.mock('@storybook/channel-websocket', () => () => ({ on: vi.fn() })); const storyIndex: StoryIndex = { v: 4, diff --git a/code/lib/preview-api/src/modules/store/StoryStore.test.ts b/code/lib/preview-api/src/modules/store/StoryStore.test.ts index fbbd5bca9d36..628008ce2556 100644 --- a/code/lib/preview-api/src/modules/store/StoryStore.test.ts +++ b/code/lib/preview-api/src/modules/store/StoryStore.test.ts @@ -1,5 +1,5 @@ +import { describe, it, expect, vi } from 'vitest'; import type { Renderer, ProjectAnnotations, StoryIndex } from '@storybook/types'; -import { expect } from 'vitest'; import { prepareStory } from './csf/prepareStory'; import { processCSFFile } from './csf/processCSFFile'; @@ -7,17 +7,17 @@ import { StoryStore } from './StoryStore'; import type { HooksContext } from './hooks'; // Spy on prepareStory/processCSFFile -vi.mock('./csf/prepareStory', () => ({ - ...jest.requireActual('./csf/prepareStory'), - prepareStory: jest.fn(jest.requireActual('./csf/prepareStory').prepareStory), +vi.mock('./csf/prepareStory', async () => ({ + ...(await vi.importActual('./csf/prepareStory')), + prepareStory: vi.fn((await vi.importActual('./csf/prepareStory')).prepareStory), })); -vi.mock('./csf/processCSFFile', () => ({ - processCSFFile: jest.fn(jest.requireActual('./csf/processCSFFile').processCSFFile), +vi.mock('./csf/processCSFFile', async () => ({ + processCSFFile: vi.fn((await vi.importActual('./csf/processCSFFile')).processCSFFile), })); -vi.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', async () => ({ global: { - ...(jest.requireActual('@storybook/global') as any), + ...((await vi.importActual('@storybook/global')) as any), }, })); @@ -38,7 +38,7 @@ const componentTwoExports = { default: { title: 'Component Two' }, c: { args: { foo: 'c' } }, }; -const importFn = jest.fn(async (path) => { +const importFn = vi.fn(async (path) => { return path === './src/ComponentOne.stories.js' ? componentOneExports : componentTwoExports; }); @@ -46,7 +46,7 @@ const projectAnnotations: ProjectAnnotations = { globals: { a: 'b' }, globalTypes: { a: { type: 'string' } }, argTypes: { a: { type: 'string' } }, - render: jest.fn(), + render: vi.fn(), }; const storyIndex: StoryIndex = { @@ -178,7 +178,7 @@ describe('StoryStore', () => { expect(processCSFFile).toHaveBeenCalledTimes(1); expect(prepareStory).toHaveBeenCalledTimes(1); - store.setProjectAnnotations({ ...projectAnnotations, decorators: [jest.fn()] }); + store.setProjectAnnotations({ ...projectAnnotations, decorators: [vi.fn()] }); // We are intentionally checking exact equality here, we need the object to be identical expect(await store.loadStory({ storyId: 'component-one--a' })).not.toBe(story); @@ -270,7 +270,7 @@ describe('StoryStore', () => { expect(importFn).toHaveBeenCalledWith(storyIndex.entries['component-one--a'].importPath); const newImportPath = './src/ComponentOne-new.stories.js'; - const newImportFn = jest.fn(async () => componentOneExports); + const newImportFn = vi.fn(async () => componentOneExports); await store.onStoriesChanged({ importFn: newImportFn, storyIndex: { @@ -301,7 +301,7 @@ describe('StoryStore', () => { expect(importFn).toHaveBeenCalledWith(storyIndex.entries['component-one--a'].importPath); const newImportPath = './src/ComponentOne-new.stories.js'; - const newImportFn = jest.fn(async () => componentOneExports); + const newImportFn = vi.fn(async () => componentOneExports); await store.onStoriesChanged({ importFn: newImportFn, storyIndex: { @@ -465,7 +465,7 @@ describe('StoryStore', () => { const story = await store.loadStory({ storyId: 'component-one--a' }); const { hooks } = store.getStoryContext(story) as { hooks: HooksContext }; - hooks.clean = jest.fn(); + hooks.clean = vi.fn(); store.cleanupStory(story); expect(hooks.clean).toHaveBeenCalled(); }); @@ -489,7 +489,7 @@ describe('StoryStore', () => { it('imports in batches', async () => { const [gate, openGate] = createGate(); - const blockedImportFn = jest.fn(async (file) => { + const blockedImportFn = vi.fn(async (file) => { await gate; return importFn(file); }); @@ -642,7 +642,7 @@ describe('StoryStore', () => { }); it('does not include (legacy) docs only stories by default', async () => { - const docsOnlyImportFn = jest.fn(async (path) => { + const docsOnlyImportFn = vi.fn(async (path) => { return path === './src/ComponentOne.stories.js' ? { ...componentOneExports, diff --git a/code/lib/preview-api/src/modules/store/args.test.ts b/code/lib/preview-api/src/modules/store/args.test.ts index d4a742bf18db..a7dbf9b8cefd 100644 --- a/code/lib/preview-api/src/modules/store/args.test.ts +++ b/code/lib/preview-api/src/modules/store/args.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import { once } from '@storybook/client-logger'; import { expect } from 'vitest'; import type { SBType } from '@storybook/types'; diff --git a/code/lib/preview-api/src/modules/store/autoTitle.test.ts b/code/lib/preview-api/src/modules/store/autoTitle.test.ts index e17c50717796..d31e3cf7c911 100644 --- a/code/lib/preview-api/src/modules/store/autoTitle.test.ts +++ b/code/lib/preview-api/src/modules/store/autoTitle.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { normalizeStoriesEntry } from '@storybook/core-common'; import { expect } from 'vitest'; diff --git a/code/lib/preview-api/src/modules/store/csf/composeConfigs.test.ts b/code/lib/preview-api/src/modules/store/csf/composeConfigs.test.ts index e223880b2990..238885f44ba3 100644 --- a/code/lib/preview-api/src/modules/store/csf/composeConfigs.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/composeConfigs.test.ts @@ -1,4 +1,4 @@ -import { expect } from 'vitest'; +import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; import { global } from '@storybook/global'; import { composeConfigs } from './composeConfigs'; @@ -257,7 +257,7 @@ describe('composeConfigs', () => { }); it('composes step runners', () => { - const fn = jest.fn(); + const fn = vi.fn(); const { runStep } = composeConfigs([ // @ts-expect-error (not defined) diff --git a/code/lib/preview-api/src/modules/store/csf/normalizeInputTypes.test.ts b/code/lib/preview-api/src/modules/store/csf/normalizeInputTypes.test.ts index a90e0c82369f..58f38ea79324 100644 --- a/code/lib/preview-api/src/modules/store/csf/normalizeInputTypes.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/normalizeInputTypes.test.ts @@ -1,4 +1,4 @@ -import { expect } from 'vitest'; +import { describe, it, expect } from 'vitest'; import { normalizeInputType, normalizeInputTypes } from './normalizeInputTypes'; diff --git a/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts b/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts index f086ff5cdf2c..aaa3e56a886f 100644 --- a/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts @@ -1,4 +1,4 @@ -import { expect, describe, it } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import type { Renderer, StoryAnnotationsOrFn } from '@storybook/types'; import { normalizeStory } from './normalizeStory'; @@ -74,15 +74,15 @@ describe('normalizeStory', () => { }); it('user-provided story render function', () => { - const storyObj = { render: jest.fn() }; - const meta = { id: 'title', title: 'title', render: jest.fn() }; + const storyObj = { render: vi.fn() }; + const meta = { id: 'title', title: 'title', render: vi.fn() }; const normalized = normalizeStory('storyExport', storyObj, meta); expect(normalized.render).toBe(storyObj.render); }); it('user-provided meta render function', () => { const storyObj = {}; - const meta = { id: 'title', title: 'title', render: jest.fn() }; + const meta = { id: 'title', title: 'title', render: vi.fn() }; const normalized = normalizeStory('storyExport', storyObj, meta); expect(normalized.render).toBeUndefined(); }); @@ -97,15 +97,15 @@ describe('normalizeStory', () => { }); it('user-provided story render function', () => { - const storyObj = { play: jest.fn() }; - const meta = { id: 'title', title: 'title', play: jest.fn() }; + const storyObj = { play: vi.fn() }; + const meta = { id: 'title', title: 'title', play: vi.fn() }; const normalized = normalizeStory('storyExport', storyObj, meta); expect(normalized.play).toBe(storyObj.play); }); it('user-provided meta render function', () => { const storyObj = {}; - const meta = { id: 'title', title: 'title', play: jest.fn() }; + const meta = { id: 'title', title: 'title', play: vi.fn() }; const normalized = normalizeStory('storyExport', storyObj, meta); expect(normalized.play).toBeUndefined(); }); diff --git a/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts b/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts index 0198e525e700..cdc203d61f7d 100644 --- a/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/prepareStory.test.ts @@ -1,5 +1,4 @@ -import { describe, test, it, expect } from 'vitest'; - +import { describe, beforeEach, it, expect, vi } from 'vitest'; import { global } from '@storybook/global'; import type { Renderer, ArgsEnhancer, PlayFunctionContext, SBScalarType } from '@storybook/types'; import { addons, HooksContext } from '../../addons'; @@ -7,9 +6,9 @@ import { addons, HooksContext } from '../../addons'; import { UNTARGETED } from '../args'; import { prepareStory, prepareMeta, prepareContext } from './prepareStory'; -vi.mock('@storybook/global', () => ({ +vi.mock('@storybook/global', async () => ({ global: { - ...(jest.requireActual('@storybook/global') as any), + ...((await vi.importActual('@storybook/global')) as any), }, })); @@ -198,7 +197,7 @@ describe('prepareStory', () => { }); it('allow you to add args', () => { - const enhancer = jest.fn(() => ({ c: 'd' })); + const enhancer = vi.fn(() => ({ c: 'd' })); const { initialArgs } = prepareStory( { id, name, args: { a: 'b' }, moduleExport }, @@ -211,14 +210,14 @@ describe('prepareStory', () => { }); it('passes result of earlier enhancers into subsequent ones, and composes their output', () => { - const enhancerOne = jest.fn(() => ({ b: 'B' })); - const enhancerTwo = jest.fn(({ initialArgs }) => + const enhancerOne = vi.fn(() => ({ b: 'B' })); + const enhancerTwo = vi.fn(({ initialArgs }) => Object.entries(initialArgs).reduce( (acc, [key, val]) => ({ ...acc, [key]: `enhanced ${val}` }), {} ) ); - const enhancerThree = jest.fn(() => ({ c: 'C' })); + const enhancerThree = vi.fn(() => ({ c: 'C' })); const { initialArgs } = prepareStory( { id, name, args: { a: 'A' }, moduleExport }, @@ -285,7 +284,7 @@ describe('prepareStory', () => { }); describe('argTypesEnhancers', () => { it('allows you to alter argTypes when stories are added', () => { - const enhancer = jest.fn((context) => ({ ...context.argTypes, c: { name: 'd' } })); + const enhancer = vi.fn((context) => ({ ...context.argTypes, c: { name: 'd' } })); const { argTypes } = prepareStory( { id, name, argTypes: { a: { name: 'b' } }, moduleExport }, { id, title }, @@ -299,7 +298,7 @@ describe('prepareStory', () => { }); it('does not merge argType enhancer results', () => { - const enhancer = jest.fn(() => ({ c: { name: 'd' } })); + const enhancer = vi.fn(() => ({ c: { name: 'd' } })); const { argTypes } = prepareStory( { id, name, argTypes: { a: { name: 'b' } }, moduleExport }, { id, title }, @@ -313,8 +312,8 @@ describe('prepareStory', () => { }); it('recursively passes argTypes to successive enhancers', () => { - const firstEnhancer = jest.fn((context) => ({ ...context.argTypes, c: { name: 'd' } })); - const secondEnhancer = jest.fn((context) => ({ ...context.argTypes, e: { name: 'f' } })); + const firstEnhancer = vi.fn((context) => ({ ...context.argTypes, c: { name: 'd' } })); + const secondEnhancer = vi.fn((context) => ({ ...context.argTypes, e: { name: 'f' } })); const { argTypes } = prepareStory( { id, name, argTypes: { a: { name: 'b' } }, moduleExport }, { id, title }, @@ -334,7 +333,7 @@ describe('prepareStory', () => { describe('applyLoaders', () => { it('awaits the result of a loader', async () => { - const loader = jest.fn(async () => new Promise((r) => setTimeout(() => r({ foo: 7 }), 100))); + const loader = vi.fn(async () => new Promise((r) => setTimeout(() => r({ foo: 7 }), 100))); const { applyLoaders } = prepareStory( { id, name, loaders: [loader as any], moduleExport }, { id, title }, @@ -395,7 +394,7 @@ describe('prepareStory', () => { describe('undecoratedStoryFn', () => { it('args are mapped by argTypes[x].mapping', () => { - const renderMock = jest.fn(); + const renderMock = vi.fn(); const story = prepareStory( { id, @@ -420,7 +419,7 @@ describe('prepareStory', () => { }); it('passes args as the first argument to the story if `parameters.passArgsFirst` is true', () => { - const renderMock = jest.fn(); + const renderMock = vi.fn(); const firstStory = prepareStory( { id, name, args: { a: 1 }, parameters: { passArgsFirst: true }, moduleExport }, { id, title }, @@ -446,10 +445,10 @@ describe('prepareStory', () => { describe('storyFn', () => { it('produces a story with inherited decorators applied', () => { - const renderMock = jest.fn(); - const globalDecorator = jest.fn((s) => s()); - const componentDecorator = jest.fn((s) => s()); - const storyDecorator = jest.fn((s) => s()); + const renderMock = vi.fn(); + const globalDecorator = vi.fn((s) => s()); + const componentDecorator = vi.fn((s) => s()); + const storyDecorator = vi.fn((s) => s()); const story = prepareStory( { id, @@ -461,7 +460,7 @@ describe('prepareStory', () => { { render: renderMock, decorators: [globalDecorator] } ); - addons.setChannel({ on: jest.fn(), removeListener: jest.fn() } as any); + addons.setChannel({ on: vi.fn(), removeListener: vi.fn() } as any); const hooks = new HooksContext(); story.unboundStoryFn({ args: story.initialArgs, hooks, ...story } as any); @@ -474,20 +473,20 @@ describe('prepareStory', () => { }); it('prepared context is applied to decorators', () => { - const renderMock = jest.fn(); + const renderMock = vi.fn(); let ctx1; let ctx2; let ctx3; - const globalDecorator = jest.fn((fn, ctx) => { + const globalDecorator = vi.fn((fn, ctx) => { ctx1 = ctx; return fn(); }); - const componentDecorator = jest.fn((fn, ctx) => { + const componentDecorator = vi.fn((fn, ctx) => { ctx2 = ctx; return fn(); }); - const storyDecorator = jest.fn((fn, ctx) => { + const storyDecorator = vi.fn((fn, ctx) => { ctx3 = ctx; return fn(); }); @@ -530,7 +529,7 @@ describe('prepareStory', () => { moduleExport, }, { id, title }, - { render: jest.fn() } + { render: vi.fn() } ); const context = prepareContext({ args: { one: 1 }, globals: {}, ...story }); @@ -550,7 +549,7 @@ describe('prepareStory', () => { moduleExport, }, { id, title }, - { render: jest.fn() } + { render: vi.fn() } ); const context = prepareContext({ @@ -569,7 +568,7 @@ describe('prepareStory', () => { global.FEATURES = { argTypeTargetsV7: true }; }); it('filters out targeted args', () => { - const renderMock = jest.fn(); + const renderMock = vi.fn(); const firstStory = prepareStory( { id, @@ -591,7 +590,7 @@ describe('prepareStory', () => { }); it('filters out conditional args', () => { - const renderMock = jest.fn(); + const renderMock = vi.fn(); const firstStory = prepareStory( { id, @@ -613,7 +612,7 @@ describe('prepareStory', () => { }); it('adds argsByTarget to context', () => { - const renderMock = jest.fn(); + const renderMock = vi.fn(); const firstStory = prepareStory( { id, @@ -635,7 +634,7 @@ describe('prepareStory', () => { }); it('always sets args, even when all are targetted', () => { - const renderMock = jest.fn(); + const renderMock = vi.fn(); const firstStory = prepareStory( { id, @@ -657,7 +656,7 @@ describe('prepareStory', () => { }); it('always sets args, even when none are set for the story', () => { - const renderMock = jest.fn(); + const renderMock = vi.fn(); const firstStory = prepareStory( { id, @@ -677,8 +676,8 @@ describe('prepareStory', () => { describe('playFunction', () => { it('awaits play if defined', async () => { - const inner = jest.fn(); - const play = jest.fn(async () => { + const inner = vi.fn(); + const play = vi.fn(async () => { await new Promise((r) => setTimeout(r, 0)); // Ensure this puts an async boundary in inner(); }); @@ -694,14 +693,14 @@ describe('playFunction', () => { }); it('provides step via runStep', async () => { - const stepPlay = jest.fn((context) => { + const stepPlay = vi.fn((context) => { expect(context).not.toBeUndefined(); expect(context.step).toEqual(expect.any(Function)); }); - const play = jest.fn(async ({ step }) => { + const play = vi.fn(async ({ step }) => { await step('label', stepPlay); }); - const runStep = jest.fn((label, p, c) => p(c)); + const runStep = vi.fn((label, p, c) => p(c)); const { playFunction } = prepareStory( { id, name, play, moduleExport }, { id, title }, diff --git a/code/lib/preview-api/src/modules/store/csf/processCSFFile.test.ts b/code/lib/preview-api/src/modules/store/csf/processCSFFile.test.ts index 2895228bb2cf..8ff880caed3a 100644 --- a/code/lib/preview-api/src/modules/store/csf/processCSFFile.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/processCSFFile.test.ts @@ -1,4 +1,4 @@ -import { expect } from 'vitest'; +import { describe, it, expect } from 'vitest'; import { processCSFFile } from './processCSFFile'; diff --git a/code/lib/preview-api/src/modules/store/csf/stepRunners.test.ts b/code/lib/preview-api/src/modules/store/csf/stepRunners.test.ts index 35d8ca883416..4858cfa7e995 100644 --- a/code/lib/preview-api/src/modules/store/csf/stepRunners.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/stepRunners.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import type { PlayFunctionContext, StepRunner } from '@storybook/types'; import { composeStepRunners } from './stepRunners'; @@ -19,10 +20,10 @@ describe('stepRunners', () => { const composed = composeStepRunners([firstStepRunner, secondStepRunner]); - const playFnA = jest.fn(); + const playFnA = vi.fn(); const playContextA = {} as PlayFunctionContext; await composed('a', playFnA, playContextA); - const playFnB = jest.fn(); + const playFnB = vi.fn(); const playContextB = {} as PlayFunctionContext; await composed('b', playFnB, playContextB); @@ -45,10 +46,10 @@ describe('stepRunners', () => { it('creates a sensible default if no step runner is provided', async () => { const composed = composeStepRunners([]); - const playFnA = jest.fn(); + const playFnA = vi.fn(); const playContextA = {} as PlayFunctionContext; await composed('a', playFnA, playContextA); - const playFnB = jest.fn(); + const playFnB = vi.fn(); const playContextB = {} as PlayFunctionContext; await composed('b', playFnB, playContextB); diff --git a/code/lib/preview-api/src/modules/store/csf/testing-utils/index.test.ts b/code/lib/preview-api/src/modules/store/csf/testing-utils/index.test.ts index f7e02d95a559..a2dc159ab40e 100644 --- a/code/lib/preview-api/src/modules/store/csf/testing-utils/index.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/testing-utils/index.test.ts @@ -1,3 +1,4 @@ +import { describe, expect, vi } from 'vitest'; import { composeStory, composeStories } from './index'; // Most integration tests for this functionality are located under renderers/react @@ -39,7 +40,7 @@ describe('composeStory', () => { describe('composeStories', () => { test('should call composeStoryFn with stories', () => { - const composeConfigFn = jest.fn((v) => v); + const composeConfigFn = vi.fn((v) => v); const module = { default: { title: 'Button', @@ -64,7 +65,7 @@ describe('composeStories', () => { }); test('should not call composeStoryFn for non-story exports', () => { - const composeConfigFn = jest.fn((v) => v); + const composeConfigFn = vi.fn((v) => v); const module = { default: { title: 'Button', diff --git a/code/lib/preview-api/src/modules/store/decorators.test.ts b/code/lib/preview-api/src/modules/store/decorators.test.ts index a24aec1a41e2..c187fb2b5d8b 100644 --- a/code/lib/preview-api/src/modules/store/decorators.test.ts +++ b/code/lib/preview-api/src/modules/store/decorators.test.ts @@ -1,4 +1,4 @@ -import { expect } from 'vitest'; +import { describe, it, expect } from 'vitest'; import type { Renderer, StoryContext } from '@storybook/types'; import { defaultDecorateStory } from './decorators'; diff --git a/code/lib/preview-api/src/modules/store/hooks.test.ts b/code/lib/preview-api/src/modules/store/hooks.test.ts index 4e4a8f49efcb..1b82b26de6c4 100644 --- a/code/lib/preview-api/src/modules/store/hooks.test.ts +++ b/code/lib/preview-api/src/modules/store/hooks.test.ts @@ -1,4 +1,4 @@ -import { expect } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import { FORCE_RE_RENDER, STORY_RENDERED, @@ -27,7 +27,7 @@ import { import { defaultDecorateStory } from './decorators'; vi.mock('@storybook/client-logger', () => ({ - logger: { warn: jest.fn(), log: jest.fn() }, + logger: { warn: vi.fn(), log: vi.fn() }, })); const SOME_EVENT = 'someEvent'; @@ -36,10 +36,10 @@ let hooks: any; let onSomeEvent: any; let removeSomeEventListener: any; beforeEach(() => { - onSomeEvent = jest.fn(); - removeSomeEventListener = jest.fn(); + onSomeEvent = vi.fn(); + removeSomeEventListener = vi.fn(); mockChannel = { - emit: jest.fn(), + emit: vi.fn(), on(event: any, callback: any) { switch (event) { case STORY_RENDERED: @@ -69,14 +69,14 @@ const run = (storyFn: any, decorators: DecoratorFunction[] = [], context = {}) = describe('Preview hooks', () => { describe('useEffect', () => { it('triggers the effect from story function', () => { - const effect = jest.fn(); + const effect = vi.fn(); run(() => { useEffect(effect); }); expect(effect).toHaveBeenCalledTimes(1); }); it('triggers the effect from decorator', () => { - const effect = jest.fn(); + const effect = vi.fn(); run(() => {}, [ (storyFn) => { useEffect(effect); @@ -86,7 +86,7 @@ describe('Preview hooks', () => { expect(effect).toHaveBeenCalledTimes(1); }); it('triggers the effect from decorator if story call comes before useEffect', () => { - const effect = jest.fn(); + const effect = vi.fn(); run(() => {}, [ (storyFn) => { const story = storyFn(); @@ -97,7 +97,7 @@ describe('Preview hooks', () => { expect(effect).toHaveBeenCalledTimes(1); }); it('retriggers the effect if no deps array is provided', () => { - const effect = jest.fn(); + const effect = vi.fn(); const storyFn = () => { useEffect(effect); }; @@ -106,7 +106,7 @@ describe('Preview hooks', () => { expect(effect).toHaveBeenCalledTimes(2); }); it("doesn't retrigger the effect if empty deps array is provided", () => { - const effect = jest.fn(); + const effect = vi.fn(); const storyFn = () => { useEffect(effect, []); }; @@ -115,7 +115,7 @@ describe('Preview hooks', () => { expect(effect).toHaveBeenCalledTimes(1); }); it("doesn't retrigger the effect from decorator if story has changed", () => { - const effect = jest.fn(); + const effect = vi.fn(); const decorator = (storyFn: any) => { useEffect(effect, []); return storyFn(); @@ -125,7 +125,7 @@ describe('Preview hooks', () => { expect(effect).toHaveBeenCalledTimes(1); }); it("doesn't retrigger the effect from decorator if story has changed and story call comes before useEffect", () => { - const effect = jest.fn(); + const effect = vi.fn(); const decorator = (storyFn: any) => { const story = storyFn(); useEffect(effect, []); @@ -136,7 +136,7 @@ describe('Preview hooks', () => { expect(effect).toHaveBeenCalledTimes(1); }); it("doesn't retrigger the effect from if decorator calls story twice", () => { - const effect = jest.fn(); + const effect = vi.fn(); const story = () => { useEffect(effect, []); }; @@ -148,7 +148,7 @@ describe('Preview hooks', () => { expect(effect).toHaveBeenCalledTimes(1); }); it('handles decorator conditionally rendering the story', () => { - const effect = jest.fn(); + const effect = vi.fn(); const story = () => { useEffect(effect, []); }; @@ -167,7 +167,7 @@ describe('Preview hooks', () => { expect(effect).toHaveBeenCalledTimes(2); }); it('retriggers the effect if some of the deps are changed', () => { - const effect = jest.fn(); + const effect = vi.fn(); let counter = 0; const storyFn = () => { useEffect(effect, [counter]); @@ -178,7 +178,7 @@ describe('Preview hooks', () => { expect(effect).toHaveBeenCalledTimes(2); }); it("doesn't retrigger the effect if none of the deps are changed", () => { - const effect = jest.fn(); + const effect = vi.fn(); const storyFn = () => { useEffect(effect, [0]); }; @@ -187,7 +187,7 @@ describe('Preview hooks', () => { expect(effect).toHaveBeenCalledTimes(1); }); it('performs cleanup when retriggering', () => { - const destroy = jest.fn(); + const destroy = vi.fn(); const storyFn = () => { useEffect(() => destroy); }; @@ -196,7 +196,7 @@ describe('Preview hooks', () => { expect(destroy).toHaveBeenCalledTimes(1); }); it("doesn't perform cleanup when keeping the current effect", () => { - const destroy = jest.fn(); + const destroy = vi.fn(); const storyFn = () => { useEffect(() => destroy, []); }; @@ -205,7 +205,7 @@ describe('Preview hooks', () => { expect(destroy).not.toHaveBeenCalled(); }); it('performs cleanup when removing the decorator', () => { - const destroy = jest.fn(); + const destroy = vi.fn(); run(() => {}, [ (storyFn) => { useEffect(() => destroy); @@ -299,7 +299,7 @@ describe('Preview hooks', () => { describe('useMemo', () => { it('performs the calculation', () => { let result; - const nextCreate = jest.fn(() => 'foo'); + const nextCreate = vi.fn(() => 'foo'); const storyFn = () => { result = useMemo(nextCreate, []); }; @@ -309,7 +309,7 @@ describe('Preview hooks', () => { }); it('performs the calculation once if deps are unchanged', () => { let result; - const nextCreate = jest.fn(() => 'foo'); + const nextCreate = vi.fn(() => 'foo'); const storyFn = () => { result = useMemo(nextCreate, []); }; @@ -321,7 +321,7 @@ describe('Preview hooks', () => { it('performs the calculation again if deps are changed', () => { let result; let counter = 0; - const nextCreate = jest.fn(() => counter); + const nextCreate = vi.fn(() => counter); const storyFn = () => { counter += 1; result = useMemo(nextCreate, [counter]); @@ -412,7 +412,7 @@ describe('Preview hooks', () => { it('performs synchronous state updates', () => { let state; let setState; - const storyFn = jest.fn(() => { + const storyFn = vi.fn(() => { [state, setState] = useState('foo'); if (state === 'foo') { setState('bar'); @@ -423,8 +423,8 @@ describe('Preview hooks', () => { expect(state).toBe('bar'); }); it('triggers only the last effect when updating state synchronously', () => { - const effects = [jest.fn(), jest.fn()]; - const storyFn = jest.fn(() => { + const effects = [vi.fn(), vi.fn()]; + const storyFn = vi.fn(() => { const [effectIndex, setEffectIndex] = useState(0); useEffect(effects[effectIndex], [effectIndex]); if (effectIndex === 0) { @@ -438,7 +438,7 @@ describe('Preview hooks', () => { it('performs synchronous state updates with updater function', () => { let state; let setState; - const storyFn = jest.fn(() => { + const storyFn = vi.fn(() => { [state, setState] = useState(0); if (state < 3) { setState((prevState) => prevState + 1); @@ -451,7 +451,7 @@ describe('Preview hooks', () => { it('performs asynchronous state updates', () => { let state; let setState: any; - const storyFn = jest.fn(() => { + const storyFn = vi.fn(() => { [state, setState] = useState('foo'); }); run(storyFn); @@ -485,7 +485,7 @@ describe('Preview hooks', () => { it('performs synchronous state updates', () => { let state; let dispatch; - const storyFn = jest.fn(() => { + const storyFn = vi.fn(() => { [state, dispatch] = useReducer((prevState, action) => { switch (action) { case 'INCREMENT': @@ -505,7 +505,7 @@ describe('Preview hooks', () => { it('performs asynchronous state updates', () => { let state: any; let dispatch: any; - const storyFn = jest.fn(() => { + const storyFn = vi.fn(() => { [state, dispatch] = useReducer((prevState, action) => { switch (action) { case 'INCREMENT': diff --git a/code/lib/preview-api/src/modules/store/inferArgTypes.test.ts b/code/lib/preview-api/src/modules/store/inferArgTypes.test.ts index b5f520c80e5b..45fe81870aa4 100644 --- a/code/lib/preview-api/src/modules/store/inferArgTypes.test.ts +++ b/code/lib/preview-api/src/modules/store/inferArgTypes.test.ts @@ -1,5 +1,6 @@ +import type { Mocked } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import { logger } from '@storybook/client-logger'; -import { expect } from 'vitest'; import { inferArgTypes } from './inferArgTypes'; @@ -83,7 +84,7 @@ describe('inferArgTypes', () => { const cyclic: any = {}; cyclic.foo = cyclic; - (logger.warn as vi.mockedFunction).mockClear(); + (logger.warn as Mocked).mockClear(); expect( inferArgTypes({ initialArgs: { @@ -100,7 +101,7 @@ describe('inferArgTypes', () => { }); it('ensures names', () => { - (logger.warn as vi.mockedFunction).mockClear(); + (logger.warn as Mocked).mockClear(); expect( inferArgTypes({ initialArgs: { @@ -124,7 +125,7 @@ describe('inferArgTypes', () => { }); it('ensures names even with no arg', () => { - (logger.warn as vi.mockedFunction).mockClear(); + (logger.warn as Mocked).mockClear(); expect( inferArgTypes({ argTypes: { diff --git a/code/lib/preview-api/src/modules/store/inferControls.test.ts b/code/lib/preview-api/src/modules/store/inferControls.test.ts index da66bd24adbd..976d3b316e73 100644 --- a/code/lib/preview-api/src/modules/store/inferControls.test.ts +++ b/code/lib/preview-api/src/modules/store/inferControls.test.ts @@ -1,4 +1,5 @@ -import { expect } from 'vitest'; +import type { SpyInstance } from 'vitest'; +import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; import { logger } from '@storybook/client-logger'; import type { StoryContextForEnhancers } from '@storybook/types'; @@ -26,9 +27,9 @@ const getStoryContext = (overrides: any = {}): StoryContextForEnhancers => ({ const [inferControls] = argTypesEnhancers; describe('inferControls', () => { describe('with custom matchers', () => { - let warnSpy: jest.SpyInstance; + let warnSpy: SpyInstance; beforeEach(() => { - warnSpy = jest.spyOn(logger, 'warn'); + warnSpy = vi.spyOn(logger, 'warn'); warnSpy.mockImplementation(() => {}); }); afterEach(() => { diff --git a/code/lib/preview-api/src/modules/store/parameters.test.ts b/code/lib/preview-api/src/modules/store/parameters.test.ts index 0669481f602c..d408f641a0a9 100644 --- a/code/lib/preview-api/src/modules/store/parameters.test.ts +++ b/code/lib/preview-api/src/modules/store/parameters.test.ts @@ -1,4 +1,4 @@ -import { expect } from 'vitest'; +import { describe, it, expect } from 'vitest'; import { combineParameters } from './parameters'; describe('client-api.parameters', () => { diff --git a/code/lib/router/src/utils.test.ts b/code/lib/router/src/utils.test.ts index d6ddf6f69b31..ee149a8a6478 100644 --- a/code/lib/router/src/utils.test.ts +++ b/code/lib/router/src/utils.test.ts @@ -1,7 +1,8 @@ +import { describe, it, expect, vi } from 'vitest'; import { buildArgsParam, deepDiff, DEEPLY_EQUAL, getMatch, parsePath } from './utils'; vi.mock('@storybook/client-logger', () => ({ - once: { warn: jest.fn() }, + once: { warn: vi.fn() }, })); describe('getMatch', () => { diff --git a/code/lib/source-loader/src/abstract-syntax-tree/inject-decorator.csf.test.js b/code/lib/source-loader/src/abstract-syntax-tree/inject-decorator.csf.test.js index b74c46354fdd..f21638d1c8ce 100644 --- a/code/lib/source-loader/src/abstract-syntax-tree/inject-decorator.csf.test.js +++ b/code/lib/source-loader/src/abstract-syntax-tree/inject-decorator.csf.test.js @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { readFile } from 'fs/promises'; import path from 'path'; import 'jest-specific-snapshot'; diff --git a/code/lib/source-loader/src/abstract-syntax-tree/inject-decorator.test.js b/code/lib/source-loader/src/abstract-syntax-tree/inject-decorator.test.js index 755feb9117fd..4d4217387a89 100644 --- a/code/lib/source-loader/src/abstract-syntax-tree/inject-decorator.test.js +++ b/code/lib/source-loader/src/abstract-syntax-tree/inject-decorator.test.js @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import fs from 'fs'; import path from 'path'; import injectDecorator from './inject-decorator'; diff --git a/code/lib/telemetry/src/anonymous-id.test.ts b/code/lib/telemetry/src/anonymous-id.test.ts index ad8f01ad0b1f..01caff1cd1fe 100644 --- a/code/lib/telemetry/src/anonymous-id.test.ts +++ b/code/lib/telemetry/src/anonymous-id.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { normalizeGitUrl } from './anonymous-id'; describe('normalizeGitUrl', () => { diff --git a/code/lib/telemetry/src/event-cache.test.ts b/code/lib/telemetry/src/event-cache.test.ts index 7d1fd463bd94..788fb5270c64 100644 --- a/code/lib/telemetry/src/event-cache.test.ts +++ b/code/lib/telemetry/src/event-cache.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { getPrecedingUpgrade } from './event-cache'; expect.addSnapshotSerializer({ diff --git a/code/lib/telemetry/src/get-chromatic-version.test.ts b/code/lib/telemetry/src/get-chromatic-version.test.ts index 9ee07f3d45e0..85627012c799 100644 --- a/code/lib/telemetry/src/get-chromatic-version.test.ts +++ b/code/lib/telemetry/src/get-chromatic-version.test.ts @@ -1,3 +1,4 @@ +import { it, expect } from 'vitest'; import { getChromaticVersionSpecifier } from './get-chromatic-version'; it('works for dependencies', () => { diff --git a/code/lib/telemetry/src/get-framework-info.test.ts b/code/lib/telemetry/src/get-framework-info.test.ts index f5b8e22df596..370b34be01fb 100644 --- a/code/lib/telemetry/src/get-framework-info.test.ts +++ b/code/lib/telemetry/src/get-framework-info.test.ts @@ -1,10 +1,12 @@ +import type { Mock } from 'vitest'; +import { describe, it, expect, vi } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import path from 'path'; import { getFrameworkInfo } from './get-framework-info'; import { getActualPackageJson } from './package-json'; vi.mock('./package-json', () => ({ - getActualPackageJson: jest.fn(), + getActualPackageJson: vi.fn(), })); describe('getFrameworkInfo', () => { @@ -36,7 +38,7 @@ describe('getFrameworkInfo', () => { }, }; - (getActualPackageJson as vi.mock).mockResolvedValueOnce(frameworkPackageJson); + (getActualPackageJson as Mock).mockResolvedValueOnce(frameworkPackageJson); const result = await getFrameworkInfo({ framework } as StorybookConfig); diff --git a/code/lib/telemetry/src/get-monorepo-type.test.ts b/code/lib/telemetry/src/get-monorepo-type.test.ts index 896996828954..1f66a4a288f8 100644 --- a/code/lib/telemetry/src/get-monorepo-type.test.ts +++ b/code/lib/telemetry/src/get-monorepo-type.test.ts @@ -1,4 +1,5 @@ /* eslint-disable no-underscore-dangle */ +import { describe, it, expect, vi } from 'vitest'; import path from 'path'; import { getMonorepoType, monorepoConfigs } from './get-monorepo-type'; @@ -6,8 +7,8 @@ import { getMonorepoType, monorepoConfigs } from './get-monorepo-type'; // eslint-disable-next-line global-require, jest/no-mocks-import vi.mock('fs-extra', () => require('../../../__mocks__/fs-extra')); -vi.mock('@storybook/core-common', () => { - const coreCommon = jest.requireActual('@storybook/core-common'); +vi.mock('@storybook/core-common', async () => { + const coreCommon = await vi.importActual('@storybook/core-common'); return { ...coreCommon, getProjectRoot: () => 'root', diff --git a/code/lib/telemetry/src/sanitize.test.ts b/code/lib/telemetry/src/sanitize.test.ts index 934695e1e70b..6edd7f0cb804 100644 --- a/code/lib/telemetry/src/sanitize.test.ts +++ b/code/lib/telemetry/src/sanitize.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; /* eslint-disable local-rules/no-uncategorized-errors */ import { sanitizeError, cleanPaths } from './sanitize'; @@ -64,7 +65,7 @@ describe(`Errors Helpers`, () => { expect(e.message).toEqual(errorMessage); expect(e.stack).toBeDefined(); - const mockCwd = jest + const mockCwd = vi .spyOn(process, `cwd`) .mockImplementation(() => `/Users/username/Code/storybook-app`); @@ -85,7 +86,7 @@ describe(`Errors Helpers`, () => { `should clean path on unix: %s`, (filePath) => { const cwdMockPath = `/Users/username/storybook-app`; - const mockCwd = jest.spyOn(process, `cwd`).mockImplementation(() => cwdMockPath); + const mockCwd = vi.spyOn(process, `cwd`).mockImplementation(() => cwdMockPath); const errorMessage = `Path 1 /Users/Username/storybook-app/${filePath} Path 2 /Users/username/storybook-app/${filePath}`; @@ -101,7 +102,7 @@ describe(`Errors Helpers`, () => { (filePath) => { const cwdMockPath = `C:\\Users\\username\\storybook-app`; - const mockCwd = jest.spyOn(process, `cwd`).mockImplementationOnce(() => cwdMockPath); + const mockCwd = vi.spyOn(process, `cwd`).mockImplementationOnce(() => cwdMockPath); const errorMessage = `Path 1 C:\\Users\\username\\storybook-app\\${filePath} Path 2 c:\\Users\\username\\storybook-app\\${filePath}`; expect(cleanPaths(errorMessage, `\\`)).toBe( diff --git a/code/lib/telemetry/src/session-id.test.ts b/code/lib/telemetry/src/session-id.test.ts index 919245d8d3db..cdc87df6121a 100644 --- a/code/lib/telemetry/src/session-id.test.ts +++ b/code/lib/telemetry/src/session-id.test.ts @@ -1,24 +1,26 @@ +import type { SpyInstance } from 'vitest'; +import { describe, test, beforeEach, expect, vi } from 'vitest'; import { nanoid } from 'nanoid'; import { cache } from '@storybook/core-common'; import { resetSessionIdForTest, getSessionId, SESSION_TIMEOUT } from './session-id'; -vi.mock('@storybook/core-common', () => { - const actual = jest.requireActual('@storybook/core-common'); +vi.mock('@storybook/core-common', async () => { + const actual = await vi.importActual('@storybook/core-common'); return { ...actual, cache: { - get: jest.fn(), - set: jest.fn(), + get: vi.fn(), + set: vi.fn(), }, }; }); vi.mock('nanoid'); -const spy = (x: any) => x as jest.SpyInstance; +const spy = (x: any) => x as SpyInstance; describe('getSessionId', () => { beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); resetSessionIdForTest(); }); @@ -60,7 +62,7 @@ describe('getSessionId', () => { test('generates new sessionId when none exists', async () => { const newSessionId = 'new-session-id'; - (nanoid as any as jest.SpyInstance).mockReturnValueOnce(newSessionId); + (nanoid as any as SpyInstance).mockReturnValueOnce(newSessionId); spy(cache.get).mockResolvedValueOnce(undefined); diff --git a/code/lib/telemetry/src/storybook-metadata.test.ts b/code/lib/telemetry/src/storybook-metadata.test.ts index a3d1b6c85fb0..da44e8d959af 100644 --- a/code/lib/telemetry/src/storybook-metadata.test.ts +++ b/code/lib/telemetry/src/storybook-metadata.test.ts @@ -1,3 +1,5 @@ +import type { SpyInstance } from 'vitest'; +import { describe, beforeEach, afterEach, expect, vi } from 'vitest'; import type { PackageJson, StorybookConfig } from '@storybook/types'; import path from 'path'; @@ -13,18 +15,18 @@ const mainJsMock: StorybookConfig = { }; vi.mock('./package-json', () => { - const getActualPackageVersion = jest.fn((name) => + const getActualPackageVersion = vi.fn((name) => Promise.resolve({ name, version: 'x.x.x', }) ); - const getActualPackageVersions = jest.fn((packages) => + const getActualPackageVersions = vi.fn((packages) => Promise.all(Object.keys(packages).map(getActualPackageVersion)) ); - const getActualPackageJson = jest.fn((name) => ({ + const getActualPackageJson = vi.fn((name) => ({ dependencies: { '@storybook/react': 'x.x.x', '@storybook/builder-vite': 'x.x.x', @@ -50,7 +52,7 @@ vi.mock('detect-package-manager', () => ({ const originalSep = path.sep; describe('storybook-metadata', () => { - let cwdSpy: jest.SpyInstance; + let cwdSpy: SpyInstance; beforeEach(() => { // @ts-expect-error the property is read only but we can change it for testing purposes path.sep = originalSep; @@ -91,7 +93,7 @@ describe('storybook-metadata', () => { // @ts-expect-error the property is read only but we can change it for testing purposes path.sep = '\\'; const cwdMockPath = `C:\\Users\\username\\storybook-app`; - cwdSpy = jest.spyOn(process, `cwd`).mockReturnValueOnce(cwdMockPath); + cwdSpy = vi.spyOn(process, `cwd`).mockReturnValueOnce(cwdMockPath); expect(sanitizeAddonName(`${cwdMockPath}\\local-addon\\themes.js`)).toEqual( '$SNIP\\local-addon\\themes' @@ -102,7 +104,7 @@ describe('storybook-metadata', () => { // @ts-expect-error the property is read only but we can change it for testing purposes path.sep = '/'; const cwdMockPath = `/Users/username/storybook-app`; - cwdSpy = jest.spyOn(process, `cwd`).mockReturnValue(cwdMockPath); + cwdSpy = vi.spyOn(process, `cwd`).mockReturnValue(cwdMockPath); expect(sanitizeAddonName(`${cwdMockPath}/local-addon/themes.js`)).toEqual( '$SNIP/local-addon/themes' @@ -183,7 +185,7 @@ describe('storybook-metadata', () => { test('should sanitize pnp paths for local frameworks', async () => { // @ts-expect-error the property is read only but we can change it for testing purposes path.sep = '/'; - cwdSpy = jest.spyOn(process, 'cwd').mockReturnValue('/Users/foo/my-projects'); + cwdSpy = vi.spyOn(process, 'cwd').mockReturnValue('/Users/foo/my-projects'); const unixResult = await computeStorybookMetadata({ packageJson: packageJsonMock, @@ -201,7 +203,7 @@ describe('storybook-metadata', () => { // @ts-expect-error the property is read only but we can change it for testing purposes path.sep = '\\'; - cwdSpy = jest.spyOn(process, 'cwd').mockReturnValue('C:\\Users\\foo\\my-project'); + cwdSpy = vi.spyOn(process, 'cwd').mockReturnValue('C:\\Users\\foo\\my-project'); const windowsResult = await computeStorybookMetadata({ packageJson: packageJsonMock, mainConfig: { diff --git a/code/lib/telemetry/src/telemetry.test.ts b/code/lib/telemetry/src/telemetry.test.ts index ba88abc1ee4a..a9b3f730b84a 100644 --- a/code/lib/telemetry/src/telemetry.test.ts +++ b/code/lib/telemetry/src/telemetry.test.ts @@ -1,12 +1,14 @@ -import { describe, test, it, expect } from 'vitest'; - +/// import fetch from 'node-fetch'; +import type { Mock } from 'vitest'; +import { beforeEach, it, expect, vi } from 'vitest'; + import { sendTelemetry } from './telemetry'; vi.mock('node-fetch'); vi.mock('./event-cache', () => { - return { set: jest.fn() }; + return { set: vi.fn() }; }); vi.mock('./session-id', () => { @@ -17,7 +19,7 @@ vi.mock('./session-id', () => { }; }); -const fetchMock = fetch as vi.mock; +const fetchMock = fetch as Mock; beforeEach(() => { fetchMock.mockResolvedValue({ status: 200 }); diff --git a/code/lib/theming/src/tests/convert.test.js b/code/lib/theming/src/tests/convert.test.js index 69516fdc386f..80a2512cb4d1 100644 --- a/code/lib/theming/src/tests/convert.test.js +++ b/code/lib/theming/src/tests/convert.test.js @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { convert } from '../convert'; import { create } from '../create'; import darkThemeVars from '../themes/dark'; diff --git a/code/lib/theming/src/tests/create.test.js b/code/lib/theming/src/tests/create.test.js index 26746246640c..b5f037e0a2e0 100644 --- a/code/lib/theming/src/tests/create.test.js +++ b/code/lib/theming/src/tests/create.test.js @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { create } from '../create'; describe('create base', () => { diff --git a/code/lib/theming/src/tests/util.test.js b/code/lib/theming/src/tests/util.test.js index 024fcaf14201..457230fdeb68 100644 --- a/code/lib/theming/src/tests/util.test.js +++ b/code/lib/theming/src/tests/util.test.js @@ -1,3 +1,4 @@ +import { describe, it, expect, vi } from 'vitest'; import { global } from '@storybook/global'; import { lightenColor as lighten, darkenColor as darken, getPreferredColorScheme } from '../utils'; @@ -87,7 +88,7 @@ describe('utils', () => { }); it('should return "light" if the preferred color scheme is light or undefined', () => { - globalWindow.matchMedia = jest.fn().mockImplementation(() => ({ + globalWindow.matchMedia = vi.fn().mockImplementation(() => ({ matches: false, })); @@ -99,7 +100,7 @@ describe('utils', () => { // By setting matches to always be true any checks for prefer-color-scheme // will match and since we only check if the preferred scheme is dark this // is a simple way to test it - globalWindow.matchMedia = jest.fn().mockImplementation(() => ({ + globalWindow.matchMedia = vi.fn().mockImplementation(() => ({ matches: true, })); diff --git a/code/presets/react-webpack/src/cra-config.test.ts b/code/presets/react-webpack/src/cra-config.test.ts index bef1eab4ebf7..755d8136e0ae 100644 --- a/code/presets/react-webpack/src/cra-config.test.ts +++ b/code/presets/react-webpack/src/cra-config.test.ts @@ -1,11 +1,13 @@ +import type { Mock } from 'vitest'; +import { describe, beforeEach, it, expect, vi } from 'vitest'; import fs from 'fs'; import path from 'path'; import { getReactScriptsPath } from './cra-config'; vi.mock('fs', () => ({ - realpathSync: jest.fn(() => '/test-project'), - readFileSync: jest.fn(), - existsSync: jest.fn(() => true), + realpathSync: vi.fn(() => '/test-project'), + readFileSync: vi.fn(), + existsSync: vi.fn(() => true), })); const SCRIPT_PATH = path.join('.bin', 'react-scripts'); @@ -13,7 +15,7 @@ const SCRIPT_PATH = path.join('.bin', 'react-scripts'); describe('cra-config', () => { describe('when used with the default react-scripts package', () => { beforeEach(() => { - (fs.realpathSync as unknown as vi.mock).mockImplementationOnce((filePath) => + (fs.realpathSync as unknown as Mock).mockImplementationOnce((filePath) => filePath.replace(SCRIPT_PATH, `react-scripts/${SCRIPT_PATH}`) ); }); @@ -27,7 +29,7 @@ describe('cra-config', () => { describe('when used with a custom react-scripts package', () => { beforeEach(() => { - (fs.realpathSync as unknown as vi.mock).mockImplementationOnce((filePath) => + (fs.realpathSync as unknown as Mock).mockImplementationOnce((filePath) => filePath.replace(SCRIPT_PATH, `custom-react-scripts/${SCRIPT_PATH}`) ); }); @@ -43,9 +45,9 @@ describe('cra-config', () => { beforeEach(() => { // In case of .bin/react-scripts is not symlink (like it happens on Windows), // realpathSync() method does not translate the path. - (fs.realpathSync as unknown as vi.mock).mockImplementationOnce((filePath) => filePath); + (fs.realpathSync as unknown as Mock).mockImplementationOnce((filePath) => filePath); - (fs.readFileSync as unknown as vi.mock).mockImplementationOnce( + (fs.readFileSync as unknown as Mock).mockImplementationOnce( () => `#!/bin/sh basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") diff --git a/code/presets/react-webpack/src/framework-preset-react-docs.test.ts b/code/presets/react-webpack/src/framework-preset-react-docs.test.ts index 991f084746ba..1d1529985e2a 100644 --- a/code/presets/react-webpack/src/framework-preset-react-docs.test.ts +++ b/code/presets/react-webpack/src/framework-preset-react-docs.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import ReactDocgenTypescriptPlugin from '@storybook/react-docgen-typescript-plugin'; import type { TypescriptOptions } from '@storybook/core-webpack'; import * as preset from './framework-preset-react-docs'; diff --git a/code/presets/react-webpack/src/framework-preset-react.test.ts b/code/presets/react-webpack/src/framework-preset-react.test.ts index a9898ad9b91b..3e555a7673b1 100644 --- a/code/presets/react-webpack/src/framework-preset-react.test.ts +++ b/code/presets/react-webpack/src/framework-preset-react.test.ts @@ -1,11 +1,12 @@ +import { describe, it, expect, vi } from 'vitest'; import type { Configuration } from 'webpack'; import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin'; import type { Options } from '@storybook/core-webpack'; import * as preset from './framework-preset-react'; -const mockApply = jest.fn(); +const mockApply = vi.fn(); vi.mock('@pmmmwh/react-refresh-webpack-plugin', () => { - return jest.fn().mockImplementation(() => { + return vi.fn().mockImplementation(() => { return { apply: mockApply }; }); }); diff --git a/code/renderers/html/src/docs/sourceDecorator.test.ts b/code/renderers/html/src/docs/sourceDecorator.test.ts index effc416a0a40..dc40a1da0daa 100644 --- a/code/renderers/html/src/docs/sourceDecorator.test.ts +++ b/code/renderers/html/src/docs/sourceDecorator.test.ts @@ -1,11 +1,13 @@ import { SNIPPET_RENDERED } from '@storybook/docs-tools'; import { addons, useEffect } from '@storybook/preview-api'; +import type { Mock } from 'vitest'; +import { vi, describe, beforeEach, it, expect } from 'vitest'; import { sourceDecorator } from './sourceDecorator'; import type { StoryContext } from '../types'; vi.mock('@storybook/preview-api'); -const mockedAddons = addons as vi.mocked; -const mockedUseEffect = useEffect as vi.mocked; +const mockedAddons = addons as Mock; +const mockedUseEffect = useEffect as Mock; expect.addSnapshotSerializer({ print: (val: any) => val, @@ -34,13 +36,13 @@ const makeContext = (name: string, parameters: any, args: any, extra?: object): } as StoryContext); describe('sourceDecorator', () => { - let mockChannel: { on: vi.mock; emit?: vi.mock }; + let mockChannel: { on: Mock; emit?: Mock }; beforeEach(() => { mockedAddons.getChannel.mockReset(); // @ts-expect-error (Converted from ts-ignore) mockedUseEffect.mockImplementation((cb) => setTimeout(() => cb(), 0)); - mockChannel = { on: jest.fn(), emit: jest.fn() }; + mockChannel = { on: vi.fn(), emit: vi.fn() }; mockedAddons.getChannel.mockReturnValue(mockChannel as any); }); diff --git a/code/renderers/react/src/__test__/composeStories.test.tsx b/code/renderers/react/src/__test__/composeStories.test.tsx index ef706b79ce81..cf2092cda6d7 100644 --- a/code/renderers/react/src/__test__/composeStories.test.tsx +++ b/code/renderers/react/src/__test__/composeStories.test.tsx @@ -1,4 +1,4 @@ -import { describe, test, it, expect } from 'vitest'; +import { vi, test, expect } from 'vitest'; import React from 'react'; import { render, screen } from '@testing-library/react'; @@ -28,7 +28,7 @@ test('reuses args from composed story', () => { }); test('onclick handler is called', async () => { - const onClickSpy = jest.fn(); + const onClickSpy = vi.fn(); render(); const buttonElement = screen.getByRole('button'); buttonElement.click(); diff --git a/code/renderers/react/src/__test__/internals.test.tsx b/code/renderers/react/src/__test__/internals.test.tsx index d3e23b0a9c37..60c79663e580 100644 --- a/code/renderers/react/src/__test__/internals.test.tsx +++ b/code/renderers/react/src/__test__/internals.test.tsx @@ -1,4 +1,3 @@ -import { describe, test, it, expect } from 'vitest'; /* eslint-disable @typescript-eslint/no-non-null-assertion */ import React from 'react'; import { addons } from '@storybook/preview-api'; diff --git a/code/renderers/react/src/docs/jsxDecorator.test.tsx b/code/renderers/react/src/docs/jsxDecorator.test.tsx index cb561e12ecc4..da8e4303b8db 100644 --- a/code/renderers/react/src/docs/jsxDecorator.test.tsx +++ b/code/renderers/react/src/docs/jsxDecorator.test.tsx @@ -1,14 +1,16 @@ /* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */ import type { FC, PropsWithChildren } from 'react'; import React, { createElement, Profiler } from 'react'; +import type { Mocked } from 'vitest'; +import { vi, describe, it } from 'vitest'; import PropTypes from 'prop-types'; import { addons, useEffect } from '@storybook/preview-api'; import { SNIPPET_RENDERED } from '@storybook/docs-tools'; import { renderJsx, jsxDecorator } from './jsxDecorator'; vi.mock('@storybook/preview-api'); -const mockedAddons = addons as vi.mocked; -const mockedUseEffect = useEffect as vi.mocked; +const mockedAddons = addons as Mocked; +const mockedUseEffect = useEffect as Mocked; expect.addSnapshotSerializer({ print: (val: any) => val, @@ -189,13 +191,13 @@ const makeContext = (name: string, parameters: any, args: any, extra?: object): }); describe('jsxDecorator', () => { - let mockChannel: { on: vi.mock; emit?: vi.mock }; + let mockChannel: { on: Mocked; emit?: Mocked }; beforeEach(() => { mockedAddons.getChannel.mockReset(); // @ts-expect-error (Converted from ts-ignore) mockedUseEffect.mockImplementation((cb) => setTimeout(() => cb(), 0)); - mockChannel = { on: jest.fn(), emit: jest.fn() }; + mockChannel = { on: vi.fn(), emit: vi.fn() }; mockedAddons.getChannel.mockReturnValue(mockChannel as any); }); @@ -273,7 +275,7 @@ describe('jsxDecorator', () => { it('handles stories that trigger Suspense', async () => { // if a story function uses a hook or other library that triggers suspense, it will throw a Promise until it is resolved // and then it will return the story content after the promise is resolved - const storyFn = jest.fn(); + const storyFn = vi.fn(); storyFn .mockImplementationOnce(() => { // eslint-disable-next-line @typescript-eslint/no-throw-literal diff --git a/code/renderers/react/src/public-api.test.ts b/code/renderers/react/src/public-api.test.ts index c27393afbce4..789515881215 100644 --- a/code/renderers/react/src/public-api.test.ts +++ b/code/renderers/react/src/public-api.test.ts @@ -1,8 +1,9 @@ +import { describe, afterEach, it, expect, vi } from 'vitest'; import * as api from '.'; describe('preview', () => { afterEach(() => { - jest.resetModules(); + vi.resetModules(); }); const isFunction = (value: unknown) => typeof value === 'function'; diff --git a/code/renderers/vue/src/public-types.test.ts b/code/renderers/vue/src/public-types.test.ts index 0f3b90fbe04d..98bf904e1b72 100644 --- a/code/renderers/vue/src/public-types.test.ts +++ b/code/renderers/vue/src/public-types.test.ts @@ -1,3 +1,4 @@ +import { describe, test } from 'vitest'; import { satisfies } from '@storybook/core-common'; import type { ComponentAnnotations, StoryAnnotations } from '@storybook/types'; import { expectTypeOf } from 'expect-type'; diff --git a/code/renderers/vue3/src/render.test.ts b/code/renderers/vue3/src/render.test.ts index d1d04cf40638..83f2465cc92e 100644 --- a/code/renderers/vue3/src/render.test.ts +++ b/code/renderers/vue3/src/render.test.ts @@ -1,3 +1,4 @@ +import { describe, expect } from 'vitest'; import { expectTypeOf } from 'expect-type'; import { reactive } from 'vue'; diff --git a/code/renderers/vue3/template/cli/ts-4-9/Page.stories.ts b/code/renderers/vue3/template/cli/ts-4-9/Page.stories.ts index e9988015819d..0aa9bea0a98d 100644 --- a/code/renderers/vue3/template/cli/ts-4-9/Page.stories.ts +++ b/code/renderers/vue3/template/cli/ts-4-9/Page.stories.ts @@ -10,10 +10,8 @@ const meta = { template: '', }), parameters: { - // More on how to position stories at: https://storybook.js.org/docs/vue/configure/story-layout layout: 'fullscreen', }, - // This component will have an automatically generated docsPage entry: https://storybook.js.org/docs/vue/writing-docs/autodocs tags: ['autodocs'], } satisfies Meta; diff --git a/code/renderers/web-components/src/docs/sourceDecorator.test.ts b/code/renderers/web-components/src/docs/sourceDecorator.test.ts index 784396b9b100..b288aceb3601 100644 --- a/code/renderers/web-components/src/docs/sourceDecorator.test.ts +++ b/code/renderers/web-components/src/docs/sourceDecorator.test.ts @@ -1,4 +1,6 @@ import { html, render } from 'lit'; +import type { Mocked } from 'vitest'; +import { describe, beforeEach, it, vi } from 'vitest'; import { styleMap } from 'lit/directives/style-map.js'; import { addons, useEffect } from '@storybook/preview-api'; import { SNIPPET_RENDERED } from '@storybook/docs-tools'; @@ -6,8 +8,8 @@ import type { StoryContext } from '../types'; import { sourceDecorator } from './sourceDecorator'; vi.mock('@storybook/preview-api'); -const mockedAddons = addons as vi.mocked; -const mockedUseEffect = useEffect as vi.mock; +const mockedAddons = addons as Mocked; +const mockedUseEffect = useEffect as Mocked; expect.addSnapshotSerializer({ print: (val: any) => val, @@ -30,12 +32,12 @@ const makeContext = (name: string, parameters: any, args: any, extra?: Partial { - let mockChannel: { on: vi.mock; emit?: vi.mock }; + let mockChannel: { on: Mock; emit?: Mock }; beforeEach(() => { mockedAddons.getChannel.mockReset(); mockedUseEffect.mockImplementation((cb) => setTimeout(() => cb(), 0)); - mockChannel = { on: jest.fn(), emit: jest.fn() }; + mockChannel = { on: vi.fn(), emit: vi.fn() }; mockedAddons.getChannel.mockReturnValue(mockChannel as any); }); diff --git a/code/renderers/web-components/src/docs/web-components-properties.test.ts b/code/renderers/web-components/src/docs/web-components-properties.test.ts index 70b8c3e6f449..7c61cdecd7cd 100644 --- a/code/renderers/web-components/src/docs/web-components-properties.test.ts +++ b/code/renderers/web-components/src/docs/web-components-properties.test.ts @@ -1,5 +1,6 @@ import 'jest-specific-snapshot'; import path from 'path'; +import { vi, describe, it, expect } from 'vitest'; import fs from 'fs'; import tmp from 'tmp'; import { sync as spawnSync } from 'cross-spawn'; diff --git a/code/ui/blocks/src/blocks/internal/InternalCanvas.stories.tsx b/code/ui/blocks/src/blocks/internal/InternalCanvas.stories.tsx index 4c1460b42749..77602505077a 100644 --- a/code/ui/blocks/src/blocks/internal/InternalCanvas.stories.tsx +++ b/code/ui/blocks/src/blocks/internal/InternalCanvas.stories.tsx @@ -1,4 +1,4 @@ -import { describe, test, it, expect } from 'vitest'; +/// ; /// ; import React from 'react'; import type { Meta, StoryObj } from '@storybook/react'; diff --git a/code/ui/components/src/components/typography/link/link.test.tsx b/code/ui/components/src/components/typography/link/link.test.tsx index 8c909ab48cad..dd6726cd0876 100644 --- a/code/ui/components/src/components/typography/link/link.test.tsx +++ b/code/ui/components/src/components/typography/link/link.test.tsx @@ -1,3 +1,4 @@ +import { vi, describe, it, expect } from 'vitest'; import type { AnchorHTMLAttributes } from 'react'; import React from 'react'; import { render, screen } from '@testing-library/react'; @@ -21,49 +22,49 @@ function ThemedLink(props: LinkProps & AnchorHTMLAttributes) describe('Link', () => { describe('events', () => { it('should call onClick on a plain left click', () => { - const handleClick = jest.fn(); + const handleClick = vi.fn(); render(Content); userEvent.click(screen.getByText('Content'), { button: LEFT_BUTTON }); expect(handleClick).toHaveBeenCalled(); }); it("shouldn't call onClick on a middle click", () => { - const handleClick = jest.fn(); + const handleClick = vi.fn(); render(Content); userEvent.click(screen.getByText('Content'), { button: MIDDLE_BUTTON }); expect(handleClick).not.toHaveBeenCalled(); }); it("shouldn't call onClick on a right click", () => { - const handleClick = jest.fn(); + const handleClick = vi.fn(); render(Content); userEvent.click(screen.getByText('Content'), { button: RIGHT_BUTTON }); expect(handleClick).not.toHaveBeenCalled(); }); it("shouldn't call onClick on alt+click", () => { - const handleClick = jest.fn(); + const handleClick = vi.fn(); render(Content); userEvent.click(screen.getByText('Content'), { altKey: true }); expect(handleClick).not.toHaveBeenCalled(); }); it("shouldn't call onClick on ctrl+click", () => { - const handleClick = jest.fn(); + const handleClick = vi.fn(); render(Content); userEvent.click(screen.getByText('Content'), { ctrlKey: true }); expect(handleClick).not.toHaveBeenCalled(); }); it("shouldn't call onClick on cmd+click / win+click", () => { - const handleClick = jest.fn(); + const handleClick = vi.fn(); render(Content); userEvent.click(screen.getByText('Content'), { metaKey: true }); expect(handleClick).not.toHaveBeenCalled(); }); it("shouldn't call onClick on shift+click", () => { - const handleClick = jest.fn(); + const handleClick = vi.fn(); render(Content); userEvent.click(screen.getByText('Content'), { shiftKey: true }); expect(handleClick).not.toHaveBeenCalled(); diff --git a/scripts/__mocks__/simple-git.js b/scripts/__mocks__/simple-git.js index 89fa9f23c7b1..40462bfd8eeb 100644 --- a/scripts/__mocks__/simple-git.js +++ b/scripts/__mocks__/simple-git.js @@ -1,11 +1,12 @@ +import { vi } from 'vitest'; /* eslint-disable no-underscore-dangle */ -const mod = jest.createMockFromModule('simple-git'); +const mod = vi.createMockFromModule('simple-git'); -mod.__getRemotes = jest +mod.__getRemotes = vi .fn() .mockReturnValue([{ name: 'origin', refs: { fetch: 'origin', push: 'origin' } }]); -mod.__fetch = jest.fn(); -mod.__revparse = jest.fn().mockResolvedValue('mockedGitCommitHash'); +mod.__fetch = vi.fn(); +mod.__revparse = vi.fn().mockResolvedValue('mockedGitCommitHash'); mod.simpleGit = () => { return { diff --git a/scripts/__mocks__/uuid.ts b/scripts/__mocks__/uuid.ts index bd6e08f5a6eb..e549823d3929 100644 --- a/scripts/__mocks__/uuid.ts +++ b/scripts/__mocks__/uuid.ts @@ -1,4 +1,4 @@ -const { v5 } = jest.requireActual('uuid'); +const { v5 } = await vi.importActual('uuid'); let seed = 0; diff --git a/scripts/release/__tests__/generate-pr-description.test.ts b/scripts/release/__tests__/generate-pr-description.test.ts index b0f1bbe89db5..62477b604864 100644 --- a/scripts/release/__tests__/generate-pr-description.test.ts +++ b/scripts/release/__tests__/generate-pr-description.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { generateReleaseDescription, generateNonReleaseDescription, diff --git a/scripts/release/__tests__/is-pr-frozen.test.ts b/scripts/release/__tests__/is-pr-frozen.test.ts index 717d9de7c15a..c7f94665264d 100644 --- a/scripts/release/__tests__/is-pr-frozen.test.ts +++ b/scripts/release/__tests__/is-pr-frozen.test.ts @@ -1,7 +1,7 @@ +import { describe, beforeEach, it, expect, vi } from 'vitest'; /* eslint-disable no-underscore-dangle */ /* eslint-disable global-require */ import path from 'path'; -import { vi, describe, expect, it } from 'vitest'; import { run as isPrFrozen } from '../is-pr-frozen'; // eslint-disable-next-line jest/no-mocks-import @@ -20,6 +20,10 @@ fsExtra.__setMockFiles({ }); describe('isPrFrozen', () => { + beforeEach(() => { + vi.clearAllMocks(); + }); + it('should return true when PR is frozen', async () => { getPullInfoFromCommit.mockResolvedValue({ labels: ['freeze'], diff --git a/scripts/release/__tests__/label-patches.test.ts b/scripts/release/__tests__/label-patches.test.ts index 65ec494c33e6..6b2b8646a387 100644 --- a/scripts/release/__tests__/label-patches.test.ts +++ b/scripts/release/__tests__/label-patches.test.ts @@ -1,3 +1,4 @@ +import { beforeEach, expect, vi } from 'vitest'; import type { LogResult } from 'simple-git'; import ansiRegex from 'ansi-regex'; import { run } from '../label-patches'; @@ -8,7 +9,9 @@ import * as github_ from '../utils/github-client'; vi.mock('uuid'); vi.mock('../utils/get-github-info'); vi.mock('../utils/github-client'); -vi.mock('../utils/git-client', () => jest.requireActual('jest-mock-extended').mockDeep()); +vi.mock('../utils/git-client', async () => + (await vi.importActual('jest-mock-extended')).mockDeep() +); const gitClient = vi.mocked(gitClient_); const github = vi.mocked(github_); @@ -68,7 +71,7 @@ const pullInfoMock = { beforeEach(() => { // mock IO - jest.clearAllMocks(); + vi.clearAllMocks(); gitClient.getLatestTag.mockResolvedValue('v7.2.1'); gitClient.git.log.mockResolvedValue(gitLogMock); gitClient.git.getRemotes.mockResolvedValue(remoteMock); @@ -102,7 +105,7 @@ test('it should fail early when no GH_TOKEN is set', async () => { test('it should label the PR associated with cheery picks in the current branch', async () => { process.env.GH_TOKEN = 'MY_SECRET'; - const writeStderr = jest.spyOn(process.stderr, 'write').mockImplementation(); + const writeStderr = vi.spyOn(process.stderr, 'write').mockImplementation(); await run({}); expect(github.githubGraphQlClient.mock.calls).toMatchInlineSnapshot(` @@ -162,7 +165,7 @@ test('it should label all PRs when the --all flag is passed', async () => { total: 0, }); - const writeStderr = jest.spyOn(process.stderr, 'write').mockImplementation(); + const writeStderr = vi.spyOn(process.stderr, 'write').mockImplementation(); await run({ all: true }); expect(github.githubGraphQlClient.mock.calls).toMatchInlineSnapshot(` diff --git a/scripts/release/__tests__/version.test.ts b/scripts/release/__tests__/version.test.ts index 297752184cb9..972d6fd3c274 100644 --- a/scripts/release/__tests__/version.test.ts +++ b/scripts/release/__tests__/version.test.ts @@ -1,3 +1,4 @@ +import { describe, beforeEach, it, expect, vi } from 'vitest'; /* eslint-disable global-require */ /* eslint-disable no-underscore-dangle */ import path from 'path'; @@ -15,7 +16,7 @@ vi.mock('../../utils/exec'); const { execaCommand } = require('../../utils/exec'); vi.mock('../../utils/workspace', () => ({ - getWorkspaces: jest.fn().mockResolvedValue([ + getWorkspaces: vi.fn().mockResolvedValue([ { name: '@storybook/addon-a11y', location: 'addons/a11y', @@ -23,12 +24,12 @@ vi.mock('../../utils/workspace', () => ({ ]), })); -jest.spyOn(console, 'log').mockImplementation(() => {}); -jest.spyOn(console, 'warn').mockImplementation(() => {}); -jest.spyOn(console, 'error').mockImplementation(() => {}); +vi.spyOn(console, 'log').mockImplementation(() => {}); +vi.spyOn(console, 'warn').mockImplementation(() => {}); +vi.spyOn(console, 'error').mockImplementation(() => {}); beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); describe('Version', () => { diff --git a/scripts/release/__tests__/write-changelog.test.ts b/scripts/release/__tests__/write-changelog.test.ts index a17a5a4bb189..274346b4c972 100644 --- a/scripts/release/__tests__/write-changelog.test.ts +++ b/scripts/release/__tests__/write-changelog.test.ts @@ -1,3 +1,4 @@ +import { describe, beforeEach, it, expect, vi } from 'vitest'; /* eslint-disable global-require */ /* eslint-disable no-underscore-dangle */ import path from 'path'; @@ -9,11 +10,11 @@ import * as changesUtils from '../utils/get-changes'; vi.mock('fs-extra', () => require('../../../code/__mocks__/fs-extra')); const fsExtra = require('fs-extra'); -const getChangesMock = jest.spyOn(changesUtils, 'getChanges'); +const getChangesMock = vi.spyOn(changesUtils, 'getChanges'); -jest.spyOn(console, 'log').mockImplementation(() => {}); -jest.spyOn(console, 'warn').mockImplementation(() => {}); -jest.spyOn(console, 'error').mockImplementation(() => {}); +vi.spyOn(console, 'log').mockImplementation(() => {}); +vi.spyOn(console, 'warn').mockImplementation(() => {}); +vi.spyOn(console, 'error').mockImplementation(() => {}); const STABLE_CHANGELOG_PATH = path.join(__dirname, '..', '..', '..', 'CHANGELOG.md'); const PRERELEASE_CHANGELOG_PATH = path.join(__dirname, '..', '..', '..', 'CHANGELOG.prerelease.md'); @@ -29,7 +30,7 @@ const LATEST_VERSION_PATH = path.join( const NEXT_VERSION_PATH = path.join(__dirname, '..', '..', '..', 'docs', 'versions', 'next.json'); beforeEach(() => { - jest.clearAllMocks(); + vi.clearAllMocks(); }); const EXISTING_STABLE_CHANGELOG = dedent`## 7.0.0 From 799b7c78d0e8a010989437ef4e3eed6a91c910bc Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Thu, 14 Sep 2023 17:37:22 +0200 Subject: [PATCH 009/105] update snapshots --- code/addons/a11y/src/manager.test.tsx | 4 +- .../angular-builders.test.ts.snap | 4 +- .../src/automigrate/fixes/add-react.test.ts | 12 +- .../src/automigrate/fixes/mdx-1-to-2.test.ts | 22 +- .../src/js-package-manager/NPMProxy.test.ts | 34 +- .../src/js-package-manager/PNPMProxy.test.ts | 38 +- .../src/js-package-manager/Yarn1Proxy.test.ts | 22 +- .../src/js-package-manager/Yarn2Proxy.test.ts | 34 +- .../StoryIndexGenerator.deprecated.test.ts | 314 ++-- .../src/utils/summarizeIndex.test.ts | 14 +- .../merge-webpack-config.test.ts.snap | 92 +- .../src/getStorySortParameter.test.ts | 134 +- code/lib/manager-api/src/lib/stories.test.ts | 36 +- code/lib/manager-api/src/tests/refs.test.ts | 322 ++--- .../lib/manager-api/src/tests/stories.test.ts | 62 +- .../src/modules/core-client/start.test.ts | 1258 ++++++++--------- .../PreviewWeb.integration.test.ts | 8 +- .../src/modules/store/StoryStore.test.ts | 306 ++-- .../modules/store/csf/normalizeStory.test.ts | 70 +- .../vue3/src/docs/sourceDecorator.test.ts | 124 +- code/yarn.lock | 1079 +------------- 21 files changed, 1508 insertions(+), 2481 deletions(-) diff --git a/code/addons/a11y/src/manager.test.tsx b/code/addons/a11y/src/manager.test.tsx index 61511c6435e5..19064b0142bc 100644 --- a/code/addons/a11y/src/manager.test.tsx +++ b/code/addons/a11y/src/manager.test.tsx @@ -47,7 +47,7 @@ describe('A11yManager', () => { > { > angular builders > Angular < 14.0.0 > should throw an Error 1`] = ` "❌ Your project uses Angular < 14.0.0. Storybook 7.0 for Angular requires Angular 14.0.0 or higher. Please upgrade your Angular version to at least version 14.0.0 to use Storybook 7.0 in your project." `; diff --git a/code/lib/cli/src/automigrate/fixes/add-react.test.ts b/code/lib/cli/src/automigrate/fixes/add-react.test.ts index 0a7fba10f887..69e5b7d983b6 100644 --- a/code/lib/cli/src/automigrate/fixes/add-react.test.ts +++ b/code/lib/cli/src/automigrate/fixes/add-react.test.ts @@ -36,11 +36,11 @@ describe('addReact fix', () => { devDependencies: { '@storybook/addon-docs': '*', 'react-dom': '*' }, }) ).resolves.toMatchInlineSnapshot(` - Object { - "additionalDependencies": Array [ + { + "additionalDependencies": [ "react", ], - "dependents": Array [ + "dependents": [ "@storybook/addon-docs", ], } @@ -54,11 +54,11 @@ describe('addReact fix', () => { devDependencies: { '@storybook/addon-essentials': '*', react: '*' }, }) ).resolves.toMatchInlineSnapshot(` - Object { - "additionalDependencies": Array [ + { + "additionalDependencies": [ "react-dom", ], - "dependents": Array [ + "dependents": [ "@storybook/addon-essentials", ], } diff --git a/code/lib/cli/src/automigrate/fixes/mdx-1-to-2.test.ts b/code/lib/cli/src/automigrate/fixes/mdx-1-to-2.test.ts index 9560a570d391..c471d478fdc6 100644 --- a/code/lib/cli/src/automigrate/fixes/mdx-1-to-2.test.ts +++ b/code/lib/cli/src/automigrate/fixes/mdx-1-to-2.test.ts @@ -34,17 +34,17 @@ it('fixMdxStyleTags fixes multiple style blocks', () => { \`} `) ).toMatchInlineSnapshot(` - - - `); + " + " + `); }); it('fixMdxComments fixes all comments', () => { diff --git a/code/lib/cli/src/js-package-manager/NPMProxy.test.ts b/code/lib/cli/src/js-package-manager/NPMProxy.test.ts index b320bd355b35..31225ac2e2d0 100644 --- a/code/lib/cli/src/js-package-manager/NPMProxy.test.ts +++ b/code/lib/cli/src/js-package-manager/NPMProxy.test.ts @@ -375,54 +375,54 @@ describe('NPM Proxy', () => { const installations = await npmProxy.findInstallations(); expect(installations).toMatchInlineSnapshot(` - Object { + { "dedupeCommand": "npm dedupe", - "dependencies": Object { - "@storybook/addon-interactions": Array [ - Object { + "dependencies": { + "@storybook/addon-interactions": [ + { "location": "", "version": "7.0.0-rc.7", }, ], - "@storybook/channels": Array [ - Object { + "@storybook/channels": [ + { "location": "", "version": "7.0.0-rc.7", }, ], - "@storybook/instrumenter": Array [ - Object { + "@storybook/instrumenter": [ + { "location": "", "version": "6.0.0", }, - Object { + { "location": "", "version": "7.0.0-beta.11", }, - Object { + { "location": "", "version": "7.0.0-alpha.21", }, - Object { + { "location": "", "version": "5.4.2-alpha.0", }, ], - "@storybook/jest": Array [ - Object { + "@storybook/jest": [ + { "location": "", "version": "0.0.11-next.1", }, ], - "@storybook/testing-library": Array [ - Object { + "@storybook/testing-library": [ + { "location": "", "version": "0.0.14-next.1", }, ], }, - "duplicatedDependencies": Object { - "@storybook/instrumenter": Array [ + "duplicatedDependencies": { + "@storybook/instrumenter": [ "5.4.2-alpha.0", "6.0.0", "7.0.0-alpha.21", diff --git a/code/lib/cli/src/js-package-manager/PNPMProxy.test.ts b/code/lib/cli/src/js-package-manager/PNPMProxy.test.ts index 1cd761729c22..7b3d4dd24686 100644 --- a/code/lib/cli/src/js-package-manager/PNPMProxy.test.ts +++ b/code/lib/cli/src/js-package-manager/PNPMProxy.test.ts @@ -312,58 +312,58 @@ describe('PNPM Proxy', () => { const installations = await pnpmProxy.findInstallations(['@storybook/*']); expect(installations).toMatchInlineSnapshot(` - Object { + { "dedupeCommand": "pnpm dedupe", - "dependencies": Object { - "@storybook/addon-interactions": Array [ - Object { + "dependencies": { + "@storybook/addon-interactions": [ + { "location": "", "version": "7.0.0-beta.13", }, ], - "@storybook/addons": Array [ - Object { + "@storybook/addons": [ + { "location": "", "version": "7.0.0-beta.13", }, ], - "@storybook/builder-webpack5": Array [ - Object { + "@storybook/builder-webpack5": [ + { "location": "", "version": "7.0.0-beta.13", }, ], - "@storybook/instrumenter": Array [ - Object { + "@storybook/instrumenter": [ + { "location": "", "version": "7.0.0-rc.7", }, - Object { + { "location": "", "version": "7.0.0-beta.13", }, ], - "@storybook/jest": Array [ - Object { + "@storybook/jest": [ + { "location": "", "version": "0.0.11-next.0", }, ], - "@storybook/nextjs": Array [ - Object { + "@storybook/nextjs": [ + { "location": "", "version": "7.0.0-beta.13", }, ], - "@storybook/testing-library": Array [ - Object { + "@storybook/testing-library": [ + { "location": "", "version": "0.0.14-next.1", }, ], }, - "duplicatedDependencies": Object { - "@storybook/instrumenter": Array [ + "duplicatedDependencies": { + "@storybook/instrumenter": [ "7.0.0-rc.7", "7.0.0-beta.13", ], diff --git a/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts b/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts index 87bd0f7b66da..36dc9684fab7 100644 --- a/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts +++ b/code/lib/cli/src/js-package-manager/Yarn1Proxy.test.ts @@ -237,34 +237,34 @@ describe('Yarn 1 Proxy', () => { const installations = await yarn1Proxy.findInstallations(['@storybook/*']); expect(installations).toMatchInlineSnapshot(` - Object { + { "dedupeCommand": "yarn dedupe", - "dependencies": Object { - "@storybook/addon-interactions": Array [ - Object { + "dependencies": { + "@storybook/addon-interactions": [ + { "location": "", "version": "7.0.0-beta.19", }, ], - "@storybook/instrumenter": Array [ - Object { + "@storybook/instrumenter": [ + { "location": "", "version": "7.0.0-beta.12", }, - Object { + { "location": "", "version": "7.0.0-beta.19", }, ], - "@storybook/types": Array [ - Object { + "@storybook/types": [ + { "location": "", "version": "7.0.0-beta.12", }, ], }, - "duplicatedDependencies": Object { - "@storybook/instrumenter": Array [ + "duplicatedDependencies": { + "@storybook/instrumenter": [ "7.0.0-beta.12", "7.0.0-beta.19", ], diff --git a/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts b/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts index 3ef5389287df..50f4b69484f0 100644 --- a/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts +++ b/code/lib/cli/src/js-package-manager/Yarn2Proxy.test.ts @@ -215,52 +215,52 @@ describe('Yarn 2 Proxy', () => { const installations = await yarn2Proxy.findInstallations(['@storybook/*']); expect(installations).toMatchInlineSnapshot(` - Object { + { "dedupeCommand": "yarn dedupe", - "dependencies": Object { - "@storybook/global": Array [ - Object { + "dependencies": { + "@storybook/global": [ + { "location": "", "version": "5.0.0", }, ], - "@storybook/instrumenter": Array [ - Object { + "@storybook/instrumenter": [ + { "location": "", "version": "7.0.0-beta.12", }, - Object { + { "location": "", "version": "7.0.0-beta.19", }, ], - "@storybook/jest": Array [ - Object { + "@storybook/jest": [ + { "location": "", "version": "0.0.11-next.0", }, ], - "@storybook/manager": Array [ - Object { + "@storybook/manager": [ + { "location": "", "version": "7.0.0-beta.19", }, ], - "@storybook/manager-api": Array [ - Object { + "@storybook/manager-api": [ + { "location": "", "version": "7.0.0-beta.19", }, ], - "@storybook/mdx2-csf": Array [ - Object { + "@storybook/mdx2-csf": [ + { "location": "", "version": "0.1.0-next.5", }, ], }, - "duplicatedDependencies": Object { - "@storybook/instrumenter": Array [ + "duplicatedDependencies": { + "@storybook/instrumenter": [ "7.0.0-beta.12", "7.0.0-beta.19", ], diff --git a/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts b/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts index d15507c44029..abbf94141bcc 100644 --- a/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts +++ b/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts @@ -86,13 +86,13 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "a--story-one": Object { + { + "entries": { + "a--story-one": { "id": "a--story-one", "importPath": "./src/A.stories.js", "name": "Story One", - "tags": Array [ + "tags": [ "component-tag", "story-tag", "story", @@ -117,24 +117,24 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "nested-button--story-one": Object { + { + "entries": { + "nested-button--story-one": { "id": "nested-button--story-one", "importPath": "./src/nested/Button.stories.ts", "name": "Story One", - "tags": Array [ + "tags": [ "component-tag", "story", ], "title": "nested/Button", "type": "story", }, - "second-nested-g--story-one": Object { + "second-nested-g--story-one": { "id": "second-nested-g--story-one", "importPath": "./src/second-nested/G.stories.ts", "name": "Story One", - "tags": Array [ + "tags": [ "story", ], "title": "second-nested/G", @@ -157,13 +157,13 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "a--story-one": Object { + { + "entries": { + "a--story-one": { "id": "a--story-one", "importPath": "./src/A.stories.js", "name": "Story One", - "tags": Array [ + "tags": [ "component-tag", "story-tag", "story", @@ -171,65 +171,65 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { "title": "A", "type": "story", }, - "b--story-one": Object { + "b--story-one": { "id": "b--story-one", "importPath": "./src/B.stories.ts", "name": "Story One", - "tags": Array [ + "tags": [ "autodocs", "story", ], "title": "B", "type": "story", }, - "d--story-one": Object { + "d--story-one": { "id": "d--story-one", "importPath": "./src/D.stories.jsx", "name": "Story One", - "tags": Array [ + "tags": [ "autodocs", "story", ], "title": "D", "type": "story", }, - "first-nested-deeply-f--story-one": Object { + "first-nested-deeply-f--story-one": { "id": "first-nested-deeply-f--story-one", "importPath": "./src/first-nested/deeply/F.stories.js", "name": "Story One", - "tags": Array [ + "tags": [ "story", ], "title": "first-nested/deeply/F", "type": "story", }, - "h--story-one": Object { + "h--story-one": { "id": "h--story-one", "importPath": "./src/H.stories.mjs", "name": "Story One", - "tags": Array [ + "tags": [ "autodocs", "story", ], "title": "H", "type": "story", }, - "nested-button--story-one": Object { + "nested-button--story-one": { "id": "nested-button--story-one", "importPath": "./src/nested/Button.stories.ts", "name": "Story One", - "tags": Array [ + "tags": [ "component-tag", "story", ], "title": "nested/Button", "type": "story", }, - "second-nested-g--story-one": Object { + "second-nested-g--story-one": { "id": "second-nested-g--story-one", "importPath": "./src/second-nested/G.stories.ts", "name": "Story One", - "tags": Array [ + "tags": [ "story", ], "title": "second-nested/G", @@ -255,25 +255,25 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "page--docs": Object { + { + "entries": { + "page--docs": { "id": "page--docs", "importPath": "./src/nested/Page.stories.mdx", "name": "docs", - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "stories-mdx", "docs", ], "title": "Page", "type": "docs", }, - "page--story-one": Object { + "page--story-one": { "id": "page--story-one", "importPath": "./src/nested/Page.stories.mdx", "name": "StoryOne", - "tags": Array [ + "tags": [ "stories-mdx", "story", ], @@ -302,13 +302,13 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "a--story-one": Object { + { + "entries": { + "a--story-one": { "id": "a--story-one", "importPath": "./src/A.stories.js", "name": "Story One", - "tags": Array [ + "tags": [ "component-tag", "story-tag", "story", @@ -316,101 +316,101 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { "title": "A", "type": "story", }, - "b--docs": Object { + "b--docs": { "id": "b--docs", "importPath": "./src/B.stories.ts", "name": "docs", - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "autodocs", "docs", ], "title": "B", "type": "docs", }, - "b--story-one": Object { + "b--story-one": { "id": "b--story-one", "importPath": "./src/B.stories.ts", "name": "Story One", - "tags": Array [ + "tags": [ "autodocs", "story", ], "title": "B", "type": "story", }, - "d--docs": Object { + "d--docs": { "id": "d--docs", "importPath": "./src/D.stories.jsx", "name": "docs", - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "autodocs", "docs", ], "title": "D", "type": "docs", }, - "d--story-one": Object { + "d--story-one": { "id": "d--story-one", "importPath": "./src/D.stories.jsx", "name": "Story One", - "tags": Array [ + "tags": [ "autodocs", "story", ], "title": "D", "type": "story", }, - "first-nested-deeply-f--story-one": Object { + "first-nested-deeply-f--story-one": { "id": "first-nested-deeply-f--story-one", "importPath": "./src/first-nested/deeply/F.stories.js", "name": "Story One", - "tags": Array [ + "tags": [ "story", ], "title": "first-nested/deeply/F", "type": "story", }, - "h--docs": Object { + "h--docs": { "id": "h--docs", "importPath": "./src/H.stories.mjs", "name": "docs", - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "autodocs", "docs", ], "title": "H", "type": "docs", }, - "h--story-one": Object { + "h--story-one": { "id": "h--story-one", "importPath": "./src/H.stories.mjs", "name": "Story One", - "tags": Array [ + "tags": [ "autodocs", "story", ], "title": "H", "type": "story", }, - "nested-button--story-one": Object { + "nested-button--story-one": { "id": "nested-button--story-one", "importPath": "./src/nested/Button.stories.ts", "name": "Story One", - "tags": Array [ + "tags": [ "component-tag", "story", ], "title": "nested/Button", "type": "story", }, - "second-nested-g--story-one": Object { + "second-nested-g--story-one": { "id": "second-nested-g--story-one", "importPath": "./src/second-nested/G.stories.ts", "name": "Story One", - "tags": Array [ + "tags": [ "story", ], "title": "second-nested/G", @@ -439,7 +439,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(Object.keys((await generator.getIndex()).entries)).toMatchInlineSnapshot(` - Array [ + [ "a--docs", "a--story-one", "b--docs", @@ -526,39 +526,39 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "b--docs": Object { + { + "entries": { + "b--docs": { "id": "b--docs", "importPath": "./src/B.stories.ts", "name": "docs", - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "autodocs", "docs", ], "title": "B", "type": "docs", }, - "b--metaofnoname": Object { + "b--metaofnoname": { "id": "b--metaofnoname", "importPath": "./errors/MetaOfNoName.mdx", "name": "MetaOfNoName", - "storiesImports": Array [ + "storiesImports": [ "./src/B.stories.ts", ], - "tags": Array [ + "tags": [ "attached-mdx", "docs", ], "title": "B", "type": "docs", }, - "b--story-one": Object { + "b--story-one": { "id": "b--story-one", "importPath": "./src/B.stories.ts", "name": "Story One", - "tags": Array [ + "tags": [ "autodocs", "story", ], @@ -585,39 +585,39 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "b--docs": Object { + { + "entries": { + "b--docs": { "id": "b--docs", "importPath": "./src/B.stories.ts", "name": "docs", - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "autodocs", "docs", ], "title": "B", "type": "docs", }, - "b--name": Object { + "b--name": { "id": "b--name", "importPath": "./errors/MetaOfName.mdx", "name": "name", - "storiesImports": Array [ + "storiesImports": [ "./src/B.stories.ts", ], - "tags": Array [ + "tags": [ "attached-mdx", "docs", ], "title": "B", "type": "docs", }, - "b--story-one": Object { + "b--story-one": { "id": "b--story-one", "importPath": "./src/B.stories.ts", "name": "Story One", - "tags": Array [ + "tags": [ "autodocs", "story", ], @@ -648,27 +648,27 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "a--docs": Object { + { + "entries": { + "a--docs": { "id": "a--docs", "importPath": "./errors/A.mdx", "name": "docs", - "storiesImports": Array [ + "storiesImports": [ "./src/A.stories.js", ], - "tags": Array [ + "tags": [ "attached-mdx", "docs", ], "title": "A", "type": "docs", }, - "a--story-one": Object { + "a--story-one": { "id": "a--story-one", "importPath": "./src/A.stories.js", "name": "Story One", - "tags": Array [ + "tags": [ "component-tag", "story-tag", "story", @@ -692,38 +692,38 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "duplicate-a--docs": Object { + { + "entries": { + "duplicate-a--docs": { "id": "duplicate-a--docs", "importPath": "./duplicate/A.stories.js", "name": "docs", - "storiesImports": Array [ + "storiesImports": [ "./duplicate/SecondA.stories.js", ], - "tags": Array [ + "tags": [ "autodocs", "docs", ], "title": "duplicate/A", "type": "docs", }, - "duplicate-a--story-one": Object { + "duplicate-a--story-one": { "id": "duplicate-a--story-one", "importPath": "./duplicate/A.stories.js", "name": "Story One", - "tags": Array [ + "tags": [ "autodocs", "story", ], "title": "duplicate/A", "type": "story", }, - "duplicate-a--story-two": Object { + "duplicate-a--story-two": { "id": "duplicate-a--story-two", "importPath": "./duplicate/SecondA.stories.js", "name": "Story Two", - "tags": Array [ + "tags": [ "autodocs", "story", ], @@ -747,8 +747,8 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object {}, + { + "entries": {}, "v": 4, } `); @@ -761,41 +761,41 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "a--metaof": Object { + { + "entries": { + "a--metaof": { "id": "a--metaof", "importPath": "./src/docs2/MetaOf.mdx", "name": "MetaOf", - "storiesImports": Array [ + "storiesImports": [ "./src/A.stories.js", ], - "tags": Array [ + "tags": [ "attached-mdx", "docs", ], "title": "A", "type": "docs", }, - "a--second-docs": Object { + "a--second-docs": { "id": "a--second-docs", "importPath": "./src/docs2/SecondMetaOf.mdx", "name": "Second Docs", - "storiesImports": Array [ + "storiesImports": [ "./src/A.stories.js", ], - "tags": Array [ + "tags": [ "attached-mdx", "docs", ], "title": "A", "type": "docs", }, - "a--story-one": Object { + "a--story-one": { "id": "a--story-one", "importPath": "./src/A.stories.js", "name": "Story One", - "tags": Array [ + "tags": [ "component-tag", "story-tag", "story", @@ -803,36 +803,36 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { "title": "A", "type": "story", }, - "componentreference--docs": Object { + "componentreference--docs": { "id": "componentreference--docs", "importPath": "./src/docs2/ComponentReference.mdx", "name": "docs", - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "unattached-mdx", "docs", ], "title": "ComponentReference", "type": "docs", }, - "docs2-yabbadabbadooo--docs": Object { + "docs2-yabbadabbadooo--docs": { "id": "docs2-yabbadabbadooo--docs", "importPath": "./src/docs2/Title.mdx", "name": "docs", - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "unattached-mdx", "docs", ], "title": "docs2/Yabbadabbadooo", "type": "docs", }, - "notitle--docs": Object { + "notitle--docs": { "id": "notitle--docs", "importPath": "./src/docs2/NoTitle.mdx", "name": "docs", - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "unattached-mdx", "docs", ], @@ -862,15 +862,15 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { // not sorted by default. expect(Object.values((await generator.getIndex()).entries).map((e) => e.title)) .toMatchInlineSnapshot(` - Array [ - "A", - "titlePrefix/ComponentReference", - "A", - "titlePrefix/NoTitle", - "A", - "titlePrefix/docs2/Yabbadabbadooo", - ] - `); + [ + "A", + "titlePrefix/ComponentReference", + "A", + "titlePrefix/NoTitle", + "A", + "titlePrefix/docs2/Yabbadabbadooo", + ] + `); }); it('Allows you to override default name for docs files', async () => { @@ -884,41 +884,41 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "a--metaof": Object { + { + "entries": { + "a--metaof": { "id": "a--metaof", "importPath": "./src/docs2/MetaOf.mdx", "name": "MetaOf", - "storiesImports": Array [ + "storiesImports": [ "./src/A.stories.js", ], - "tags": Array [ + "tags": [ "attached-mdx", "docs", ], "title": "A", "type": "docs", }, - "a--second-docs": Object { + "a--second-docs": { "id": "a--second-docs", "importPath": "./src/docs2/SecondMetaOf.mdx", "name": "Second Docs", - "storiesImports": Array [ + "storiesImports": [ "./src/A.stories.js", ], - "tags": Array [ + "tags": [ "attached-mdx", "docs", ], "title": "A", "type": "docs", }, - "a--story-one": Object { + "a--story-one": { "id": "a--story-one", "importPath": "./src/A.stories.js", "name": "Story One", - "tags": Array [ + "tags": [ "component-tag", "story-tag", "story", @@ -926,36 +926,36 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { "title": "A", "type": "story", }, - "componentreference--info": Object { + "componentreference--info": { "id": "componentreference--info", "importPath": "./src/docs2/ComponentReference.mdx", "name": "Info", - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "unattached-mdx", "docs", ], "title": "ComponentReference", "type": "docs", }, - "docs2-yabbadabbadooo--info": Object { + "docs2-yabbadabbadooo--info": { "id": "docs2-yabbadabbadooo--info", "importPath": "./src/docs2/Title.mdx", "name": "Info", - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "unattached-mdx", "docs", ], "title": "docs2/Yabbadabbadooo", "type": "docs", }, - "notitle--info": Object { + "notitle--info": { "id": "notitle--info", "importPath": "./src/docs2/NoTitle.mdx", "name": "Info", - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "unattached-mdx", "docs", ], @@ -979,13 +979,13 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { ); await generator.initialize(); expect(await generator.getIndex()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "a--story-one": Object { + { + "entries": { + "a--story-one": { "id": "a--story-one", "importPath": "./src/A.stories.js", "name": "Story One", - "tags": Array [ + "tags": [ "component-tag", "story-tag", "story", @@ -993,26 +993,26 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { "title": "A", "type": "story", }, - "b--story-one": Object { + "b--story-one": { "id": "b--story-one", "importPath": "./src/B.stories.ts", "name": "Story One", - "tags": Array [ + "tags": [ "autodocs", "story", ], "title": "B", "type": "story", }, - "b--twostoryreferences": Object { + "b--twostoryreferences": { "id": "b--twostoryreferences", "importPath": "./complex/TwoStoryReferences.mdx", "name": "TwoStoryReferences", - "storiesImports": Array [ + "storiesImports": [ "./src/B.stories.ts", "./src/A.stories.js", ], - "tags": Array [ + "tags": [ "attached-mdx", "docs", ], @@ -1133,7 +1133,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.initialize(); expect(Object.keys((await generator.getIndex()).entries)).toMatchInlineSnapshot(` - Array [ + [ "a--story-one", "componentreference--docs", "a--metaof", @@ -1152,7 +1152,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { }); await generator.initialize(); expect(Object.keys((await generator.getIndex()).entries)).toMatchInlineSnapshot(` - Array [ + [ "a--story-one", ] `); @@ -1187,7 +1187,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { }); await generator.initialize(); expect(Object.keys((await generator.getIndex()).entries)).toMatchInlineSnapshot(` - Array [ + [ "a--story-one", ] `); @@ -1216,7 +1216,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { }); expect(Object.keys((await generator.getIndex()).entries)).toMatchInlineSnapshot(` - Array [ + [ "docs2-yabbadabbadooo--docs", "d--story-one", "b--story-one", diff --git a/code/lib/core-server/src/utils/summarizeIndex.test.ts b/code/lib/core-server/src/utils/summarizeIndex.test.ts index 1de47dc6e6d7..8647c007463b 100644 --- a/code/lib/core-server/src/utils/summarizeIndex.test.ts +++ b/code/lib/core-server/src/utils/summarizeIndex.test.ts @@ -134,7 +134,7 @@ describe('summarizeIndex', () => { }, }) ).toMatchInlineSnapshot(` - Object { + { "autodocsCount": 0, "componentCount": 0, "exampleDocsCount": 3, @@ -192,7 +192,7 @@ describe('summarizeIndex', () => { }, }) ).toMatchInlineSnapshot(` - Object { + { "autodocsCount": 0, "componentCount": 0, "exampleDocsCount": 2, @@ -248,7 +248,7 @@ describe('summarizeIndex', () => { }, }) ).toMatchInlineSnapshot(` - Object { + { "autodocsCount": 0, "componentCount": 3, "exampleDocsCount": 0, @@ -305,7 +305,7 @@ describe('summarizeIndex', () => { }, }) ).toMatchInlineSnapshot(` - Object { + { "autodocsCount": 1, "componentCount": 1, "exampleDocsCount": 0, @@ -362,7 +362,7 @@ describe('summarizeIndex', () => { }, }) ).toMatchInlineSnapshot(` - Object { + { "autodocsCount": 0, "componentCount": 1, "exampleDocsCount": 0, @@ -420,7 +420,7 @@ describe('summarizeIndex', () => { }, }) ).toMatchInlineSnapshot(` - Object { + { "autodocsCount": 1, "componentCount": 0, "exampleDocsCount": 1, @@ -471,7 +471,7 @@ describe('summarizeIndex', () => { }, }) ).toMatchInlineSnapshot(` - Object { + { "autodocsCount": 0, "componentCount": 0, "exampleDocsCount": 1, diff --git a/code/lib/core-webpack/src/__snapshots__/merge-webpack-config.test.ts.snap b/code/lib/core-webpack/src/__snapshots__/merge-webpack-config.test.ts.snap index ddc929b507ad..9d6a9c7ff68d 100644 --- a/code/lib/core-webpack/src/__snapshots__/merge-webpack-config.test.ts.snap +++ b/code/lib/core-webpack/src/__snapshots__/merge-webpack-config.test.ts.snap @@ -1,42 +1,42 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`mergeConfigs merges partial custom config 1`] = ` -Object { +exports[`mergeConfigs > merges partial custom config 1`] = ` +{ "devtool": "source-map", - "entry": Object { + "entry": { "bundle": "index.js", }, - "module": Object { - "rules": Array [ - Object { + "module": { + "rules": [ + { "use": "r1", }, - Object { + { "use": "r2", }, ], }, - "optimization": Object { + "optimization": { "runtimeChunk": true, - "splitChunks": Object { + "splitChunks": { "chunks": "all", }, }, - "output": Object { + "output": { "filename": "[name].js", }, - "plugins": Array [ + "plugins": [ "p1", "p2", "p3", ], - "resolve": Object { - "alias": Object { + "resolve": { + "alias": { "A1": "src/B1", "A2": "src/B2", }, "enforceExtension": true, - "extensions": Array [ + "extensions": [ ".js", ".json", ".ts", @@ -46,42 +46,42 @@ Object { } `; -exports[`mergeConfigs merges successfully if custom config is empty 1`] = ` -Object { +exports[`mergeConfigs > merges successfully if custom config is empty 1`] = ` +{ "devtool": "source-map", - "entry": Object { + "entry": { "bundle": "index.js", }, - "module": Object { - "rules": Array [ - Object { + "module": { + "rules": [ + { "use": "r1", }, - Object { + { "use": "r2", }, ], }, - "optimization": Object { + "optimization": { "runtimeChunk": true, - "splitChunks": Object { + "splitChunks": { "chunks": "all", }, }, - "output": Object { + "output": { "filename": "[name].js", }, - "plugins": Array [ + "plugins": [ "p1", "p2", ], - "resolve": Object { - "alias": Object { + "resolve": { + "alias": { "A1": "src/B1", "A2": "src/B2", }, "enforceExtension": true, - "extensions": Array [ + "extensions": [ ".js", ".json", ], @@ -89,57 +89,57 @@ Object { } `; -exports[`mergeConfigs merges two full configs in one 1`] = ` -Object { +exports[`mergeConfigs > merges two full configs in one 1`] = ` +{ "devtool": "source-map", - "entry": Object { + "entry": { "bundle": "index.js", }, - "module": Object { + "module": { "noParse": /jquery\\|lodash/, - "rules": Array [ - Object { + "rules": [ + { "use": "r1", }, - Object { + { "use": "r2", }, - Object { + { "use": "r3", }, - Object { + { "use": "r4", }, ], }, - "optimization": Object { - "minimizer": Array [ + "optimization": { + "minimizer": [ "banana", ], "runtimeChunk": true, - "splitChunks": Object { + "splitChunks": { "chunks": "all", }, }, - "output": Object { + "output": { "filename": "[name].js", }, - "plugins": Array [ + "plugins": [ "p1", "p2", "p3", "p4", ], "profile": true, - "resolve": Object { - "alias": Object { + "resolve": { + "alias": { "A1": "src/B1", "A2": "src/B2", "A3": "src/B3", "A4": "src/B4", }, "enforceExtension": false, - "extensions": Array [ + "extensions": [ ".js", ".json", ".ts", diff --git a/code/lib/csf-tools/src/getStorySortParameter.test.ts b/code/lib/csf-tools/src/getStorySortParameter.test.ts index 78216cb01f9a..42fd5e3c6546 100644 --- a/code/lib/csf-tools/src/getStorySortParameter.test.ts +++ b/code/lib/csf-tools/src/getStorySortParameter.test.ts @@ -40,19 +40,19 @@ describe('getStorySortParameter', () => { }; `) ).toMatchInlineSnapshot(` - Array [ - "Intro", - "Pages", - Array [ - "Home", - "Login", - "Admin", - ], - "Components", - "*", - "WIP", - ] - `); + [ + "Intro", + "Pages", + [ + "Home", + "Login", + "Admin", + ], + "Components", + "*", + "WIP", + ] + `); }); it('arrow function', () => { @@ -100,12 +100,12 @@ describe('getStorySortParameter', () => { }; `) ).toMatchInlineSnapshot(` - Object { - "locales": "", - "method": "", - "order": Array [], - } - `); + { + "locales": "", + "method": "", + "order": [], + } + `); }); it('parameters typescript', () => { @@ -122,12 +122,12 @@ describe('getStorySortParameter', () => { } as Parameters; `) ).toMatchInlineSnapshot(` - Object { - "locales": "", - "method": "", - "order": Array [], - } - `); + { + "locales": "", + "method": "", + "order": [], + } + `); }); it('parameters typescript satisfies', () => { @@ -144,12 +144,12 @@ describe('getStorySortParameter', () => { } satisfies Parameters; `) ).toMatchInlineSnapshot(` - Object { - "locales": "", - "method": "", - "order": Array [], - } - `); + { + "locales": "", + "method": "", + "order": [], + } + `); }); }); @@ -280,12 +280,12 @@ describe('getStorySortParameter', () => { }; `) ).toMatchInlineSnapshot(` - Array [ - "Intro", - "*", - "WIP", - ] - `); + [ + "Intro", + "*", + "WIP", + ] + `); }); it('no storysort', () => { @@ -346,12 +346,12 @@ describe('getStorySortParameter', () => { export default preview; `) ).toMatchInlineSnapshot(` - Array [ - "Intro", - "*", - "WIP", - ] - `); + [ + "Intro", + "*", + "WIP", + ] + `); }); it('inline typescript', () => { @@ -370,12 +370,12 @@ describe('getStorySortParameter', () => { } satisfies Preview; `) ).toMatchInlineSnapshot(` - Array [ - "Intro", - "*", - "WIP", - ] - `); + [ + "Intro", + "*", + "WIP", + ] + `); }); it('variable', () => { @@ -395,12 +395,12 @@ describe('getStorySortParameter', () => { export default preview; `) ).toMatchInlineSnapshot(` - Array [ - "Intro", - "*", - "WIP", - ] - `); + [ + "Intro", + "*", + "WIP", + ] + `); }); it('typescript var', () => { @@ -420,12 +420,12 @@ describe('getStorySortParameter', () => { export default preview; `) ).toMatchInlineSnapshot(` - Array [ - "Intro", - "*", - "WIP", - ] - `); + [ + "Intro", + "*", + "WIP", + ] + `); }); it('typescript satisfies var', () => { @@ -445,12 +445,12 @@ describe('getStorySortParameter', () => { export default preview; `) ).toMatchInlineSnapshot(` - Array [ - "Intro", - "*", - "WIP", - ] - `); + [ + "Intro", + "*", + "WIP", + ] + `); }); }); describe('unsupported', () => { diff --git a/code/lib/manager-api/src/lib/stories.test.ts b/code/lib/manager-api/src/lib/stories.test.ts index af5807ac2d14..fcce4a94d874 100644 --- a/code/lib/manager-api/src/lib/stories.test.ts +++ b/code/lib/manager-api/src/lib/stories.test.ts @@ -40,23 +40,23 @@ describe('transformStoryIndexV2toV3', () => { }; expect(transformStoryIndexV2toV3(indexV2)).toMatchInlineSnapshot(` - Object { - "stories": Object { - "1": Object { + { + "stories": { + "1": { "id": "1", "importPath": "", "kind": "story", "name": "Story 1", - "parameters": Object {}, + "parameters": {}, "story": "Story 1", "title": "story", }, - "2": Object { + "2": { "id": "2", "importPath": "", "kind": "blog", "name": "Blog 1", - "parameters": Object {}, + "parameters": {}, "story": "Blog 1", "title": "blog", }, @@ -105,43 +105,43 @@ describe('transformStoryIndexV3toV4', () => { }; expect(transformStoryIndexV3toV4(indexV3)).toMatchInlineSnapshot(` - Object { - "entries": Object { - "1": Object { + { + "entries": { + "1": { "id": "1", "importPath": "", "name": "", - "parameters": Object { + "parameters": { "docsOnly": true, }, - "storiesImports": Array [], - "tags": Array [ + "storiesImports": [], + "tags": [ "stories-mdx", ], "title": "Story 1", "type": "docs", }, - "2": Object { + "2": { "id": "2", "importPath": "", "name": "Page 1", - "parameters": Object {}, + "parameters": {}, "title": "Page 1", "type": "story", }, - "3": Object { + "3": { "id": "3", "importPath": "", "name": "", - "parameters": Object {}, + "parameters": {}, "title": "Story 2", "type": "story", }, - "4": Object { + "4": { "id": "4", "importPath": "", "name": "Page 2", - "parameters": Object {}, + "parameters": {}, "title": "Page 1", "type": "story", }, diff --git a/code/lib/manager-api/src/tests/refs.test.ts b/code/lib/manager-api/src/tests/refs.test.ts index 95f917ad3dda..def1c888d32c 100644 --- a/code/lib/manager-api/src/tests/refs.test.ts +++ b/code/lib/manager-api/src/tests/refs.test.ts @@ -156,21 +156,21 @@ describe('Refs API', () => { initRefs({ provider, store } as any); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/stories.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, @@ -192,21 +192,21 @@ describe('Refs API', () => { initRefs({ provider, store } as any); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json?version=2.1.3-rc.2", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/stories.json?version=2.1.3-rc.2", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, @@ -241,21 +241,21 @@ describe('Refs API', () => { }); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/stories.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, @@ -264,12 +264,12 @@ describe('Refs API', () => { `); expect(store.setState.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "refs": Object { - "fake": Object { + { + "refs": { + "fake": { "id": "fake", "index": undefined, - "indexError": Object { + "indexError": { "message": "Error: Loading of ref failed at fetch (lib/api/src/modules/refs.ts) @@ -309,21 +309,21 @@ describe('Refs API', () => { }); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/stories.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, @@ -332,12 +332,12 @@ describe('Refs API', () => { `); expect(store.setState.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "refs": Object { - "fake": Object { + { + "refs": { + "fake": { "id": "fake", "index": undefined, - "indexError": Object { + "indexError": { "message": "Error: Loading of ref failed at fetch (lib/api/src/modules/refs.ts) @@ -384,31 +384,31 @@ describe('Refs API', () => { }); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/stories.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/metadata.json", - Object { + { "cache": "no-cache", "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, @@ -442,31 +442,31 @@ describe('Refs API', () => { }); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/stories.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/metadata.json", - Object { + { "cache": "no-cache", "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, @@ -475,11 +475,11 @@ describe('Refs API', () => { `); expect(store.setState.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "refs": Object { - "fake": Object { + { + "refs": { + "fake": { "id": "fake", - "index": Object {}, + "index": {}, "title": "Fake", "type": "lazy", "url": "https://example.com", @@ -489,11 +489,11 @@ describe('Refs API', () => { `); expect(store.setState.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "refs": Object { - "fake": Object { + { + "refs": { + "fake": { "id": "fake", - "index": Object {}, + "index": {}, "title": "Fake", "type": "lazy", "url": "https://example.com", @@ -531,31 +531,31 @@ describe('Refs API', () => { }); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/stories.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/metadata.json", - Object { + { "cache": "no-cache", "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, @@ -564,15 +564,15 @@ describe('Refs API', () => { `); expect(store.setState.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "refs": Object { - "fake": Object { + { + "refs": { + "fake": { "id": "fake", - "index": Object {}, + "index": {}, "title": "Fake", "type": "lazy", "url": "https://example.com", - "versions": Object {}, + "versions": {}, }, }, } @@ -608,31 +608,31 @@ describe('Refs API', () => { }); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/stories.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/metadata.json", - Object { + { "cache": "no-cache", "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, @@ -641,15 +641,15 @@ describe('Refs API', () => { `); expect(store.setState.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "refs": Object { - "fake": Object { + { + "refs": { + "fake": { "id": "fake", - "index": Object {}, + "index": {}, "title": "Fake", "type": "lazy", "url": "https://example.com", - "versions": Object { + "versions": { "a": "http://example.com/a", "b": "http://example.com/b", }, @@ -685,31 +685,31 @@ describe('Refs API', () => { }); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/stories.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/metadata.json", - Object { + { "cache": "no-cache", "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, @@ -718,9 +718,9 @@ describe('Refs API', () => { `); expect(store.setState.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "refs": Object { - "fake": Object { + { + "refs": { + "fake": { "id": "fake", "index": undefined, "loginUrl": "https://example.com/login", @@ -759,33 +759,33 @@ describe('Refs API', () => { }); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", "Authorization": "Basic dXNlcjpwYXNz", }, }, ], - Array [ + [ "https://example.com/stories.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", "Authorization": "Basic dXNlcjpwYXNz", }, }, ], - Array [ + [ "https://example.com/metadata.json", - Object { + { "cache": "no-cache", "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", "Authorization": "Basic dXNlcjpwYXNz", }, @@ -826,31 +826,31 @@ describe('Refs API', () => { }); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/stories.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/metadata.json", - Object { + { "cache": "no-cache", "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, @@ -859,16 +859,16 @@ describe('Refs API', () => { `); expect(store.setState.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "refs": Object { - "fake": Object { + { + "refs": { + "fake": { "id": "fake", "index": undefined, "loginUrl": "https://example.com/login", "title": "Fake", "type": "auto-inject", "url": "https://example.com", - "versions": Object { + "versions": { "1.0.0": "https://example.com/v1", "2.0.0": "https://example.com", }, @@ -907,31 +907,31 @@ describe('Refs API', () => { }); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json", - Object { + { "credentials": "omit", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/stories.json", - Object { + { "credentials": "omit", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/metadata.json", - Object { + { "cache": "no-cache", "credentials": "omit", - "headers": Object { + "headers": { "Accept": "application/json", }, }, @@ -940,15 +940,15 @@ describe('Refs API', () => { `); expect(store.setState.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "refs": Object { - "fake": Object { + { + "refs": { + "fake": { "id": "fake", - "index": Object {}, + "index": {}, "title": "Fake", "type": "lazy", "url": "https://example.com", - "versions": Object {}, + "versions": {}, }, }, } @@ -984,31 +984,31 @@ describe('Refs API', () => { }); expect(fetchMock.mock.calls).toMatchInlineSnapshot(` - Array [ - Array [ + [ + [ "https://example.com/index.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/stories.json", - Object { + { "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, ], - Array [ + [ "https://example.com/metadata.json", - Object { + { "cache": "no-cache", "credentials": "include", - "headers": Object { + "headers": { "Accept": "application/json", }, }, @@ -1017,15 +1017,15 @@ describe('Refs API', () => { `); expect(store.setState.mock.calls[0][0]).toMatchInlineSnapshot(` - Object { - "refs": Object { - "fake": Object { + { + "refs": { + "fake": { "id": "fake", - "index": Object {}, + "index": {}, "title": "Fake", "type": "lazy", "url": "https://example.com", - "versions": Object {}, + "versions": {}, }, }, } diff --git a/code/lib/manager-api/src/tests/stories.test.ts b/code/lib/manager-api/src/tests/stories.test.ts index a70783738135..24cd930fc237 100644 --- a/code/lib/manager-api/src/tests/stories.test.ts +++ b/code/lib/manager-api/src/tests/stories.test.ts @@ -1227,9 +1227,9 @@ describe('stories API', () => { }) ).resolves.not.toThrow(); expect(store.getState().status).toMatchInlineSnapshot(` - Object { - "a-story-id": Object { - "a-addon-id": Object { + { + "a-story-id": { + "a-addon-id": { "description": "an addon description", "status": "pending", "title": "an addon title", @@ -1256,16 +1256,16 @@ describe('stories API', () => { }) ).resolves.not.toThrow(); expect(store.getState().status).toMatchInlineSnapshot(` - Object { - "a-story-id": Object { - "a-addon-id": Object { + { + "a-story-id": { + "a-addon-id": { "description": "an addon description", "status": "pending", "title": "an addon title", }, }, - "another-story-id": Object { - "a-addon-id": Object { + "another-story-id": { + "a-addon-id": { "description": "", "status": "success", "title": "a addon title", @@ -1301,9 +1301,9 @@ describe('stories API', () => { ).resolves.not.toThrow(); expect(store.getState().status).toMatchInlineSnapshot(` - Object { - "another-story-id": Object { - "a-addon-id": Object { + { + "another-story-id": { + "a-addon-id": { "description": "", "status": "success", "title": "a addon title", @@ -1340,16 +1340,16 @@ describe('stories API', () => { }) ).resolves.not.toThrow(); expect(store.getState().status).toMatchInlineSnapshot(` - Object { - "a-story-id": Object { - "a-addon-id": Object { + { + "a-story-id": { + "a-addon-id": { "description": "an addon description", "status": "success", "title": "an addon title", }, }, - "another-story-id": Object { - "a-addon-id": Object { + "another-story-id": { + "a-addon-id": { "description": "", "status": "success", "title": "a addon title", @@ -1401,9 +1401,9 @@ describe('stories API', () => { const { index } = store.getState(); expect(index).toMatchInlineSnapshot(` - Object { - "a": Object { - "children": Array [ + { + "a": { + "children": [ "a--1", "a--2", ], @@ -1417,7 +1417,7 @@ describe('stories API', () => { "renderLabel": undefined, "type": "component", }, - "a--1": Object { + "a--1": { "depth": 1, "id": "a--1", "importPath": "./a.ts", @@ -1432,7 +1432,7 @@ describe('stories API', () => { "title": "a", "type": "story", }, - "a--2": Object { + "a--2": { "depth": 1, "id": "a--2", "importPath": "./a.ts", @@ -1465,7 +1465,7 @@ describe('stories API', () => { ); // empty, because there are no stories with status - expect(store.getState().index).toMatchInlineSnapshot(`Object {}`); + expect(store.getState().index).toMatchInlineSnapshot('{}'); // setting status should update the index await api.experimental_updateStatus('a-addon-id', { @@ -1478,9 +1478,9 @@ describe('stories API', () => { }); expect(store.getState().index).toMatchInlineSnapshot(` - Object { - "a": Object { - "children": Array [ + { + "a": { + "children": [ "a--1", ], "depth": 0, @@ -1493,7 +1493,7 @@ describe('stories API', () => { "renderLabel": undefined, "type": "component", }, - "a--1": Object { + "a--1": { "depth": 1, "id": "a--1", "importPath": "./a.ts", @@ -1525,9 +1525,9 @@ describe('stories API', () => { const { index } = store.getState(); expect(index).toMatchInlineSnapshot(` - Object { - "a": Object { - "children": Array [ + { + "a": { + "children": [ "a--1", "a--2", ], @@ -1541,7 +1541,7 @@ describe('stories API', () => { "renderLabel": undefined, "type": "component", }, - "a--1": Object { + "a--1": { "depth": 1, "id": "a--1", "importPath": "./a.ts", @@ -1556,7 +1556,7 @@ describe('stories API', () => { "title": "a", "type": "story", }, - "a--2": Object { + "a--2": { "depth": 1, "id": "a--2", "importPath": "./a.ts", diff --git a/code/lib/preview-api/src/modules/core-client/start.test.ts b/code/lib/preview-api/src/modules/core-client/start.test.ts index 239f887e17fd..eba4d843fa61 100644 --- a/code/lib/preview-api/src/modules/core-client/start.test.ts +++ b/code/lib/preview-api/src/modules/core-client/start.test.ts @@ -137,72 +137,72 @@ describe('start', () => { expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) .toMatchInlineSnapshot(` - Object { - "entries": Object { - "component-a--story-one": Object { - "argTypes": Object {}, - "args": Object {}, - "componentId": "component-a", - "id": "component-a--story-one", - "importPath": "file1", - "initialArgs": Object {}, - "name": "Story One", - "parameters": Object { - "__id": "component-a--story-one", - "__isArgsStory": false, - "fileName": "file1", - "renderer": "test", + { + "entries": { + "component-a--story-one": { + "argTypes": {}, + "args": {}, + "componentId": "component-a", + "id": "component-a--story-one", + "importPath": "file1", + "initialArgs": {}, + "name": "Story One", + "parameters": { + "__id": "component-a--story-one", + "__isArgsStory": false, + "fileName": "file1", + "renderer": "test", + }, + "tags": [ + "story", + ], + "title": "Component A", + "type": "story", }, - "tags": Array [ - "story", - ], - "title": "Component A", - "type": "story", - }, - "component-a--story-two": Object { - "argTypes": Object {}, - "args": Object {}, - "componentId": "component-a", - "id": "component-a--story-two", - "importPath": "file1", - "initialArgs": Object {}, - "name": "Story Two", - "parameters": Object { - "__id": "component-a--story-two", - "__isArgsStory": false, - "fileName": "file1", - "renderer": "test", + "component-a--story-two": { + "argTypes": {}, + "args": {}, + "componentId": "component-a", + "id": "component-a--story-two", + "importPath": "file1", + "initialArgs": {}, + "name": "Story Two", + "parameters": { + "__id": "component-a--story-two", + "__isArgsStory": false, + "fileName": "file1", + "renderer": "test", + }, + "tags": [ + "story", + ], + "title": "Component A", + "type": "story", }, - "tags": Array [ - "story", - ], - "title": "Component A", - "type": "story", - }, - "component-b--story-three": Object { - "argTypes": Object {}, - "args": Object {}, - "componentId": "component-b", - "id": "component-b--story-three", - "importPath": "file2", - "initialArgs": Object {}, - "name": "Story Three", - "parameters": Object { - "__id": "component-b--story-three", - "__isArgsStory": false, - "fileName": "file2", - "renderer": "test", + "component-b--story-three": { + "argTypes": {}, + "args": {}, + "componentId": "component-b", + "id": "component-b--story-three", + "importPath": "file2", + "initialArgs": {}, + "name": "Story Three", + "parameters": { + "__id": "component-b--story-three", + "__isArgsStory": false, + "fileName": "file2", + "renderer": "test", + }, + "tags": [ + "story", + ], + "title": "Component B", + "type": "story", }, - "tags": Array [ - "story", - ], - "title": "Component B", - "type": "story", }, - }, - "v": 4, - } - `); + "v": 4, + } + `); await waitForRender(); expect(mockChannel.emit).toHaveBeenCalledWith(STORY_RENDERED, 'component-a--story-one'); @@ -419,52 +419,52 @@ describe('start', () => { await waitForEvents([SET_INDEX]); expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) .toMatchInlineSnapshot(` - Object { - "entries": Object { - "component-a--default": Object { - "argTypes": Object {}, - "args": Object {}, - "componentId": "component-a", - "id": "component-a--default", - "importPath": "file1", - "initialArgs": Object {}, - "name": "default", - "parameters": Object { - "__id": "component-a--default", - "__isArgsStory": false, - "fileName": "file1", - "renderer": "test", + { + "entries": { + "component-a--default": { + "argTypes": {}, + "args": {}, + "componentId": "component-a", + "id": "component-a--default", + "importPath": "file1", + "initialArgs": {}, + "name": "default", + "parameters": { + "__id": "component-a--default", + "__isArgsStory": false, + "fileName": "file1", + "renderer": "test", + }, + "tags": [ + "story", + ], + "title": "Component A", + "type": "story", }, - "tags": Array [ - "story", - ], - "title": "Component A", - "type": "story", - }, - "component-a--new": Object { - "argTypes": Object {}, - "args": Object {}, - "componentId": "component-a", - "id": "component-a--new", - "importPath": "file1", - "initialArgs": Object {}, - "name": "new", - "parameters": Object { - "__id": "component-a--new", - "__isArgsStory": false, - "fileName": "file1", - "renderer": "test", + "component-a--new": { + "argTypes": {}, + "args": {}, + "componentId": "component-a", + "id": "component-a--new", + "importPath": "file1", + "initialArgs": {}, + "name": "new", + "parameters": { + "__id": "component-a--new", + "__isArgsStory": false, + "fileName": "file1", + "renderer": "test", + }, + "tags": [ + "story", + ], + "title": "Component A", + "type": "story", }, - "tags": Array [ - "story", - ], - "title": "Component A", - "type": "story", }, - }, - "v": 4, - } - `); + "v": 4, + } + `); }); it('re-emits SET_INDEX when a story file is removed', async () => { @@ -490,84 +490,84 @@ describe('start', () => { await waitForEvents([SET_INDEX]); expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) .toMatchInlineSnapshot(` - Object { - "entries": Object { - "component-a--default": Object { - "argTypes": Object {}, - "args": Object {}, - "componentId": "component-a", - "id": "component-a--default", - "importPath": "file1", - "initialArgs": Object {}, - "name": "default", - "parameters": Object { - "__id": "component-a--default", - "__isArgsStory": false, - "fileName": "file1", - "renderer": "test", + { + "entries": { + "component-a--default": { + "argTypes": {}, + "args": {}, + "componentId": "component-a", + "id": "component-a--default", + "importPath": "file1", + "initialArgs": {}, + "name": "default", + "parameters": { + "__id": "component-a--default", + "__isArgsStory": false, + "fileName": "file1", + "renderer": "test", + }, + "tags": [ + "story", + ], + "title": "Component A", + "type": "story", }, - "tags": Array [ - "story", - ], - "title": "Component A", - "type": "story", - }, - "component-b--default": Object { - "argTypes": Object {}, - "args": Object {}, - "componentId": "component-b", - "id": "component-b--default", - "importPath": "file2", - "initialArgs": Object {}, - "name": "default", - "parameters": Object { - "__id": "component-b--default", - "__isArgsStory": false, - "fileName": "file2", - "renderer": "test", + "component-b--default": { + "argTypes": {}, + "args": {}, + "componentId": "component-b", + "id": "component-b--default", + "importPath": "file2", + "initialArgs": {}, + "name": "default", + "parameters": { + "__id": "component-b--default", + "__isArgsStory": false, + "fileName": "file2", + "renderer": "test", + }, + "tags": [ + "story", + ], + "title": "Component B", + "type": "story", }, - "tags": Array [ - "story", - ], - "title": "Component B", - "type": "story", }, - }, - "v": 4, - } - `); + "v": 4, + } + `); mockChannel.emit.mockClear(); disposeCallback(); await waitForEvents([SET_INDEX]); expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) .toMatchInlineSnapshot(` - Object { - "entries": Object { - "component-a--default": Object { - "argTypes": Object {}, - "args": Object {}, - "componentId": "component-a", - "id": "component-a--default", - "importPath": "file1", - "initialArgs": Object {}, - "name": "default", - "parameters": Object { - "__id": "component-a--default", - "__isArgsStory": false, - "fileName": "file1", - "renderer": "test", + { + "entries": { + "component-a--default": { + "argTypes": {}, + "args": {}, + "componentId": "component-a", + "id": "component-a--default", + "importPath": "file1", + "initialArgs": {}, + "name": "default", + "parameters": { + "__id": "component-a--default", + "__isArgsStory": false, + "fileName": "file1", + "renderer": "test", + }, + "tags": [ + "story", + ], + "title": "Component A", + "type": "story", }, - "tags": Array [ - "story", - ], - "title": "Component A", - "type": "story", }, - }, - "v": 4, - } - `); + "v": 4, + } + `); }); }); @@ -593,51 +593,51 @@ describe('start', () => { await waitForRender(); expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) .toMatchInlineSnapshot(` - Object { - "entries": Object { - "component-c--story-one": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "component-c--story-one", - "importPath": "exports-map-0", - "initialArgs": Object {}, - "name": "Story One", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-0", - "renderer": "test", + { + "entries": { + "component-c--story-one": { + "argTypes": {}, + "args": {}, + "id": "component-c--story-one", + "importPath": "exports-map-0", + "initialArgs": {}, + "name": "Story One", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-0", + "renderer": "test", + }, + "tags": [ + "story-tag", + "story", + ], + "title": "Component C", + "type": "story", }, - "tags": Array [ - "story-tag", - "story", - ], - "title": "Component C", - "type": "story", - }, - "component-c--story-two": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "component-c--story-two", - "importPath": "exports-map-0", - "initialArgs": Object {}, - "name": "Story Two", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-0", - "renderer": "test", + "component-c--story-two": { + "argTypes": {}, + "args": {}, + "id": "component-c--story-two", + "importPath": "exports-map-0", + "initialArgs": {}, + "name": "Story Two", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-0", + "renderer": "test", + }, + "tags": [ + "component-tag", + "autodocs", + "story", + ], + "title": "Component C", + "type": "story", }, - "tags": Array [ - "component-tag", - "autodocs", - "story", - ], - "title": "Component C", - "type": "story", }, - }, - "v": 4, - } - `); + "v": 4, + } + `); await waitForRender(); expect(mockChannel.emit).toHaveBeenCalledWith(STORY_RENDERED, 'component-c--story-one'); @@ -714,71 +714,71 @@ describe('start', () => { await waitForEvents([SET_INDEX]); expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) .toMatchInlineSnapshot(` - Object { - "entries": Object { - "component-c--story-one": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "component-c--story-one", - "importPath": "exports-map-0", - "initialArgs": Object {}, - "name": "Story One", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-0", - "renderer": "test", + { + "entries": { + "component-c--story-one": { + "argTypes": {}, + "args": {}, + "id": "component-c--story-one", + "importPath": "exports-map-0", + "initialArgs": {}, + "name": "Story One", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-0", + "renderer": "test", + }, + "tags": [ + "story-tag", + "story", + ], + "title": "Component C", + "type": "story", }, - "tags": Array [ - "story-tag", - "story", - ], - "title": "Component C", - "type": "story", - }, - "component-c--story-three": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "component-c--story-three", - "importPath": "exports-map-0", - "initialArgs": Object {}, - "name": "Story Three", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-0", - "renderer": "test", + "component-c--story-three": { + "argTypes": {}, + "args": {}, + "id": "component-c--story-three", + "importPath": "exports-map-0", + "initialArgs": {}, + "name": "Story Three", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-0", + "renderer": "test", + }, + "tags": [ + "component-tag", + "autodocs", + "story", + ], + "title": "Component C", + "type": "story", }, - "tags": Array [ - "component-tag", - "autodocs", - "story", - ], - "title": "Component C", - "type": "story", - }, - "component-c--story-two": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "component-c--story-two", - "importPath": "exports-map-0", - "initialArgs": Object {}, - "name": "Story Two", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-0", - "renderer": "test", + "component-c--story-two": { + "argTypes": {}, + "args": {}, + "id": "component-c--story-two", + "importPath": "exports-map-0", + "initialArgs": {}, + "name": "Story Two", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-0", + "renderer": "test", + }, + "tags": [ + "component-tag", + "autodocs", + "story", + ], + "title": "Component C", + "type": "story", }, - "tags": Array [ - "component-tag", - "autodocs", - "story", - ], - "title": "Component C", - "type": "story", }, - }, - "v": 4, - } - `); + "v": 4, + } + `); }); it('re-emits SET_INDEX when a story file is removed', async () => { @@ -805,69 +805,69 @@ describe('start', () => { await waitForEvents([SET_INDEX]); expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) .toMatchInlineSnapshot(` - Object { - "entries": Object { - "component-c--story-one": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "component-c--story-one", - "importPath": "exports-map-0", - "initialArgs": Object {}, - "name": "Story One", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-0", - "renderer": "test", + { + "entries": { + "component-c--story-one": { + "argTypes": {}, + "args": {}, + "id": "component-c--story-one", + "importPath": "exports-map-0", + "initialArgs": {}, + "name": "Story One", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-0", + "renderer": "test", + }, + "tags": [ + "story-tag", + "story", + ], + "title": "Component C", + "type": "story", }, - "tags": Array [ - "story-tag", - "story", - ], - "title": "Component C", - "type": "story", - }, - "component-c--story-two": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "component-c--story-two", - "importPath": "exports-map-0", - "initialArgs": Object {}, - "name": "Story Two", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-0", - "renderer": "test", + "component-c--story-two": { + "argTypes": {}, + "args": {}, + "id": "component-c--story-two", + "importPath": "exports-map-0", + "initialArgs": {}, + "name": "Story Two", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-0", + "renderer": "test", + }, + "tags": [ + "component-tag", + "autodocs", + "story", + ], + "title": "Component C", + "type": "story", }, - "tags": Array [ - "component-tag", - "autodocs", - "story", - ], - "title": "Component C", - "type": "story", - }, - "component-d--story-four": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "component-d--story-four", - "importPath": "exports-map-1", - "initialArgs": Object {}, - "name": "Story Four", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-1", - "renderer": "test", + "component-d--story-four": { + "argTypes": {}, + "args": {}, + "id": "component-d--story-four", + "importPath": "exports-map-1", + "initialArgs": {}, + "name": "Story Four", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-1", + "renderer": "test", + }, + "tags": [ + "story", + ], + "title": "Component D", + "type": "story", }, - "tags": Array [ - "story", - ], - "title": "Component D", - "type": "story", }, - }, - "v": 4, - } - `); + "v": 4, + } + `); await waitForRender(); mockChannel.emit.mockClear(); @@ -877,51 +877,51 @@ describe('start', () => { await waitForEvents([SET_INDEX]); expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) .toMatchInlineSnapshot(` - Object { - "entries": Object { - "component-c--story-one": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "component-c--story-one", - "importPath": "exports-map-0", - "initialArgs": Object {}, - "name": "Story One", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-0", - "renderer": "test", + { + "entries": { + "component-c--story-one": { + "argTypes": {}, + "args": {}, + "id": "component-c--story-one", + "importPath": "exports-map-0", + "initialArgs": {}, + "name": "Story One", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-0", + "renderer": "test", + }, + "tags": [ + "story-tag", + "story", + ], + "title": "Component C", + "type": "story", }, - "tags": Array [ - "story-tag", - "story", - ], - "title": "Component C", - "type": "story", - }, - "component-c--story-two": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "component-c--story-two", - "importPath": "exports-map-0", - "initialArgs": Object {}, - "name": "Story Two", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-0", - "renderer": "test", + "component-c--story-two": { + "argTypes": {}, + "args": {}, + "id": "component-c--story-two", + "importPath": "exports-map-0", + "initialArgs": {}, + "name": "Story Two", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-0", + "renderer": "test", + }, + "tags": [ + "component-tag", + "autodocs", + "story", + ], + "title": "Component C", + "type": "story", }, - "tags": Array [ - "component-tag", - "autodocs", - "story", - ], - "title": "Component C", - "type": "story", }, - }, - "v": 4, - } - `); + "v": 4, + } + `); await waitForEvents([STORY_UNCHANGED]); }); @@ -977,28 +977,28 @@ describe('start', () => { await waitForEvents([SET_INDEX]); expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) .toMatchInlineSnapshot(` - Object { - "entries": Object { - "introduction": Object { - "id": "introduction", - "importPath": "./Introduction.stories.mdx", - "name": undefined, - "parameters": Object { - "fileName": "./Introduction.stories.mdx", - "renderer": "test", + { + "entries": { + "introduction": { + "id": "introduction", + "importPath": "./Introduction.stories.mdx", + "name": undefined, + "parameters": { + "fileName": "./Introduction.stories.mdx", + "renderer": "test", + }, + "storiesImports": [], + "tags": [ + "stories-mdx", + "docs", + ], + "title": "Introduction", + "type": "docs", }, - "storiesImports": Array [], - "tags": Array [ - "stories-mdx", - "docs", - ], - "title": "Introduction", - "type": "docs", }, - }, - "v": 4, - } - `); + "v": 4, + } + `); // Wait a second to let the docs "render" finish (and maybe throw) await waitForQuiescence(); @@ -1055,278 +1055,100 @@ describe('start', () => { await waitForRender(); expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) .toMatchInlineSnapshot(` - Object { - "entries": Object { - "component-a--story-one": Object { - "argTypes": Object {}, - "args": Object {}, - "componentId": "component-a", - "id": "component-a--story-one", - "importPath": "file1", - "initialArgs": Object {}, - "name": "Story One", - "parameters": Object { - "__id": "component-a--story-one", - "__isArgsStory": false, - "fileName": "file1", - "renderer": "test", - }, - "tags": Array [ - "story", - ], - "title": "Component A", - "type": "story", - }, - "component-a--story-two": Object { - "argTypes": Object {}, - "args": Object {}, - "componentId": "component-a", - "id": "component-a--story-two", - "importPath": "file1", - "initialArgs": Object {}, - "name": "Story Two", - "parameters": Object { - "__id": "component-a--story-two", - "__isArgsStory": false, - "fileName": "file1", - "renderer": "test", - }, - "tags": Array [ - "story", - ], - "title": "Component A", - "type": "story", - }, - "component-b--story-three": Object { - "argTypes": Object {}, - "args": Object {}, - "componentId": "component-b", - "id": "component-b--story-three", - "importPath": "file2", - "initialArgs": Object {}, - "name": "Story Three", - "parameters": Object { - "__id": "component-b--story-three", - "__isArgsStory": false, - "fileName": "file2", - "renderer": "test", - }, - "tags": Array [ - "story", - ], - "title": "Component B", - "type": "story", - }, - "component-c--story-one": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "component-c--story-one", - "importPath": "exports-map-0", - "initialArgs": Object {}, - "name": "Story One", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-0", - "renderer": "test", - }, - "tags": Array [ - "story-tag", - "story", - ], - "title": "Component C", - "type": "story", - }, - "component-c--story-two": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "component-c--story-two", - "importPath": "exports-map-0", - "initialArgs": Object {}, - "name": "Story Two", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-0", - "renderer": "test", - }, - "tags": Array [ - "component-tag", - "autodocs", - "story", - ], - "title": "Component C", - "type": "story", - }, - }, - "v": 4, - } - `); - - await waitForRender(); - expect(mockChannel.emit).toHaveBeenCalledWith(STORY_RENDERED, 'component-a--story-one'); - - expect(renderToCanvas).toHaveBeenCalledWith( - expect.objectContaining({ - id: 'component-a--story-one', - }), - 'story-root' - ); - }); - - describe('autodocs', () => { - beforeEach(() => { - global.DOCS_OPTIONS = { autodocs: 'tag', defaultName: 'Docs' }; - }); - - it('adds stories for each component with autodocs tag', async () => { - const renderToCanvas = vi.fn(); - - const { configure, clientApi } = start(renderToCanvas); - configure('test', () => { - clientApi - .storiesOf('Component A', { id: 'file1' } as NodeModule) - .add('Story One', vi.fn()) - .add('Story Two', vi.fn()); - - clientApi - .storiesOf('Component B', { id: 'file2' } as NodeModule) - .addParameters({ tags: ['autodocs'] }) - .add('Story Three', vi.fn()); - - return [componentCExports]; - }); - - await waitForRender(); - expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) - .toMatchInlineSnapshot(` - Object { - "entries": Object { - "component-a--story-one": Object { - "argTypes": Object {}, - "args": Object {}, + { + "entries": { + "component-a--story-one": { + "argTypes": {}, + "args": {}, "componentId": "component-a", "id": "component-a--story-one", "importPath": "file1", - "initialArgs": Object {}, + "initialArgs": {}, "name": "Story One", - "parameters": Object { + "parameters": { "__id": "component-a--story-one", "__isArgsStory": false, "fileName": "file1", "renderer": "test", }, - "tags": Array [ + "tags": [ "story", ], "title": "Component A", "type": "story", }, - "component-a--story-two": Object { - "argTypes": Object {}, - "args": Object {}, + "component-a--story-two": { + "argTypes": {}, + "args": {}, "componentId": "component-a", "id": "component-a--story-two", "importPath": "file1", - "initialArgs": Object {}, + "initialArgs": {}, "name": "Story Two", - "parameters": Object { + "parameters": { "__id": "component-a--story-two", "__isArgsStory": false, "fileName": "file1", "renderer": "test", }, - "tags": Array [ + "tags": [ "story", ], "title": "Component A", "type": "story", }, - "component-b--docs": Object { - "componentId": "component-b", - "id": "component-b--docs", - "importPath": "file2", - "name": "Docs", - "parameters": Object { - "fileName": "file2", - "renderer": "test", - }, - "storiesImports": Array [], - "tags": Array [ - "autodocs", - "docs", - ], - "title": "Component B", - "type": "docs", - }, - "component-b--story-three": Object { - "argTypes": Object {}, - "args": Object {}, + "component-b--story-three": { + "argTypes": {}, + "args": {}, "componentId": "component-b", "id": "component-b--story-three", "importPath": "file2", - "initialArgs": Object {}, + "initialArgs": {}, "name": "Story Three", - "parameters": Object { + "parameters": { "__id": "component-b--story-three", "__isArgsStory": false, "fileName": "file2", "renderer": "test", }, - "tags": Array [ - "autodocs", + "tags": [ "story", ], "title": "Component B", "type": "story", }, - "component-c--docs": Object { - "id": "component-c--docs", - "importPath": "exports-map-0", - "name": "Docs", - "parameters": Object { - "fileName": "exports-map-0", - "renderer": "test", - }, - "storiesImports": Array [], - "tags": Array [ - "component-tag", - "autodocs", - "docs", - ], - "title": "Component C", - "type": "docs", - }, - "component-c--story-one": Object { - "argTypes": Object {}, - "args": Object {}, + "component-c--story-one": { + "argTypes": {}, + "args": {}, "id": "component-c--story-one", "importPath": "exports-map-0", - "initialArgs": Object {}, + "initialArgs": {}, "name": "Story One", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "exports-map-0", "renderer": "test", }, - "tags": Array [ + "tags": [ "story-tag", "story", ], "title": "Component C", "type": "story", }, - "component-c--story-two": Object { - "argTypes": Object {}, - "args": Object {}, + "component-c--story-two": { + "argTypes": {}, + "args": {}, "id": "component-c--story-two", "importPath": "exports-map-0", - "initialArgs": Object {}, + "initialArgs": {}, "name": "Story Two", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "exports-map-0", "renderer": "test", }, - "tags": Array [ + "tags": [ "component-tag", "autodocs", "story", @@ -1338,6 +1160,184 @@ describe('start', () => { "v": 4, } `); + + await waitForRender(); + expect(mockChannel.emit).toHaveBeenCalledWith(STORY_RENDERED, 'component-a--story-one'); + + expect(renderToCanvas).toHaveBeenCalledWith( + expect.objectContaining({ + id: 'component-a--story-one', + }), + 'story-root' + ); + }); + + describe('autodocs', () => { + beforeEach(() => { + global.DOCS_OPTIONS = { autodocs: 'tag', defaultName: 'Docs' }; + }); + + it('adds stories for each component with autodocs tag', async () => { + const renderToCanvas = vi.fn(); + + const { configure, clientApi } = start(renderToCanvas); + configure('test', () => { + clientApi + .storiesOf('Component A', { id: 'file1' } as NodeModule) + .add('Story One', vi.fn()) + .add('Story Two', vi.fn()); + + clientApi + .storiesOf('Component B', { id: 'file2' } as NodeModule) + .addParameters({ tags: ['autodocs'] }) + .add('Story Three', vi.fn()); + + return [componentCExports]; + }); + + await waitForRender(); + expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) + .toMatchInlineSnapshot(` + { + "entries": { + "component-a--story-one": { + "argTypes": {}, + "args": {}, + "componentId": "component-a", + "id": "component-a--story-one", + "importPath": "file1", + "initialArgs": {}, + "name": "Story One", + "parameters": { + "__id": "component-a--story-one", + "__isArgsStory": false, + "fileName": "file1", + "renderer": "test", + }, + "tags": [ + "story", + ], + "title": "Component A", + "type": "story", + }, + "component-a--story-two": { + "argTypes": {}, + "args": {}, + "componentId": "component-a", + "id": "component-a--story-two", + "importPath": "file1", + "initialArgs": {}, + "name": "Story Two", + "parameters": { + "__id": "component-a--story-two", + "__isArgsStory": false, + "fileName": "file1", + "renderer": "test", + }, + "tags": [ + "story", + ], + "title": "Component A", + "type": "story", + }, + "component-b--docs": { + "componentId": "component-b", + "id": "component-b--docs", + "importPath": "file2", + "name": "Docs", + "parameters": { + "fileName": "file2", + "renderer": "test", + }, + "storiesImports": [], + "tags": [ + "autodocs", + "docs", + ], + "title": "Component B", + "type": "docs", + }, + "component-b--story-three": { + "argTypes": {}, + "args": {}, + "componentId": "component-b", + "id": "component-b--story-three", + "importPath": "file2", + "initialArgs": {}, + "name": "Story Three", + "parameters": { + "__id": "component-b--story-three", + "__isArgsStory": false, + "fileName": "file2", + "renderer": "test", + }, + "tags": [ + "autodocs", + "story", + ], + "title": "Component B", + "type": "story", + }, + "component-c--docs": { + "id": "component-c--docs", + "importPath": "exports-map-0", + "name": "Docs", + "parameters": { + "fileName": "exports-map-0", + "renderer": "test", + }, + "storiesImports": [], + "tags": [ + "component-tag", + "autodocs", + "docs", + ], + "title": "Component C", + "type": "docs", + }, + "component-c--story-one": { + "argTypes": {}, + "args": {}, + "id": "component-c--story-one", + "importPath": "exports-map-0", + "initialArgs": {}, + "name": "Story One", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-0", + "renderer": "test", + }, + "tags": [ + "story-tag", + "story", + ], + "title": "Component C", + "type": "story", + }, + "component-c--story-two": { + "argTypes": {}, + "args": {}, + "id": "component-c--story-two", + "importPath": "exports-map-0", + "initialArgs": {}, + "name": "Story Two", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-0", + "renderer": "test", + }, + "tags": [ + "component-tag", + "autodocs", + "story", + ], + "title": "Component C", + "type": "story", + }, + }, + "v": 4, + } + `); }); }); describe('when docsOptions.autodocs = true', () => { @@ -1369,7 +1369,7 @@ describe('start', () => { await waitForRender(); const setIndexData = mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]; expect(Object.keys(setIndexData.entries)).toMatchInlineSnapshot(` - Array [ + [ "component-a--docs", "component-a--story-one", "component-a--story-two", @@ -1400,30 +1400,30 @@ describe('start', () => { await waitForEvents([SET_INDEX]); expect(mockChannel.emit.mock.calls.find((call) => call[0] === SET_INDEX)?.[1]) .toMatchInlineSnapshot(` - Object { - "entries": Object { - "auto-title--story-one": Object { - "argTypes": Object {}, - "args": Object {}, - "id": "auto-title--story-one", - "importPath": "exports-map-0", - "initialArgs": Object {}, - "name": "Story One", - "parameters": Object { - "__isArgsStory": false, - "fileName": "exports-map-0", - "renderer": "test", + { + "entries": { + "auto-title--story-one": { + "argTypes": {}, + "args": {}, + "id": "auto-title--story-one", + "importPath": "exports-map-0", + "initialArgs": {}, + "name": "Story One", + "parameters": { + "__isArgsStory": false, + "fileName": "exports-map-0", + "renderer": "test", + }, + "tags": [ + "story", + ], + "title": "auto-title", + "type": "story", }, - "tags": Array [ - "story", - ], - "title": "auto-title", - "type": "story", }, - }, - "v": 4, - } - `); + "v": 4, + } + `); await waitForRender(); }); diff --git a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.integration.test.ts b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.integration.test.ts index 186082073d5b..e2b2adaa5045 100644 --- a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.integration.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.integration.test.ts @@ -111,13 +111,7 @@ describe('PreviewWeb', () => { await preview.initialize({ importFn, getProjectAnnotations }); await waitForRender(); - expect(docsRoot.outerHTML).toMatchInlineSnapshot(` -
-
- INSIDE -
-
- `); + expect(docsRoot.outerHTML).toMatchInlineSnapshot('"
INSIDE
"'); }); it('sends docs rendering exceptions to showException', async () => { diff --git a/code/lib/preview-api/src/modules/store/StoryStore.test.ts b/code/lib/preview-api/src/modules/store/StoryStore.test.ts index 628008ce2556..51894cf0610e 100644 --- a/code/lib/preview-api/src/modules/store/StoryStore.test.ts +++ b/code/lib/preview-api/src/modules/store/StoryStore.test.ts @@ -319,41 +319,41 @@ describe('StoryStore', () => { }); expect(store.extract()).toMatchInlineSnapshot(` - Object { - "component-one--a": Object { - "argTypes": Object { - "a": Object { + { + "component-one--a": { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "a", }, "component": undefined, "componentId": "component-one", "id": "component-one--a", - "initialArgs": Object { + "initialArgs": { "foo": "a", }, "kind": "Component One", "name": "A", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentOne-new.stories.js", }, "playFunction": undefined, "story": "A", "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component One", @@ -522,117 +522,117 @@ describe('StoryStore', () => { await store.cacheAllCSFFiles(); expect(store.extract()).toMatchInlineSnapshot(` - Object { - "component-one--a": Object { - "argTypes": Object { - "a": Object { + { + "component-one--a": { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "a", }, "component": undefined, "componentId": "component-one", "id": "component-one--a", - "initialArgs": Object { + "initialArgs": { "foo": "a", }, "kind": "Component One", "name": "A", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentOne.stories.js", }, "playFunction": undefined, "story": "A", "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component One", }, - "component-one--b": Object { - "argTypes": Object { - "a": Object { + "component-one--b": { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "b", }, "component": undefined, "componentId": "component-one", "id": "component-one--b", - "initialArgs": Object { + "initialArgs": { "foo": "b", }, "kind": "Component One", "name": "B", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentOne.stories.js", }, "playFunction": undefined, "story": "B", "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component One", }, - "component-two--c": Object { - "argTypes": Object { - "a": Object { + "component-two--c": { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "c", }, "component": undefined, "componentId": "component-two", "id": "component-two--c", - "initialArgs": Object { + "initialArgs": { "foo": "c", }, "kind": "Component Two", "name": "C", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentTwo.stories.js", }, "playFunction": undefined, "story": "C", "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component Two", @@ -714,19 +714,19 @@ describe('StoryStore', () => { await store.cacheAllCSFFiles(); expect(store.raw()).toMatchInlineSnapshot(` - Array [ - Object { + [ + { "applyLoaders": [Function], - "argTypes": Object { - "a": Object { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, @@ -734,18 +734,18 @@ describe('StoryStore', () => { "component": undefined, "componentId": "component-one", "id": "component-one--a", - "initialArgs": Object { + "initialArgs": { "foo": "a", }, "kind": "Component One", - "moduleExport": Object { - "args": Object { + "moduleExport": { + "args": { "foo": "a", }, }, "name": "A", - "originalStoryFn": [MockFunction], - "parameters": Object { + "originalStoryFn": [MockFunction spy], + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentOne.stories.js", }, @@ -753,25 +753,25 @@ describe('StoryStore', () => { "story": "A", "storyFn": [Function], "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component One", "unboundStoryFn": [Function], "undecoratedStoryFn": [Function], }, - Object { + { "applyLoaders": [Function], - "argTypes": Object { - "a": Object { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, @@ -779,18 +779,18 @@ describe('StoryStore', () => { "component": undefined, "componentId": "component-one", "id": "component-one--b", - "initialArgs": Object { + "initialArgs": { "foo": "b", }, "kind": "Component One", - "moduleExport": Object { - "args": Object { + "moduleExport": { + "args": { "foo": "b", }, }, "name": "B", - "originalStoryFn": [MockFunction], - "parameters": Object { + "originalStoryFn": [MockFunction spy], + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentOne.stories.js", }, @@ -798,25 +798,25 @@ describe('StoryStore', () => { "story": "B", "storyFn": [Function], "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component One", "unboundStoryFn": [Function], "undecoratedStoryFn": [Function], }, - Object { + { "applyLoaders": [Function], - "argTypes": Object { - "a": Object { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, @@ -824,18 +824,18 @@ describe('StoryStore', () => { "component": undefined, "componentId": "component-two", "id": "component-two--c", - "initialArgs": Object { + "initialArgs": { "foo": "c", }, "kind": "Component Two", - "moduleExport": Object { - "args": Object { + "moduleExport": { + "args": { "foo": "c", }, }, "name": "C", - "originalStoryFn": [MockFunction], - "parameters": Object { + "originalStoryFn": [MockFunction spy], + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentTwo.stories.js", }, @@ -843,7 +843,7 @@ describe('StoryStore', () => { "story": "C", "storyFn": [Function], "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component Two", @@ -863,126 +863,126 @@ describe('StoryStore', () => { await store.cacheAllCSFFiles(); expect(store.getSetStoriesPayload()).toMatchInlineSnapshot(` - Object { - "globalParameters": Object {}, - "globals": Object { + { + "globalParameters": {}, + "globals": { "a": "b", }, - "kindParameters": Object { - "Component One": Object {}, - "Component Two": Object {}, + "kindParameters": { + "Component One": {}, + "Component Two": {}, }, - "stories": Object { - "component-one--a": Object { - "argTypes": Object { - "a": Object { + "stories": { + "component-one--a": { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "a", }, "component": undefined, "componentId": "component-one", "id": "component-one--a", - "initialArgs": Object { + "initialArgs": { "foo": "a", }, "kind": "Component One", "name": "A", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentOne.stories.js", }, "playFunction": undefined, "story": "A", "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component One", }, - "component-one--b": Object { - "argTypes": Object { - "a": Object { + "component-one--b": { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "b", }, "component": undefined, "componentId": "component-one", "id": "component-one--b", - "initialArgs": Object { + "initialArgs": { "foo": "b", }, "kind": "Component One", "name": "B", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentOne.stories.js", }, "playFunction": undefined, "story": "B", "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component One", }, - "component-two--c": Object { - "argTypes": Object { - "a": Object { + "component-two--c": { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "c", }, "component": undefined, "componentId": "component-two", "id": "component-two--c", - "initialArgs": Object { + "initialArgs": { "foo": "c", }, "kind": "Component Two", "name": "C", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentTwo.stories.js", }, "playFunction": undefined, "story": "C", "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component Two", @@ -1003,38 +1003,38 @@ describe('StoryStore', () => { await store.cacheAllCSFFiles(); expect(store.getStoriesJsonData()).toMatchInlineSnapshot(` - Object { - "stories": Object { - "component-one--a": Object { + { + "stories": { + "component-one--a": { "id": "component-one--a", "importPath": "./src/ComponentOne.stories.js", "kind": "Component One", "name": "A", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentOne.stories.js", }, "story": "A", "title": "Component One", }, - "component-one--b": Object { + "component-one--b": { "id": "component-one--b", "importPath": "./src/ComponentOne.stories.js", "kind": "Component One", "name": "B", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentOne.stories.js", }, "story": "B", "title": "Component One", }, - "component-two--c": Object { + "component-two--c": { "id": "component-two--c", "importPath": "./src/ComponentTwo.stories.js", "kind": "Component Two", "name": "C", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentTwo.stories.js", }, @@ -1057,95 +1057,95 @@ describe('StoryStore', () => { await store.cacheAllCSFFiles(); expect(store.getSetIndexPayload()).toMatchInlineSnapshot(` - Object { - "entries": Object { - "component-one--a": Object { - "argTypes": Object { - "a": Object { + { + "entries": { + "component-one--a": { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "a", }, "id": "component-one--a", "importPath": "./src/ComponentOne.stories.js", - "initialArgs": Object { + "initialArgs": { "foo": "a", }, "name": "A", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentOne.stories.js", }, "title": "Component One", "type": "story", }, - "component-one--b": Object { - "argTypes": Object { - "a": Object { + "component-one--b": { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "b", }, "id": "component-one--b", "importPath": "./src/ComponentOne.stories.js", - "initialArgs": Object { + "initialArgs": { "foo": "b", }, "name": "B", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentOne.stories.js", }, "title": "Component One", "type": "story", }, - "component-two--c": Object { - "argTypes": Object { - "a": Object { + "component-two--c": { + "argTypes": { + "a": { "name": "a", - "type": Object { + "type": { "name": "string", }, }, - "foo": Object { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "c", }, "id": "component-two--c", "importPath": "./src/ComponentTwo.stories.js", - "initialArgs": Object { + "initialArgs": { "foo": "c", }, "name": "C", - "parameters": Object { + "parameters": { "__isArgsStory": false, "fileName": "./src/ComponentTwo.stories.js", }, diff --git a/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts b/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts index aaa3e56a886f..a4bf5a04fdeb 100644 --- a/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts @@ -48,16 +48,16 @@ describe('normalizeStory', () => { const storyFn = () => {}; const meta = { id: 'title', title: 'title' }; expect(normalizeStory('storyExport', storyFn, meta)).toMatchInlineSnapshot(` - Object { - "argTypes": Object {}, - "args": Object {}, - "decorators": Array [], + { + "argTypes": {}, + "args": {}, + "decorators": [], "id": "title--story-export", - "loaders": Array [], + "loaders": [], "moduleExport": [Function], "name": "Story Export", - "parameters": Object {}, - "tags": Array [], + "parameters": {}, + "tags": [], "userStoryFn": [Function], } `); @@ -117,16 +117,16 @@ describe('normalizeStory', () => { const meta = { id: 'title', title: 'title' }; const normalized = normalizeStory('storyExport', storyObj, meta); expect(normalized).toMatchInlineSnapshot(` - Object { - "argTypes": Object {}, - "args": Object {}, - "decorators": Array [], + { + "argTypes": {}, + "args": {}, + "decorators": [], "id": "title--story-export", - "loaders": Array [], - "moduleExport": Object {}, + "loaders": [], + "moduleExport": {}, "name": "Story Export", - "parameters": Object {}, - "tags": Array [], + "parameters": {}, + "tags": [], } `); expect(normalized.moduleExport).toBe(storyObj); @@ -144,30 +144,30 @@ describe('normalizeStory', () => { const meta = { id: 'title', title: 'title' }; const { moduleExport, ...normalized } = normalizeStory('storyExport', storyObj, meta); expect(normalized).toMatchInlineSnapshot(` - Object { - "argTypes": Object { - "storyArgType": Object { + { + "argTypes": { + "storyArgType": { "name": "storyArgType", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "storyArg": "val", }, - "decorators": Array [ + "decorators": [ [Function], ], "id": "title--story-export", - "loaders": Array [ + "loaders": [ [Function], ], "name": "story name", - "parameters": Object { + "parameters": { "storyParam": "val", }, - "tags": Array [], + "tags": [], } `); expect(moduleExport).toBe(storyObj); @@ -192,40 +192,40 @@ describe('normalizeStory', () => { const meta = { id: 'title', title: 'title' }; const { moduleExport, ...normalized } = normalizeStory('storyExport', storyObj, meta); expect(normalized).toMatchInlineSnapshot(` - Object { - "argTypes": Object { - "storyArgType": Object { + { + "argTypes": { + "storyArgType": { "name": "storyArgType", - "type": Object { + "type": { "name": "string", }, }, - "storyArgType2": Object { + "storyArgType2": { "name": "storyArgType2", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "storyArg": "val", "storyArg2": "legacy", }, - "decorators": Array [ + "decorators": [ [Function], [Function], ], "id": "title--story-export", - "loaders": Array [ + "loaders": [ [Function], [Function], ], "name": "story name", - "parameters": Object { + "parameters": { "storyParam": "val", "storyParam2": "legacy", }, - "tags": Array [], + "tags": [], } `); expect(moduleExport).toBe(storyObj); diff --git a/code/renderers/vue3/src/docs/sourceDecorator.test.ts b/code/renderers/vue3/src/docs/sourceDecorator.test.ts index d5393a65e5bc..3bba1dc7df79 100644 --- a/code/renderers/vue3/src/docs/sourceDecorator.test.ts +++ b/code/renderers/vue3/src/docs/sourceDecorator.test.ts @@ -15,24 +15,24 @@ expect.addSnapshotSerializer({ describe('Vue3: sourceDecorator->mapAttributesAndDirective()', () => { test('camelCase boolean Arg', () => { expect(mapAttributesAndDirectives({ camelCaseBooleanArg: true })).toMatchInlineSnapshot(` - Array [ - Object { - arg: Object { + [ + { + arg: { content: camel-case-boolean-arg, - loc: Object { + loc: { source: camel-case-boolean-arg, }, }, - exp: Object { + exp: { isStatic: false, - loc: Object { + loc: { source: true, }, }, - loc: Object { + loc: { source: :camel-case-boolean-arg="true", }, - modifiers: Array [ + modifiers: [ , ], name: bind, @@ -43,24 +43,24 @@ describe('Vue3: sourceDecorator->mapAttributesAndDirective()', () => { }); test('camelCase string Arg', () => { expect(mapAttributesAndDirectives({ camelCaseStringArg: 'foo' })).toMatchInlineSnapshot(` - Array [ - Object { - arg: Object { + [ + { + arg: { content: camel-case-string-arg, - loc: Object { + loc: { source: camel-case-string-arg, }, }, - exp: Object { + exp: { isStatic: false, - loc: Object { + loc: { source: foo, }, }, - loc: Object { + loc: { source: camel-case-string-arg="foo", }, - modifiers: Array [ + modifiers: [ , ], name: bind, @@ -71,24 +71,24 @@ describe('Vue3: sourceDecorator->mapAttributesAndDirective()', () => { }); test('boolean arg', () => { expect(mapAttributesAndDirectives({ booleanarg: true })).toMatchInlineSnapshot(` - Array [ - Object { - arg: Object { + [ + { + arg: { content: booleanarg, - loc: Object { + loc: { source: booleanarg, }, }, - exp: Object { + exp: { isStatic: false, - loc: Object { + loc: { source: true, }, }, - loc: Object { + loc: { source: :booleanarg="true", }, - modifiers: Array [ + modifiers: [ , ], name: bind, @@ -99,24 +99,24 @@ describe('Vue3: sourceDecorator->mapAttributesAndDirective()', () => { }); test('string arg', () => { expect(mapAttributesAndDirectives({ stringarg: 'bar' })).toMatchInlineSnapshot(` - Array [ - Object { - arg: Object { + [ + { + arg: { content: stringarg, - loc: Object { + loc: { source: stringarg, }, }, - exp: Object { + exp: { isStatic: false, - loc: Object { + loc: { source: bar, }, }, - loc: Object { + loc: { source: stringarg="bar", }, - modifiers: Array [ + modifiers: [ , ], name: bind, @@ -127,24 +127,24 @@ describe('Vue3: sourceDecorator->mapAttributesAndDirective()', () => { }); test('number arg', () => { expect(mapAttributesAndDirectives({ numberarg: 2023 })).toMatchInlineSnapshot(` - Array [ - Object { - arg: Object { + [ + { + arg: { content: numberarg, - loc: Object { + loc: { source: numberarg, }, }, - exp: Object { + exp: { isStatic: false, - loc: Object { + loc: { source: 2023, }, }, - loc: Object { + loc: { source: :numberarg="2023", }, - modifiers: Array [ + modifiers: [ , ], name: bind, @@ -161,68 +161,68 @@ describe('Vue3: sourceDecorator->mapAttributesAndDirective()', () => { cameCaseNumberArg: 2023, }) ).toMatchInlineSnapshot(` - Array [ - Object { - arg: Object { + [ + { + arg: { content: camel-case-boolean-arg, - loc: Object { + loc: { source: camel-case-boolean-arg, }, }, - exp: Object { + exp: { isStatic: false, - loc: Object { + loc: { source: true, }, }, - loc: Object { + loc: { source: :camel-case-boolean-arg="true", }, - modifiers: Array [ + modifiers: [ , ], name: bind, type: 6, }, - Object { - arg: Object { + { + arg: { content: camel-case-string-arg, - loc: Object { + loc: { source: camel-case-string-arg, }, }, - exp: Object { + exp: { isStatic: false, - loc: Object { + loc: { source: foo, }, }, - loc: Object { + loc: { source: camel-case-string-arg="foo", }, - modifiers: Array [ + modifiers: [ , ], name: bind, type: 6, }, - Object { - arg: Object { + { + arg: { content: came-case-number-arg, - loc: Object { + loc: { source: came-case-number-arg, }, }, - exp: Object { + exp: { isStatic: false, - loc: Object { + loc: { source: 2023, }, }, - loc: Object { + loc: { source: :came-case-number-arg="2023", }, - modifiers: Array [ + modifiers: [ , ], name: bind, diff --git a/code/yarn.lock b/code/yarn.lock index 2bc07ae18103..f06b5123b4c1 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -393,18 +393,7 @@ __metadata: languageName: node linkType: hard -"@axe-core/puppeteer@npm:^4.2.0": - version: 4.7.3 - resolution: "@axe-core/puppeteer@npm:4.7.3" - dependencies: - axe-core: ^4.7.0 - peerDependencies: - puppeteer: ">=1.10.0" - checksum: 24161a6c8ee3ab33f09e66f73bb81d70c69feb5c2e8cb1a1ba6a6e06ecb204768dbf443bc76abfa95c3fb637fd21ea4270478591b45a00a939b9b3909c11bc4e - languageName: node - linkType: hard - -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.22.5, @babel/code-frame@npm:^7.8.3": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.22.5": version: 7.22.13 resolution: "@babel/code-frame@npm:7.22.13" dependencies: @@ -467,29 +456,6 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:7.8.7": - version: 7.8.7 - resolution: "@babel/core@npm:7.8.7" - dependencies: - "@babel/code-frame": ^7.8.3 - "@babel/generator": ^7.8.7 - "@babel/helpers": ^7.8.4 - "@babel/parser": ^7.8.7 - "@babel/template": ^7.8.6 - "@babel/traverse": ^7.8.6 - "@babel/types": ^7.8.7 - convert-source-map: ^1.7.0 - debug: ^4.1.0 - gensync: ^1.0.0-beta.1 - json5: ^2.1.0 - lodash: ^4.17.13 - resolve: ^1.3.2 - semver: ^5.4.1 - source-map: ^0.5.0 - checksum: ffff3e94f219c7a4a32c825eca57c9beb1a83a60c0c5c37e7ddbcecd45c5c188cece5352f56a91a14c05c25ffcb298155429fedb9e86477cf2c91c3388b1f2c9 - languageName: node - linkType: hard - "@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.0, @babel/core@npm:^7.12.3, @babel/core@npm:^7.13.16, @babel/core@npm:^7.19.6, @babel/core@npm:^7.20.12, @babel/core@npm:^7.22.0, @babel/core@npm:^7.22.1, @babel/core@npm:^7.22.9, @babel/core@npm:^7.3.4, @babel/core@npm:^7.7.5": version: 7.22.17 resolution: "@babel/core@npm:7.22.17" @@ -525,7 +491,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.12.11, @babel/generator@npm:^7.22.15, @babel/generator@npm:^7.22.5, @babel/generator@npm:^7.22.9, @babel/generator@npm:^7.7.2, @babel/generator@npm:^7.8.7": +"@babel/generator@npm:^7.12.11, @babel/generator@npm:^7.22.15, @babel/generator@npm:^7.22.5, @babel/generator@npm:^7.22.9, @babel/generator@npm:^7.7.2": version: 7.22.15 resolution: "@babel/generator@npm:7.22.15" dependencies: @@ -775,7 +741,7 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.22.15, @babel/helpers@npm:^7.22.5, @babel/helpers@npm:^7.22.6, @babel/helpers@npm:^7.8.4": +"@babel/helpers@npm:^7.22.15, @babel/helpers@npm:^7.22.5, @babel/helpers@npm:^7.22.6": version: 7.22.15 resolution: "@babel/helpers@npm:7.22.15" dependencies: @@ -797,7 +763,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.11.5, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.18.4, @babel/parser@npm:^7.20.15, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.3, @babel/parser@npm:^7.21.4, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.22.16, @babel/parser@npm:^7.22.5, @babel/parser@npm:^7.22.7, @babel/parser@npm:^7.4.5, @babel/parser@npm:^7.6.0, @babel/parser@npm:^7.7.0, @babel/parser@npm:^7.8.6, @babel/parser@npm:^7.8.7, @babel/parser@npm:^7.9.6": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.11.5, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.18.4, @babel/parser@npm:^7.20.15, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.3, @babel/parser@npm:^7.21.4, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.22.16, @babel/parser@npm:^7.22.5, @babel/parser@npm:^7.22.7, @babel/parser@npm:^7.4.5, @babel/parser@npm:^7.6.0, @babel/parser@npm:^7.7.0, @babel/parser@npm:^7.9.6": version: 7.22.16 resolution: "@babel/parser@npm:7.22.16" bin: @@ -2306,18 +2272,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:7.8.6": - version: 7.8.6 - resolution: "@babel/template@npm:7.8.6" - dependencies: - "@babel/code-frame": ^7.8.3 - "@babel/parser": ^7.8.6 - "@babel/types": ^7.8.6 - checksum: c89b2f39452083303beaaabc794ebf83194bb5599647c54591d3b8358b42d720bab050daa34450052e4fdf21bcb77cf60b6419fec73d50eb2ce60c4abfe7292e - languageName: node - linkType: hard - -"@babel/template@npm:^7.22.15, @babel/template@npm:^7.22.5, @babel/template@npm:^7.3.3, @babel/template@npm:^7.7.0, @babel/template@npm:^7.8.6": +"@babel/template@npm:^7.22.15, @babel/template@npm:^7.22.5, @babel/template@npm:^7.3.3, @babel/template@npm:^7.7.0": version: 7.22.15 resolution: "@babel/template@npm:7.22.15" dependencies: @@ -2328,7 +2283,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.22.15, @babel/traverse@npm:^7.22.17, @babel/traverse@npm:^7.22.5, @babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.4.5, @babel/traverse@npm:^7.7.0, @babel/traverse@npm:^7.8.6": +"@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.22.15, @babel/traverse@npm:^7.22.17, @babel/traverse@npm:^7.22.5, @babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.4.5, @babel/traverse@npm:^7.7.0": version: 7.22.17 resolution: "@babel/traverse@npm:7.22.17" dependencies: @@ -2346,7 +2301,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.11.5, @babel/types@npm:^7.2.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.4, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.17, @babel/types@npm:^7.22.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.6.1, @babel/types@npm:^7.7.0, @babel/types@npm:^7.7.2, @babel/types@npm:^7.8.3, @babel/types@npm:^7.8.6, @babel/types@npm:^7.8.7, @babel/types@npm:^7.9.6": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.11.5, @babel/types@npm:^7.2.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.4, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.17, @babel/types@npm:^7.22.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.6.1, @babel/types@npm:^7.7.0, @babel/types@npm:^7.7.2, @babel/types@npm:^7.8.3, @babel/types@npm:^7.9.6": version: 7.22.17 resolution: "@babel/types@npm:7.22.17" dependencies: @@ -2558,16 +2513,6 @@ __metadata: languageName: node linkType: hard -"@emotion/css-prettifier@npm:^1.1.3": - version: 1.1.3 - resolution: "@emotion/css-prettifier@npm:1.1.3" - dependencies: - "@emotion/memoize": ^0.8.1 - stylis: 4.2.0 - checksum: 9ce3d7e5851054a24ca68cca4f6973de47d64567d03b6be730aa83f1cf9ae15e4da8c4611e68620e7b972f7a9fb7c36099fdf7e26b78589eb64f094fce46ce1b - languageName: node - linkType: hard - "@emotion/hash@npm:^0.9.1": version: 0.9.1 resolution: "@emotion/hash@npm:0.9.1" @@ -2584,27 +2529,6 @@ __metadata: languageName: node linkType: hard -"@emotion/jest@npm:^11.10.0, @emotion/jest@npm:^11.8.0": - version: 11.11.0 - resolution: "@emotion/jest@npm:11.11.0" - dependencies: - "@babel/runtime": ^7.18.3 - "@emotion/css-prettifier": ^1.1.3 - chalk: ^4.1.0 - specificity: ^0.4.1 - stylis: 4.2.0 - peerDependencies: - "@types/jest": ^26.0.14 || ^27.0.0 || ^28.0.0 || ^29.0.0 - enzyme-to-json: ^3.2.1 - peerDependenciesMeta: - "@types/jest": - optional: true - enzyme-to-json: - optional: true - checksum: 919def636000234c4af8447a6cdf7f9675146bb020074fd06cf3c6eb42c365e727354ae79b2a7cdccb472d38da8ed8d6fd57f4235cab2e1b7605a2c6672a0fc5 - languageName: node - linkType: hard - "@emotion/memoize@npm:^0.8.1": version: 0.8.1 resolution: "@emotion/memoize@npm:0.8.1" @@ -3548,15 +3472,6 @@ __metadata: languageName: node linkType: hard -"@jest/create-cache-key-function@npm:^27.4.2": - version: 27.5.1 - resolution: "@jest/create-cache-key-function@npm:27.5.1" - dependencies: - "@jest/types": ^27.5.1 - checksum: 1890ac93fad852e0a98c31de1e5f2c548974aefd36e838d27b70834dda1654a153ed6a52258447ebacfd47463e9bdb83750631bee827797c7b9973c083998a96 - languageName: node - linkType: hard - "@jest/environment@npm:^29.7.0": version: 29.7.0 resolution: "@jest/environment@npm:29.7.0" @@ -6115,116 +6030,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/addon-storyshots-puppeteer@workspace:*, @storybook/addon-storyshots-puppeteer@workspace:addons/storyshots-puppeteer": - version: 0.0.0-use.local - resolution: "@storybook/addon-storyshots-puppeteer@workspace:addons/storyshots-puppeteer" - dependencies: - "@axe-core/puppeteer": ^4.2.0 - "@storybook/csf": ^0.1.0 - "@storybook/node-logger": "workspace:*" - "@storybook/types": "workspace:*" - "@types/jest-image-snapshot": ^6.0.0 - "@types/puppeteer": ^5.4.0 - enzyme: ^3.11.0 - enzyme-to-json: ^3.6.1 - jest-image-snapshot: ^6.0.0 - puppeteer: ^2.0.0 || ^3.0.0 - peerDependencies: - "@storybook/addon-storyshots": "workspace:*" - puppeteer: ">=2.0.0" - peerDependenciesMeta: - puppeteer: - optional: true - languageName: unknown - linkType: soft - -"@storybook/addon-storyshots@workspace:*, @storybook/addon-storyshots@workspace:addons/storyshots-core": - version: 0.0.0-use.local - resolution: "@storybook/addon-storyshots@workspace:addons/storyshots-core" - dependencies: - "@angular/core": ^16.0.0-rc.4 - "@angular/platform-browser-dynamic": ^16.0.0-rc.4 - "@emotion/jest": ^11.8.0 - "@jest/transform": ^29.3.1 - "@storybook/addon-docs": "workspace:*" - "@storybook/angular": "workspace:*" - "@storybook/babel-plugin-require-context-hook": 1.0.1 - "@storybook/client-api": "workspace:*" - "@storybook/core-common": "workspace:*" - "@storybook/core-webpack": "workspace:*" - "@storybook/global": ^5.0.0 - "@storybook/preview-api": "workspace:*" - "@storybook/react": "workspace:*" - "@storybook/types": "workspace:*" - "@storybook/vue": "workspace:*" - "@storybook/vue3": "workspace:*" - "@types/jest-specific-snapshot": ^0.5.6 - babel-loader: ^9.1.2 - enzyme: ^3.11.0 - enzyme-adapter-react-16: ^1.15.5 - enzyme-to-json: ^3.6.1 - glob: ^10.0.0 - jest-preset-angular: ^13.0.1 - jest-specific-snapshot: ^8.0.0 - jest-vue-preprocessor: ^1.7.1 - preact-render-to-string: ^5.1.19 - pretty-format: ^29.0.0 - react-test-renderer: ^16 - read-pkg-up: ^7.0.1 - rxjs: ^6.6.3 - ts-dedent: ^2.0.0 - vue-jest: ^5.0.0-alpha.8 - peerDependencies: - "@angular/core": ">=13.0.0" - "@angular/platform-browser-dynamic": ">=13.0.0" - "@storybook/angular": "*" - "@storybook/react": "*" - "@storybook/vue": "*" - "@storybook/vue3": "*" - jest: "*" - jest-preset-angular: " >= 12.2.3" - jest-vue-preprocessor: "*" - preact: ^10.5.13 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - rxjs: "*" - svelte: "*" - vue: "*" - vue-jest: "*" - peerDependenciesMeta: - "@angular/core": - optional: true - "@angular/platform-browser-dynamic": - optional: true - "@storybook/angular": - optional: true - "@storybook/react": - optional: true - "@storybook/vue": - optional: true - "@storybook/vue3": - optional: true - jest-preset-angular: - optional: true - jest-vue-preprocessor: - optional: true - preact: - optional: true - react: - optional: true - react-dom: - optional: true - rxjs: - optional: true - svelte: - optional: true - vue: - optional: true - vue-jest: - optional: true - languageName: unknown - linkType: soft - "@storybook/addon-storysource@workspace:*, @storybook/addon-storysource@workspace:addons/storysource": version: 0.0.0-use.local resolution: "@storybook/addon-storysource@workspace:addons/storysource" @@ -7826,8 +7631,6 @@ __metadata: "@babel/preset-react": ^7.22.5 "@babel/preset-typescript": ^7.22.5 "@babel/runtime": ^7.22.6 - "@emotion/jest": ^11.10.0 - "@jest/globals": ^29.3.1 "@nx/workspace": 16.2.1 "@playwright/test": 1.36.0 "@storybook/addon-a11y": "workspace:*" @@ -7843,8 +7646,6 @@ __metadata: "@storybook/addon-mdx-gfm": "workspace:*" "@storybook/addon-measure": "workspace:*" "@storybook/addon-outline": "workspace:*" - "@storybook/addon-storyshots": "workspace:*" - "@storybook/addon-storyshots-puppeteer": "workspace:*" "@storybook/addon-storysource": "workspace:*" "@storybook/addon-toolbars": "workspace:*" "@storybook/addon-viewport": "workspace:*" @@ -7926,9 +7727,7 @@ __metadata: "@storybook/web-components-vite": "workspace:*" "@storybook/web-components-webpack5": "workspace:*" "@swc/core": 1.3.82 - "@swc/jest": ^0.2.26 "@testing-library/dom": ^7.29.4 - "@testing-library/jest-dom": ^5.11.9 "@testing-library/react": ^11.2.2 "@testing-library/user-event": ^13.2.1 "@types/express": ^4.17.11 @@ -7963,13 +7762,6 @@ __metadata: glob: ^10.0.0 http-server: ^14.1.1 husky: ^4.3.7 - jest: ^29.5.0 - jest-environment-jsdom: ^29.5.0 - jest-image-snapshot: ^6.0.0 - jest-junit: ^16.0.0 - jest-os-detection: ^1.3.1 - jest-serializer-html: ^7.1.0 - jest-watch-typeahead: ^2.2.1 lerna: ^6.4.0 lint-staged: ^13.2.2 lodash: ^4.17.21 @@ -8741,18 +8533,6 @@ __metadata: languageName: node linkType: hard -"@swc/jest@npm:^0.2.26": - version: 0.2.29 - resolution: "@swc/jest@npm:0.2.29" - dependencies: - "@jest/create-cache-key-function": ^27.4.2 - jsonc-parser: ^3.2.0 - peerDependencies: - "@swc/core": "*" - checksum: 10f34341f9bc8003cec44f91a88b531ba44094aad97b2f8410fb2f94db9eb3b8fc7f6d14ba867eb9c1dc6ba29cc46058244b8280d673a7c681062fe0dc73c3f0 - languageName: node - linkType: hard - "@swc/types@npm:^0.1.4": version: 0.1.4 resolution: "@swc/types@npm:0.1.4" @@ -9035,15 +8815,6 @@ __metadata: languageName: node linkType: hard -"@types/cheerio@npm:^0.22.22": - version: 0.22.32 - resolution: "@types/cheerio@npm:0.22.32" - dependencies: - "@types/node": "*" - checksum: 02c64de8e198e9bb2b162c3d426a00df8b558730df84bebf7d586cf23493043217f0dc81efabc13b32589839a82a974f02ade618ecdd7c528c3b574cf95bff97 - languageName: node - linkType: hard - "@types/color-convert@npm:^2.0.0": version: 2.0.1 resolution: "@types/color-convert@npm:2.0.1" @@ -9335,26 +9106,6 @@ __metadata: languageName: node linkType: hard -"@types/jest-image-snapshot@npm:^6.0.0": - version: 6.2.0 - resolution: "@types/jest-image-snapshot@npm:6.2.0" - dependencies: - "@types/jest": "*" - "@types/pixelmatch": "*" - ssim.js: ^3.1.1 - checksum: 65e7b951eee31521b4f53fa6a49134fad137a5636886594ea10324624afe074d4c88e1f579715934e0eab340951bbc864b81c99c00f51f8cf31230de415078c5 - languageName: node - linkType: hard - -"@types/jest-specific-snapshot@npm:^0.5.6": - version: 0.5.6 - resolution: "@types/jest-specific-snapshot@npm:0.5.6" - dependencies: - "@types/jest": "*" - checksum: 5fc9234afdf704eb7fa69bbf7860c2e9f9e76aed750e98aa44824bb47e048d1e57c5386eb3c919534a4225147f205742c6f9dac0e458e092de30efde77cc1ebe - languageName: node - linkType: hard - "@types/jest@npm:*": version: 28.1.3 resolution: "@types/jest@npm:28.1.3" @@ -9561,15 +9312,6 @@ __metadata: languageName: node linkType: hard -"@types/pixelmatch@npm:*": - version: 5.2.4 - resolution: "@types/pixelmatch@npm:5.2.4" - dependencies: - "@types/node": "*" - checksum: 10ce0b806112743237a75f0fcb145cc972cc7934131b971fea375b70fb69c6dc1ee2ba63e77265348c87d69260461ae812cca140412b50e7cd42118944b41e0d - languageName: node - linkType: hard - "@types/pluralize@npm:^0.0.29": version: 0.0.29 resolution: "@types/pluralize@npm:0.0.29" @@ -9640,15 +9382,6 @@ __metadata: languageName: node linkType: hard -"@types/puppeteer@npm:^5.4.0": - version: 5.4.7 - resolution: "@types/puppeteer@npm:5.4.7" - dependencies: - "@types/node": "*" - checksum: f15bccf30526151c6e42c797b844f24eb7489f0180b391857c8d6902dfa96c7f48730540229a681505ca70e9197cdac0dfbeaca0c2537526358ad5656bef703d - languageName: node - linkType: hard - "@types/qs@npm:*, @types/qs@npm:^6, @types/qs@npm:^6.9.5": version: 6.9.8 resolution: "@types/qs@npm:6.9.8" @@ -10002,15 +9735,6 @@ __metadata: languageName: node linkType: hard -"@types/yauzl@npm:^2.9.1": - version: 2.10.0 - resolution: "@types/yauzl@npm:2.10.0" - dependencies: - "@types/node": "*" - checksum: e917cf11c78e9ca7d037d0e6e0d6d5d99443d9d7201f8f1a556f02a2bc57ae457487e9bfec89dfa848d16979b35de6e5b34840d4d0bb9e5f33849d077ac15154 - languageName: node - linkType: hard - "@typescript-eslint/eslint-plugin@npm:^5.45.0": version: 5.62.0 resolution: "@typescript-eslint/eslint-plugin@npm:5.62.0" @@ -11006,25 +10730,6 @@ __metadata: languageName: node linkType: hard -"airbnb-prop-types@npm:^2.16.0": - version: 2.16.0 - resolution: "airbnb-prop-types@npm:2.16.0" - dependencies: - array.prototype.find: ^2.1.1 - function.prototype.name: ^1.1.2 - is-regex: ^1.1.0 - object-is: ^1.1.2 - object.assign: ^4.1.0 - object.entries: ^1.1.2 - prop-types: ^15.7.2 - prop-types-exact: ^1.2.0 - react-is: ^16.13.1 - peerDependencies: - react: ^0.14 || ^15.0.0 || ^16.0.0-alpha - checksum: c3666777bf9ee3a077ce79a02fcf79b7cf3123b11a626750826912e1f0f44772177e6667176558e10384f4501556f5e7eeb198231e9f61794864465167c8ee33 - languageName: node - linkType: hard - "ajv-formats@npm:2.1.1, ajv-formats@npm:^2.1.1": version: 2.1.1 resolution: "ajv-formats@npm:2.1.1" @@ -11134,15 +10839,6 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^6.0.0": - version: 6.2.0 - resolution: "ansi-escapes@npm:6.2.0" - dependencies: - type-fest: ^3.0.0 - checksum: 3eec75deedd8b10192c5f98e4cd9715cc3ff268d33fc463c24b7d22446668bfcd4ad1803993ea89c0f51f88b5a3399572bacb7c8cb1a067fc86e189c5f3b0c7e - languageName: node - linkType: hard - "ansi-html-community@npm:0.0.8, ansi-html-community@npm:^0.0.8": version: 0.0.8 resolution: "ansi-html-community@npm:0.0.8" @@ -11439,31 +11135,6 @@ __metadata: languageName: node linkType: hard -"array.prototype.filter@npm:^1.0.0": - version: 1.0.3 - resolution: "array.prototype.filter@npm:1.0.3" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - es-array-method-boxes-properly: ^1.0.0 - is-string: ^1.0.7 - checksum: 8b70b5f866df5d90fa27aa5bfa30f5fefc44cbea94b0513699d761713658077c2a24cbf06aac5179eabddb6c93adc467af4c288b7a839c5bc5a769ee5a2d48ad - languageName: node - linkType: hard - -"array.prototype.find@npm:^2.1.1": - version: 2.2.2 - resolution: "array.prototype.find@npm:2.2.2" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - es-shim-unscopables: ^1.0.0 - checksum: 5008d3e6089f7047db1886d0dc2d75bdd342b886528dbca3c67920f18fd435dbc878b9c55243c96e18423d139d5ddb08cdbc8f95bd89ed4f2f53c63260eb444a - languageName: node - linkType: hard - "array.prototype.findlastindex@npm:^1.2.2": version: 1.2.3 resolution: "array.prototype.findlastindex@npm:1.2.3" @@ -11477,7 +11148,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.flat@npm:^1.2.3, array.prototype.flat@npm:^1.3.1": +"array.prototype.flat@npm:^1.3.1": version: 1.3.2 resolution: "array.prototype.flat@npm:1.3.2" dependencies: @@ -11751,7 +11422,7 @@ __metadata: languageName: node linkType: hard -"axe-core@npm:^4.2.0, axe-core@npm:^4.6.2, axe-core@npm:^4.7.0": +"axe-core@npm:^4.2.0, axe-core@npm:^4.6.2": version: 4.8.1 resolution: "axe-core@npm:4.8.1" checksum: 160887aac11d0a249adade104379bb3b05d1bca26386137b50ea82861cc4bbbdcc76091309b3c5f03da1fae0f27ab02d8d4aef3d041a16e67f3a012cb5080c90 @@ -12024,15 +11695,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-transform-runtime@npm:6.23.0": - version: 6.23.0 - resolution: "babel-plugin-transform-runtime@npm:6.23.0" - dependencies: - babel-runtime: ^6.22.0 - checksum: c9e9eaeb19de4c5527c2c4494e29e2d5e2ca37ab35b24ae7dd8c93943365526114a9d144237a2976197511dd22e8eb8cdb4d69291b346b468e0736a733d2499d - languageName: node - linkType: hard - "babel-preset-current-node-syntax@npm:^1.0.0": version: 1.0.1 resolution: "babel-preset-current-node-syntax@npm:1.0.1" @@ -12067,16 +11729,6 @@ __metadata: languageName: node linkType: hard -"babel-runtime@npm:^6.22.0": - version: 6.26.0 - resolution: "babel-runtime@npm:6.26.0" - dependencies: - core-js: ^2.4.0 - regenerator-runtime: ^0.11.0 - checksum: caa752004936b1463765ed3199c52f6a55d0613b9bed108743d6f13ca532b821d4ea9decc4be1b583193164462b1e3e7eefdfa36b15c72e7daac58dd72c1772f - languageName: node - linkType: hard - "babel-walk@npm:3.0.0-canary-5": version: 3.0.0-canary-5 resolution: "babel-walk@npm:3.0.0-canary-5" @@ -12744,7 +12396,7 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^5.2.1, buffer@npm:^5.5.0": +"buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" dependencies: @@ -13049,7 +12701,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:5.3.0, chalk@npm:^5.2.0": +"chalk@npm:5.3.0": version: 5.3.0 resolution: "chalk@npm:5.3.0" checksum: 8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09 @@ -13094,13 +12746,6 @@ __metadata: languageName: node linkType: hard -"char-regex@npm:^2.0.0": - version: 2.0.1 - resolution: "char-regex@npm:2.0.1" - checksum: ec592229ac3ef18f2ea1f5676ae9a829c37150db55fd7f709edce1bcdc9f506de22ae19388d853704806e51af71fe9239bcb7e7be583296951bfbf2a9a9763a2 - languageName: node - linkType: hard - "character-entities-html4@npm:^2.0.0": version: 2.1.0 resolution: "character-entities-html4@npm:2.1.0" @@ -13180,35 +12825,6 @@ __metadata: languageName: node linkType: hard -"cheerio-select@npm:^2.1.0": - version: 2.1.0 - resolution: "cheerio-select@npm:2.1.0" - dependencies: - boolbase: ^1.0.0 - css-select: ^5.1.0 - css-what: ^6.1.0 - domelementtype: ^2.3.0 - domhandler: ^5.0.3 - domutils: ^3.0.1 - checksum: 2242097e593919dba4aacb97d7b8275def8b9ec70b00aa1f43335456870cfc9e284eae2080bdc832ed232dabb9eefcf56c722d152da4a154813fb8814a55d282 - languageName: node - linkType: hard - -"cheerio@npm:^1.0.0-rc.3": - version: 1.0.0-rc.12 - resolution: "cheerio@npm:1.0.0-rc.12" - dependencies: - cheerio-select: ^2.1.0 - dom-serializer: ^2.0.0 - domhandler: ^5.0.3 - domutils: ^3.0.1 - htmlparser2: ^8.0.1 - parse5: ^7.0.0 - parse5-htmlparser2-tree-adapter: ^7.0.0 - checksum: c85d2f2461e3f024345b78e0bb16ad8e41492356210470dd1e7d5a91391da9fcf6c0a7cb48a9ba8820330153f0cedb4d0a60c7af15d96ecdb3092299b9d9c0cc - languageName: node - linkType: hard - "chokidar@npm:3.5.3, chokidar@npm:>=3.0.0 <4.0.0, chokidar@npm:^3.0.0, chokidar@npm:^3.4.1, chokidar@npm:^3.5.1, chokidar@npm:^3.5.3": version: 3.5.3 resolution: "chokidar@npm:3.5.3" @@ -14090,7 +13706,7 @@ __metadata: languageName: node linkType: hard -"core-js@npm:^2.4.0, core-js@npm:^2.6.5": +"core-js@npm:^2.6.5": version: 2.6.12 resolution: "core-js@npm:2.6.12" checksum: 00128efe427789120a06b819adc94cc72b96955acb331cb71d09287baf9bd37bebd191d91f1ee4939c893a050307ead4faea08876f09115112612b6a05684b63 @@ -14374,18 +13990,6 @@ __metadata: languageName: node linkType: hard -"css@npm:^2.1.0": - version: 2.2.4 - resolution: "css@npm:2.2.4" - dependencies: - inherits: ^2.0.3 - source-map: ^0.6.1 - source-map-resolve: ^0.5.2 - urix: ^0.1.0 - checksum: 496fa66568ebd9e51b3153817dd36ec004a45780da6f818e13117e3c4e50b774af41fff70a6ff2fa03777b239c4028ff655fe571b20964b90e886441cd141569 - languageName: node - linkType: hard - "css@npm:^3.0.0": version: 3.0.0 resolution: "css@npm:3.0.0" @@ -14993,15 +14597,6 @@ __metadata: languageName: node linkType: hard -"diffable-html@npm:^4.1.0": - version: 4.1.0 - resolution: "diffable-html@npm:4.1.0" - dependencies: - htmlparser2: ^3.9.2 - checksum: 4224133455312e03dd5b84cec0a7d7390552ae30fc5ceb24256c4973e7b51ab2ba69f8b8dbeaaa3feb2b92d3fdd57476dcb7afeada793130ab340720c6a553c7 - languageName: node - linkType: hard - "diffie-hellman@npm:^5.0.0": version: 5.0.3 resolution: "diffie-hellman@npm:5.0.3" @@ -15031,13 +14626,6 @@ __metadata: languageName: node linkType: hard -"discontinuous-range@npm:1.0.0": - version: 1.0.0 - resolution: "discontinuous-range@npm:1.0.0" - checksum: 487b105f83c1cc528e25e65d3c4b73958ec79769b7bd0e264414702a23a7e2b282c72982b4bef4af29fcab53f47816c3f0a5c40d85a99a490f4bc35b83dc00f8 - languageName: node - linkType: hard - "dns-equal@npm:^1.0.0": version: 1.0.0 resolution: "dns-equal@npm:1.0.0" @@ -15095,16 +14683,6 @@ __metadata: languageName: node linkType: hard -"dom-serializer@npm:0": - version: 0.2.2 - resolution: "dom-serializer@npm:0.2.2" - dependencies: - domelementtype: ^2.0.1 - entities: ^2.0.0 - checksum: 5cb595fb77e1a23eca56742f47631e6f4af66ce1982c7ed28b3d0ef21f1f50304c067adc29d3eaf824c572be022cee88627d0ac9b929408f24e923f3c7bed37b - languageName: node - linkType: hard - "dom-serializer@npm:^1.0.1": version: 1.4.1 resolution: "dom-serializer@npm:1.4.1" @@ -15134,13 +14712,6 @@ __metadata: languageName: node linkType: hard -"domelementtype@npm:1, domelementtype@npm:^1.3.1": - version: 1.3.1 - resolution: "domelementtype@npm:1.3.1" - checksum: 6d4f5761060a21eaf3c96545501e9d188745c7e1c31b8d141bf15d8748feeadba868f4ea32877751b8678b286fb1afbe6ae905ca3fb8f0214d8322e482cdbec0 - languageName: node - linkType: hard - "domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0, domelementtype@npm:^2.3.0": version: 2.3.0 resolution: "domelementtype@npm:2.3.0" @@ -15166,15 +14737,6 @@ __metadata: languageName: node linkType: hard -"domhandler@npm:^2.3.0": - version: 2.4.2 - resolution: "domhandler@npm:2.4.2" - dependencies: - domelementtype: 1 - checksum: 6670cab73e97e3c6771dcf22b537db3f6a0be0ad6b370f03bb5f1b585d3b563d326787fdabe1190b7ca9d81c804e9b3f8a1431159c27c44f6c05f94afa92be2d - languageName: node - linkType: hard - "domhandler@npm:^3.0.0": version: 3.3.0 resolution: "domhandler@npm:3.3.0" @@ -15202,16 +14764,6 @@ __metadata: languageName: node linkType: hard -"domutils@npm:^1.5.1": - version: 1.7.0 - resolution: "domutils@npm:1.7.0" - dependencies: - dom-serializer: 0 - domelementtype: 1 - checksum: 437fcd2d6d6be03f488152e73c6f953e289c58496baa22be9626b2b46f9cfd40486ae77d144487ff6b102929a3231cdb9a8bf8ef485fb7b7c30c985daedc77eb - languageName: node - linkType: hard - "domutils@npm:^2.0.0, domutils@npm:^2.5.2, domutils@npm:^2.8.0": version: 2.8.0 resolution: "domutils@npm:2.8.0" @@ -15663,13 +15215,6 @@ __metadata: languageName: node linkType: hard -"entities@npm:^1.1.1": - version: 1.1.2 - resolution: "entities@npm:1.1.2" - checksum: 5b12fa8c4fb942f88af6f8791bbe7be0a59ebd91c8933cee091d94455efd1eeb200418c7b1bc8dd0f74cdd4db8cf4538eb043db14cfd1919130c25d8c6095215 - languageName: node - linkType: hard - "entities@npm:^2.0.0": version: 2.2.0 resolution: "entities@npm:2.2.0" @@ -15683,118 +15228,27 @@ __metadata: checksum: 2d93f48fd86de0b0ed8ee34456aa47b4e74a916a5e663cfcc7048302e2c7e932002926daf5a00ad6d5691e3c90673a15d413704d86d7e1b9532f9bc00d975590 languageName: node linkType: hard - -"entities@npm:^4.2.0, entities@npm:^4.3.0, entities@npm:^4.4.0": - version: 4.5.0 - resolution: "entities@npm:4.5.0" - checksum: 5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250 - languageName: node - linkType: hard - -"env-paths@npm:^2.2.0": - version: 2.2.1 - resolution: "env-paths@npm:2.2.1" - checksum: 285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 - languageName: node - linkType: hard - -"envinfo@npm:^7.7.3, envinfo@npm:^7.7.4": - version: 7.10.0 - resolution: "envinfo@npm:7.10.0" - bin: - envinfo: dist/cli.js - checksum: ebc7792fbedca72bc829913abe0c2a3384b883903012f97b56085afd4e83d26f7dd0652403fedd99cd3e1c93d4fb0706f5d2c3dc06ac6a1eda348280a06a9dcf - languageName: node - linkType: hard - -"enzyme-adapter-react-16@npm:^1.15.5": - version: 1.15.7 - resolution: "enzyme-adapter-react-16@npm:1.15.7" - dependencies: - enzyme-adapter-utils: ^1.14.1 - enzyme-shallow-equal: ^1.0.5 - has: ^1.0.3 - object.assign: ^4.1.4 - object.values: ^1.1.5 - prop-types: ^15.8.1 - react-is: ^16.13.1 - react-test-renderer: ^16.0.0-0 - semver: ^5.7.0 - peerDependencies: - enzyme: ^3.0.0 - react: ^16.0.0-0 - react-dom: ^16.0.0-0 - checksum: 7cb69fcdc4bf2390ffe440cfa906c698b90d533032180b5b6ddf5ace1edac0e09a687b7f36706e1bba3b02a91585d8d5bd0317c237b5f5eab00bdb5512f330ee - languageName: node - linkType: hard - -"enzyme-adapter-utils@npm:^1.14.1": - version: 1.14.1 - resolution: "enzyme-adapter-utils@npm:1.14.1" - dependencies: - airbnb-prop-types: ^2.16.0 - function.prototype.name: ^1.1.5 - has: ^1.0.3 - object.assign: ^4.1.4 - object.fromentries: ^2.0.5 - prop-types: ^15.8.1 - semver: ^5.7.1 - peerDependencies: - react: 0.13.x || 0.14.x || ^15.0.0-0 || ^16.0.0-0 - checksum: f07423c9181ed22fda4d761ec54aca6d9fb65d8b95da48c1471d39892f8af3d3fa54c971ed73a16acbc9a483ccda3a58f97a590bf95b4d5f77f99ae37c1ac8bb - languageName: node - linkType: hard - -"enzyme-shallow-equal@npm:^1.0.1, enzyme-shallow-equal@npm:^1.0.5": - version: 1.0.5 - resolution: "enzyme-shallow-equal@npm:1.0.5" - dependencies: - has: ^1.0.3 - object-is: ^1.1.5 - checksum: 30ace0c5be2d454fb001a50dd30791c18e1f86b3b7238456b464921017f6add73ea6b2a2527f1e96958d8bfe84d0afcba30b0c9e4087ebda2feb42b7800419c4 + +"entities@npm:^4.2.0, entities@npm:^4.3.0, entities@npm:^4.4.0": + version: 4.5.0 + resolution: "entities@npm:4.5.0" + checksum: 5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250 languageName: node linkType: hard -"enzyme-to-json@npm:^3.6.1": - version: 3.6.2 - resolution: "enzyme-to-json@npm:3.6.2" - dependencies: - "@types/cheerio": ^0.22.22 - lodash: ^4.17.21 - react-is: ^16.12.0 - peerDependencies: - enzyme: ^3.4.0 - checksum: 90fba5bbcfda37f456d483a46d7a077123fb65f74e59bab1e137e30c84f5b3149114efae7f9736f7ea49dd9171299645816bc5f6649b16a19d47c8bd1d6d8065 +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 languageName: node linkType: hard -"enzyme@npm:^3.11.0": - version: 3.11.0 - resolution: "enzyme@npm:3.11.0" - dependencies: - array.prototype.flat: ^1.2.3 - cheerio: ^1.0.0-rc.3 - enzyme-shallow-equal: ^1.0.1 - function.prototype.name: ^1.1.2 - has: ^1.0.3 - html-element-map: ^1.2.0 - is-boolean-object: ^1.0.1 - is-callable: ^1.1.5 - is-number-object: ^1.0.4 - is-regex: ^1.0.5 - is-string: ^1.0.5 - is-subset: ^0.1.1 - lodash.escape: ^4.0.1 - lodash.isequal: ^4.5.0 - object-inspect: ^1.7.0 - object-is: ^1.0.2 - object.assign: ^4.1.0 - object.entries: ^1.1.1 - object.values: ^1.1.1 - raf: ^3.4.1 - rst-selector-parser: ^2.2.3 - string.prototype.trim: ^1.2.1 - checksum: 14081671ed77924026036ed4edb1168cdac826aadd1ab2c77a5b7fdda625589dc5a4062cd0c65ec88add3ea3f7c0ebcbf3178bcf84b43335a175d8c71a016809 +"envinfo@npm:^7.7.3, envinfo@npm:^7.7.4": + version: 7.10.0 + resolution: "envinfo@npm:7.10.0" + bin: + envinfo: dist/cli.js + checksum: ebc7792fbedca72bc829913abe0c2a3384b883903012f97b56085afd4e83d26f7dd0652403fedd99cd3e1c93d4fb0706f5d2c3dc06ac6a1eda348280a06a9dcf languageName: node linkType: hard @@ -15881,13 +15335,6 @@ __metadata: languageName: node linkType: hard -"es-array-method-boxes-properly@npm:^1.0.0": - version: 1.0.0 - resolution: "es-array-method-boxes-properly@npm:1.0.0" - checksum: 4b7617d3fbd460d6f051f684ceca6cf7e88e6724671d9480388d3ecdd72119ddaa46ca31f2c69c5426a82e4b3091c1e81867c71dcdc453565cd90005ff2c382d - languageName: node - linkType: hard - "es-get-iterator@npm:^1.1.3": version: 1.1.3 resolution: "es-get-iterator@npm:1.1.3" @@ -16950,15 +16397,6 @@ __metadata: languageName: node linkType: hard -"extract-from-css@npm:^0.4.4": - version: 0.4.4 - resolution: "extract-from-css@npm:0.4.4" - dependencies: - css: ^2.1.0 - checksum: 8ee304fb2efbff67e41097b1b44fe8fd3bea0abb23d9e29381cc92506c2ac5ca1d2390887676e3e26636af894743b4c367899d756115df5b510804ae592a37cf - languageName: node - linkType: hard - "extract-zip@npm:^1.6.6": version: 1.7.0 resolution: "extract-zip@npm:1.7.0" @@ -16973,23 +16411,6 @@ __metadata: languageName: node linkType: hard -"extract-zip@npm:^2.0.0": - version: 2.0.1 - resolution: "extract-zip@npm:2.0.1" - dependencies: - "@types/yauzl": ^2.9.1 - debug: ^4.1.1 - get-stream: ^5.1.0 - yauzl: ^2.10.0 - dependenciesMeta: - "@types/yauzl": - optional: true - bin: - extract-zip: cli.js - checksum: 9afbd46854aa15a857ae0341a63a92743a7b89c8779102c3b4ffc207516b2019337353962309f85c66ee3d9092202a83cdc26dbf449a11981272038443974aee - languageName: node - linkType: hard - "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -17252,7 +16673,7 @@ __metadata: languageName: node linkType: hard -"find-babel-config@npm:1.2.0, find-babel-config@npm:^1.1.0": +"find-babel-config@npm:^1.1.0": version: 1.2.0 resolution: "find-babel-config@npm:1.2.0" dependencies: @@ -17801,7 +17222,7 @@ __metadata: languageName: node linkType: hard -"function.prototype.name@npm:^1.1.2, function.prototype.name@npm:^1.1.5": +"function.prototype.name@npm:^1.1.5": version: 1.1.6 resolution: "function.prototype.name@npm:1.1.6" dependencies: @@ -17908,7 +17329,7 @@ __metadata: languageName: node linkType: hard -"gensync@npm:^1.0.0-beta.1, gensync@npm:^1.0.0-beta.2": +"gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" checksum: 782aba6cba65b1bb5af3b095d96249d20edbe8df32dbf4696fd49be2583faf676173bf4809386588828e4dd76a3354fcbeb577bab1c833ccd9fc4577f26103f8 @@ -17983,13 +17404,6 @@ __metadata: languageName: node linkType: hard -"get-stdin@npm:^5.0.1": - version: 5.0.1 - resolution: "get-stdin@npm:5.0.1" - checksum: 309f933f08a4d6783681674451027802299124e596324cd628c5e5138bbc5de843bbaa345a8ce0fc72304869f9de3b50086407aca551e292b13f7cb02351479e - languageName: node - linkType: hard - "get-stdin@npm:^6.0.0": version: 6.0.0 resolution: "get-stdin@npm:6.0.0" @@ -18373,13 +17787,6 @@ __metadata: languageName: node linkType: hard -"glur@npm:^1.1.2": - version: 1.1.2 - resolution: "glur@npm:1.1.2" - checksum: 756fcbc7f1a8576755811e31367feeaffbd13b7f20d788672bccbd65956839065e256621a7576f4ab321352b28a0aea442d64567bca23882526b891767ffbe3e - languageName: node - linkType: hard - "google-auth-library@npm:^7.14.0": version: 7.14.1 resolution: "google-auth-library@npm:7.14.1" @@ -18880,16 +18287,6 @@ __metadata: languageName: node linkType: hard -"html-element-map@npm:^1.2.0": - version: 1.3.1 - resolution: "html-element-map@npm:1.3.1" - dependencies: - array.prototype.filter: ^1.0.0 - call-bind: ^1.0.2 - checksum: 5ae8b37546601864eb41363a05871a896df36e59714607b1386a114d45f1c6b6cd1633d6fb09e09e5ee0f1c909d6b9c1bbca831333b8eef936312f61b1b5ecb8 - languageName: node - linkType: hard - "html-encoding-sniffer@npm:^2.0.1": version: 2.0.1 resolution: "html-encoding-sniffer@npm:2.0.1" @@ -18985,20 +18382,6 @@ __metadata: languageName: node linkType: hard -"htmlparser2@npm:^3.9.2": - version: 3.10.1 - resolution: "htmlparser2@npm:3.10.1" - dependencies: - domelementtype: ^1.3.1 - domhandler: ^2.3.0 - domutils: ^1.5.1 - entities: ^1.1.1 - inherits: ^2.0.1 - readable-stream: ^3.1.1 - checksum: b1424536ff062088501efa06a2afd478545d3134a5ad2e28bbe02dc2d092784982286b90f1c87fa3d86692958dbfb8936352dfd71d1cb2ff7cb61208c00fcdb1 - languageName: node - linkType: hard - "htmlparser2@npm:^6.1.0": version: 6.1.0 resolution: "htmlparser2@npm:6.1.0" @@ -19023,7 +18406,7 @@ __metadata: languageName: node linkType: hard -"htmlparser2@npm:^8.0.1, htmlparser2@npm:^8.0.2": +"htmlparser2@npm:^8.0.2": version: 8.0.2 resolution: "htmlparser2@npm:8.0.2" dependencies: @@ -19663,7 +19046,7 @@ __metadata: languageName: node linkType: hard -"is-boolean-object@npm:^1.0.1, is-boolean-object@npm:^1.1.0": +"is-boolean-object@npm:^1.1.0": version: 1.1.2 resolution: "is-boolean-object@npm:1.1.2" dependencies: @@ -19687,7 +19070,7 @@ __metadata: languageName: node linkType: hard -"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.1.5, is-callable@npm:^1.2.7": +"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" checksum: ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f @@ -20060,7 +19443,7 @@ __metadata: languageName: node linkType: hard -"is-regex@npm:^1.0.3, is-regex@npm:^1.0.4, is-regex@npm:^1.0.5, is-regex@npm:^1.1.0, is-regex@npm:^1.1.4": +"is-regex@npm:^1.0.3, is-regex@npm:^1.0.4, is-regex@npm:^1.1.4": version: 1.1.4 resolution: "is-regex@npm:1.1.4" dependencies: @@ -20132,13 +19515,6 @@ __metadata: languageName: node linkType: hard -"is-subset@npm:^0.1.1": - version: 0.1.1 - resolution: "is-subset@npm:0.1.1" - checksum: d8125598ab9077a76684e18726fb915f5cea7a7358ed0c6ff723f4484d71a0a9981ee5aae06c44de99cfdef0fefce37438c6257ab129e53c82045ea0c2acdebf - languageName: node - linkType: hard - "is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": version: 1.0.4 resolution: "is-symbol@npm:1.0.4" @@ -20544,7 +19920,7 @@ __metadata: languageName: node linkType: hard -"jest-environment-jsdom@npm:^29.0.0, jest-environment-jsdom@npm:^29.5.0": +"jest-environment-jsdom@npm:^29.0.0": version: 29.7.0 resolution: "jest-environment-jsdom@npm:29.7.0" dependencies: @@ -20616,39 +19992,6 @@ __metadata: languageName: node linkType: hard -"jest-image-snapshot@npm:^6.0.0": - version: 6.2.0 - resolution: "jest-image-snapshot@npm:6.2.0" - dependencies: - chalk: ^4.0.0 - get-stdin: ^5.0.1 - glur: ^1.1.2 - lodash: ^4.17.4 - pixelmatch: ^5.1.0 - pngjs: ^3.4.0 - rimraf: ^2.6.2 - ssim.js: ^3.1.1 - peerDependencies: - jest: ">=20 <=29" - peerDependenciesMeta: - jest: - optional: true - checksum: 62e415f86f2bed30fe126520519014beed61a38a678285de44c6544d10eed7381b28958d3406f131a60c05715f42ab7bf7ea4ecfdab4f55946cec6739de23924 - languageName: node - linkType: hard - -"jest-junit@npm:^16.0.0": - version: 16.0.0 - resolution: "jest-junit@npm:16.0.0" - dependencies: - mkdirp: ^1.0.4 - strip-ansi: ^6.0.1 - uuid: ^8.3.2 - xml: ^1.0.1 - checksum: d813d4d142341c2b51b634db7ad6ceb9849514cb58f96ec5e7e4cf4031a557133490452710c2d9dec9b1dd546334d9ca663e042d3070c3e8f102ce6217bd8e2e - languageName: node - linkType: hard - "jest-leak-detector@npm:^29.7.0": version: 29.7.0 resolution: "jest-leak-detector@npm:29.7.0" @@ -20765,7 +20108,7 @@ __metadata: languageName: node linkType: hard -"jest-regex-util@npm:^29.0.0, jest-regex-util@npm:^29.6.3": +"jest-regex-util@npm:^29.6.3": version: 29.6.3 resolution: "jest-regex-util@npm:29.6.3" checksum: 4e33fb16c4f42111159cafe26397118dcfc4cf08bc178a67149fb05f45546a91928b820894572679d62559839d0992e21080a1527faad65daaae8743a5705a3b @@ -20858,15 +20201,6 @@ __metadata: languageName: node linkType: hard -"jest-serializer-html@npm:^7.1.0": - version: 7.1.0 - resolution: "jest-serializer-html@npm:7.1.0" - dependencies: - diffable-html: ^4.1.0 - checksum: e8383431fbacd5ebb9a7c053c849a0d1e0a183e625aba1ede726260186931b229468dc6456b9b821a137123a88ea3b4325884a5c01c5d78b39c106c3d5c18fcc - languageName: node - linkType: hard - "jest-snapshot@npm:^29.0.0, jest-snapshot@npm:^29.7.0": version: 29.7.0 resolution: "jest-snapshot@npm:29.7.0" @@ -20934,39 +20268,7 @@ __metadata: languageName: node linkType: hard -"jest-vue-preprocessor@npm:^1.7.1": - version: 1.7.1 - resolution: "jest-vue-preprocessor@npm:1.7.1" - dependencies: - babel-plugin-transform-runtime: 6.23.0 - find-babel-config: 1.2.0 - vue-property-decorator: 8.3.0 - peerDependencies: - typescript: "*" - vue-template-compiler: 2.6.x - vue-template-es2015-compiler: 1.9.x - checksum: 2e8ae5af00fd41eef5e8d9b6408f7729d6a9d984a7d7d67a6532bc214490a9038297e34592c14b4260fd2262e657e8b5a09dfe2f97c5560509b63aba9e3f79e0 - languageName: node - linkType: hard - -"jest-watch-typeahead@npm:^2.2.1": - version: 2.2.2 - resolution: "jest-watch-typeahead@npm:2.2.2" - dependencies: - ansi-escapes: ^6.0.0 - chalk: ^5.2.0 - jest-regex-util: ^29.0.0 - jest-watcher: ^29.0.0 - slash: ^5.0.0 - string-length: ^5.0.1 - strip-ansi: ^7.0.1 - peerDependencies: - jest: ^27.0.0 || ^28.0.0 || ^29.0.0 - checksum: 5a55a571d616958cd6c6b52c4bf57cfaa97132cd9681af8ebfa8ebde9fa1d829426ff36f4ef2eaa867142ee97577fdad1735c58c3db62cbb33a39ad97125ee00 - languageName: node - linkType: hard - -"jest-watcher@npm:^29.0.0, jest-watcher@npm:^29.7.0": +"jest-watcher@npm:^29.7.0": version: 29.7.0 resolution: "jest-watcher@npm:29.7.0" dependencies: @@ -21005,7 +20307,7 @@ __metadata: languageName: node linkType: hard -"jest@npm:^29.3.1, jest@npm:^29.5.0": +"jest@npm:^29.3.1": version: 29.7.0 resolution: "jest@npm:29.7.0" dependencies: @@ -22103,13 +21405,6 @@ __metadata: languageName: node linkType: hard -"lodash.escape@npm:^4.0.1": - version: 4.0.1 - resolution: "lodash.escape@npm:4.0.1" - checksum: 90ade409cec05b6869090476952fdfb84d4d87b1ff4a0e03ebd590f980d9a1248d93ba14579f10d80c6429e4d6af13ba137c28db64cae6dadb71442e54a3ad2b - languageName: node - linkType: hard - "lodash.find@npm:^4.6.0": version: 4.6.0 resolution: "lodash.find@npm:4.6.0" @@ -22117,13 +21412,6 @@ __metadata: languageName: node linkType: hard -"lodash.flattendeep@npm:^4.4.0": - version: 4.4.0 - resolution: "lodash.flattendeep@npm:4.4.0" - checksum: 83cb80754b921fb4ed2c222b91a82b2524f3bdc60c3ae91e00688bd4bf1bcc28b8a2cc250e11fdc1b6da3a2de09e57008e13f15a209cafdd4f9163d047f97544 - languageName: node - linkType: hard - "lodash.includes@npm:^4.3.0": version: 4.3.0 resolution: "lodash.includes@npm:4.3.0" @@ -22138,13 +21426,6 @@ __metadata: languageName: node linkType: hard -"lodash.isequal@npm:^4.5.0": - version: 4.5.0 - resolution: "lodash.isequal@npm:4.5.0" - checksum: dfdb2356db19631a4b445d5f37868a095e2402292d59539a987f134a8778c62a2810c2452d11ae9e6dcac71fc9de40a6fedcb20e2952a15b431ad8b29e50e28f - languageName: node - linkType: hard - "lodash.isinteger@npm:^4.0.4": version: 4.0.4 resolution: "lodash.isinteger@npm:4.0.4" @@ -22236,7 +21517,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.13, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:^4.7.0": +"lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.7.0": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c @@ -23853,13 +23134,6 @@ __metadata: languageName: node linkType: hard -"moo@npm:^0.5.0": - version: 0.5.2 - resolution: "moo@npm:0.5.2" - checksum: a9d9ad8198a51fe35d297f6e9fdd718298ca0b39a412e868a0ebd92286379ab4533cfc1f1f34516177f5129988ab25fe598f78e77c84e3bfe0d4a877b56525a8 - languageName: node - linkType: hard - "mount-point@npm:^3.0.0": version: 3.0.0 resolution: "mount-point@npm:3.0.0" @@ -24012,23 +23286,6 @@ __metadata: languageName: node linkType: hard -"nearley@npm:^2.7.10": - version: 2.20.1 - resolution: "nearley@npm:2.20.1" - dependencies: - commander: ^2.19.0 - moo: ^0.5.0 - railroad-diagrams: ^1.0.0 - randexp: 0.4.6 - bin: - nearley-railroad: bin/nearley-railroad.js - nearley-test: bin/nearley-test.js - nearley-unparse: bin/nearley-unparse.js - nearleyc: bin/nearleyc.js - checksum: d25e1fd40b19c53a0ada6a688670f4a39063fd9553ab62885e81a82927d51572ce47193b946afa3d85efa608ba2c68f433c421f69b854bfb7f599eacb5fae37e - languageName: node - linkType: hard - "needle@npm:^3.1.0": version: 3.2.0 resolution: "needle@npm:3.2.0" @@ -24880,14 +24137,14 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.12.3, object-inspect@npm:^1.7.0, object-inspect@npm:^1.9.0": +"object-inspect@npm:^1.12.3, object-inspect@npm:^1.9.0": version: 1.12.3 resolution: "object-inspect@npm:1.12.3" checksum: 752bb5f4dc595e214157ea8f442adb77bdb850ace762b078d151d8b6486331ab12364997a89ee6509be1023b15adf2b3774437a7105f8a5043dfda11ed622411 languageName: node linkType: hard -"object-is@npm:^1.0.1, object-is@npm:^1.0.2, object-is@npm:^1.1.2, object-is@npm:^1.1.5": +"object-is@npm:^1.0.1, object-is@npm:^1.1.5": version: 1.1.5 resolution: "object-is@npm:1.1.5" dependencies: @@ -24920,7 +24177,7 @@ __metadata: languageName: node linkType: hard -"object.assign@npm:^4.1.0, object.assign@npm:^4.1.2, object.assign@npm:^4.1.4": +"object.assign@npm:^4.1.2, object.assign@npm:^4.1.4": version: 4.1.4 resolution: "object.assign@npm:4.1.4" dependencies: @@ -24932,7 +24189,7 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.1, object.entries@npm:^1.1.2, object.entries@npm:^1.1.6": +"object.entries@npm:^1.1.2, object.entries@npm:^1.1.6": version: 1.1.7 resolution: "object.entries@npm:1.1.7" dependencies: @@ -24943,7 +24200,7 @@ __metadata: languageName: node linkType: hard -"object.fromentries@npm:^2.0.5, object.fromentries@npm:^2.0.6": +"object.fromentries@npm:^2.0.6": version: 2.0.7 resolution: "object.fromentries@npm:2.0.7" dependencies: @@ -24985,7 +24242,7 @@ __metadata: languageName: node linkType: hard -"object.values@npm:^1.1.1, object.values@npm:^1.1.5, object.values@npm:^1.1.6": +"object.values@npm:^1.1.6": version: 1.1.7 resolution: "object.values@npm:1.1.7" dependencies: @@ -25605,16 +24862,6 @@ __metadata: languageName: node linkType: hard -"parse5-htmlparser2-tree-adapter@npm:^7.0.0": - version: 7.0.0 - resolution: "parse5-htmlparser2-tree-adapter@npm:7.0.0" - dependencies: - domhandler: ^5.0.2 - parse5: ^7.0.0 - checksum: e820cacb8486e6f7ede403327d18480df086d70e32ede2f6654d8c3a8b4b8dc4a4d5c21c03c18a92ba2466c513b93ca63be4a138dd73cd0995f384eb3b9edf11 - languageName: node - linkType: hard - "parse5-sax-parser@npm:^7.0.0": version: 7.0.0 resolution: "parse5-sax-parser@npm:7.0.0" @@ -25949,17 +25196,6 @@ __metadata: languageName: node linkType: hard -"pixelmatch@npm:^5.1.0": - version: 5.3.0 - resolution: "pixelmatch@npm:5.3.0" - dependencies: - pngjs: ^6.0.0 - bin: - pixelmatch: bin/pixelmatch - checksum: 30850661db29b57cefbe6cf36e930b7517aea4e0ed129e85fcc8ec04a7e6e7648a822a972f8e01d2d3db268ca3c735555caf6b8099a164d8b64d105986d682d2 - languageName: node - linkType: hard - "pkg-dir@npm:^3.0.0": version: 3.0.0 resolution: "pkg-dir@npm:3.0.0" @@ -26052,20 +25288,6 @@ __metadata: languageName: node linkType: hard -"pngjs@npm:^3.4.0": - version: 3.4.0 - resolution: "pngjs@npm:3.4.0" - checksum: 88ee73e2ad3f736e0b2573722309eb80bd2aa28916f0862379b4fd0f904751b4f61bb6bd1ecd7d4242d331f2b5c28c13309dd4b7d89a9b78306e35122fdc5011 - languageName: node - linkType: hard - -"pngjs@npm:^6.0.0": - version: 6.0.0 - resolution: "pngjs@npm:6.0.0" - checksum: ac23ea329b1881d1a10575aff58116dc27b894ec3f5b84ba15c7f527d21e609fbce7ba16d48f8ccb86c7ce45ceed622472765476ab2875949d4bec55e153f87a - languageName: node - linkType: hard - "pnp-webpack-plugin@npm:^1.7.0": version: 1.7.0 resolution: "pnp-webpack-plugin@npm:1.7.0" @@ -26294,17 +25516,6 @@ __metadata: languageName: node linkType: hard -"preact-render-to-string@npm:^5.1.19": - version: 5.2.6 - resolution: "preact-render-to-string@npm:5.2.6" - dependencies: - pretty-format: ^3.8.0 - peerDependencies: - preact: ">=10" - checksum: fb40f952f377900d87d3274e8ede1b59271347f7a3f41ae390aedeb088d162fe15f0a8040272404bd4477551cc2ec83b8a661e2fd3084702498b1543bb08dd11 - languageName: node - linkType: hard - "preact@npm:^10.5.13": version: 10.17.1 resolution: "preact@npm:10.17.1" @@ -26420,13 +25631,6 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^3.8.0": - version: 3.8.0 - resolution: "pretty-format@npm:3.8.0" - checksum: 69f12937bfb7b2a537a7463b9f875a16322401f1e44d7702d643faa0d21991126c24c093217ef6da403b54c15942a834174fa1c016b72e2cb9edaae6bb3729b6 - languageName: node - linkType: hard - "pretty-hrtime@npm:^1.0.3": version: 1.0.3 resolution: "pretty-hrtime@npm:1.0.3" @@ -26584,17 +25788,6 @@ __metadata: languageName: node linkType: hard -"prop-types-exact@npm:^1.2.0": - version: 1.2.0 - resolution: "prop-types-exact@npm:1.2.0" - dependencies: - has: ^1.0.3 - object.assign: ^4.1.0 - reflect.ownkeys: ^0.2.0 - checksum: 71e186c5b982f72b8226f052b710ef6b87fff7275fcf5834b4913fa5b6c325c44be111488786fd3c4e422fb4bb4e91f3c7f35445366c9a4585405d3b02872587 - languageName: node - linkType: hard - "prop-types@npm:^15.5.10, prop-types@npm:^15.6.1, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" @@ -26871,24 +26064,6 @@ __metadata: languageName: node linkType: hard -"puppeteer@npm:^2.0.0 || ^3.0.0": - version: 3.3.0 - resolution: "puppeteer@npm:3.3.0" - dependencies: - debug: ^4.1.0 - extract-zip: ^2.0.0 - https-proxy-agent: ^4.0.0 - mime: ^2.0.3 - progress: ^2.0.1 - proxy-from-env: ^1.0.0 - rimraf: ^3.0.2 - tar-fs: ^2.0.0 - unbzip2-stream: ^1.3.3 - ws: ^7.2.3 - checksum: 9f8d7f00458425f9ca42580f509f5406ddf27767dbf93080d05157a7882efaf0e32c77e540c8a4d2bd295ab11584a8447d9e6593d6316bf04ce1a16d6fd11b4e - languageName: node - linkType: hard - "pure-rand@npm:^6.0.0": version: 6.0.3 resolution: "pure-rand@npm:6.0.3" @@ -27004,13 +26179,6 @@ __metadata: languageName: node linkType: hard -"railroad-diagrams@npm:^1.0.0": - version: 1.0.0 - resolution: "railroad-diagrams@npm:1.0.0" - checksum: 81bf8f86870a69fb9ed243102db9ad6416d09c4cb83964490d44717690e07dd982f671503236a1f8af28f4cb79d5d7a87613930f10ac08defa845ceb6764e364 - languageName: node - linkType: hard - "ramda@npm:0.29.0": version: 0.29.0 resolution: "ramda@npm:0.29.0" @@ -27018,16 +26186,6 @@ __metadata: languageName: node linkType: hard -"randexp@npm:0.4.6": - version: 0.4.6 - resolution: "randexp@npm:0.4.6" - dependencies: - discontinuous-range: 1.0.0 - ret: ~0.1.10 - checksum: 14ee14b6d7f5ce69609b51cc914fb7a7c82ad337820a141c5f762c5ad1fe868f5191ea6e82359aee019b625ee1359486628fa833909d12c3b5dd9571908c3345 - languageName: node - linkType: hard - "randombytes@npm:^2.0.0, randombytes@npm:^2.0.1, randombytes@npm:^2.0.5, randombytes@npm:^2.1.0": version: 2.1.0 resolution: "randombytes@npm:2.1.0" @@ -27221,7 +26379,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.12.0, react-is@npm:^16.13.1, react-is@npm:^16.7.0, react-is@npm:^16.8.6": +"react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: 33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1 @@ -27446,20 +26604,6 @@ __metadata: languageName: node linkType: hard -"react-test-renderer@npm:^16, react-test-renderer@npm:^16.0.0-0": - version: 16.14.0 - resolution: "react-test-renderer@npm:16.14.0" - dependencies: - object-assign: ^4.1.1 - prop-types: ^15.6.2 - react-is: ^16.8.6 - scheduler: ^0.19.1 - peerDependencies: - react: ^16.14.0 - checksum: 119e3ce5509c3443393ca750e39dd4ac9ee9ddfaafca58c9067b477447edc2badb75660b9fea7e9ddef012e37bbba427681cf6f8d3fde61b8054655a133bfbf5 - languageName: node - linkType: hard - "react-textarea-autosize@npm:^8.3.0": version: 8.5.3 resolution: "react-textarea-autosize@npm:8.5.3" @@ -27775,13 +26919,6 @@ __metadata: languageName: node linkType: hard -"reflect.ownkeys@npm:^0.2.0": - version: 0.2.0 - resolution: "reflect.ownkeys@npm:0.2.0" - checksum: 169f20287ad33b76fc8b6932734b3e1469ee59f31d8357858e96718a6f71fa60d7a13f2fc4e9191e47c2a51e4183151290f3a35315ba461190d87b0593725557 - languageName: node - linkType: hard - "refractor@npm:^3.6.0": version: 3.6.0 resolution: "refractor@npm:3.6.0" @@ -27809,13 +26946,6 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.11.0": - version: 0.11.1 - resolution: "regenerator-runtime@npm:0.11.1" - checksum: 69cfa839efcf2d627fe358bf302ab8b24e5f182cb69f13e66f0612d3640d7838aad1e55662135e3ef2c1cc4322315b757626094fab13a48f9a64ab4bdeb8795b - languageName: node - linkType: hard - "regenerator-runtime@npm:^0.13.11, regenerator-runtime@npm:^0.13.2, regenerator-runtime@npm:^0.13.4, regenerator-runtime@npm:^0.13.9": version: 0.13.11 resolution: "regenerator-runtime@npm:0.13.11" @@ -28430,7 +27560,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.13.1, resolve@npm:^1.14.2, resolve@npm:^1.15.1, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.4, resolve@npm:^1.3.2, resolve@npm:^1.4.0": +"resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.13.1, resolve@npm:^1.14.2, resolve@npm:^1.15.1, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.4, resolve@npm:^1.4.0": version: 1.22.4 resolution: "resolve@npm:1.22.4" dependencies: @@ -28469,7 +27599,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.13.1#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.15.1#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.3.2#~builtin, resolve@patch:resolve@^1.4.0#~builtin": +"resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.13.1#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.15.1#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.4.0#~builtin": version: 1.22.4 resolution: "resolve@patch:resolve@npm%3A1.22.4#~builtin::version=1.22.4&hash=c3c19d" dependencies: @@ -28637,16 +27767,6 @@ __metadata: languageName: node linkType: hard -"rst-selector-parser@npm:^2.2.3": - version: 2.2.3 - resolution: "rst-selector-parser@npm:2.2.3" - dependencies: - lodash.flattendeep: ^4.4.0 - nearley: ^2.7.10 - checksum: b631aca2cb451fbde8d78dbc9a9479f20f1f40565cd8eb63773cb6e2a395ed87b392291986b84c2c7da68b70084e3469fbe958261300a10dff41c87fa3bc58aa - languageName: node - linkType: hard - "rsvp@npm:^3.0.14, rsvp@npm:^3.0.18": version: 3.6.2 resolution: "rsvp@npm:3.6.2" @@ -28693,7 +27813,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^6.5.2, rxjs@npm:^6.6.3": +"rxjs@npm:^6.5.2": version: 6.6.7 resolution: "rxjs@npm:6.6.7" dependencies: @@ -28957,7 +28077,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.3.0, semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.6.0, semver@npm:^5.7.0, semver@npm:^5.7.1": +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.3.0, semver@npm:^5.5.0, semver@npm:^5.6.0": version: 5.7.2 resolution: "semver@npm:5.7.2" bin: @@ -29450,7 +28570,7 @@ __metadata: languageName: node linkType: hard -"source-map-resolve@npm:^0.5.0, source-map-resolve@npm:^0.5.2": +"source-map-resolve@npm:^0.5.0": version: 0.5.3 resolution: "source-map-resolve@npm:0.5.3" dependencies: @@ -29537,7 +28657,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.5.0, source-map@npm:^0.5.6, source-map@npm:^0.5.7": +"source-map@npm:^0.5.6, source-map@npm:^0.5.7": version: 0.5.7 resolution: "source-map@npm:0.5.7" checksum: 904e767bb9c494929be013017380cbba013637da1b28e5943b566031e29df04fba57edf3f093e0914be094648b577372bd8ad247fa98cfba9c600794cd16b599 @@ -29626,15 +28746,6 @@ __metadata: languageName: node linkType: hard -"specificity@npm:^0.4.1": - version: 0.4.1 - resolution: "specificity@npm:0.4.1" - bin: - specificity: ./bin/specificity - checksum: 5da85a05052b55e344cb0f5bce5d07cbabbbe8945da176a481589db5a13e9fbcfa879ceb075cf564b94e680fae0a2ab14ea55cc87496b86a6d5122545946d7c2 - languageName: node - linkType: hard - "split-on-first@npm:^1.0.0": version: 1.1.0 resolution: "split-on-first@npm:1.1.0" @@ -29683,13 +28794,6 @@ __metadata: languageName: node linkType: hard -"ssim.js@npm:^3.1.1": - version: 3.5.0 - resolution: "ssim.js@npm:3.5.0" - checksum: 9e7101da17395d3acbd417aac712d8f156522e79059a27cb38882eedd5a8868e31871c8f58bec3a150f8cf0660883cf22310cbd2fd63b408c1fd0ab02fda9fbc - languageName: node - linkType: hard - "ssri@npm:9.0.1, ssri@npm:^9.0.0": version: 9.0.1 resolution: "ssri@npm:9.0.1" @@ -29865,16 +28969,6 @@ __metadata: languageName: node linkType: hard -"string-length@npm:^5.0.1": - version: 5.0.1 - resolution: "string-length@npm:5.0.1" - dependencies: - char-regex: ^2.0.0 - strip-ansi: ^7.0.1 - checksum: 311fa5758d397bd616be17150dfefaab4755ed292a3112237924d10ba5122f606064ad4880a293387401c1d7aa20d79f7936728bac2abed17a5e48f5b317cbc8 - languageName: node - linkType: hard - "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -29924,7 +29018,7 @@ __metadata: languageName: node linkType: hard -"string.prototype.trim@npm:^1.2.1, string.prototype.trim@npm:^1.2.7": +"string.prototype.trim@npm:^1.2.7": version: 1.2.8 resolution: "string.prototype.trim@npm:1.2.8" dependencies: @@ -30385,7 +29479,7 @@ __metadata: languageName: node linkType: hard -"tar-fs@npm:^2.0.0, tar-fs@npm:^2.1.1": +"tar-fs@npm:^2.1.1": version: 2.1.1 resolution: "tar-fs@npm:2.1.1" dependencies: @@ -30610,7 +29704,7 @@ __metadata: languageName: node linkType: hard -"through@npm:2, through@npm:>=2.2.7 <3, through@npm:^2.3.4, through@npm:^2.3.6, through@npm:^2.3.8": +"through@npm:2, through@npm:>=2.2.7 <3, through@npm:^2.3.4, through@npm:^2.3.6": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: 4b09f3774099de0d4df26d95c5821a62faee32c7e96fb1f4ebd54a2d7c11c57fe88b0a0d49cf375de5fee5ae6bf4eb56dbbf29d07366864e2ee805349970d3cc @@ -31299,16 +30393,6 @@ __metadata: languageName: node linkType: hard -"unbzip2-stream@npm:^1.3.3": - version: 1.4.3 - resolution: "unbzip2-stream@npm:1.4.3" - dependencies: - buffer: ^5.2.1 - through: ^2.3.8 - checksum: 2ea2048f3c9db3499316ccc1d95ff757017ccb6f46c812d7c42466247e3b863fb178864267482f7f178254214247779daf68e85f50bd7736c3c97ba2d58b910a - languageName: node - linkType: hard - "underscore.string@npm:~3.3.4": version: 3.3.6 resolution: "underscore.string@npm:3.3.6" @@ -32378,15 +31462,6 @@ __metadata: languageName: node linkType: hard -"vue-class-component@npm:^7.1.0": - version: 7.2.6 - resolution: "vue-class-component@npm:7.2.6" - peerDependencies: - vue: ^2.0.0 - checksum: 2c187815e3569b4836929dc45ace5715398c4037312ef5fc27da9cb12fbbc21cabbdfc5fb678451ad45321ffabacbd184907e33db2539c13963c00883a6645c1 - languageName: node - linkType: hard - "vue-component-type-helpers@npm:latest": version: 1.8.10 resolution: "vue-component-type-helpers@npm:1.8.10" @@ -32444,32 +31519,6 @@ __metadata: languageName: node linkType: hard -"vue-jest@npm:^5.0.0-alpha.8": - version: 5.0.0-alpha.10 - resolution: "vue-jest@npm:5.0.0-alpha.10" - dependencies: - "@babel/plugin-transform-modules-commonjs": ^7.2.0 - chalk: ^2.1.0 - convert-source-map: ^1.6.0 - extract-from-css: ^0.4.4 - source-map: 0.5.6 - tsconfig: ^7.0.0 - peerDependencies: - "@babel/core": 7.x - babel-jest: ">= 24 < 27" - jest: ">= 24 < 27 " - ts-jest: ">= 24 < 27 " - typescript: ">= 3.x" - vue: ^3.0.0-0 - peerDependenciesMeta: - ts-jest: - optional: true - typescript: - optional: true - checksum: dd2dabd4ab4030d7fe567304ba035f61e0abe48501a18b9a3e331e60aac44a03f782746859347ea0cfeb906b8dcf5d5ca58b854c9656ea2feee08e8f00f7c54b - languageName: node - linkType: hard - "vue-loader@npm:^15.7.0": version: 15.10.2 resolution: "vue-loader@npm:15.10.2" @@ -32506,15 +31555,6 @@ __metadata: languageName: node linkType: hard -"vue-property-decorator@npm:8.3.0": - version: 8.3.0 - resolution: "vue-property-decorator@npm:8.3.0" - dependencies: - vue-class-component: ^7.1.0 - checksum: 8e0c9ece0a5bb2e8b24bfa9f6516731feabe44773bf75bfdf66ce5cbb59c30fc837d4dbe2b2edf991b12d78fc75b57a76346ca658d561172935eb51db244fc3d - languageName: node - linkType: hard - "vue-style-loader@npm:^4.1.0": version: 4.1.3 resolution: "vue-style-loader@npm:4.1.3" @@ -33358,7 +32398,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^7.2.3, ws@npm:^7.4.6": +"ws@npm:^7.4.6": version: 7.5.9 resolution: "ws@npm:7.5.9" peerDependencies: @@ -33428,13 +32468,6 @@ __metadata: languageName: node linkType: hard -"xml@npm:^1.0.1": - version: 1.0.1 - resolution: "xml@npm:1.0.1" - checksum: 04bcc9b8b5e7b49392072fbd9c6b0f0958bd8e8f8606fee460318e43991349a68cbc5384038d179ff15aef7d222285f69ca0f067f53d071084eb14c7fdb30411 - languageName: node - linkType: hard - "xmlchars@npm:^2.2.0": version: 2.2.0 resolution: "xmlchars@npm:2.2.0" From d91a91e81b21fe13e2819d4a825adae867f956b0 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Thu, 14 Sep 2023 18:31:02 +0200 Subject: [PATCH 010/105] more fixes --- .../cli/src/automigrate/fixes/mdx-gfm.test.ts | 2 +- .../cli/src/automigrate/fixes/vue3.test.ts | 27 +- .../inject-decorator.test.js.snap | 492 +++++++++--------- 3 files changed, 250 insertions(+), 271 deletions(-) diff --git a/code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts b/code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts index 52020fc4f793..c6db107066a6 100644 --- a/code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts +++ b/code/lib/cli/src/automigrate/fixes/mdx-gfm.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, vi } from 'vitest'; +import { describe, expect, vi, test } from 'vitest'; import type { StorybookConfig } from '@storybook/types'; import { mdxgfm } from './mdx-gfm'; diff --git a/code/lib/cli/src/automigrate/fixes/vue3.test.ts b/code/lib/cli/src/automigrate/fixes/vue3.test.ts index 790a02f64803..1f3c999d6196 100644 --- a/code/lib/cli/src/automigrate/fixes/vue3.test.ts +++ b/code/lib/cli/src/automigrate/fixes/vue3.test.ts @@ -21,32 +21,11 @@ const checkVue3 = async ({ }; describe('vue3 fix', () => { - afterEach(vi.restoreAllMocks); + afterEach(() => { + vi.restoreAllMocks(); + }); describe('sb < 6.3', () => { - describe('vue3 dependency', () => { - const packageManager = { - getPackageVersion: (packageName) => { - switch (packageName) { - case '@storybook/vue': - return Promise.resolve('6.2.0'); - case 'vue': - return Promise.resolve('3.0.0'); - default: - return null; - } - }, - } as Partial; - - it('should fail', async () => { - await expect( - checkVue3({ - packageManager, - storybookVersion: '6.2.0', - }) - ).rejects.toThrow(); - }); - }); describe('no vue dependency', () => { const packageManager = { getPackageVersion: (packageName) => { diff --git a/code/lib/source-loader/src/abstract-syntax-tree/__snapshots__/inject-decorator.test.js.snap b/code/lib/source-loader/src/abstract-syntax-tree/__snapshots__/inject-decorator.test.js.snap index f1d57185b39b..cda3309d6cc4 100644 --- a/code/lib/source-loader/src/abstract-syntax-tree/__snapshots__/inject-decorator.test.js.snap +++ b/code/lib/source-loader/src/abstract-syntax-tree/__snapshots__/inject-decorator.test.js.snap @@ -1,99 +1,6 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`inject-decorator injectDecorator option is false - angular does not inject stories decorator after the all "storiesOf" functions 1`] = ` -"import { Component } from '@angular/core'; -import { storiesOf } from '@storybook/angular'; - -@Component({ - selector: 'storybook-with-ng-content', - template: \`
\`, -}) -class WithNgContentComponent {} - -storiesOf('Custom|ng-content', module).add('Default', () => ({ - template: \`

This is rendered in ng-content

\`, - moduleMetadata: { - declarations: [WithNgContentComponent], - }, -})); -" -`; - -exports[`inject-decorator injectDecorator option is false - flow does not inject stories decorator after the all "storiesOf" functions 1`] = ` -"// @flow -import React from 'react'; -import { storiesOf } from '@storybook/react'; -import { withInfo } from '@storybook/addon-info'; - -import TableComponent from '../components/TableComponent'; - -import type { JssClasses } from '../types'; - -type State = { - value: any, -}; - -type Props = { - classes: JssClasses, - name: string, -}; - -class Table extends React.Component { - constructor(props) { - super(props); - this.state = { - value: undefined, - }; - } - - state: State; - - render() { - return ; - } -} - -const stories = storiesOf('Table', module); -stories.add('Flow Class', withInfo('Lorum Ipsum Nem')(() => )); -" -`; - -exports[`inject-decorator injectDecorator option is false - ts does not inject stories decorator after the all "storiesOf" functions 1`] = ` -"import { Component } from '@angular/core'; -import { Store, StoreModule } from '@ngrx/store'; -import { storiesOf, moduleMetadata } from '@storybook/angular'; - -@Component({ - selector: 'storybook-comp-with-store', - template: '
{{this.getStoreState()}}
', -}) -class WithStoreComponent { - private store: Store; - - constructor(store: Store) { - this.store = store; - } - - getStoreState(): string { - return this.store === undefined ? 'Store is NOT injected' : 'Store is injected'; - } -} - -storiesOf('ngrx|Store', module) - .addDecorator( - moduleMetadata({ - imports: [StoreModule.forRoot({})], - declarations: [WithStoreComponent], - }) - ) - .add('With component', () => { - return { - component: WithStoreComponent, - }; - });" -`; - -exports[`inject-decorator injectDecorator option is false does not inject stories decorator after the all "storiesOf" functions 1`] = ` +exports[`inject-decorator > injectDecorator option is false > does not inject stories decorator after the all "storiesOf" functions 1`] = ` "import React from 'react'; import { storiesOf } from '@storybook/react'; import { withInfo } from '@storybook/addon-info'; @@ -249,30 +156,7 @@ storiesOf('Addons|Info.GitHub issues', module).add( " `; -exports[`inject-decorator positive - angular calculates "adds" map 1`] = ` -Object { - "default": Object { - "endBody": Object { - "col": 2, - "line": 15, - }, - "endLoc": Object { - "col": 2, - "line": 15, - }, - "startBody": Object { - "col": 54, - "line": 10, - }, - "startLoc": Object { - "col": 43, - "line": 10, - }, - }, -} -`; - -exports[`inject-decorator positive - angular injects stories decorator after the all "storiesOf" functions 1`] = ` +exports[`inject-decorator > injectDecorator option is false - angular > does not inject stories decorator after the all "storiesOf" functions 1`] = ` "import { Component } from '@angular/core'; import { storiesOf } from '@storybook/angular'; @@ -282,7 +166,7 @@ import { storiesOf } from '@storybook/angular'; }) class WithNgContentComponent {} -storiesOf('Custom|ng-content', module).addParameters({ storySource: { source: __STORY__, locationsMap: __LOCATIONS_MAP__ } }).add('Default', () => ({ +storiesOf('Custom|ng-content', module).add('Default', () => ({ template: \`

This is rendered in ng-content

\`, moduleMetadata: { declarations: [WithNgContentComponent], @@ -291,30 +175,7 @@ storiesOf('Custom|ng-content', module).addParameters({ storySource: { source: __ " `; -exports[`inject-decorator positive - flow calculates "adds" map 1`] = ` -Object { - "flow-class": Object { - "endBody": Object { - "col": 70, - "line": 35, - }, - "endLoc": Object { - "col": 70, - "line": 35, - }, - "startBody": Object { - "col": 26, - "line": 35, - }, - "startLoc": Object { - "col": 12, - "line": 35, - }, - }, -} -`; - -exports[`inject-decorator positive - flow injects stories decorator after the all "storiesOf" functions 1`] = ` +exports[`inject-decorator > injectDecorator option is false - flow > does not inject stories decorator after the all "storiesOf" functions 1`] = ` "// @flow import React from 'react'; import { storiesOf } from '@storybook/react'; @@ -348,35 +209,12 @@ class Table extends React.Component { } } -const stories = storiesOf('Table', module).addParameters({ storySource: { source: __STORY__, locationsMap: __LOCATIONS_MAP__ } }); +const stories = storiesOf('Table', module); stories.add('Flow Class', withInfo('Lorum Ipsum Nem')(() =>
)); " `; -exports[`inject-decorator positive - ts calculates "adds" map 1`] = ` -Object { - "with-component": Object { - "endBody": Object { - "col": 3, - "line": 32, - }, - "endLoc": Object { - "col": 3, - "line": 32, - }, - "startBody": Object { - "col": 25, - "line": 28, - }, - "startLoc": Object { - "col": 7, - "line": 28, - }, - }, -} -`; - -exports[`inject-decorator positive - ts injects stories decorator after the all "storiesOf" functions 1`] = ` +exports[`inject-decorator > injectDecorator option is false - ts > does not inject stories decorator after the all "storiesOf" functions 1`] = ` "import { Component } from '@angular/core'; import { Store, StoreModule } from '@ngrx/store'; import { storiesOf, moduleMetadata } from '@storybook/angular'; @@ -397,7 +235,7 @@ class WithStoreComponent { } } -storiesOf('ngrx|Store', module).addParameters({ storySource: { source: __STORY__, locationsMap: __LOCATIONS_MAP__ } }) +storiesOf('ngrx|Store', module) .addDecorator( moduleMetadata({ imports: [StoreModule.forRoot({})], @@ -411,256 +249,256 @@ storiesOf('ngrx|Store', module).addParameters({ storySource: { source: __STORY__ });" `; -exports[`inject-decorator positive calculates "adds" map 1`] = ` -Object { - "1814": Object { - "endBody": Object { +exports[`inject-decorator > positive > calculates "adds" map 1`] = ` +{ + "1814": { + "endBody": { "col": 4, "line": 151, }, - "endLoc": Object { + "endLoc": { "col": 4, "line": 151, }, - "startBody": Object { + "startBody": { "col": 2, "line": 146, }, - "startLoc": Object { + "startLoc": { "col": 2, "line": 145, }, }, - "comments-from-component-declaration": Object { - "endBody": Object { + "comments-from-component-declaration": { + "endBody": { "col": 42, "line": 27, }, - "endLoc": Object { + "endLoc": { "col": 42, "line": 27, }, - "startBody": Object { + "startBody": { "col": 4, "line": 25, }, - "startLoc": Object { + "startLoc": { "col": 4, "line": 24, }, }, - "comments-from-flow-declarations": Object { - "endBody": Object { + "comments-from-flow-declarations": { + "endBody": { "col": 57, "line": 21, }, - "endLoc": Object { + "endLoc": { "col": 57, "line": 21, }, - "startBody": Object { + "startBody": { "col": 4, "line": 19, }, - "startLoc": Object { + "startLoc": { "col": 4, "line": 18, }, }, - "comments-from-proptype-declarations": Object { - "endBody": Object { + "comments-from-proptype-declarations": { + "endBody": { "col": 51, "line": 15, }, - "endLoc": Object { + "endLoc": { "col": 51, "line": 15, }, - "startBody": Object { + "startBody": { "col": 4, "line": 13, }, - "startLoc": Object { + "startLoc": { "col": 4, "line": 12, }, }, - "displays-markdown-in-description": Object { - "endBody": Object { + "displays-markdown-in-description": { + "endBody": { "col": 68, "line": 43, }, - "endLoc": Object { + "endLoc": { "col": 68, "line": 43, }, - "startBody": Object { + "startBody": { "col": 2, "line": 43, }, - "startLoc": Object { + "startLoc": { "col": 2, "line": 42, }, }, - "exclude-component-from-prop-tables": Object { - "endBody": Object { + "exclude-component-from-prop-tables": { + "endBody": { "col": 4, "line": 88, }, - "endLoc": Object { + "endLoc": { "col": 4, "line": 88, }, - "startBody": Object { + "startBody": { "col": 2, "line": 80, }, - "startLoc": Object { + "startLoc": { "col": 2, "line": 79, }, }, - "extend-info-styles-with-an-object": Object { - "endBody": Object { + "extend-info-styles-with-an-object": { + "endBody": { "col": 43, "line": 107, }, - "endLoc": Object { + "endLoc": { "col": 43, "line": 107, }, - "startBody": Object { + "startBody": { "col": 4, "line": 94, }, - "startLoc": Object { + "startLoc": { "col": 4, "line": 93, }, }, - "full-control-over-styles-using-a-function": Object { - "endBody": Object { + "full-control-over-styles-using-a-function": { + "endBody": { "col": 43, "line": 122, }, - "endLoc": Object { + "endLoc": { "col": 43, "line": 122, }, - "startBody": Object { + "startBody": { "col": 4, "line": 111, }, - "startLoc": Object { + "startLoc": { "col": 4, "line": 110, }, }, - "inlines-component-inside-story": Object { - "endBody": Object { + "inlines-component-inside-story": { + "endBody": { "col": 41, "line": 51, }, - "endLoc": Object { + "endLoc": { "col": 41, "line": 51, }, - "startBody": Object { + "startBody": { "col": 2, "line": 48, }, - "startLoc": Object { + "startLoc": { "col": 2, "line": 47, }, }, - "shows-additional-component-prop-tables": Object { - "endBody": Object { + "shows-additional-component-prop-tables": { + "endBody": { "col": 41, "line": 75, }, - "endLoc": Object { + "endLoc": { "col": 41, "line": 75, }, - "startBody": Object { + "startBody": { "col": 2, "line": 72, }, - "startLoc": Object { + "startLoc": { "col": 2, "line": 71, }, }, - "shows-or-hides-info-addon-header": Object { - "endBody": Object { + "shows-or-hides-info-addon-header": { + "endBody": { "col": 41, "line": 59, }, - "endLoc": Object { + "endLoc": { "col": 41, "line": 59, }, - "startBody": Object { + "startBody": { "col": 2, "line": 56, }, - "startLoc": Object { + "startLoc": { "col": 2, "line": 55, }, }, - "shows-or-hides-info-addon-source": Object { - "endBody": Object { + "shows-or-hides-info-addon-source": { + "endBody": { "col": 41, "line": 67, }, - "endLoc": Object { + "endLoc": { "col": 41, "line": 67, }, - "startBody": Object { + "startBody": { "col": 2, "line": 64, }, - "startLoc": Object { + "startLoc": { "col": 2, "line": 63, }, }, - "use-a-custom-component-for-the-table": Object { - "endBody": Object { + "use-a-custom-component-for-the-table": { + "endBody": { "col": 41, "line": 129, }, - "endLoc": Object { + "endLoc": { "col": 41, "line": 129, }, - "startBody": Object { + "startBody": { "col": 2, "line": 127, }, - "startLoc": Object { + "startLoc": { "col": 2, "line": 126, }, }, - "use-info-as-story-decorator": Object { - "endBody": Object { + "use-info-as-story-decorator": { + "endBody": { "col": 73, "line": 136, }, - "endLoc": Object { + "endLoc": { "col": 73, "line": 136, }, - "startBody": Object { + "startBody": { "col": 38, "line": 136, }, - "startLoc": Object { + "startLoc": { "col": 7, "line": 136, }, @@ -668,7 +506,7 @@ Object { } `; -exports[`inject-decorator positive injects stories decorator after the all "storiesOf" functions 1`] = ` +exports[`inject-decorator > positive > injects stories decorator after the all "storiesOf" functions 1`] = ` "import React from 'react'; import { storiesOf } from '@storybook/react'; import { withInfo } from '@storybook/addon-info'; @@ -824,10 +662,137 @@ storiesOf('Addons|Info.GitHub issues', module).addParameters({ storySource: { so " `; -exports[`inject-decorator stories with ugly comments in ts should delete ugly comments from the generated story source 1`] = ` +exports[`inject-decorator > positive - angular > calculates "adds" map 1`] = ` +{ + "default": { + "endBody": { + "col": 2, + "line": 15, + }, + "endLoc": { + "col": 2, + "line": 15, + }, + "startBody": { + "col": 54, + "line": 10, + }, + "startLoc": { + "col": 43, + "line": 10, + }, + }, +} +`; + +exports[`inject-decorator > positive - angular > injects stories decorator after the all "storiesOf" functions 1`] = ` +"import { Component } from '@angular/core'; +import { storiesOf } from '@storybook/angular'; + +@Component({ + selector: 'storybook-with-ng-content', + template: \`
\`, +}) +class WithNgContentComponent {} + +storiesOf('Custom|ng-content', module).addParameters({ storySource: { source: __STORY__, locationsMap: __LOCATIONS_MAP__ } }).add('Default', () => ({ + template: \`

This is rendered in ng-content

\`, + moduleMetadata: { + declarations: [WithNgContentComponent], + }, +})); " +`; +exports[`inject-decorator > positive - flow > calculates "adds" map 1`] = ` +{ + "flow-class": { + "endBody": { + "col": 70, + "line": 35, + }, + "endLoc": { + "col": 70, + "line": 35, + }, + "startBody": { + "col": 26, + "line": 35, + }, + "startLoc": { + "col": 12, + "line": 35, + }, + }, +} +`; + +exports[`inject-decorator > positive - flow > injects stories decorator after the all "storiesOf" functions 1`] = ` +"// @flow import React from 'react'; +import { storiesOf } from '@storybook/react'; +import { withInfo } from '@storybook/addon-info'; + +import TableComponent from '../components/TableComponent'; + +import type { JssClasses } from '../types'; + +type State = { + value: any, +}; + +type Props = { + classes: JssClasses, + name: string, +}; + +class Table extends React.Component { + constructor(props) { + super(props); + this.state = { + value: undefined, + }; + } + + state: State; + + render() { + return ; + } +} + +const stories = storiesOf('Table', module).addParameters({ storySource: { source: __STORY__, locationsMap: __LOCATIONS_MAP__ } }); +stories.add('Flow Class', withInfo('Lorum Ipsum Nem')(() =>
)); +" +`; + +exports[`inject-decorator > positive - ts > calculates "adds" map 1`] = ` +{ + "with-component": { + "endBody": { + "col": 3, + "line": 32, + }, + "endLoc": { + "col": 3, + "line": 32, + }, + "startBody": { + "col": 25, + "line": 28, + }, + "startLoc": { + "col": 7, + "line": 28, + }, + }, +} +`; + +exports[`inject-decorator > positive - ts > injects stories decorator after the all "storiesOf" functions 1`] = ` +"import { Component } from '@angular/core'; +import { Store, StoreModule } from '@ngrx/store'; +import { storiesOf, moduleMetadata } from '@storybook/angular'; @Component({ selector: 'storybook-comp-with-store', @@ -845,6 +810,25 @@ class WithStoreComponent { } } +storiesOf('ngrx|Store', module).addParameters({ storySource: { source: __STORY__, locationsMap: __LOCATIONS_MAP__ } }) + .addDecorator( + moduleMetadata({ + imports: [StoreModule.forRoot({})], + declarations: [WithStoreComponent], + }) + ) + .add('With component', () => { + return { + component: WithStoreComponent, + }; + });" +`; + +exports[`inject-decorator > stories with ugly comments > should delete ugly comments from the generated story source 1`] = ` +" + +import React from 'react'; + import { storiesOf } from '@storybook/react'; @@ -861,11 +845,27 @@ storiesOf('Foo', module) */" `; -exports[`inject-decorator stories with ugly comments should delete ugly comments from the generated story source 1`] = ` +exports[`inject-decorator > stories with ugly comments in ts > should delete ugly comments from the generated story source 1`] = ` " import React from 'react'; +@Component({ + selector: 'storybook-comp-with-store', + template: '
{{this.getStoreState()}}
', +}) +class WithStoreComponent { + private store: Store; + + constructor(store: Store) { + this.store = store; + } + + getStoreState(): string { + return this.store === undefined ? 'Store is NOT injected' : 'Store is injected'; + } +} + import { storiesOf } from '@storybook/react'; @@ -882,7 +882,7 @@ storiesOf('Foo', module) */" `; -exports[`inject-decorator will not change the source when there are no "storiesOf" functions 1`] = ` +exports[`inject-decorator > will not change the source when there are no "storiesOf" functions 1`] = ` "while(true) { console.log(\\"it's a kind of magic\\"); }" From 604a4421f24b6bce4d42f4ac89b64c928f36e02c Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 14 Sep 2023 18:31:06 +0200 Subject: [PATCH 011/105] progress on fixes --- code/__mocks__/fs-extra.js | 37 - code/__mocks__/fs-extra.ts | 30 + .../modules/store/csf/normalizeStory.test.ts | 70 +- code/yarn.lock | 1079 +---------------- scripts/__mocks__/simple-git.js | 18 - scripts/__mocks__/simple-git.ts | 18 + scripts/__mocks__/uuid.ts | 4 +- .../__tests__/generate-pr-description.test.ts | 115 +- .../release/__tests__/is-pr-frozen.test.ts | 40 +- .../release/__tests__/label-patches.test.ts | 12 +- scripts/release/__tests__/version.test.ts | 4 - .../release/__tests__/write-changelog.test.ts | 42 +- .../utils/__mocks__/get-github-info.js | 4 - .../utils/__mocks__/get-github-info.ts | 4 + scripts/release/utils/get-changes.ts | 1 + scripts/vitest.config.ts | 6 +- 16 files changed, 258 insertions(+), 1226 deletions(-) delete mode 100644 code/__mocks__/fs-extra.js create mode 100644 code/__mocks__/fs-extra.ts delete mode 100644 scripts/__mocks__/simple-git.js create mode 100644 scripts/__mocks__/simple-git.ts delete mode 100644 scripts/release/utils/__mocks__/get-github-info.js create mode 100644 scripts/release/utils/__mocks__/get-github-info.ts diff --git a/code/__mocks__/fs-extra.js b/code/__mocks__/fs-extra.js deleted file mode 100644 index 7e18c3ead80d..000000000000 --- a/code/__mocks__/fs-extra.js +++ /dev/null @@ -1,37 +0,0 @@ -const fs = jest.createMockFromModule('fs-extra'); - -// This is a custom function that our tests can use during setup to specify -// what the files on the "mock" filesystem should look like when any of the -// `fs` APIs are used. -let mockFiles = Object.create(null); - -// eslint-disable-next-line no-underscore-dangle, @typescript-eslint/naming-convention -function __setMockFiles(newMockFiles) { - mockFiles = newMockFiles; -} - -// A custom version of `readdirSync` that reads from the special mocked out -// file list set via __setMockFiles -const readFile = async (filePath) => mockFiles[filePath]; -const readFileSync = (filePath = '') => mockFiles[filePath]; -const existsSync = (filePath) => !!mockFiles[filePath]; -const readJson = (filePath = '') => JSON.parse(mockFiles[filePath]); -const readJsonSync = (filePath = '') => JSON.parse(mockFiles[filePath]); -const lstatSync = (filePath) => ({ - isFile: () => !!mockFiles[filePath], -}); -const writeJson = jest.fn((filePath, json, { spaces } = {}) => { - mockFiles[filePath] = JSON.stringify(json, null, spaces); -}); - -// eslint-disable-next-line no-underscore-dangle -fs.__setMockFiles = __setMockFiles; -fs.readFile = readFile; -fs.readFileSync = readFileSync; -fs.readJson = readJson; -fs.readJsonSync = readJsonSync; -fs.existsSync = existsSync; -fs.lstatSync = lstatSync; -fs.writeJson = writeJson; - -module.exports = fs; diff --git a/code/__mocks__/fs-extra.ts b/code/__mocks__/fs-extra.ts new file mode 100644 index 000000000000..3296a9e3fee7 --- /dev/null +++ b/code/__mocks__/fs-extra.ts @@ -0,0 +1,30 @@ +import { vi } from 'vitest'; + +vi.mock('fs-extra'); + +// This is a custom function that our tests can use during setup to specify +// what the files on the "mock" filesystem should look like when any of the +// `fs` APIs are used. +let mockFiles = Object.create(null); + +// eslint-disable-next-line no-underscore-dangle, @typescript-eslint/naming-convention +export function __setMockFiles(newMockFiles: Record) { + mockFiles = newMockFiles; +} + +// A custom version of `readdirSync` that reads from the special mocked out +// file list set via __setMockFiles +export const writeFile = vi.fn(async (filePath: string, content: string) => { + mockFiles[filePath] = content; +}); +export const readFile = vi.fn(async (filePath: string) => mockFiles[filePath]); +export const readFileSync = vi.fn((filePath = '') => mockFiles[filePath]); +export const existsSync = vi.fn((filePath: string) => !!mockFiles[filePath]); +export const readJson = vi.fn((filePath = '') => JSON.parse(mockFiles[filePath])); +export const readJsonSync = vi.fn((filePath = '') => JSON.parse(mockFiles[filePath])); +export const lstatSync = vi.fn((filePath: string) => ({ + isFile: () => !!mockFiles[filePath], +})); +export const writeJson = vi.fn((filePath, json, { spaces } = {}) => { + mockFiles[filePath] = JSON.stringify(json, null, spaces); +}); diff --git a/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts b/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts index f086ff5cdf2c..7142f12f3e31 100644 --- a/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts +++ b/code/lib/preview-api/src/modules/store/csf/normalizeStory.test.ts @@ -48,16 +48,16 @@ describe('normalizeStory', () => { const storyFn = () => {}; const meta = { id: 'title', title: 'title' }; expect(normalizeStory('storyExport', storyFn, meta)).toMatchInlineSnapshot(` - Object { - "argTypes": Object {}, - "args": Object {}, - "decorators": Array [], + { + "argTypes": {}, + "args": {}, + "decorators": [], "id": "title--story-export", - "loaders": Array [], + "loaders": [], "moduleExport": [Function], "name": "Story Export", - "parameters": Object {}, - "tags": Array [], + "parameters": {}, + "tags": [], "userStoryFn": [Function], } `); @@ -117,16 +117,16 @@ describe('normalizeStory', () => { const meta = { id: 'title', title: 'title' }; const normalized = normalizeStory('storyExport', storyObj, meta); expect(normalized).toMatchInlineSnapshot(` - Object { - "argTypes": Object {}, - "args": Object {}, - "decorators": Array [], + { + "argTypes": {}, + "args": {}, + "decorators": [], "id": "title--story-export", - "loaders": Array [], - "moduleExport": Object {}, + "loaders": [], + "moduleExport": {}, "name": "Story Export", - "parameters": Object {}, - "tags": Array [], + "parameters": {}, + "tags": [], } `); expect(normalized.moduleExport).toBe(storyObj); @@ -144,30 +144,30 @@ describe('normalizeStory', () => { const meta = { id: 'title', title: 'title' }; const { moduleExport, ...normalized } = normalizeStory('storyExport', storyObj, meta); expect(normalized).toMatchInlineSnapshot(` - Object { - "argTypes": Object { - "storyArgType": Object { + { + "argTypes": { + "storyArgType": { "name": "storyArgType", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "storyArg": "val", }, - "decorators": Array [ + "decorators": [ [Function], ], "id": "title--story-export", - "loaders": Array [ + "loaders": [ [Function], ], "name": "story name", - "parameters": Object { + "parameters": { "storyParam": "val", }, - "tags": Array [], + "tags": [], } `); expect(moduleExport).toBe(storyObj); @@ -192,40 +192,40 @@ describe('normalizeStory', () => { const meta = { id: 'title', title: 'title' }; const { moduleExport, ...normalized } = normalizeStory('storyExport', storyObj, meta); expect(normalized).toMatchInlineSnapshot(` - Object { - "argTypes": Object { - "storyArgType": Object { + { + "argTypes": { + "storyArgType": { "name": "storyArgType", - "type": Object { + "type": { "name": "string", }, }, - "storyArgType2": Object { + "storyArgType2": { "name": "storyArgType2", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "storyArg": "val", "storyArg2": "legacy", }, - "decorators": Array [ + "decorators": [ [Function], [Function], ], "id": "title--story-export", - "loaders": Array [ + "loaders": [ [Function], [Function], ], "name": "story name", - "parameters": Object { + "parameters": { "storyParam": "val", "storyParam2": "legacy", }, - "tags": Array [], + "tags": [], } `); expect(moduleExport).toBe(storyObj); diff --git a/code/yarn.lock b/code/yarn.lock index 2bc07ae18103..f06b5123b4c1 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -393,18 +393,7 @@ __metadata: languageName: node linkType: hard -"@axe-core/puppeteer@npm:^4.2.0": - version: 4.7.3 - resolution: "@axe-core/puppeteer@npm:4.7.3" - dependencies: - axe-core: ^4.7.0 - peerDependencies: - puppeteer: ">=1.10.0" - checksum: 24161a6c8ee3ab33f09e66f73bb81d70c69feb5c2e8cb1a1ba6a6e06ecb204768dbf443bc76abfa95c3fb637fd21ea4270478591b45a00a939b9b3909c11bc4e - languageName: node - linkType: hard - -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.22.5, @babel/code-frame@npm:^7.8.3": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.22.5": version: 7.22.13 resolution: "@babel/code-frame@npm:7.22.13" dependencies: @@ -467,29 +456,6 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:7.8.7": - version: 7.8.7 - resolution: "@babel/core@npm:7.8.7" - dependencies: - "@babel/code-frame": ^7.8.3 - "@babel/generator": ^7.8.7 - "@babel/helpers": ^7.8.4 - "@babel/parser": ^7.8.7 - "@babel/template": ^7.8.6 - "@babel/traverse": ^7.8.6 - "@babel/types": ^7.8.7 - convert-source-map: ^1.7.0 - debug: ^4.1.0 - gensync: ^1.0.0-beta.1 - json5: ^2.1.0 - lodash: ^4.17.13 - resolve: ^1.3.2 - semver: ^5.4.1 - source-map: ^0.5.0 - checksum: ffff3e94f219c7a4a32c825eca57c9beb1a83a60c0c5c37e7ddbcecd45c5c188cece5352f56a91a14c05c25ffcb298155429fedb9e86477cf2c91c3388b1f2c9 - languageName: node - linkType: hard - "@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.0, @babel/core@npm:^7.12.3, @babel/core@npm:^7.13.16, @babel/core@npm:^7.19.6, @babel/core@npm:^7.20.12, @babel/core@npm:^7.22.0, @babel/core@npm:^7.22.1, @babel/core@npm:^7.22.9, @babel/core@npm:^7.3.4, @babel/core@npm:^7.7.5": version: 7.22.17 resolution: "@babel/core@npm:7.22.17" @@ -525,7 +491,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.12.11, @babel/generator@npm:^7.22.15, @babel/generator@npm:^7.22.5, @babel/generator@npm:^7.22.9, @babel/generator@npm:^7.7.2, @babel/generator@npm:^7.8.7": +"@babel/generator@npm:^7.12.11, @babel/generator@npm:^7.22.15, @babel/generator@npm:^7.22.5, @babel/generator@npm:^7.22.9, @babel/generator@npm:^7.7.2": version: 7.22.15 resolution: "@babel/generator@npm:7.22.15" dependencies: @@ -775,7 +741,7 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.22.15, @babel/helpers@npm:^7.22.5, @babel/helpers@npm:^7.22.6, @babel/helpers@npm:^7.8.4": +"@babel/helpers@npm:^7.22.15, @babel/helpers@npm:^7.22.5, @babel/helpers@npm:^7.22.6": version: 7.22.15 resolution: "@babel/helpers@npm:7.22.15" dependencies: @@ -797,7 +763,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.11.5, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.18.4, @babel/parser@npm:^7.20.15, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.3, @babel/parser@npm:^7.21.4, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.22.16, @babel/parser@npm:^7.22.5, @babel/parser@npm:^7.22.7, @babel/parser@npm:^7.4.5, @babel/parser@npm:^7.6.0, @babel/parser@npm:^7.7.0, @babel/parser@npm:^7.8.6, @babel/parser@npm:^7.8.7, @babel/parser@npm:^7.9.6": +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.11.5, @babel/parser@npm:^7.13.16, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.18.4, @babel/parser@npm:^7.20.15, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.21.3, @babel/parser@npm:^7.21.4, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.22.16, @babel/parser@npm:^7.22.5, @babel/parser@npm:^7.22.7, @babel/parser@npm:^7.4.5, @babel/parser@npm:^7.6.0, @babel/parser@npm:^7.7.0, @babel/parser@npm:^7.9.6": version: 7.22.16 resolution: "@babel/parser@npm:7.22.16" bin: @@ -2306,18 +2272,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:7.8.6": - version: 7.8.6 - resolution: "@babel/template@npm:7.8.6" - dependencies: - "@babel/code-frame": ^7.8.3 - "@babel/parser": ^7.8.6 - "@babel/types": ^7.8.6 - checksum: c89b2f39452083303beaaabc794ebf83194bb5599647c54591d3b8358b42d720bab050daa34450052e4fdf21bcb77cf60b6419fec73d50eb2ce60c4abfe7292e - languageName: node - linkType: hard - -"@babel/template@npm:^7.22.15, @babel/template@npm:^7.22.5, @babel/template@npm:^7.3.3, @babel/template@npm:^7.7.0, @babel/template@npm:^7.8.6": +"@babel/template@npm:^7.22.15, @babel/template@npm:^7.22.5, @babel/template@npm:^7.3.3, @babel/template@npm:^7.7.0": version: 7.22.15 resolution: "@babel/template@npm:7.22.15" dependencies: @@ -2328,7 +2283,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.22.15, @babel/traverse@npm:^7.22.17, @babel/traverse@npm:^7.22.5, @babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.4.5, @babel/traverse@npm:^7.7.0, @babel/traverse@npm:^7.8.6": +"@babel/traverse@npm:^7.1.6, @babel/traverse@npm:^7.22.15, @babel/traverse@npm:^7.22.17, @babel/traverse@npm:^7.22.5, @babel/traverse@npm:^7.22.8, @babel/traverse@npm:^7.4.5, @babel/traverse@npm:^7.7.0": version: 7.22.17 resolution: "@babel/traverse@npm:7.22.17" dependencies: @@ -2346,7 +2301,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.11.5, @babel/types@npm:^7.2.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.4, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.17, @babel/types@npm:^7.22.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.6.1, @babel/types@npm:^7.7.0, @babel/types@npm:^7.7.2, @babel/types@npm:^7.8.3, @babel/types@npm:^7.8.6, @babel/types@npm:^7.8.7, @babel/types@npm:^7.9.6": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.11.5, @babel/types@npm:^7.2.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.4, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.17, @babel/types@npm:^7.22.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.6.1, @babel/types@npm:^7.7.0, @babel/types@npm:^7.7.2, @babel/types@npm:^7.8.3, @babel/types@npm:^7.9.6": version: 7.22.17 resolution: "@babel/types@npm:7.22.17" dependencies: @@ -2558,16 +2513,6 @@ __metadata: languageName: node linkType: hard -"@emotion/css-prettifier@npm:^1.1.3": - version: 1.1.3 - resolution: "@emotion/css-prettifier@npm:1.1.3" - dependencies: - "@emotion/memoize": ^0.8.1 - stylis: 4.2.0 - checksum: 9ce3d7e5851054a24ca68cca4f6973de47d64567d03b6be730aa83f1cf9ae15e4da8c4611e68620e7b972f7a9fb7c36099fdf7e26b78589eb64f094fce46ce1b - languageName: node - linkType: hard - "@emotion/hash@npm:^0.9.1": version: 0.9.1 resolution: "@emotion/hash@npm:0.9.1" @@ -2584,27 +2529,6 @@ __metadata: languageName: node linkType: hard -"@emotion/jest@npm:^11.10.0, @emotion/jest@npm:^11.8.0": - version: 11.11.0 - resolution: "@emotion/jest@npm:11.11.0" - dependencies: - "@babel/runtime": ^7.18.3 - "@emotion/css-prettifier": ^1.1.3 - chalk: ^4.1.0 - specificity: ^0.4.1 - stylis: 4.2.0 - peerDependencies: - "@types/jest": ^26.0.14 || ^27.0.0 || ^28.0.0 || ^29.0.0 - enzyme-to-json: ^3.2.1 - peerDependenciesMeta: - "@types/jest": - optional: true - enzyme-to-json: - optional: true - checksum: 919def636000234c4af8447a6cdf7f9675146bb020074fd06cf3c6eb42c365e727354ae79b2a7cdccb472d38da8ed8d6fd57f4235cab2e1b7605a2c6672a0fc5 - languageName: node - linkType: hard - "@emotion/memoize@npm:^0.8.1": version: 0.8.1 resolution: "@emotion/memoize@npm:0.8.1" @@ -3548,15 +3472,6 @@ __metadata: languageName: node linkType: hard -"@jest/create-cache-key-function@npm:^27.4.2": - version: 27.5.1 - resolution: "@jest/create-cache-key-function@npm:27.5.1" - dependencies: - "@jest/types": ^27.5.1 - checksum: 1890ac93fad852e0a98c31de1e5f2c548974aefd36e838d27b70834dda1654a153ed6a52258447ebacfd47463e9bdb83750631bee827797c7b9973c083998a96 - languageName: node - linkType: hard - "@jest/environment@npm:^29.7.0": version: 29.7.0 resolution: "@jest/environment@npm:29.7.0" @@ -6115,116 +6030,6 @@ __metadata: languageName: unknown linkType: soft -"@storybook/addon-storyshots-puppeteer@workspace:*, @storybook/addon-storyshots-puppeteer@workspace:addons/storyshots-puppeteer": - version: 0.0.0-use.local - resolution: "@storybook/addon-storyshots-puppeteer@workspace:addons/storyshots-puppeteer" - dependencies: - "@axe-core/puppeteer": ^4.2.0 - "@storybook/csf": ^0.1.0 - "@storybook/node-logger": "workspace:*" - "@storybook/types": "workspace:*" - "@types/jest-image-snapshot": ^6.0.0 - "@types/puppeteer": ^5.4.0 - enzyme: ^3.11.0 - enzyme-to-json: ^3.6.1 - jest-image-snapshot: ^6.0.0 - puppeteer: ^2.0.0 || ^3.0.0 - peerDependencies: - "@storybook/addon-storyshots": "workspace:*" - puppeteer: ">=2.0.0" - peerDependenciesMeta: - puppeteer: - optional: true - languageName: unknown - linkType: soft - -"@storybook/addon-storyshots@workspace:*, @storybook/addon-storyshots@workspace:addons/storyshots-core": - version: 0.0.0-use.local - resolution: "@storybook/addon-storyshots@workspace:addons/storyshots-core" - dependencies: - "@angular/core": ^16.0.0-rc.4 - "@angular/platform-browser-dynamic": ^16.0.0-rc.4 - "@emotion/jest": ^11.8.0 - "@jest/transform": ^29.3.1 - "@storybook/addon-docs": "workspace:*" - "@storybook/angular": "workspace:*" - "@storybook/babel-plugin-require-context-hook": 1.0.1 - "@storybook/client-api": "workspace:*" - "@storybook/core-common": "workspace:*" - "@storybook/core-webpack": "workspace:*" - "@storybook/global": ^5.0.0 - "@storybook/preview-api": "workspace:*" - "@storybook/react": "workspace:*" - "@storybook/types": "workspace:*" - "@storybook/vue": "workspace:*" - "@storybook/vue3": "workspace:*" - "@types/jest-specific-snapshot": ^0.5.6 - babel-loader: ^9.1.2 - enzyme: ^3.11.0 - enzyme-adapter-react-16: ^1.15.5 - enzyme-to-json: ^3.6.1 - glob: ^10.0.0 - jest-preset-angular: ^13.0.1 - jest-specific-snapshot: ^8.0.0 - jest-vue-preprocessor: ^1.7.1 - preact-render-to-string: ^5.1.19 - pretty-format: ^29.0.0 - react-test-renderer: ^16 - read-pkg-up: ^7.0.1 - rxjs: ^6.6.3 - ts-dedent: ^2.0.0 - vue-jest: ^5.0.0-alpha.8 - peerDependencies: - "@angular/core": ">=13.0.0" - "@angular/platform-browser-dynamic": ">=13.0.0" - "@storybook/angular": "*" - "@storybook/react": "*" - "@storybook/vue": "*" - "@storybook/vue3": "*" - jest: "*" - jest-preset-angular: " >= 12.2.3" - jest-vue-preprocessor: "*" - preact: ^10.5.13 - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 - rxjs: "*" - svelte: "*" - vue: "*" - vue-jest: "*" - peerDependenciesMeta: - "@angular/core": - optional: true - "@angular/platform-browser-dynamic": - optional: true - "@storybook/angular": - optional: true - "@storybook/react": - optional: true - "@storybook/vue": - optional: true - "@storybook/vue3": - optional: true - jest-preset-angular: - optional: true - jest-vue-preprocessor: - optional: true - preact: - optional: true - react: - optional: true - react-dom: - optional: true - rxjs: - optional: true - svelte: - optional: true - vue: - optional: true - vue-jest: - optional: true - languageName: unknown - linkType: soft - "@storybook/addon-storysource@workspace:*, @storybook/addon-storysource@workspace:addons/storysource": version: 0.0.0-use.local resolution: "@storybook/addon-storysource@workspace:addons/storysource" @@ -7826,8 +7631,6 @@ __metadata: "@babel/preset-react": ^7.22.5 "@babel/preset-typescript": ^7.22.5 "@babel/runtime": ^7.22.6 - "@emotion/jest": ^11.10.0 - "@jest/globals": ^29.3.1 "@nx/workspace": 16.2.1 "@playwright/test": 1.36.0 "@storybook/addon-a11y": "workspace:*" @@ -7843,8 +7646,6 @@ __metadata: "@storybook/addon-mdx-gfm": "workspace:*" "@storybook/addon-measure": "workspace:*" "@storybook/addon-outline": "workspace:*" - "@storybook/addon-storyshots": "workspace:*" - "@storybook/addon-storyshots-puppeteer": "workspace:*" "@storybook/addon-storysource": "workspace:*" "@storybook/addon-toolbars": "workspace:*" "@storybook/addon-viewport": "workspace:*" @@ -7926,9 +7727,7 @@ __metadata: "@storybook/web-components-vite": "workspace:*" "@storybook/web-components-webpack5": "workspace:*" "@swc/core": 1.3.82 - "@swc/jest": ^0.2.26 "@testing-library/dom": ^7.29.4 - "@testing-library/jest-dom": ^5.11.9 "@testing-library/react": ^11.2.2 "@testing-library/user-event": ^13.2.1 "@types/express": ^4.17.11 @@ -7963,13 +7762,6 @@ __metadata: glob: ^10.0.0 http-server: ^14.1.1 husky: ^4.3.7 - jest: ^29.5.0 - jest-environment-jsdom: ^29.5.0 - jest-image-snapshot: ^6.0.0 - jest-junit: ^16.0.0 - jest-os-detection: ^1.3.1 - jest-serializer-html: ^7.1.0 - jest-watch-typeahead: ^2.2.1 lerna: ^6.4.0 lint-staged: ^13.2.2 lodash: ^4.17.21 @@ -8741,18 +8533,6 @@ __metadata: languageName: node linkType: hard -"@swc/jest@npm:^0.2.26": - version: 0.2.29 - resolution: "@swc/jest@npm:0.2.29" - dependencies: - "@jest/create-cache-key-function": ^27.4.2 - jsonc-parser: ^3.2.0 - peerDependencies: - "@swc/core": "*" - checksum: 10f34341f9bc8003cec44f91a88b531ba44094aad97b2f8410fb2f94db9eb3b8fc7f6d14ba867eb9c1dc6ba29cc46058244b8280d673a7c681062fe0dc73c3f0 - languageName: node - linkType: hard - "@swc/types@npm:^0.1.4": version: 0.1.4 resolution: "@swc/types@npm:0.1.4" @@ -9035,15 +8815,6 @@ __metadata: languageName: node linkType: hard -"@types/cheerio@npm:^0.22.22": - version: 0.22.32 - resolution: "@types/cheerio@npm:0.22.32" - dependencies: - "@types/node": "*" - checksum: 02c64de8e198e9bb2b162c3d426a00df8b558730df84bebf7d586cf23493043217f0dc81efabc13b32589839a82a974f02ade618ecdd7c528c3b574cf95bff97 - languageName: node - linkType: hard - "@types/color-convert@npm:^2.0.0": version: 2.0.1 resolution: "@types/color-convert@npm:2.0.1" @@ -9335,26 +9106,6 @@ __metadata: languageName: node linkType: hard -"@types/jest-image-snapshot@npm:^6.0.0": - version: 6.2.0 - resolution: "@types/jest-image-snapshot@npm:6.2.0" - dependencies: - "@types/jest": "*" - "@types/pixelmatch": "*" - ssim.js: ^3.1.1 - checksum: 65e7b951eee31521b4f53fa6a49134fad137a5636886594ea10324624afe074d4c88e1f579715934e0eab340951bbc864b81c99c00f51f8cf31230de415078c5 - languageName: node - linkType: hard - -"@types/jest-specific-snapshot@npm:^0.5.6": - version: 0.5.6 - resolution: "@types/jest-specific-snapshot@npm:0.5.6" - dependencies: - "@types/jest": "*" - checksum: 5fc9234afdf704eb7fa69bbf7860c2e9f9e76aed750e98aa44824bb47e048d1e57c5386eb3c919534a4225147f205742c6f9dac0e458e092de30efde77cc1ebe - languageName: node - linkType: hard - "@types/jest@npm:*": version: 28.1.3 resolution: "@types/jest@npm:28.1.3" @@ -9561,15 +9312,6 @@ __metadata: languageName: node linkType: hard -"@types/pixelmatch@npm:*": - version: 5.2.4 - resolution: "@types/pixelmatch@npm:5.2.4" - dependencies: - "@types/node": "*" - checksum: 10ce0b806112743237a75f0fcb145cc972cc7934131b971fea375b70fb69c6dc1ee2ba63e77265348c87d69260461ae812cca140412b50e7cd42118944b41e0d - languageName: node - linkType: hard - "@types/pluralize@npm:^0.0.29": version: 0.0.29 resolution: "@types/pluralize@npm:0.0.29" @@ -9640,15 +9382,6 @@ __metadata: languageName: node linkType: hard -"@types/puppeteer@npm:^5.4.0": - version: 5.4.7 - resolution: "@types/puppeteer@npm:5.4.7" - dependencies: - "@types/node": "*" - checksum: f15bccf30526151c6e42c797b844f24eb7489f0180b391857c8d6902dfa96c7f48730540229a681505ca70e9197cdac0dfbeaca0c2537526358ad5656bef703d - languageName: node - linkType: hard - "@types/qs@npm:*, @types/qs@npm:^6, @types/qs@npm:^6.9.5": version: 6.9.8 resolution: "@types/qs@npm:6.9.8" @@ -10002,15 +9735,6 @@ __metadata: languageName: node linkType: hard -"@types/yauzl@npm:^2.9.1": - version: 2.10.0 - resolution: "@types/yauzl@npm:2.10.0" - dependencies: - "@types/node": "*" - checksum: e917cf11c78e9ca7d037d0e6e0d6d5d99443d9d7201f8f1a556f02a2bc57ae457487e9bfec89dfa848d16979b35de6e5b34840d4d0bb9e5f33849d077ac15154 - languageName: node - linkType: hard - "@typescript-eslint/eslint-plugin@npm:^5.45.0": version: 5.62.0 resolution: "@typescript-eslint/eslint-plugin@npm:5.62.0" @@ -11006,25 +10730,6 @@ __metadata: languageName: node linkType: hard -"airbnb-prop-types@npm:^2.16.0": - version: 2.16.0 - resolution: "airbnb-prop-types@npm:2.16.0" - dependencies: - array.prototype.find: ^2.1.1 - function.prototype.name: ^1.1.2 - is-regex: ^1.1.0 - object-is: ^1.1.2 - object.assign: ^4.1.0 - object.entries: ^1.1.2 - prop-types: ^15.7.2 - prop-types-exact: ^1.2.0 - react-is: ^16.13.1 - peerDependencies: - react: ^0.14 || ^15.0.0 || ^16.0.0-alpha - checksum: c3666777bf9ee3a077ce79a02fcf79b7cf3123b11a626750826912e1f0f44772177e6667176558e10384f4501556f5e7eeb198231e9f61794864465167c8ee33 - languageName: node - linkType: hard - "ajv-formats@npm:2.1.1, ajv-formats@npm:^2.1.1": version: 2.1.1 resolution: "ajv-formats@npm:2.1.1" @@ -11134,15 +10839,6 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^6.0.0": - version: 6.2.0 - resolution: "ansi-escapes@npm:6.2.0" - dependencies: - type-fest: ^3.0.0 - checksum: 3eec75deedd8b10192c5f98e4cd9715cc3ff268d33fc463c24b7d22446668bfcd4ad1803993ea89c0f51f88b5a3399572bacb7c8cb1a067fc86e189c5f3b0c7e - languageName: node - linkType: hard - "ansi-html-community@npm:0.0.8, ansi-html-community@npm:^0.0.8": version: 0.0.8 resolution: "ansi-html-community@npm:0.0.8" @@ -11439,31 +11135,6 @@ __metadata: languageName: node linkType: hard -"array.prototype.filter@npm:^1.0.0": - version: 1.0.3 - resolution: "array.prototype.filter@npm:1.0.3" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - es-array-method-boxes-properly: ^1.0.0 - is-string: ^1.0.7 - checksum: 8b70b5f866df5d90fa27aa5bfa30f5fefc44cbea94b0513699d761713658077c2a24cbf06aac5179eabddb6c93adc467af4c288b7a839c5bc5a769ee5a2d48ad - languageName: node - linkType: hard - -"array.prototype.find@npm:^2.1.1": - version: 2.2.2 - resolution: "array.prototype.find@npm:2.2.2" - dependencies: - call-bind: ^1.0.2 - define-properties: ^1.2.0 - es-abstract: ^1.22.1 - es-shim-unscopables: ^1.0.0 - checksum: 5008d3e6089f7047db1886d0dc2d75bdd342b886528dbca3c67920f18fd435dbc878b9c55243c96e18423d139d5ddb08cdbc8f95bd89ed4f2f53c63260eb444a - languageName: node - linkType: hard - "array.prototype.findlastindex@npm:^1.2.2": version: 1.2.3 resolution: "array.prototype.findlastindex@npm:1.2.3" @@ -11477,7 +11148,7 @@ __metadata: languageName: node linkType: hard -"array.prototype.flat@npm:^1.2.3, array.prototype.flat@npm:^1.3.1": +"array.prototype.flat@npm:^1.3.1": version: 1.3.2 resolution: "array.prototype.flat@npm:1.3.2" dependencies: @@ -11751,7 +11422,7 @@ __metadata: languageName: node linkType: hard -"axe-core@npm:^4.2.0, axe-core@npm:^4.6.2, axe-core@npm:^4.7.0": +"axe-core@npm:^4.2.0, axe-core@npm:^4.6.2": version: 4.8.1 resolution: "axe-core@npm:4.8.1" checksum: 160887aac11d0a249adade104379bb3b05d1bca26386137b50ea82861cc4bbbdcc76091309b3c5f03da1fae0f27ab02d8d4aef3d041a16e67f3a012cb5080c90 @@ -12024,15 +11695,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-transform-runtime@npm:6.23.0": - version: 6.23.0 - resolution: "babel-plugin-transform-runtime@npm:6.23.0" - dependencies: - babel-runtime: ^6.22.0 - checksum: c9e9eaeb19de4c5527c2c4494e29e2d5e2ca37ab35b24ae7dd8c93943365526114a9d144237a2976197511dd22e8eb8cdb4d69291b346b468e0736a733d2499d - languageName: node - linkType: hard - "babel-preset-current-node-syntax@npm:^1.0.0": version: 1.0.1 resolution: "babel-preset-current-node-syntax@npm:1.0.1" @@ -12067,16 +11729,6 @@ __metadata: languageName: node linkType: hard -"babel-runtime@npm:^6.22.0": - version: 6.26.0 - resolution: "babel-runtime@npm:6.26.0" - dependencies: - core-js: ^2.4.0 - regenerator-runtime: ^0.11.0 - checksum: caa752004936b1463765ed3199c52f6a55d0613b9bed108743d6f13ca532b821d4ea9decc4be1b583193164462b1e3e7eefdfa36b15c72e7daac58dd72c1772f - languageName: node - linkType: hard - "babel-walk@npm:3.0.0-canary-5": version: 3.0.0-canary-5 resolution: "babel-walk@npm:3.0.0-canary-5" @@ -12744,7 +12396,7 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^5.2.1, buffer@npm:^5.5.0": +"buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" dependencies: @@ -13049,7 +12701,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:5.3.0, chalk@npm:^5.2.0": +"chalk@npm:5.3.0": version: 5.3.0 resolution: "chalk@npm:5.3.0" checksum: 8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09 @@ -13094,13 +12746,6 @@ __metadata: languageName: node linkType: hard -"char-regex@npm:^2.0.0": - version: 2.0.1 - resolution: "char-regex@npm:2.0.1" - checksum: ec592229ac3ef18f2ea1f5676ae9a829c37150db55fd7f709edce1bcdc9f506de22ae19388d853704806e51af71fe9239bcb7e7be583296951bfbf2a9a9763a2 - languageName: node - linkType: hard - "character-entities-html4@npm:^2.0.0": version: 2.1.0 resolution: "character-entities-html4@npm:2.1.0" @@ -13180,35 +12825,6 @@ __metadata: languageName: node linkType: hard -"cheerio-select@npm:^2.1.0": - version: 2.1.0 - resolution: "cheerio-select@npm:2.1.0" - dependencies: - boolbase: ^1.0.0 - css-select: ^5.1.0 - css-what: ^6.1.0 - domelementtype: ^2.3.0 - domhandler: ^5.0.3 - domutils: ^3.0.1 - checksum: 2242097e593919dba4aacb97d7b8275def8b9ec70b00aa1f43335456870cfc9e284eae2080bdc832ed232dabb9eefcf56c722d152da4a154813fb8814a55d282 - languageName: node - linkType: hard - -"cheerio@npm:^1.0.0-rc.3": - version: 1.0.0-rc.12 - resolution: "cheerio@npm:1.0.0-rc.12" - dependencies: - cheerio-select: ^2.1.0 - dom-serializer: ^2.0.0 - domhandler: ^5.0.3 - domutils: ^3.0.1 - htmlparser2: ^8.0.1 - parse5: ^7.0.0 - parse5-htmlparser2-tree-adapter: ^7.0.0 - checksum: c85d2f2461e3f024345b78e0bb16ad8e41492356210470dd1e7d5a91391da9fcf6c0a7cb48a9ba8820330153f0cedb4d0a60c7af15d96ecdb3092299b9d9c0cc - languageName: node - linkType: hard - "chokidar@npm:3.5.3, chokidar@npm:>=3.0.0 <4.0.0, chokidar@npm:^3.0.0, chokidar@npm:^3.4.1, chokidar@npm:^3.5.1, chokidar@npm:^3.5.3": version: 3.5.3 resolution: "chokidar@npm:3.5.3" @@ -14090,7 +13706,7 @@ __metadata: languageName: node linkType: hard -"core-js@npm:^2.4.0, core-js@npm:^2.6.5": +"core-js@npm:^2.6.5": version: 2.6.12 resolution: "core-js@npm:2.6.12" checksum: 00128efe427789120a06b819adc94cc72b96955acb331cb71d09287baf9bd37bebd191d91f1ee4939c893a050307ead4faea08876f09115112612b6a05684b63 @@ -14374,18 +13990,6 @@ __metadata: languageName: node linkType: hard -"css@npm:^2.1.0": - version: 2.2.4 - resolution: "css@npm:2.2.4" - dependencies: - inherits: ^2.0.3 - source-map: ^0.6.1 - source-map-resolve: ^0.5.2 - urix: ^0.1.0 - checksum: 496fa66568ebd9e51b3153817dd36ec004a45780da6f818e13117e3c4e50b774af41fff70a6ff2fa03777b239c4028ff655fe571b20964b90e886441cd141569 - languageName: node - linkType: hard - "css@npm:^3.0.0": version: 3.0.0 resolution: "css@npm:3.0.0" @@ -14993,15 +14597,6 @@ __metadata: languageName: node linkType: hard -"diffable-html@npm:^4.1.0": - version: 4.1.0 - resolution: "diffable-html@npm:4.1.0" - dependencies: - htmlparser2: ^3.9.2 - checksum: 4224133455312e03dd5b84cec0a7d7390552ae30fc5ceb24256c4973e7b51ab2ba69f8b8dbeaaa3feb2b92d3fdd57476dcb7afeada793130ab340720c6a553c7 - languageName: node - linkType: hard - "diffie-hellman@npm:^5.0.0": version: 5.0.3 resolution: "diffie-hellman@npm:5.0.3" @@ -15031,13 +14626,6 @@ __metadata: languageName: node linkType: hard -"discontinuous-range@npm:1.0.0": - version: 1.0.0 - resolution: "discontinuous-range@npm:1.0.0" - checksum: 487b105f83c1cc528e25e65d3c4b73958ec79769b7bd0e264414702a23a7e2b282c72982b4bef4af29fcab53f47816c3f0a5c40d85a99a490f4bc35b83dc00f8 - languageName: node - linkType: hard - "dns-equal@npm:^1.0.0": version: 1.0.0 resolution: "dns-equal@npm:1.0.0" @@ -15095,16 +14683,6 @@ __metadata: languageName: node linkType: hard -"dom-serializer@npm:0": - version: 0.2.2 - resolution: "dom-serializer@npm:0.2.2" - dependencies: - domelementtype: ^2.0.1 - entities: ^2.0.0 - checksum: 5cb595fb77e1a23eca56742f47631e6f4af66ce1982c7ed28b3d0ef21f1f50304c067adc29d3eaf824c572be022cee88627d0ac9b929408f24e923f3c7bed37b - languageName: node - linkType: hard - "dom-serializer@npm:^1.0.1": version: 1.4.1 resolution: "dom-serializer@npm:1.4.1" @@ -15134,13 +14712,6 @@ __metadata: languageName: node linkType: hard -"domelementtype@npm:1, domelementtype@npm:^1.3.1": - version: 1.3.1 - resolution: "domelementtype@npm:1.3.1" - checksum: 6d4f5761060a21eaf3c96545501e9d188745c7e1c31b8d141bf15d8748feeadba868f4ea32877751b8678b286fb1afbe6ae905ca3fb8f0214d8322e482cdbec0 - languageName: node - linkType: hard - "domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0, domelementtype@npm:^2.3.0": version: 2.3.0 resolution: "domelementtype@npm:2.3.0" @@ -15166,15 +14737,6 @@ __metadata: languageName: node linkType: hard -"domhandler@npm:^2.3.0": - version: 2.4.2 - resolution: "domhandler@npm:2.4.2" - dependencies: - domelementtype: 1 - checksum: 6670cab73e97e3c6771dcf22b537db3f6a0be0ad6b370f03bb5f1b585d3b563d326787fdabe1190b7ca9d81c804e9b3f8a1431159c27c44f6c05f94afa92be2d - languageName: node - linkType: hard - "domhandler@npm:^3.0.0": version: 3.3.0 resolution: "domhandler@npm:3.3.0" @@ -15202,16 +14764,6 @@ __metadata: languageName: node linkType: hard -"domutils@npm:^1.5.1": - version: 1.7.0 - resolution: "domutils@npm:1.7.0" - dependencies: - dom-serializer: 0 - domelementtype: 1 - checksum: 437fcd2d6d6be03f488152e73c6f953e289c58496baa22be9626b2b46f9cfd40486ae77d144487ff6b102929a3231cdb9a8bf8ef485fb7b7c30c985daedc77eb - languageName: node - linkType: hard - "domutils@npm:^2.0.0, domutils@npm:^2.5.2, domutils@npm:^2.8.0": version: 2.8.0 resolution: "domutils@npm:2.8.0" @@ -15663,13 +15215,6 @@ __metadata: languageName: node linkType: hard -"entities@npm:^1.1.1": - version: 1.1.2 - resolution: "entities@npm:1.1.2" - checksum: 5b12fa8c4fb942f88af6f8791bbe7be0a59ebd91c8933cee091d94455efd1eeb200418c7b1bc8dd0f74cdd4db8cf4538eb043db14cfd1919130c25d8c6095215 - languageName: node - linkType: hard - "entities@npm:^2.0.0": version: 2.2.0 resolution: "entities@npm:2.2.0" @@ -15683,118 +15228,27 @@ __metadata: checksum: 2d93f48fd86de0b0ed8ee34456aa47b4e74a916a5e663cfcc7048302e2c7e932002926daf5a00ad6d5691e3c90673a15d413704d86d7e1b9532f9bc00d975590 languageName: node linkType: hard - -"entities@npm:^4.2.0, entities@npm:^4.3.0, entities@npm:^4.4.0": - version: 4.5.0 - resolution: "entities@npm:4.5.0" - checksum: 5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250 - languageName: node - linkType: hard - -"env-paths@npm:^2.2.0": - version: 2.2.1 - resolution: "env-paths@npm:2.2.1" - checksum: 285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 - languageName: node - linkType: hard - -"envinfo@npm:^7.7.3, envinfo@npm:^7.7.4": - version: 7.10.0 - resolution: "envinfo@npm:7.10.0" - bin: - envinfo: dist/cli.js - checksum: ebc7792fbedca72bc829913abe0c2a3384b883903012f97b56085afd4e83d26f7dd0652403fedd99cd3e1c93d4fb0706f5d2c3dc06ac6a1eda348280a06a9dcf - languageName: node - linkType: hard - -"enzyme-adapter-react-16@npm:^1.15.5": - version: 1.15.7 - resolution: "enzyme-adapter-react-16@npm:1.15.7" - dependencies: - enzyme-adapter-utils: ^1.14.1 - enzyme-shallow-equal: ^1.0.5 - has: ^1.0.3 - object.assign: ^4.1.4 - object.values: ^1.1.5 - prop-types: ^15.8.1 - react-is: ^16.13.1 - react-test-renderer: ^16.0.0-0 - semver: ^5.7.0 - peerDependencies: - enzyme: ^3.0.0 - react: ^16.0.0-0 - react-dom: ^16.0.0-0 - checksum: 7cb69fcdc4bf2390ffe440cfa906c698b90d533032180b5b6ddf5ace1edac0e09a687b7f36706e1bba3b02a91585d8d5bd0317c237b5f5eab00bdb5512f330ee - languageName: node - linkType: hard - -"enzyme-adapter-utils@npm:^1.14.1": - version: 1.14.1 - resolution: "enzyme-adapter-utils@npm:1.14.1" - dependencies: - airbnb-prop-types: ^2.16.0 - function.prototype.name: ^1.1.5 - has: ^1.0.3 - object.assign: ^4.1.4 - object.fromentries: ^2.0.5 - prop-types: ^15.8.1 - semver: ^5.7.1 - peerDependencies: - react: 0.13.x || 0.14.x || ^15.0.0-0 || ^16.0.0-0 - checksum: f07423c9181ed22fda4d761ec54aca6d9fb65d8b95da48c1471d39892f8af3d3fa54c971ed73a16acbc9a483ccda3a58f97a590bf95b4d5f77f99ae37c1ac8bb - languageName: node - linkType: hard - -"enzyme-shallow-equal@npm:^1.0.1, enzyme-shallow-equal@npm:^1.0.5": - version: 1.0.5 - resolution: "enzyme-shallow-equal@npm:1.0.5" - dependencies: - has: ^1.0.3 - object-is: ^1.1.5 - checksum: 30ace0c5be2d454fb001a50dd30791c18e1f86b3b7238456b464921017f6add73ea6b2a2527f1e96958d8bfe84d0afcba30b0c9e4087ebda2feb42b7800419c4 + +"entities@npm:^4.2.0, entities@npm:^4.3.0, entities@npm:^4.4.0": + version: 4.5.0 + resolution: "entities@npm:4.5.0" + checksum: 5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250 languageName: node linkType: hard -"enzyme-to-json@npm:^3.6.1": - version: 3.6.2 - resolution: "enzyme-to-json@npm:3.6.2" - dependencies: - "@types/cheerio": ^0.22.22 - lodash: ^4.17.21 - react-is: ^16.12.0 - peerDependencies: - enzyme: ^3.4.0 - checksum: 90fba5bbcfda37f456d483a46d7a077123fb65f74e59bab1e137e30c84f5b3149114efae7f9736f7ea49dd9171299645816bc5f6649b16a19d47c8bd1d6d8065 +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 languageName: node linkType: hard -"enzyme@npm:^3.11.0": - version: 3.11.0 - resolution: "enzyme@npm:3.11.0" - dependencies: - array.prototype.flat: ^1.2.3 - cheerio: ^1.0.0-rc.3 - enzyme-shallow-equal: ^1.0.1 - function.prototype.name: ^1.1.2 - has: ^1.0.3 - html-element-map: ^1.2.0 - is-boolean-object: ^1.0.1 - is-callable: ^1.1.5 - is-number-object: ^1.0.4 - is-regex: ^1.0.5 - is-string: ^1.0.5 - is-subset: ^0.1.1 - lodash.escape: ^4.0.1 - lodash.isequal: ^4.5.0 - object-inspect: ^1.7.0 - object-is: ^1.0.2 - object.assign: ^4.1.0 - object.entries: ^1.1.1 - object.values: ^1.1.1 - raf: ^3.4.1 - rst-selector-parser: ^2.2.3 - string.prototype.trim: ^1.2.1 - checksum: 14081671ed77924026036ed4edb1168cdac826aadd1ab2c77a5b7fdda625589dc5a4062cd0c65ec88add3ea3f7c0ebcbf3178bcf84b43335a175d8c71a016809 +"envinfo@npm:^7.7.3, envinfo@npm:^7.7.4": + version: 7.10.0 + resolution: "envinfo@npm:7.10.0" + bin: + envinfo: dist/cli.js + checksum: ebc7792fbedca72bc829913abe0c2a3384b883903012f97b56085afd4e83d26f7dd0652403fedd99cd3e1c93d4fb0706f5d2c3dc06ac6a1eda348280a06a9dcf languageName: node linkType: hard @@ -15881,13 +15335,6 @@ __metadata: languageName: node linkType: hard -"es-array-method-boxes-properly@npm:^1.0.0": - version: 1.0.0 - resolution: "es-array-method-boxes-properly@npm:1.0.0" - checksum: 4b7617d3fbd460d6f051f684ceca6cf7e88e6724671d9480388d3ecdd72119ddaa46ca31f2c69c5426a82e4b3091c1e81867c71dcdc453565cd90005ff2c382d - languageName: node - linkType: hard - "es-get-iterator@npm:^1.1.3": version: 1.1.3 resolution: "es-get-iterator@npm:1.1.3" @@ -16950,15 +16397,6 @@ __metadata: languageName: node linkType: hard -"extract-from-css@npm:^0.4.4": - version: 0.4.4 - resolution: "extract-from-css@npm:0.4.4" - dependencies: - css: ^2.1.0 - checksum: 8ee304fb2efbff67e41097b1b44fe8fd3bea0abb23d9e29381cc92506c2ac5ca1d2390887676e3e26636af894743b4c367899d756115df5b510804ae592a37cf - languageName: node - linkType: hard - "extract-zip@npm:^1.6.6": version: 1.7.0 resolution: "extract-zip@npm:1.7.0" @@ -16973,23 +16411,6 @@ __metadata: languageName: node linkType: hard -"extract-zip@npm:^2.0.0": - version: 2.0.1 - resolution: "extract-zip@npm:2.0.1" - dependencies: - "@types/yauzl": ^2.9.1 - debug: ^4.1.1 - get-stream: ^5.1.0 - yauzl: ^2.10.0 - dependenciesMeta: - "@types/yauzl": - optional: true - bin: - extract-zip: cli.js - checksum: 9afbd46854aa15a857ae0341a63a92743a7b89c8779102c3b4ffc207516b2019337353962309f85c66ee3d9092202a83cdc26dbf449a11981272038443974aee - languageName: node - linkType: hard - "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -17252,7 +16673,7 @@ __metadata: languageName: node linkType: hard -"find-babel-config@npm:1.2.0, find-babel-config@npm:^1.1.0": +"find-babel-config@npm:^1.1.0": version: 1.2.0 resolution: "find-babel-config@npm:1.2.0" dependencies: @@ -17801,7 +17222,7 @@ __metadata: languageName: node linkType: hard -"function.prototype.name@npm:^1.1.2, function.prototype.name@npm:^1.1.5": +"function.prototype.name@npm:^1.1.5": version: 1.1.6 resolution: "function.prototype.name@npm:1.1.6" dependencies: @@ -17908,7 +17329,7 @@ __metadata: languageName: node linkType: hard -"gensync@npm:^1.0.0-beta.1, gensync@npm:^1.0.0-beta.2": +"gensync@npm:^1.0.0-beta.2": version: 1.0.0-beta.2 resolution: "gensync@npm:1.0.0-beta.2" checksum: 782aba6cba65b1bb5af3b095d96249d20edbe8df32dbf4696fd49be2583faf676173bf4809386588828e4dd76a3354fcbeb577bab1c833ccd9fc4577f26103f8 @@ -17983,13 +17404,6 @@ __metadata: languageName: node linkType: hard -"get-stdin@npm:^5.0.1": - version: 5.0.1 - resolution: "get-stdin@npm:5.0.1" - checksum: 309f933f08a4d6783681674451027802299124e596324cd628c5e5138bbc5de843bbaa345a8ce0fc72304869f9de3b50086407aca551e292b13f7cb02351479e - languageName: node - linkType: hard - "get-stdin@npm:^6.0.0": version: 6.0.0 resolution: "get-stdin@npm:6.0.0" @@ -18373,13 +17787,6 @@ __metadata: languageName: node linkType: hard -"glur@npm:^1.1.2": - version: 1.1.2 - resolution: "glur@npm:1.1.2" - checksum: 756fcbc7f1a8576755811e31367feeaffbd13b7f20d788672bccbd65956839065e256621a7576f4ab321352b28a0aea442d64567bca23882526b891767ffbe3e - languageName: node - linkType: hard - "google-auth-library@npm:^7.14.0": version: 7.14.1 resolution: "google-auth-library@npm:7.14.1" @@ -18880,16 +18287,6 @@ __metadata: languageName: node linkType: hard -"html-element-map@npm:^1.2.0": - version: 1.3.1 - resolution: "html-element-map@npm:1.3.1" - dependencies: - array.prototype.filter: ^1.0.0 - call-bind: ^1.0.2 - checksum: 5ae8b37546601864eb41363a05871a896df36e59714607b1386a114d45f1c6b6cd1633d6fb09e09e5ee0f1c909d6b9c1bbca831333b8eef936312f61b1b5ecb8 - languageName: node - linkType: hard - "html-encoding-sniffer@npm:^2.0.1": version: 2.0.1 resolution: "html-encoding-sniffer@npm:2.0.1" @@ -18985,20 +18382,6 @@ __metadata: languageName: node linkType: hard -"htmlparser2@npm:^3.9.2": - version: 3.10.1 - resolution: "htmlparser2@npm:3.10.1" - dependencies: - domelementtype: ^1.3.1 - domhandler: ^2.3.0 - domutils: ^1.5.1 - entities: ^1.1.1 - inherits: ^2.0.1 - readable-stream: ^3.1.1 - checksum: b1424536ff062088501efa06a2afd478545d3134a5ad2e28bbe02dc2d092784982286b90f1c87fa3d86692958dbfb8936352dfd71d1cb2ff7cb61208c00fcdb1 - languageName: node - linkType: hard - "htmlparser2@npm:^6.1.0": version: 6.1.0 resolution: "htmlparser2@npm:6.1.0" @@ -19023,7 +18406,7 @@ __metadata: languageName: node linkType: hard -"htmlparser2@npm:^8.0.1, htmlparser2@npm:^8.0.2": +"htmlparser2@npm:^8.0.2": version: 8.0.2 resolution: "htmlparser2@npm:8.0.2" dependencies: @@ -19663,7 +19046,7 @@ __metadata: languageName: node linkType: hard -"is-boolean-object@npm:^1.0.1, is-boolean-object@npm:^1.1.0": +"is-boolean-object@npm:^1.1.0": version: 1.1.2 resolution: "is-boolean-object@npm:1.1.2" dependencies: @@ -19687,7 +19070,7 @@ __metadata: languageName: node linkType: hard -"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.1.5, is-callable@npm:^1.2.7": +"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" checksum: ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f @@ -20060,7 +19443,7 @@ __metadata: languageName: node linkType: hard -"is-regex@npm:^1.0.3, is-regex@npm:^1.0.4, is-regex@npm:^1.0.5, is-regex@npm:^1.1.0, is-regex@npm:^1.1.4": +"is-regex@npm:^1.0.3, is-regex@npm:^1.0.4, is-regex@npm:^1.1.4": version: 1.1.4 resolution: "is-regex@npm:1.1.4" dependencies: @@ -20132,13 +19515,6 @@ __metadata: languageName: node linkType: hard -"is-subset@npm:^0.1.1": - version: 0.1.1 - resolution: "is-subset@npm:0.1.1" - checksum: d8125598ab9077a76684e18726fb915f5cea7a7358ed0c6ff723f4484d71a0a9981ee5aae06c44de99cfdef0fefce37438c6257ab129e53c82045ea0c2acdebf - languageName: node - linkType: hard - "is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3": version: 1.0.4 resolution: "is-symbol@npm:1.0.4" @@ -20544,7 +19920,7 @@ __metadata: languageName: node linkType: hard -"jest-environment-jsdom@npm:^29.0.0, jest-environment-jsdom@npm:^29.5.0": +"jest-environment-jsdom@npm:^29.0.0": version: 29.7.0 resolution: "jest-environment-jsdom@npm:29.7.0" dependencies: @@ -20616,39 +19992,6 @@ __metadata: languageName: node linkType: hard -"jest-image-snapshot@npm:^6.0.0": - version: 6.2.0 - resolution: "jest-image-snapshot@npm:6.2.0" - dependencies: - chalk: ^4.0.0 - get-stdin: ^5.0.1 - glur: ^1.1.2 - lodash: ^4.17.4 - pixelmatch: ^5.1.0 - pngjs: ^3.4.0 - rimraf: ^2.6.2 - ssim.js: ^3.1.1 - peerDependencies: - jest: ">=20 <=29" - peerDependenciesMeta: - jest: - optional: true - checksum: 62e415f86f2bed30fe126520519014beed61a38a678285de44c6544d10eed7381b28958d3406f131a60c05715f42ab7bf7ea4ecfdab4f55946cec6739de23924 - languageName: node - linkType: hard - -"jest-junit@npm:^16.0.0": - version: 16.0.0 - resolution: "jest-junit@npm:16.0.0" - dependencies: - mkdirp: ^1.0.4 - strip-ansi: ^6.0.1 - uuid: ^8.3.2 - xml: ^1.0.1 - checksum: d813d4d142341c2b51b634db7ad6ceb9849514cb58f96ec5e7e4cf4031a557133490452710c2d9dec9b1dd546334d9ca663e042d3070c3e8f102ce6217bd8e2e - languageName: node - linkType: hard - "jest-leak-detector@npm:^29.7.0": version: 29.7.0 resolution: "jest-leak-detector@npm:29.7.0" @@ -20765,7 +20108,7 @@ __metadata: languageName: node linkType: hard -"jest-regex-util@npm:^29.0.0, jest-regex-util@npm:^29.6.3": +"jest-regex-util@npm:^29.6.3": version: 29.6.3 resolution: "jest-regex-util@npm:29.6.3" checksum: 4e33fb16c4f42111159cafe26397118dcfc4cf08bc178a67149fb05f45546a91928b820894572679d62559839d0992e21080a1527faad65daaae8743a5705a3b @@ -20858,15 +20201,6 @@ __metadata: languageName: node linkType: hard -"jest-serializer-html@npm:^7.1.0": - version: 7.1.0 - resolution: "jest-serializer-html@npm:7.1.0" - dependencies: - diffable-html: ^4.1.0 - checksum: e8383431fbacd5ebb9a7c053c849a0d1e0a183e625aba1ede726260186931b229468dc6456b9b821a137123a88ea3b4325884a5c01c5d78b39c106c3d5c18fcc - languageName: node - linkType: hard - "jest-snapshot@npm:^29.0.0, jest-snapshot@npm:^29.7.0": version: 29.7.0 resolution: "jest-snapshot@npm:29.7.0" @@ -20934,39 +20268,7 @@ __metadata: languageName: node linkType: hard -"jest-vue-preprocessor@npm:^1.7.1": - version: 1.7.1 - resolution: "jest-vue-preprocessor@npm:1.7.1" - dependencies: - babel-plugin-transform-runtime: 6.23.0 - find-babel-config: 1.2.0 - vue-property-decorator: 8.3.0 - peerDependencies: - typescript: "*" - vue-template-compiler: 2.6.x - vue-template-es2015-compiler: 1.9.x - checksum: 2e8ae5af00fd41eef5e8d9b6408f7729d6a9d984a7d7d67a6532bc214490a9038297e34592c14b4260fd2262e657e8b5a09dfe2f97c5560509b63aba9e3f79e0 - languageName: node - linkType: hard - -"jest-watch-typeahead@npm:^2.2.1": - version: 2.2.2 - resolution: "jest-watch-typeahead@npm:2.2.2" - dependencies: - ansi-escapes: ^6.0.0 - chalk: ^5.2.0 - jest-regex-util: ^29.0.0 - jest-watcher: ^29.0.0 - slash: ^5.0.0 - string-length: ^5.0.1 - strip-ansi: ^7.0.1 - peerDependencies: - jest: ^27.0.0 || ^28.0.0 || ^29.0.0 - checksum: 5a55a571d616958cd6c6b52c4bf57cfaa97132cd9681af8ebfa8ebde9fa1d829426ff36f4ef2eaa867142ee97577fdad1735c58c3db62cbb33a39ad97125ee00 - languageName: node - linkType: hard - -"jest-watcher@npm:^29.0.0, jest-watcher@npm:^29.7.0": +"jest-watcher@npm:^29.7.0": version: 29.7.0 resolution: "jest-watcher@npm:29.7.0" dependencies: @@ -21005,7 +20307,7 @@ __metadata: languageName: node linkType: hard -"jest@npm:^29.3.1, jest@npm:^29.5.0": +"jest@npm:^29.3.1": version: 29.7.0 resolution: "jest@npm:29.7.0" dependencies: @@ -22103,13 +21405,6 @@ __metadata: languageName: node linkType: hard -"lodash.escape@npm:^4.0.1": - version: 4.0.1 - resolution: "lodash.escape@npm:4.0.1" - checksum: 90ade409cec05b6869090476952fdfb84d4d87b1ff4a0e03ebd590f980d9a1248d93ba14579f10d80c6429e4d6af13ba137c28db64cae6dadb71442e54a3ad2b - languageName: node - linkType: hard - "lodash.find@npm:^4.6.0": version: 4.6.0 resolution: "lodash.find@npm:4.6.0" @@ -22117,13 +21412,6 @@ __metadata: languageName: node linkType: hard -"lodash.flattendeep@npm:^4.4.0": - version: 4.4.0 - resolution: "lodash.flattendeep@npm:4.4.0" - checksum: 83cb80754b921fb4ed2c222b91a82b2524f3bdc60c3ae91e00688bd4bf1bcc28b8a2cc250e11fdc1b6da3a2de09e57008e13f15a209cafdd4f9163d047f97544 - languageName: node - linkType: hard - "lodash.includes@npm:^4.3.0": version: 4.3.0 resolution: "lodash.includes@npm:4.3.0" @@ -22138,13 +21426,6 @@ __metadata: languageName: node linkType: hard -"lodash.isequal@npm:^4.5.0": - version: 4.5.0 - resolution: "lodash.isequal@npm:4.5.0" - checksum: dfdb2356db19631a4b445d5f37868a095e2402292d59539a987f134a8778c62a2810c2452d11ae9e6dcac71fc9de40a6fedcb20e2952a15b431ad8b29e50e28f - languageName: node - linkType: hard - "lodash.isinteger@npm:^4.0.4": version: 4.0.4 resolution: "lodash.isinteger@npm:4.0.4" @@ -22236,7 +21517,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:^4.17.13, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:^4.7.0": +"lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.7.0": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c @@ -23853,13 +23134,6 @@ __metadata: languageName: node linkType: hard -"moo@npm:^0.5.0": - version: 0.5.2 - resolution: "moo@npm:0.5.2" - checksum: a9d9ad8198a51fe35d297f6e9fdd718298ca0b39a412e868a0ebd92286379ab4533cfc1f1f34516177f5129988ab25fe598f78e77c84e3bfe0d4a877b56525a8 - languageName: node - linkType: hard - "mount-point@npm:^3.0.0": version: 3.0.0 resolution: "mount-point@npm:3.0.0" @@ -24012,23 +23286,6 @@ __metadata: languageName: node linkType: hard -"nearley@npm:^2.7.10": - version: 2.20.1 - resolution: "nearley@npm:2.20.1" - dependencies: - commander: ^2.19.0 - moo: ^0.5.0 - railroad-diagrams: ^1.0.0 - randexp: 0.4.6 - bin: - nearley-railroad: bin/nearley-railroad.js - nearley-test: bin/nearley-test.js - nearley-unparse: bin/nearley-unparse.js - nearleyc: bin/nearleyc.js - checksum: d25e1fd40b19c53a0ada6a688670f4a39063fd9553ab62885e81a82927d51572ce47193b946afa3d85efa608ba2c68f433c421f69b854bfb7f599eacb5fae37e - languageName: node - linkType: hard - "needle@npm:^3.1.0": version: 3.2.0 resolution: "needle@npm:3.2.0" @@ -24880,14 +24137,14 @@ __metadata: languageName: node linkType: hard -"object-inspect@npm:^1.12.3, object-inspect@npm:^1.7.0, object-inspect@npm:^1.9.0": +"object-inspect@npm:^1.12.3, object-inspect@npm:^1.9.0": version: 1.12.3 resolution: "object-inspect@npm:1.12.3" checksum: 752bb5f4dc595e214157ea8f442adb77bdb850ace762b078d151d8b6486331ab12364997a89ee6509be1023b15adf2b3774437a7105f8a5043dfda11ed622411 languageName: node linkType: hard -"object-is@npm:^1.0.1, object-is@npm:^1.0.2, object-is@npm:^1.1.2, object-is@npm:^1.1.5": +"object-is@npm:^1.0.1, object-is@npm:^1.1.5": version: 1.1.5 resolution: "object-is@npm:1.1.5" dependencies: @@ -24920,7 +24177,7 @@ __metadata: languageName: node linkType: hard -"object.assign@npm:^4.1.0, object.assign@npm:^4.1.2, object.assign@npm:^4.1.4": +"object.assign@npm:^4.1.2, object.assign@npm:^4.1.4": version: 4.1.4 resolution: "object.assign@npm:4.1.4" dependencies: @@ -24932,7 +24189,7 @@ __metadata: languageName: node linkType: hard -"object.entries@npm:^1.1.1, object.entries@npm:^1.1.2, object.entries@npm:^1.1.6": +"object.entries@npm:^1.1.2, object.entries@npm:^1.1.6": version: 1.1.7 resolution: "object.entries@npm:1.1.7" dependencies: @@ -24943,7 +24200,7 @@ __metadata: languageName: node linkType: hard -"object.fromentries@npm:^2.0.5, object.fromentries@npm:^2.0.6": +"object.fromentries@npm:^2.0.6": version: 2.0.7 resolution: "object.fromentries@npm:2.0.7" dependencies: @@ -24985,7 +24242,7 @@ __metadata: languageName: node linkType: hard -"object.values@npm:^1.1.1, object.values@npm:^1.1.5, object.values@npm:^1.1.6": +"object.values@npm:^1.1.6": version: 1.1.7 resolution: "object.values@npm:1.1.7" dependencies: @@ -25605,16 +24862,6 @@ __metadata: languageName: node linkType: hard -"parse5-htmlparser2-tree-adapter@npm:^7.0.0": - version: 7.0.0 - resolution: "parse5-htmlparser2-tree-adapter@npm:7.0.0" - dependencies: - domhandler: ^5.0.2 - parse5: ^7.0.0 - checksum: e820cacb8486e6f7ede403327d18480df086d70e32ede2f6654d8c3a8b4b8dc4a4d5c21c03c18a92ba2466c513b93ca63be4a138dd73cd0995f384eb3b9edf11 - languageName: node - linkType: hard - "parse5-sax-parser@npm:^7.0.0": version: 7.0.0 resolution: "parse5-sax-parser@npm:7.0.0" @@ -25949,17 +25196,6 @@ __metadata: languageName: node linkType: hard -"pixelmatch@npm:^5.1.0": - version: 5.3.0 - resolution: "pixelmatch@npm:5.3.0" - dependencies: - pngjs: ^6.0.0 - bin: - pixelmatch: bin/pixelmatch - checksum: 30850661db29b57cefbe6cf36e930b7517aea4e0ed129e85fcc8ec04a7e6e7648a822a972f8e01d2d3db268ca3c735555caf6b8099a164d8b64d105986d682d2 - languageName: node - linkType: hard - "pkg-dir@npm:^3.0.0": version: 3.0.0 resolution: "pkg-dir@npm:3.0.0" @@ -26052,20 +25288,6 @@ __metadata: languageName: node linkType: hard -"pngjs@npm:^3.4.0": - version: 3.4.0 - resolution: "pngjs@npm:3.4.0" - checksum: 88ee73e2ad3f736e0b2573722309eb80bd2aa28916f0862379b4fd0f904751b4f61bb6bd1ecd7d4242d331f2b5c28c13309dd4b7d89a9b78306e35122fdc5011 - languageName: node - linkType: hard - -"pngjs@npm:^6.0.0": - version: 6.0.0 - resolution: "pngjs@npm:6.0.0" - checksum: ac23ea329b1881d1a10575aff58116dc27b894ec3f5b84ba15c7f527d21e609fbce7ba16d48f8ccb86c7ce45ceed622472765476ab2875949d4bec55e153f87a - languageName: node - linkType: hard - "pnp-webpack-plugin@npm:^1.7.0": version: 1.7.0 resolution: "pnp-webpack-plugin@npm:1.7.0" @@ -26294,17 +25516,6 @@ __metadata: languageName: node linkType: hard -"preact-render-to-string@npm:^5.1.19": - version: 5.2.6 - resolution: "preact-render-to-string@npm:5.2.6" - dependencies: - pretty-format: ^3.8.0 - peerDependencies: - preact: ">=10" - checksum: fb40f952f377900d87d3274e8ede1b59271347f7a3f41ae390aedeb088d162fe15f0a8040272404bd4477551cc2ec83b8a661e2fd3084702498b1543bb08dd11 - languageName: node - linkType: hard - "preact@npm:^10.5.13": version: 10.17.1 resolution: "preact@npm:10.17.1" @@ -26420,13 +25631,6 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^3.8.0": - version: 3.8.0 - resolution: "pretty-format@npm:3.8.0" - checksum: 69f12937bfb7b2a537a7463b9f875a16322401f1e44d7702d643faa0d21991126c24c093217ef6da403b54c15942a834174fa1c016b72e2cb9edaae6bb3729b6 - languageName: node - linkType: hard - "pretty-hrtime@npm:^1.0.3": version: 1.0.3 resolution: "pretty-hrtime@npm:1.0.3" @@ -26584,17 +25788,6 @@ __metadata: languageName: node linkType: hard -"prop-types-exact@npm:^1.2.0": - version: 1.2.0 - resolution: "prop-types-exact@npm:1.2.0" - dependencies: - has: ^1.0.3 - object.assign: ^4.1.0 - reflect.ownkeys: ^0.2.0 - checksum: 71e186c5b982f72b8226f052b710ef6b87fff7275fcf5834b4913fa5b6c325c44be111488786fd3c4e422fb4bb4e91f3c7f35445366c9a4585405d3b02872587 - languageName: node - linkType: hard - "prop-types@npm:^15.5.10, prop-types@npm:^15.6.1, prop-types@npm:^15.6.2, prop-types@npm:^15.7.2, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" @@ -26871,24 +26064,6 @@ __metadata: languageName: node linkType: hard -"puppeteer@npm:^2.0.0 || ^3.0.0": - version: 3.3.0 - resolution: "puppeteer@npm:3.3.0" - dependencies: - debug: ^4.1.0 - extract-zip: ^2.0.0 - https-proxy-agent: ^4.0.0 - mime: ^2.0.3 - progress: ^2.0.1 - proxy-from-env: ^1.0.0 - rimraf: ^3.0.2 - tar-fs: ^2.0.0 - unbzip2-stream: ^1.3.3 - ws: ^7.2.3 - checksum: 9f8d7f00458425f9ca42580f509f5406ddf27767dbf93080d05157a7882efaf0e32c77e540c8a4d2bd295ab11584a8447d9e6593d6316bf04ce1a16d6fd11b4e - languageName: node - linkType: hard - "pure-rand@npm:^6.0.0": version: 6.0.3 resolution: "pure-rand@npm:6.0.3" @@ -27004,13 +26179,6 @@ __metadata: languageName: node linkType: hard -"railroad-diagrams@npm:^1.0.0": - version: 1.0.0 - resolution: "railroad-diagrams@npm:1.0.0" - checksum: 81bf8f86870a69fb9ed243102db9ad6416d09c4cb83964490d44717690e07dd982f671503236a1f8af28f4cb79d5d7a87613930f10ac08defa845ceb6764e364 - languageName: node - linkType: hard - "ramda@npm:0.29.0": version: 0.29.0 resolution: "ramda@npm:0.29.0" @@ -27018,16 +26186,6 @@ __metadata: languageName: node linkType: hard -"randexp@npm:0.4.6": - version: 0.4.6 - resolution: "randexp@npm:0.4.6" - dependencies: - discontinuous-range: 1.0.0 - ret: ~0.1.10 - checksum: 14ee14b6d7f5ce69609b51cc914fb7a7c82ad337820a141c5f762c5ad1fe868f5191ea6e82359aee019b625ee1359486628fa833909d12c3b5dd9571908c3345 - languageName: node - linkType: hard - "randombytes@npm:^2.0.0, randombytes@npm:^2.0.1, randombytes@npm:^2.0.5, randombytes@npm:^2.1.0": version: 2.1.0 resolution: "randombytes@npm:2.1.0" @@ -27221,7 +26379,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.12.0, react-is@npm:^16.13.1, react-is@npm:^16.7.0, react-is@npm:^16.8.6": +"react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: 33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1 @@ -27446,20 +26604,6 @@ __metadata: languageName: node linkType: hard -"react-test-renderer@npm:^16, react-test-renderer@npm:^16.0.0-0": - version: 16.14.0 - resolution: "react-test-renderer@npm:16.14.0" - dependencies: - object-assign: ^4.1.1 - prop-types: ^15.6.2 - react-is: ^16.8.6 - scheduler: ^0.19.1 - peerDependencies: - react: ^16.14.0 - checksum: 119e3ce5509c3443393ca750e39dd4ac9ee9ddfaafca58c9067b477447edc2badb75660b9fea7e9ddef012e37bbba427681cf6f8d3fde61b8054655a133bfbf5 - languageName: node - linkType: hard - "react-textarea-autosize@npm:^8.3.0": version: 8.5.3 resolution: "react-textarea-autosize@npm:8.5.3" @@ -27775,13 +26919,6 @@ __metadata: languageName: node linkType: hard -"reflect.ownkeys@npm:^0.2.0": - version: 0.2.0 - resolution: "reflect.ownkeys@npm:0.2.0" - checksum: 169f20287ad33b76fc8b6932734b3e1469ee59f31d8357858e96718a6f71fa60d7a13f2fc4e9191e47c2a51e4183151290f3a35315ba461190d87b0593725557 - languageName: node - linkType: hard - "refractor@npm:^3.6.0": version: 3.6.0 resolution: "refractor@npm:3.6.0" @@ -27809,13 +26946,6 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.11.0": - version: 0.11.1 - resolution: "regenerator-runtime@npm:0.11.1" - checksum: 69cfa839efcf2d627fe358bf302ab8b24e5f182cb69f13e66f0612d3640d7838aad1e55662135e3ef2c1cc4322315b757626094fab13a48f9a64ab4bdeb8795b - languageName: node - linkType: hard - "regenerator-runtime@npm:^0.13.11, regenerator-runtime@npm:^0.13.2, regenerator-runtime@npm:^0.13.4, regenerator-runtime@npm:^0.13.9": version: 0.13.11 resolution: "regenerator-runtime@npm:0.13.11" @@ -28430,7 +27560,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.13.1, resolve@npm:^1.14.2, resolve@npm:^1.15.1, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.4, resolve@npm:^1.3.2, resolve@npm:^1.4.0": +"resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.13.1, resolve@npm:^1.14.2, resolve@npm:^1.15.1, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.4, resolve@npm:^1.4.0": version: 1.22.4 resolution: "resolve@npm:1.22.4" dependencies: @@ -28469,7 +27599,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.13.1#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.15.1#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.3.2#~builtin, resolve@patch:resolve@^1.4.0#~builtin": +"resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.13.1#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.15.1#~builtin, resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.4#~builtin, resolve@patch:resolve@^1.4.0#~builtin": version: 1.22.4 resolution: "resolve@patch:resolve@npm%3A1.22.4#~builtin::version=1.22.4&hash=c3c19d" dependencies: @@ -28637,16 +27767,6 @@ __metadata: languageName: node linkType: hard -"rst-selector-parser@npm:^2.2.3": - version: 2.2.3 - resolution: "rst-selector-parser@npm:2.2.3" - dependencies: - lodash.flattendeep: ^4.4.0 - nearley: ^2.7.10 - checksum: b631aca2cb451fbde8d78dbc9a9479f20f1f40565cd8eb63773cb6e2a395ed87b392291986b84c2c7da68b70084e3469fbe958261300a10dff41c87fa3bc58aa - languageName: node - linkType: hard - "rsvp@npm:^3.0.14, rsvp@npm:^3.0.18": version: 3.6.2 resolution: "rsvp@npm:3.6.2" @@ -28693,7 +27813,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^6.5.2, rxjs@npm:^6.6.3": +"rxjs@npm:^6.5.2": version: 6.6.7 resolution: "rxjs@npm:6.6.7" dependencies: @@ -28957,7 +28077,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.3.0, semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.6.0, semver@npm:^5.7.0, semver@npm:^5.7.1": +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.3.0, semver@npm:^5.5.0, semver@npm:^5.6.0": version: 5.7.2 resolution: "semver@npm:5.7.2" bin: @@ -29450,7 +28570,7 @@ __metadata: languageName: node linkType: hard -"source-map-resolve@npm:^0.5.0, source-map-resolve@npm:^0.5.2": +"source-map-resolve@npm:^0.5.0": version: 0.5.3 resolution: "source-map-resolve@npm:0.5.3" dependencies: @@ -29537,7 +28657,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.5.0, source-map@npm:^0.5.6, source-map@npm:^0.5.7": +"source-map@npm:^0.5.6, source-map@npm:^0.5.7": version: 0.5.7 resolution: "source-map@npm:0.5.7" checksum: 904e767bb9c494929be013017380cbba013637da1b28e5943b566031e29df04fba57edf3f093e0914be094648b577372bd8ad247fa98cfba9c600794cd16b599 @@ -29626,15 +28746,6 @@ __metadata: languageName: node linkType: hard -"specificity@npm:^0.4.1": - version: 0.4.1 - resolution: "specificity@npm:0.4.1" - bin: - specificity: ./bin/specificity - checksum: 5da85a05052b55e344cb0f5bce5d07cbabbbe8945da176a481589db5a13e9fbcfa879ceb075cf564b94e680fae0a2ab14ea55cc87496b86a6d5122545946d7c2 - languageName: node - linkType: hard - "split-on-first@npm:^1.0.0": version: 1.1.0 resolution: "split-on-first@npm:1.1.0" @@ -29683,13 +28794,6 @@ __metadata: languageName: node linkType: hard -"ssim.js@npm:^3.1.1": - version: 3.5.0 - resolution: "ssim.js@npm:3.5.0" - checksum: 9e7101da17395d3acbd417aac712d8f156522e79059a27cb38882eedd5a8868e31871c8f58bec3a150f8cf0660883cf22310cbd2fd63b408c1fd0ab02fda9fbc - languageName: node - linkType: hard - "ssri@npm:9.0.1, ssri@npm:^9.0.0": version: 9.0.1 resolution: "ssri@npm:9.0.1" @@ -29865,16 +28969,6 @@ __metadata: languageName: node linkType: hard -"string-length@npm:^5.0.1": - version: 5.0.1 - resolution: "string-length@npm:5.0.1" - dependencies: - char-regex: ^2.0.0 - strip-ansi: ^7.0.1 - checksum: 311fa5758d397bd616be17150dfefaab4755ed292a3112237924d10ba5122f606064ad4880a293387401c1d7aa20d79f7936728bac2abed17a5e48f5b317cbc8 - languageName: node - linkType: hard - "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -29924,7 +29018,7 @@ __metadata: languageName: node linkType: hard -"string.prototype.trim@npm:^1.2.1, string.prototype.trim@npm:^1.2.7": +"string.prototype.trim@npm:^1.2.7": version: 1.2.8 resolution: "string.prototype.trim@npm:1.2.8" dependencies: @@ -30385,7 +29479,7 @@ __metadata: languageName: node linkType: hard -"tar-fs@npm:^2.0.0, tar-fs@npm:^2.1.1": +"tar-fs@npm:^2.1.1": version: 2.1.1 resolution: "tar-fs@npm:2.1.1" dependencies: @@ -30610,7 +29704,7 @@ __metadata: languageName: node linkType: hard -"through@npm:2, through@npm:>=2.2.7 <3, through@npm:^2.3.4, through@npm:^2.3.6, through@npm:^2.3.8": +"through@npm:2, through@npm:>=2.2.7 <3, through@npm:^2.3.4, through@npm:^2.3.6": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: 4b09f3774099de0d4df26d95c5821a62faee32c7e96fb1f4ebd54a2d7c11c57fe88b0a0d49cf375de5fee5ae6bf4eb56dbbf29d07366864e2ee805349970d3cc @@ -31299,16 +30393,6 @@ __metadata: languageName: node linkType: hard -"unbzip2-stream@npm:^1.3.3": - version: 1.4.3 - resolution: "unbzip2-stream@npm:1.4.3" - dependencies: - buffer: ^5.2.1 - through: ^2.3.8 - checksum: 2ea2048f3c9db3499316ccc1d95ff757017ccb6f46c812d7c42466247e3b863fb178864267482f7f178254214247779daf68e85f50bd7736c3c97ba2d58b910a - languageName: node - linkType: hard - "underscore.string@npm:~3.3.4": version: 3.3.6 resolution: "underscore.string@npm:3.3.6" @@ -32378,15 +31462,6 @@ __metadata: languageName: node linkType: hard -"vue-class-component@npm:^7.1.0": - version: 7.2.6 - resolution: "vue-class-component@npm:7.2.6" - peerDependencies: - vue: ^2.0.0 - checksum: 2c187815e3569b4836929dc45ace5715398c4037312ef5fc27da9cb12fbbc21cabbdfc5fb678451ad45321ffabacbd184907e33db2539c13963c00883a6645c1 - languageName: node - linkType: hard - "vue-component-type-helpers@npm:latest": version: 1.8.10 resolution: "vue-component-type-helpers@npm:1.8.10" @@ -32444,32 +31519,6 @@ __metadata: languageName: node linkType: hard -"vue-jest@npm:^5.0.0-alpha.8": - version: 5.0.0-alpha.10 - resolution: "vue-jest@npm:5.0.0-alpha.10" - dependencies: - "@babel/plugin-transform-modules-commonjs": ^7.2.0 - chalk: ^2.1.0 - convert-source-map: ^1.6.0 - extract-from-css: ^0.4.4 - source-map: 0.5.6 - tsconfig: ^7.0.0 - peerDependencies: - "@babel/core": 7.x - babel-jest: ">= 24 < 27" - jest: ">= 24 < 27 " - ts-jest: ">= 24 < 27 " - typescript: ">= 3.x" - vue: ^3.0.0-0 - peerDependenciesMeta: - ts-jest: - optional: true - typescript: - optional: true - checksum: dd2dabd4ab4030d7fe567304ba035f61e0abe48501a18b9a3e331e60aac44a03f782746859347ea0cfeb906b8dcf5d5ca58b854c9656ea2feee08e8f00f7c54b - languageName: node - linkType: hard - "vue-loader@npm:^15.7.0": version: 15.10.2 resolution: "vue-loader@npm:15.10.2" @@ -32506,15 +31555,6 @@ __metadata: languageName: node linkType: hard -"vue-property-decorator@npm:8.3.0": - version: 8.3.0 - resolution: "vue-property-decorator@npm:8.3.0" - dependencies: - vue-class-component: ^7.1.0 - checksum: 8e0c9ece0a5bb2e8b24bfa9f6516731feabe44773bf75bfdf66ce5cbb59c30fc837d4dbe2b2edf991b12d78fc75b57a76346ca658d561172935eb51db244fc3d - languageName: node - linkType: hard - "vue-style-loader@npm:^4.1.0": version: 4.1.3 resolution: "vue-style-loader@npm:4.1.3" @@ -33358,7 +32398,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^7.2.3, ws@npm:^7.4.6": +"ws@npm:^7.4.6": version: 7.5.9 resolution: "ws@npm:7.5.9" peerDependencies: @@ -33428,13 +32468,6 @@ __metadata: languageName: node linkType: hard -"xml@npm:^1.0.1": - version: 1.0.1 - resolution: "xml@npm:1.0.1" - checksum: 04bcc9b8b5e7b49392072fbd9c6b0f0958bd8e8f8606fee460318e43991349a68cbc5384038d179ff15aef7d222285f69ca0f067f53d071084eb14c7fdb30411 - languageName: node - linkType: hard - "xmlchars@npm:^2.2.0": version: 2.2.0 resolution: "xmlchars@npm:2.2.0" diff --git a/scripts/__mocks__/simple-git.js b/scripts/__mocks__/simple-git.js deleted file mode 100644 index 89fa9f23c7b1..000000000000 --- a/scripts/__mocks__/simple-git.js +++ /dev/null @@ -1,18 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -const mod = jest.createMockFromModule('simple-git'); - -mod.__getRemotes = jest - .fn() - .mockReturnValue([{ name: 'origin', refs: { fetch: 'origin', push: 'origin' } }]); -mod.__fetch = jest.fn(); -mod.__revparse = jest.fn().mockResolvedValue('mockedGitCommitHash'); - -mod.simpleGit = () => { - return { - getRemotes: mod.__getRemotes, - fetch: mod.__fetch, - revparse: mod.__revparse, - }; -}; - -module.exports = mod; diff --git a/scripts/__mocks__/simple-git.ts b/scripts/__mocks__/simple-git.ts new file mode 100644 index 000000000000..2e1ec381c934 --- /dev/null +++ b/scripts/__mocks__/simple-git.ts @@ -0,0 +1,18 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/* eslint-disable no-underscore-dangle */ +import { vi } from 'vitest'; + +export const __getRemotes = vi + .fn() + .mockReturnValue([{ name: 'origin', refs: { fetch: 'origin', push: 'origin' } }]); +export const __fetch = vi.fn(); +export const __revparse = vi.fn().mockResolvedValue('mockedGitCommitHash'); + +export const simpleGit = () => { + return { + getRemotes: __getRemotes, + fetch: __fetch, + revparse: __revparse, + log: vi.fn(), + }; +}; diff --git a/scripts/__mocks__/uuid.ts b/scripts/__mocks__/uuid.ts index bd6e08f5a6eb..7f3504c901d7 100644 --- a/scripts/__mocks__/uuid.ts +++ b/scripts/__mocks__/uuid.ts @@ -1,4 +1,4 @@ -const { v5 } = jest.requireActual('uuid'); +import { v5 } from 'uuid'; let seed = 0; @@ -6,3 +6,5 @@ export const v4 = () => { seed += 1; return v5(seed.toString(), '6c7fda6d-f92f-4bd2-9d4d-da26a59196a6'); }; + +// https://github.com/Menci/vite-plugin-top-level-await diff --git a/scripts/release/__tests__/generate-pr-description.test.ts b/scripts/release/__tests__/generate-pr-description.test.ts index b0f1bbe89db5..1277b95a7e95 100644 --- a/scripts/release/__tests__/generate-pr-description.test.ts +++ b/scripts/release/__tests__/generate-pr-description.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { generateReleaseDescription, generateNonReleaseDescription, @@ -94,7 +95,7 @@ describe('Generate PR Description', () => { expect(mapToChangelist({ changes, unpickedPatches: true })).toMatchInlineSnapshot(` "- [ ] **🐛 Bug**: Some PR title for a bug [#42](https://github.com/storybookjs/storybook/pull/42) - [ ] **✨ Feature Request**: Some PR title for a 'new' feature [#48](https://github.com/storybookjs/storybook/pull/48) - - [ ] **⚠️ Direct commit**: Some title for a "direct commit" [22bb11](https://github.com/storybookjs/storybook/commit/22bb11) + - [ ] **⚠️ Direct commit**: Some title for a \\"direct commit\\" [22bb11](https://github.com/storybookjs/storybook/commit/22bb11) - [ ] **📝 Documentation**: Another PR \`title\` for docs [#11](https://github.com/storybookjs/storybook/pull/11) - [ ] **❔ Missing Label**: Some PR title with a missing label [#77](https://github.com/storybookjs/storybook/pull/77)" `); @@ -103,7 +104,7 @@ describe('Generate PR Description', () => { expect(mapToChangelist({ changes, unpickedPatches: false })).toMatchInlineSnapshot(` "- [ ] **🐛 Bug**: Some PR title for a bug [#42](https://github.com/storybookjs/storybook/pull/42) (will also be patched) - [ ] **✨ Feature Request**: Some PR title for a 'new' feature [#48](https://github.com/storybookjs/storybook/pull/48) - - [ ] **⚠️ Direct commit**: Some title for a "direct commit" [22bb11](https://github.com/storybookjs/storybook/commit/22bb11) + - [ ] **⚠️ Direct commit**: Some title for a \\"direct commit\\" [22bb11](https://github.com/storybookjs/storybook/commit/22bb11) - [ ] **📝 Documentation**: Another PR \`title\` for docs [#11](https://github.com/storybookjs/storybook/pull/11) (will also be patched) - [ ] **❔ Missing Label**: Some PR title with a missing label [#77](https://github.com/storybookjs/storybook/pull/77)" `); @@ -116,7 +117,7 @@ describe('Generate PR Description', () => { "## 🍒 Manual cherry picking needed! The following pull requests could not be cherry-picked automatically because it resulted in merge conflicts. - For each pull request below, you need to either manually cherry pick it, or discard it by replacing the "patch:yes" label with "patch:no" on the PR and re-generate this PR. + For each pull request below, you need to either manually cherry pick it, or discard it by replacing the \\"patch:yes\\" label with \\"patch:no\\" on the PR and re-generate this PR. - [ ] [#42](https://github.com/storybookjs/storybook/pull/42): \`git cherry-pick -m1 -x abc123\`" `); @@ -165,39 +166,39 @@ For each pull request below, you need to either manually cherry pick it, or disc manualCherryPicks, }) ).toMatchInlineSnapshot(` - "This is an automated pull request that bumps the version from \\\`7.1.0-alpha.10\\\` to \\\`7.1.0-alpha.11\\\`. - Once this pull request is merged, it will trigger a new release of version \\\`7.1.0-alpha.11\\\`. - If you\\'re not a core maintainer with permissions to release you can ignore this pull request. + "This is an automated pull request that bumps the version from \\\\\`7.1.0-alpha.10\\\\\` to \\\\\`7.1.0-alpha.11\\\\\`. + Once this pull request is merged, it will trigger a new release of version \\\\\`7.1.0-alpha.11\\\\\`. + If you\\\\'re not a core maintainer with permissions to release you can ignore this pull request. ## To do Before merging the PR, there are a few QA steps to go through: - - [ ] Add the \\"freeze\\" label to this PR, to ensure it doesn\\'t get automatically forced pushed by new changes. - - [ ] Add the \\"ci:daily\\" label to this PR, to trigger the full test suite to run on this PR. + - [ ] Add the \\\\\\"freeze\\\\\\" label to this PR, to ensure it doesn\\\\'t get automatically forced pushed by new changes. + - [ ] Add the \\\\\\"ci:daily\\\\\\" label to this PR, to trigger the full test suite to run on this PR. And for each change below: 1. Ensure the change is appropriate for the version bump. E.g. patch release should only contain patches, not new or de-stabilizing features. If a change is not appropriate, revert the PR. - 2. Ensure the PR is labeled correctly with one of: \\"BREAKING CHANGE\\", \\"feature request\\", \\"bug\\", \\"maintenance\\", \\"dependencies\\", \\"documentation\\", \\"build\\", \\"unknown\\". - 3. Ensure the PR title is correct, and follows the format \\"[Area]: [Summary]\\", e.g. *\\"React: Fix hooks in CSF3 render functions\\"*. If it is not correct, change the title in the PR. + 2. Ensure the PR is labeled correctly with one of: \\\\\\"BREAKING CHANGE\\\\\\", \\\\\\"feature request\\\\\\", \\\\\\"bug\\\\\\", \\\\\\"maintenance\\\\\\", \\\\\\"dependencies\\\\\\", \\\\\\"documentation\\\\\\", \\\\\\"build\\\\\\", \\\\\\"unknown\\\\\\". + 3. Ensure the PR title is correct, and follows the format \\\\\\"[Area]: [Summary]\\\\\\", e.g. *\\\\\\"React: Fix hooks in CSF3 render functions\\\\\\"*. If it is not correct, change the title in the PR. - Areas include: React, Vue, Core, Docs, Controls, etc. - First word of summary indicates the type: “Add”, “Fix”, “Upgrade”, etc. - The entire title should fit on a line - This is a list of all the PRs merged and commits pushed directly to \\\`next\\\`, that will be part of this release: + This is a list of all the PRs merged and commits pushed directly to \\\\\`next\\\\\`, that will be part of this release: - **🐛 Bug**: Some PR title for a bug [#42](https://github.com/storybookjs/storybook/pull/42) - [ ] The change is appropriate for the version bump - [ ] The PR is labeled correctly - [ ] The PR title is correct - - **⚠️ Direct commit**: Some title for a \\\\"direct commit\\\\" [22bb11](https://github.com/storybookjs/storybook/commit/22bb11) + - **⚠️ Direct commit**: Some title for a \\\\\\\\\\"direct commit\\\\\\\\\\" [22bb11](https://github.com/storybookjs/storybook/commit/22bb11) - [ ] The change is appropriate for the version bump - - **📝 Documentation**: Another PR \\\\\`title\\\\\` for docs [#11](https://github.com/storybookjs/storybook/pull/11) + - **📝 Documentation**: Another PR \\\\\\\\\`title\\\\\\\\\` for docs [#11](https://github.com/storybookjs/storybook/pull/11) - [ ] The change is appropriate for the version bump - [ ] The PR is labeled correctly - [ ] The PR title is correct - - **✨ Feature Request**: Some PR title for a \\\\'new\\\\' feature [#48](https://github.com/storybookjs/storybook/pull/48) + - **✨ Feature Request**: Some PR title for a \\\\\\\\'new\\\\\\\\' feature [#48](https://github.com/storybookjs/storybook/pull/48) - [ ] The change is appropriate for the version bump - [ ] The PR is labeled correctly - [ ] The PR title is correct @@ -209,13 +210,13 @@ For each pull request below, you need to either manually cherry pick it, or disc ## 🍒 Manual cherry picking needed! The following pull requests could not be cherry-picked automatically because it resulted in merge conflicts. - For each pull request below, you need to either manually cherry pick it, or discard it by removing the \\"patch\\" label from the PR and re-generate this PR. + For each pull request below, you need to either manually cherry pick it, or discard it by removing the \\\\\\"patch\\\\\\" label from the PR and re-generate this PR. - - [ ] [#42](https://github.com/storybookjs/storybook/pull/42): \\\`git cherry-pick -m1 -x abc123\\\` + - [ ] [#42](https://github.com/storybookjs/storybook/pull/42): \\\\\`git cherry-pick -m1 -x abc123\\\\\` - If you\\'ve made any changes doing the above QA (change PR titles, revert PRs), manually trigger a re-generation of this PR with [this workflow](https://github.com/storybookjs/storybook/actions/workflows/prepare-prerelease.yml) and wait for it to finish. It will wipe your progress in this to do, which is expected. + If you\\\\'ve made any changes doing the above QA (change PR titles, revert PRs), manually trigger a re-generation of this PR with [this workflow](https://github.com/storybookjs/storybook/actions/workflows/prepare-prerelease.yml) and wait for it to finish. It will wipe your progress in this to do, which is expected. - Feel free to manually commit any changes necessary to this branch **after** you\\'ve done the last re-generation, following the [Make Manual Changes](https://github.com/storybookjs/storybook/blob/next/CONTRIBUTING/RELEASING.md#5-make-manual-changes) section in the docs, *especially* if you\\'re making changes to the changelog. + Feel free to manually commit any changes necessary to this branch **after** you\\\\'ve done the last re-generation, following the [Make Manual Changes](https://github.com/storybookjs/storybook/blob/next/CONTRIBUTING/RELEASING.md#5-make-manual-changes) section in the docs, *especially* if you\\\\'re making changes to the changelog. When everything above is done: - Merge this PR @@ -227,37 +228,37 @@ For each pull request below, you need to either manually cherry pick it, or disc ## 7.1.0-alpha.11 - - Some PR \\\`title\\\` for a bug [#42](https://github.com/storybookjs/storybook/pull/42), thanks [@ JReinhold](https://github.com/JReinhold) - - Some PR \\'title\\' for a feature request [#48](https://github.com/storybookjs/storybook/pull/48), thanks [@ JReinhold](https://github.com/JReinhold) - - Antoher PR \\"title\\" for maintainance [#49](https://github.com/storybookjs/storybook/pull/49), thanks [@ JReinhold](https://github.com/JReinhold)" + - Some PR \\\\\`title\\\\\` for a bug [#42](https://github.com/storybookjs/storybook/pull/42), thanks [@ JReinhold](https://github.com/JReinhold) + - Some PR \\\\'title\\\\' for a feature request [#48](https://github.com/storybookjs/storybook/pull/48), thanks [@ JReinhold](https://github.com/JReinhold) + - Antoher PR \\\\\\"title\\\\\\" for maintainance [#49](https://github.com/storybookjs/storybook/pull/49), thanks [@ JReinhold](https://github.com/JReinhold)" `); }); it('should return a correct string for non-releases with cherry picks', () => { expect(generateNonReleaseDescription(changeList, manualCherryPicks)).toMatchInlineSnapshot(` "This is an automated pull request. None of the changes requires a version bump, they are only internal or documentation related. Merging this PR will not trigger a new release, but documentation will be updated. - If you\\'re not a core maintainer with permissions to release you can ignore this pull request. + If you\\\\'re not a core maintainer with permissions to release you can ignore this pull request. ## To do Before merging the PR: - - [ ] Add the \\"freeze\\" label to this PR, to ensure it doesn\\'t get automatically forced pushed by new changes. - - [ ] Add the \\"ci:daily\\" label to this PR, to trigger the full test suite to run on this PR. + - [ ] Add the \\\\\\"freeze\\\\\\" label to this PR, to ensure it doesn\\\\'t get automatically forced pushed by new changes. + - [ ] Add the \\\\\\"ci:daily\\\\\\" label to this PR, to trigger the full test suite to run on this PR. - This is a list of all the PRs merged and commits pushed directly to \\\`next\\\` since the last release: + This is a list of all the PRs merged and commits pushed directly to \\\\\`next\\\\\` since the last release: - **🐛 Bug**: Some PR title for a bug [#42](https://github.com/storybookjs/storybook/pull/42) - [ ] The change is appropriate for the version bump - [ ] The PR is labeled correctly - [ ] The PR title is correct - - **⚠️ Direct commit**: Some title for a \\\\"direct commit\\\\" [22bb11](https://github.com/storybookjs/storybook/commit/22bb11) + - **⚠️ Direct commit**: Some title for a \\\\\\\\\\"direct commit\\\\\\\\\\" [22bb11](https://github.com/storybookjs/storybook/commit/22bb11) - [ ] The change is appropriate for the version bump - - **📝 Documentation**: Another PR \\\\\`title\\\\\` for docs [#11](https://github.com/storybookjs/storybook/pull/11) + - **📝 Documentation**: Another PR \\\\\\\\\`title\\\\\\\\\` for docs [#11](https://github.com/storybookjs/storybook/pull/11) - [ ] The change is appropriate for the version bump - [ ] The PR is labeled correctly - [ ] The PR title is correct - - **✨ Feature Request**: Some PR title for a \\\\'new\\\\' feature [#48](https://github.com/storybookjs/storybook/pull/48) + - **✨ Feature Request**: Some PR title for a \\\\\\\\'new\\\\\\\\' feature [#48](https://github.com/storybookjs/storybook/pull/48) - [ ] The change is appropriate for the version bump - [ ] The PR is labeled correctly - [ ] The PR title is correct @@ -269,13 +270,13 @@ For each pull request below, you need to either manually cherry pick it, or disc ## 🍒 Manual cherry picking needed! The following pull requests could not be cherry-picked automatically because it resulted in merge conflicts. - For each pull request below, you need to either manually cherry pick it, or discard it by removing the \\"patch\\" label from the PR and re-generate this PR. + For each pull request below, you need to either manually cherry pick it, or discard it by removing the \\\\\\"patch\\\\\\" label from the PR and re-generate this PR. - - [ ] [#42](https://github.com/storybookjs/storybook/pull/42): \\\`git cherry-pick -m1 -x abc123\\\` + - [ ] [#42](https://github.com/storybookjs/storybook/pull/42): \\\\\`git cherry-pick -m1 -x abc123\\\\\` - If you\\'ve made any changes (change PR titles, revert PRs), manually trigger a re-generation of this PR with [this workflow](https://github.com/storybookjs/storybook/actions/workflows/prepare-patch-release.yml) and wait for it to finish. + If you\\\\'ve made any changes (change PR titles, revert PRs), manually trigger a re-generation of this PR with [this workflow](https://github.com/storybookjs/storybook/actions/workflows/prepare-patch-release.yml) and wait for it to finish. - Feel free to manually commit any changes necessary to this branch **after** you\\'ve done the last re-generation, following the [Make Manual Changes](https://github.com/storybookjs/storybook/blob/next/CONTRIBUTING/RELEASING.md#5-make-manual-changes) section in the docs. + Feel free to manually commit any changes necessary to this branch **after** you\\\\'ve done the last re-generation, following the [Make Manual Changes](https://github.com/storybookjs/storybook/blob/next/CONTRIBUTING/RELEASING.md#5-make-manual-changes) section in the docs. When everything above is done: - Merge this PR @@ -297,39 +298,39 @@ For each pull request below, you need to either manually cherry pick it, or disc changelogText, }) ).toMatchInlineSnapshot(` - "This is an automated pull request that bumps the version from \\\`7.1.0-alpha.10\\\` to \\\`7.1.0-alpha.11\\\`. - Once this pull request is merged, it will trigger a new release of version \\\`7.1.0-alpha.11\\\`. - If you\\'re not a core maintainer with permissions to release you can ignore this pull request. + "This is an automated pull request that bumps the version from \\\\\`7.1.0-alpha.10\\\\\` to \\\\\`7.1.0-alpha.11\\\\\`. + Once this pull request is merged, it will trigger a new release of version \\\\\`7.1.0-alpha.11\\\\\`. + If you\\\\'re not a core maintainer with permissions to release you can ignore this pull request. ## To do Before merging the PR, there are a few QA steps to go through: - - [ ] Add the \\"freeze\\" label to this PR, to ensure it doesn\\'t get automatically forced pushed by new changes. - - [ ] Add the \\"ci:daily\\" label to this PR, to trigger the full test suite to run on this PR. + - [ ] Add the \\\\\\"freeze\\\\\\" label to this PR, to ensure it doesn\\\\'t get automatically forced pushed by new changes. + - [ ] Add the \\\\\\"ci:daily\\\\\\" label to this PR, to trigger the full test suite to run on this PR. And for each change below: 1. Ensure the change is appropriate for the version bump. E.g. patch release should only contain patches, not new or de-stabilizing features. If a change is not appropriate, revert the PR. - 2. Ensure the PR is labeled correctly with one of: \\"BREAKING CHANGE\\", \\"feature request\\", \\"bug\\", \\"maintenance\\", \\"dependencies\\", \\"documentation\\", \\"build\\", \\"unknown\\". - 3. Ensure the PR title is correct, and follows the format \\"[Area]: [Summary]\\", e.g. *\\"React: Fix hooks in CSF3 render functions\\"*. If it is not correct, change the title in the PR. + 2. Ensure the PR is labeled correctly with one of: \\\\\\"BREAKING CHANGE\\\\\\", \\\\\\"feature request\\\\\\", \\\\\\"bug\\\\\\", \\\\\\"maintenance\\\\\\", \\\\\\"dependencies\\\\\\", \\\\\\"documentation\\\\\\", \\\\\\"build\\\\\\", \\\\\\"unknown\\\\\\". + 3. Ensure the PR title is correct, and follows the format \\\\\\"[Area]: [Summary]\\\\\\", e.g. *\\\\\\"React: Fix hooks in CSF3 render functions\\\\\\"*. If it is not correct, change the title in the PR. - Areas include: React, Vue, Core, Docs, Controls, etc. - First word of summary indicates the type: “Add”, “Fix”, “Upgrade”, etc. - The entire title should fit on a line - This is a list of all the PRs merged and commits pushed directly to \\\`next\\\`, that will be part of this release: + This is a list of all the PRs merged and commits pushed directly to \\\\\`next\\\\\`, that will be part of this release: - **🐛 Bug**: Some PR title for a bug [#42](https://github.com/storybookjs/storybook/pull/42) - [ ] The change is appropriate for the version bump - [ ] The PR is labeled correctly - [ ] The PR title is correct - - **⚠️ Direct commit**: Some title for a \\\\"direct commit\\\\" [22bb11](https://github.com/storybookjs/storybook/commit/22bb11) + - **⚠️ Direct commit**: Some title for a \\\\\\\\\\"direct commit\\\\\\\\\\" [22bb11](https://github.com/storybookjs/storybook/commit/22bb11) - [ ] The change is appropriate for the version bump - - **📝 Documentation**: Another PR \\\\\`title\\\\\` for docs [#11](https://github.com/storybookjs/storybook/pull/11) + - **📝 Documentation**: Another PR \\\\\\\\\`title\\\\\\\\\` for docs [#11](https://github.com/storybookjs/storybook/pull/11) - [ ] The change is appropriate for the version bump - [ ] The PR is labeled correctly - [ ] The PR title is correct - - **✨ Feature Request**: Some PR title for a \\\\'new\\\\' feature [#48](https://github.com/storybookjs/storybook/pull/48) + - **✨ Feature Request**: Some PR title for a \\\\\\\\'new\\\\\\\\' feature [#48](https://github.com/storybookjs/storybook/pull/48) - [ ] The change is appropriate for the version bump - [ ] The PR is labeled correctly - [ ] The PR title is correct @@ -340,9 +341,9 @@ For each pull request below, you need to either manually cherry pick it, or disc - If you\\'ve made any changes doing the above QA (change PR titles, revert PRs), manually trigger a re-generation of this PR with [this workflow](https://github.com/storybookjs/storybook/actions/workflows/prepare-prerelease.yml) and wait for it to finish. It will wipe your progress in this to do, which is expected. + If you\\\\'ve made any changes doing the above QA (change PR titles, revert PRs), manually trigger a re-generation of this PR with [this workflow](https://github.com/storybookjs/storybook/actions/workflows/prepare-prerelease.yml) and wait for it to finish. It will wipe your progress in this to do, which is expected. - Feel free to manually commit any changes necessary to this branch **after** you\\'ve done the last re-generation, following the [Make Manual Changes](https://github.com/storybookjs/storybook/blob/next/CONTRIBUTING/RELEASING.md#5-make-manual-changes) section in the docs, *especially* if you\\'re making changes to the changelog. + Feel free to manually commit any changes necessary to this branch **after** you\\\\'ve done the last re-generation, following the [Make Manual Changes](https://github.com/storybookjs/storybook/blob/next/CONTRIBUTING/RELEASING.md#5-make-manual-changes) section in the docs, *especially* if you\\\\'re making changes to the changelog. When everything above is done: - Merge this PR @@ -354,37 +355,37 @@ For each pull request below, you need to either manually cherry pick it, or disc ## 7.1.0-alpha.11 - - Some PR \\\`title\\\` for a bug [#42](https://github.com/storybookjs/storybook/pull/42), thanks [@ JReinhold](https://github.com/JReinhold) - - Some PR \\'title\\' for a feature request [#48](https://github.com/storybookjs/storybook/pull/48), thanks [@ JReinhold](https://github.com/JReinhold) - - Antoher PR \\"title\\" for maintainance [#49](https://github.com/storybookjs/storybook/pull/49), thanks [@ JReinhold](https://github.com/JReinhold)" + - Some PR \\\\\`title\\\\\` for a bug [#42](https://github.com/storybookjs/storybook/pull/42), thanks [@ JReinhold](https://github.com/JReinhold) + - Some PR \\\\'title\\\\' for a feature request [#48](https://github.com/storybookjs/storybook/pull/48), thanks [@ JReinhold](https://github.com/JReinhold) + - Antoher PR \\\\\\"title\\\\\\" for maintainance [#49](https://github.com/storybookjs/storybook/pull/49), thanks [@ JReinhold](https://github.com/JReinhold)" `); }); it('should return a correct string for non-releases without cherry picks', () => { expect(generateNonReleaseDescription(changeList)).toMatchInlineSnapshot(` "This is an automated pull request. None of the changes requires a version bump, they are only internal or documentation related. Merging this PR will not trigger a new release, but documentation will be updated. - If you\\'re not a core maintainer with permissions to release you can ignore this pull request. + If you\\\\'re not a core maintainer with permissions to release you can ignore this pull request. ## To do Before merging the PR: - - [ ] Add the \\"freeze\\" label to this PR, to ensure it doesn\\'t get automatically forced pushed by new changes. - - [ ] Add the \\"ci:daily\\" label to this PR, to trigger the full test suite to run on this PR. + - [ ] Add the \\\\\\"freeze\\\\\\" label to this PR, to ensure it doesn\\\\'t get automatically forced pushed by new changes. + - [ ] Add the \\\\\\"ci:daily\\\\\\" label to this PR, to trigger the full test suite to run on this PR. - This is a list of all the PRs merged and commits pushed directly to \\\`next\\\` since the last release: + This is a list of all the PRs merged and commits pushed directly to \\\\\`next\\\\\` since the last release: - **🐛 Bug**: Some PR title for a bug [#42](https://github.com/storybookjs/storybook/pull/42) - [ ] The change is appropriate for the version bump - [ ] The PR is labeled correctly - [ ] The PR title is correct - - **⚠️ Direct commit**: Some title for a \\\\"direct commit\\\\" [22bb11](https://github.com/storybookjs/storybook/commit/22bb11) + - **⚠️ Direct commit**: Some title for a \\\\\\\\\\"direct commit\\\\\\\\\\" [22bb11](https://github.com/storybookjs/storybook/commit/22bb11) - [ ] The change is appropriate for the version bump - - **📝 Documentation**: Another PR \\\\\`title\\\\\` for docs [#11](https://github.com/storybookjs/storybook/pull/11) + - **📝 Documentation**: Another PR \\\\\\\\\`title\\\\\\\\\` for docs [#11](https://github.com/storybookjs/storybook/pull/11) - [ ] The change is appropriate for the version bump - [ ] The PR is labeled correctly - [ ] The PR title is correct - - **✨ Feature Request**: Some PR title for a \\\\'new\\\\' feature [#48](https://github.com/storybookjs/storybook/pull/48) + - **✨ Feature Request**: Some PR title for a \\\\\\\\'new\\\\\\\\' feature [#48](https://github.com/storybookjs/storybook/pull/48) - [ ] The change is appropriate for the version bump - [ ] The PR is labeled correctly - [ ] The PR title is correct @@ -395,9 +396,9 @@ For each pull request below, you need to either manually cherry pick it, or disc - If you\\'ve made any changes (change PR titles, revert PRs), manually trigger a re-generation of this PR with [this workflow](https://github.com/storybookjs/storybook/actions/workflows/prepare-patch-release.yml) and wait for it to finish. + If you\\\\'ve made any changes (change PR titles, revert PRs), manually trigger a re-generation of this PR with [this workflow](https://github.com/storybookjs/storybook/actions/workflows/prepare-patch-release.yml) and wait for it to finish. - Feel free to manually commit any changes necessary to this branch **after** you\\'ve done the last re-generation, following the [Make Manual Changes](https://github.com/storybookjs/storybook/blob/next/CONTRIBUTING/RELEASING.md#5-make-manual-changes) section in the docs. + Feel free to manually commit any changes necessary to this branch **after** you\\\\'ve done the last re-generation, following the [Make Manual Changes](https://github.com/storybookjs/storybook/blob/next/CONTRIBUTING/RELEASING.md#5-make-manual-changes) section in the docs. When everything above is done: - Merge this PR diff --git a/scripts/release/__tests__/is-pr-frozen.test.ts b/scripts/release/__tests__/is-pr-frozen.test.ts index 717d9de7c15a..cc24fe46411d 100644 --- a/scripts/release/__tests__/is-pr-frozen.test.ts +++ b/scripts/release/__tests__/is-pr-frozen.test.ts @@ -1,19 +1,23 @@ -/* eslint-disable no-underscore-dangle */ -/* eslint-disable global-require */ +/* eslint-disable import/no-duplicates, jest/no-mocks-import, import/no-unresolved, no-underscore-dangle, global-require */ import path from 'path'; import { vi, describe, expect, it } from 'vitest'; +import * as fsExtraImp from 'fs-extra'; +import * as simpleGitImp from 'simple-git'; import { run as isPrFrozen } from '../is-pr-frozen'; -// eslint-disable-next-line jest/no-mocks-import -vi.mock('fs-extra', () => require('../../../code/__mocks__/fs-extra')); -vi.mock('../utils/get-github-info'); +import type * as MockedFSExtra from '../../../code/__mocks__/fs-extra'; +import type * as MockedSimpleGit from '../../__mocks__/simple-git'; + +import { getPullInfoFromCommit } from '../utils/get-github-info'; +import { CODE_DIRECTORY } from '../../utils/constants'; -const fsExtra = require('fs-extra'); -const simpleGit = require('simple-git'); -const { getPullInfoFromCommit } = require('../utils/get-github-info'); +vi.mock('../utils/get-github-info'); +vi.mock('simple-git'); +vi.mock('fs-extra', async () => import('../../../code/__mocks__/fs-extra')); +const fsExtra = fsExtraImp as unknown as typeof MockedFSExtra; +const simpleGit = simpleGitImp as unknown as typeof MockedSimpleGit; -const CODE_DIR_PATH = path.join(__dirname, '..', '..', '..', 'code'); -const CODE_PACKAGE_JSON_PATH = path.join(CODE_DIR_PATH, 'package.json'); +const CODE_PACKAGE_JSON_PATH = path.join(CODE_DIRECTORY, 'package.json'); fsExtra.__setMockFiles({ [CODE_PACKAGE_JSON_PATH]: JSON.stringify({ version: '1.0.0' }), @@ -21,23 +25,23 @@ fsExtra.__setMockFiles({ describe('isPrFrozen', () => { it('should return true when PR is frozen', async () => { - getPullInfoFromCommit.mockResolvedValue({ + vi.mocked(getPullInfoFromCommit).mockResolvedValue({ labels: ['freeze'], - }); + } as any); await expect(isPrFrozen({ patch: false })).resolves.toBe(true); }); it('should return false when PR is not frozen', async () => { - getPullInfoFromCommit.mockResolvedValue({ + vi.mocked(getPullInfoFromCommit).mockResolvedValue({ labels: [], - }); + } as any); await expect(isPrFrozen({ patch: false })).resolves.toBe(false); }); it('should look for patch PRs when patch is true', async () => { - getPullInfoFromCommit.mockResolvedValue({ + vi.mocked(getPullInfoFromCommit).mockResolvedValue({ labels: [], - }); + } as any); await isPrFrozen({ patch: true }); expect(simpleGit.__fetch).toHaveBeenCalledWith('origin', 'version-patch-from-1.0.0', { @@ -46,9 +50,9 @@ describe('isPrFrozen', () => { }); it('should look for prerelease PRs when patch is false', async () => { - getPullInfoFromCommit.mockResolvedValue({ + vi.mocked(getPullInfoFromCommit).mockResolvedValue({ labels: [], - }); + } as any); await isPrFrozen({ patch: false }); expect(simpleGit.__fetch).toHaveBeenCalledWith('origin', 'version-prerelease-from-1.0.0', { diff --git a/scripts/release/__tests__/label-patches.test.ts b/scripts/release/__tests__/label-patches.test.ts index 65ec494c33e6..eddd79a5e66b 100644 --- a/scripts/release/__tests__/label-patches.test.ts +++ b/scripts/release/__tests__/label-patches.test.ts @@ -1,14 +1,16 @@ import type { LogResult } from 'simple-git'; import ansiRegex from 'ansi-regex'; +import { beforeEach, vi, test, expect } from 'vitest'; import { run } from '../label-patches'; import * as gitClient_ from '../utils/git-client'; import * as githubInfo_ from '../utils/get-github-info'; import * as github_ from '../utils/github-client'; vi.mock('uuid'); +vi.mock('simple-git'); vi.mock('../utils/get-github-info'); vi.mock('../utils/github-client'); -vi.mock('../utils/git-client', () => jest.requireActual('jest-mock-extended').mockDeep()); +vi.mock('../utils/git-client'); const gitClient = vi.mocked(gitClient_); const github = vi.mocked(github_); @@ -67,8 +69,6 @@ const pullInfoMock = { }; beforeEach(() => { - // mock IO - jest.clearAllMocks(); gitClient.getLatestTag.mockResolvedValue('v7.2.1'); gitClient.git.log.mockResolvedValue(gitLogMock); gitClient.git.getRemotes.mockResolvedValue(remoteMock); @@ -99,10 +99,10 @@ test('it should fail early when no GH_TOKEN is set', async () => { ); }); -test('it should label the PR associated with cheery picks in the current branch', async () => { +test.only('it should label the PR associated with cherry picks in the current branch', async () => { process.env.GH_TOKEN = 'MY_SECRET'; - const writeStderr = jest.spyOn(process.stderr, 'write').mockImplementation(); + const writeStderr = vi.spyOn(process.stderr, 'write').mockImplementation(); await run({}); expect(github.githubGraphQlClient.mock.calls).toMatchInlineSnapshot(` @@ -162,7 +162,7 @@ test('it should label all PRs when the --all flag is passed', async () => { total: 0, }); - const writeStderr = jest.spyOn(process.stderr, 'write').mockImplementation(); + const writeStderr = vi.spyOn(process.stderr, 'write').mockImplementation(); await run({ all: true }); expect(github.githubGraphQlClient.mock.calls).toMatchInlineSnapshot(` diff --git a/scripts/release/__tests__/version.test.ts b/scripts/release/__tests__/version.test.ts index 297752184cb9..44c00aeed23b 100644 --- a/scripts/release/__tests__/version.test.ts +++ b/scripts/release/__tests__/version.test.ts @@ -27,10 +27,6 @@ jest.spyOn(console, 'log').mockImplementation(() => {}); jest.spyOn(console, 'warn').mockImplementation(() => {}); jest.spyOn(console, 'error').mockImplementation(() => {}); -beforeEach(() => { - jest.clearAllMocks(); -}); - describe('Version', () => { const CODE_DIR_PATH = path.join(__dirname, '..', '..', '..', 'code'); const CODE_PACKAGE_JSON_PATH = path.join(CODE_DIR_PATH, 'package.json'); diff --git a/scripts/release/__tests__/write-changelog.test.ts b/scripts/release/__tests__/write-changelog.test.ts index a17a5a4bb189..54ec5fa12510 100644 --- a/scripts/release/__tests__/write-changelog.test.ts +++ b/scripts/release/__tests__/write-changelog.test.ts @@ -1,19 +1,23 @@ +/* eslint-disable jest/no-mocks-import */ /* eslint-disable global-require */ /* eslint-disable no-underscore-dangle */ import path from 'path'; import dedent from 'ts-dedent'; +import { vi, expect, describe, it, beforeEach } from 'vitest'; +import * as fsExtraImp from 'fs-extra'; import { run as writeChangelog } from '../write-changelog'; import * as changesUtils from '../utils/get-changes'; -// eslint-disable-next-line jest/no-mocks-import -vi.mock('fs-extra', () => require('../../../code/__mocks__/fs-extra')); -const fsExtra = require('fs-extra'); +import type * as MockedFSExytra from '../../../code/__mocks__/fs-extra'; -const getChangesMock = jest.spyOn(changesUtils, 'getChanges'); +vi.mock('fs-extra', async () => import('../../../code/__mocks__/fs-extra')); +const fsExtra = fsExtraImp as unknown as typeof MockedFSExytra; -jest.spyOn(console, 'log').mockImplementation(() => {}); -jest.spyOn(console, 'warn').mockImplementation(() => {}); -jest.spyOn(console, 'error').mockImplementation(() => {}); +const getChangesMock = vi.spyOn(changesUtils, 'getChanges'); + +vi.spyOn(console, 'log').mockImplementation(() => {}); +vi.spyOn(console, 'warn').mockImplementation(() => {}); +vi.spyOn(console, 'error').mockImplementation(() => {}); const STABLE_CHANGELOG_PATH = path.join(__dirname, '..', '..', '..', 'CHANGELOG.md'); const PRERELEASE_CHANGELOG_PATH = path.join(__dirname, '..', '..', '..', 'CHANGELOG.prerelease.md'); @@ -28,10 +32,6 @@ const LATEST_VERSION_PATH = path.join( ); const NEXT_VERSION_PATH = path.join(__dirname, '..', '..', '..', 'docs', 'versions', 'next.json'); -beforeEach(() => { - jest.clearAllMocks(); -}); - const EXISTING_STABLE_CHANGELOG = dedent`## 7.0.0 - Core: Some change`; @@ -46,6 +46,10 @@ fsExtra.__setMockFiles({ }); describe('Write changelog', () => { + beforeEach(() => { + vi.resetAllMocks(); + }); + it('should write to stable changelogs and version files in docs', async () => { getChangesMock.mockResolvedValue({ changes: [], @@ -65,9 +69,7 @@ describe('Write changelog', () => { - React: Make it reactive - CLI: Not UI - ## 7.0.0 - - - Core: Some change" + " `); expect(fsExtra.writeJson).toBeCalledTimes(1); expect(fsExtra.writeJson.mock.calls[0][0]).toBe(LATEST_VERSION_PATH); @@ -100,12 +102,10 @@ describe('Write changelog', () => { "## 7.0.1 - React: Make it reactive - - Revert "CLI: Not UI" + - Revert \\"CLI: Not UI\\" - CLI: Not UI - ## 7.0.0 - - - Core: Some change" + " `); expect(fsExtra.writeJson).toBeCalledTimes(1); expect(fsExtra.writeJson.mock.calls[0][0]).toBe(LATEST_VERSION_PATH); @@ -113,7 +113,7 @@ describe('Write changelog', () => { { "info": { "plain": "- React: Make it reactive - - Revert \\"CLI: Not UI\\" + - Revert \\\\\\"CLI: Not UI\\\\\\" - CLI: Not UI", }, "version": "7.0.1", @@ -140,9 +140,7 @@ describe('Write changelog', () => { - React: Make it reactive - CLI: Not UI - ## 7.1.0-alpha.20 - - - CLI: Super fast now" + " `); expect(fsExtra.writeJson).toBeCalledTimes(1); expect(fsExtra.writeJson.mock.calls[0][0]).toBe(NEXT_VERSION_PATH); diff --git a/scripts/release/utils/__mocks__/get-github-info.js b/scripts/release/utils/__mocks__/get-github-info.js deleted file mode 100644 index 2fa98bd4cb48..000000000000 --- a/scripts/release/utils/__mocks__/get-github-info.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - getPullInfoFromCommit: jest.fn(), - getPullInfoFromPullRequest: jest.fn(), -}; diff --git a/scripts/release/utils/__mocks__/get-github-info.ts b/scripts/release/utils/__mocks__/get-github-info.ts new file mode 100644 index 000000000000..eaccaddeeaab --- /dev/null +++ b/scripts/release/utils/__mocks__/get-github-info.ts @@ -0,0 +1,4 @@ +import { vi } from 'vitest'; + +export const getPullInfoFromCommit = vi.fn(); +export const getPullInfoFromPullRequest = vi.fn(); diff --git a/scripts/release/utils/get-changes.ts b/scripts/release/utils/get-changes.ts index 1ad2a0759198..cd9a6bd25bc2 100644 --- a/scripts/release/utils/get-changes.ts +++ b/scripts/release/utils/get-changes.ts @@ -99,6 +99,7 @@ export const getAllCommitsBetween = async ({ export const getRepo = async (verbose?: boolean): Promise => { const remotes = await git.getRemotes(true); + console.log({ g: git.getRemotes, remotes }); const originRemote = remotes.find((remote) => remote.name === 'origin'); if (!originRemote) { console.error( diff --git a/scripts/vitest.config.ts b/scripts/vitest.config.ts index 94ede10e225a..34528af8bcb6 100644 --- a/scripts/vitest.config.ts +++ b/scripts/vitest.config.ts @@ -1,3 +1,7 @@ import { defineConfig } from 'vitest/config'; -export default defineConfig({}); +export default defineConfig({ + test: { + clearMocks: true, + }, +}); From c9f36de8cd536fe642772728fc137a01c7de23ad Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Thu, 14 Sep 2023 18:52:57 +0200 Subject: [PATCH 012/105] fixing tests in scripts --- scripts/package.json | 1 + .../release/__tests__/label-patches.test.ts | 6 +- scripts/release/__tests__/version.test.ts | 76 ++++++++++--------- scripts/yarn.lock | 25 ++++++ 4 files changed, 71 insertions(+), 37 deletions(-) diff --git a/scripts/package.json b/scripts/package.json index 83e36c43e5d2..3b355f931872 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -188,6 +188,7 @@ "util": "^0.12.4", "uuid": "^9.0.0", "vitest": "^0.34.4", + "vitest-mock-extended": "^1.2.1", "wait-on": "^7.0.1", "window-size": "^1.1.1", "yaml": "^2.3.1", diff --git a/scripts/release/__tests__/label-patches.test.ts b/scripts/release/__tests__/label-patches.test.ts index dc09ceff776d..0bf5a1641e2b 100644 --- a/scripts/release/__tests__/label-patches.test.ts +++ b/scripts/release/__tests__/label-patches.test.ts @@ -1,6 +1,7 @@ import { beforeEach, expect, vi, test } from 'vitest'; import type { LogResult } from 'simple-git'; import ansiRegex from 'ansi-regex'; +import { mock, mockDeep } from 'vitest-mock-extended'; import { run } from '../label-patches'; import * as gitClient_ from '../utils/git-client'; import * as githubInfo_ from '../utils/get-github-info'; @@ -10,7 +11,10 @@ vi.mock('uuid'); vi.mock('simple-git'); vi.mock('../utils/get-github-info'); vi.mock('../utils/github-client'); -vi.mock('../utils/git-client'); +vi.mock('../utils/git-client', async () => { + const y = await import('../utils/git-client'); + return mockDeep(y); +}); const gitClient = vi.mocked(gitClient_); const github = vi.mocked(github_); diff --git a/scripts/release/__tests__/version.test.ts b/scripts/release/__tests__/version.test.ts index 0eb4838c5e90..e51b1c170bcb 100644 --- a/scripts/release/__tests__/version.test.ts +++ b/scripts/release/__tests__/version.test.ts @@ -1,19 +1,23 @@ -import { describe, beforeEach, it, expect, vi } from 'vitest'; /* eslint-disable global-require */ /* eslint-disable no-underscore-dangle */ +import { describe, it, expect, vi } from 'vitest'; import path from 'path'; +import * as fsExtraImp from 'fs-extra'; import { run as version } from '../version'; +import { execaCommand } from '../../utils/exec'; // eslint-disable-next-line jest/no-mocks-import -vi.mock('fs-extra', () => require('../../../code/__mocks__/fs-extra')); -const fsExtra = require('fs-extra'); + +import type * as MockedFSToExtra from '../../../code/__mocks__/fs-extra'; + +vi.mock('fs-extra', async () => import('../../../code/__mocks__/fs-extra')); +const fsExtra = fsExtraImp as unknown as typeof MockedFSToExtra; vi.mock('../../../code/lib/cli/src/versions', () => ({ '@storybook/addon-a11y': '7.1.0-alpha.29', })); vi.mock('../../utils/exec'); -const { execaCommand } = require('../../utils/exec'); vi.mock('../../utils/workspace', () => ({ getWorkspaces: vi.fn().mockResolvedValue([ @@ -51,21 +55,21 @@ describe('Version', () => { await expect(version({ releaseType: 'invalid' })).rejects.toThrowErrorMatchingInlineSnapshot(` "[ { - "received": "invalid", - "code": "invalid_enum_value", - "options": [ - "major", - "minor", - "patch", - "prerelease", - "premajor", - "preminor", - "prepatch" + \\"received\\": \\"invalid\\", + \\"code\\": \\"invalid_enum_value\\", + \\"options\\": [ + \\"major\\", + \\"minor\\", + \\"patch\\", + \\"prerelease\\", + \\"premajor\\", + \\"preminor\\", + \\"prepatch\\" ], - "path": [ - "releaseType" + \\"path\\": [ + \\"releaseType\\" ], - "message": "Invalid enum value. Expected 'major' | 'minor' | 'patch' | 'prerelease' | 'premajor' | 'preminor' | 'prepatch', received 'invalid'" + \\"message\\": \\"Invalid enum value. Expected 'major' | 'minor' | 'patch' | 'prerelease' | 'premajor' | 'preminor' | 'prepatch', received 'invalid'\\" } ]" `); @@ -82,9 +86,9 @@ describe('Version', () => { .toThrowErrorMatchingInlineSnapshot(` "[ { - "code": "custom", - "message": "Using prerelease identifier requires one of release types: premajor, preminor, prepatch, prerelease", - "path": [] + \\"code\\": \\"custom\\", + \\"message\\": \\"Using prerelease identifier requires one of release types: premajor, preminor, prepatch, prerelease\\", + \\"path\\": [] } ]" `); @@ -101,9 +105,9 @@ describe('Version', () => { .toThrowErrorMatchingInlineSnapshot(` "[ { - "code": "custom", - "message": "Combining --exact with --release-type is invalid, but having one of them is required", - "path": [] + \\"code\\": \\"custom\\", + \\"message\\": \\"Combining --exact with --release-type is invalid, but having one of them is required\\", + \\"path\\": [] } ]" `); @@ -119,10 +123,10 @@ describe('Version', () => { await expect(version({ exact: 'not-semver' })).rejects.toThrowErrorMatchingInlineSnapshot(` "[ { - "code": "custom", - "message": "--exact version has to be a valid semver string", - "path": [ - "exact" + \\"code\\": \\"custom\\", + \\"message\\": \\"--exact version has to be a valid semver string\\", + \\"path\\": [ + \\"exact\\" ] } ]" @@ -140,9 +144,9 @@ describe('Version', () => { .toThrowErrorMatchingInlineSnapshot(` "[ { - "code": "custom", - "message": "--apply cannot be combined with --exact or --release-type, as it will always read from code/package.json#deferredNextVersion", - "path": [] + \\"code\\": \\"custom\\", + \\"message\\": \\"--apply cannot be combined with --exact or --release-type, as it will always read from code/package.json#deferredNextVersion\\", + \\"path\\": [] } ]" `); @@ -159,9 +163,9 @@ describe('Version', () => { .toThrowErrorMatchingInlineSnapshot(` "[ { - "code": "custom", - "message": "--apply cannot be combined with --exact or --release-type, as it will always read from code/package.json#deferredNextVersion", - "path": [] + \\"code\\": \\"custom\\", + \\"message\\": \\"--apply cannot be combined with --exact or --release-type, as it will always read from code/package.json#deferredNextVersion\\", + \\"path\\": [] } ]" `); @@ -178,9 +182,9 @@ describe('Version', () => { .toThrowErrorMatchingInlineSnapshot(` "[ { - "code": "custom", - "message": "--deferred cannot be combined with --apply", - "path": [] + \\"code\\": \\"custom\\", + \\"message\\": \\"--deferred cannot be combined with --apply\\", + \\"path\\": [] } ]" `); diff --git a/scripts/yarn.lock b/scripts/yarn.lock index ec4a8f036f5e..22b54156645c 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -3025,6 +3025,7 @@ __metadata: verdaccio: ^5.19.1 verdaccio-auth-memory: ^10.2.0 vitest: ^0.34.4 + vitest-mock-extended: ^1.2.1 wait-on: ^7.0.1 window-size: ^1.1.1 yaml: ^2.3.1 @@ -16335,6 +16336,18 @@ __metadata: languageName: node linkType: hard +"ts-essentials@npm:^9.3.2": + version: 9.4.0 + resolution: "ts-essentials@npm:9.4.0" + peerDependencies: + typescript: ">=4.1.0" + peerDependenciesMeta: + typescript: + optional: true + checksum: fa362e696b1acf12f9c5ae3df1c083e5259bdbd8c916939e1eb8ea63320c9a71325057b17b2de052fc95c3e0346e50250f3b1534f6d7f71635e046ff099e3f90 + languageName: node + linkType: hard + "ts-interface-checker@npm:^0.1.9": version: 0.1.13 resolution: "ts-interface-checker@npm:0.1.13" @@ -17577,6 +17590,18 @@ __metadata: languageName: node linkType: hard +"vitest-mock-extended@npm:^1.2.1": + version: 1.2.1 + resolution: "vitest-mock-extended@npm:1.2.1" + dependencies: + ts-essentials: ^9.3.2 + peerDependencies: + typescript: 3.x || 4.x || 5.x + vitest: ">=0.31.1" + checksum: 10930477a9602943ded780d68287c4c62d5c38bb96e743c973dc9d84343e008e934c134fba8a7b4bcebbd38c5e8b47c007fc99539b4f9e85187917fe2988c6b2 + languageName: node + linkType: hard + "vitest@npm:^0.34.4": version: 0.34.4 resolution: "vitest@npm:0.34.4" From 90d54092ee41d8dbdaccda04dd9b79a554c1b208 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Thu, 14 Sep 2023 19:09:44 +0200 Subject: [PATCH 013/105] remove jest-specific-snapshot and update snapshots --- code/addons/a11y/src/a11yRunner.test.ts | 5 +- code/frameworks/angular/package.json | 1 - .../client/docs/angular-properties.test.ts | 5 +- code/frameworks/react-webpack5/package.json | 3 - .../helpers/getMigrationSummary.test.ts | 9 +- code/lib/codemod/package.json | 1 - .../transforms/__tests__/transforms.tests.js | 3 +- code/lib/core-server/package.json | 1 - code/lib/docs-tools/package.json | 1 - code/lib/postinstall/package.json | 1 - code/lib/postinstall/src/codemods.test.ts | 3 +- code/lib/source-loader/package.json | 1 - .../inject-decorator.csf.test.js | 3 - code/presets/server-webpack/package.json | 1 - .../lib/compiler/json-to-csf-compiler.test.ts | 3 +- code/renderers/react/package.json | 1 - .../react/src/docs/extractArgTypes.test.ts | 7 +- .../custom-elements.snapshot | 54 ++++---- .../lit-element-demo-card/properties.snapshot | 116 +++++++++--------- .../lit-html-welcome/custom-elements.snapshot | 12 +- .../lit-html-welcome/properties.snapshot | 4 +- .../docs/web-components-properties.test.ts | 12 +- .../sidebar/__tests__/Sidebar.test.tsx | 1 + code/yarn.lock | 7 -- 24 files changed, 106 insertions(+), 149 deletions(-) diff --git a/code/addons/a11y/src/a11yRunner.test.ts b/code/addons/a11y/src/a11yRunner.test.ts index e2e46408b6b3..346ad26851a6 100644 --- a/code/addons/a11y/src/a11yRunner.test.ts +++ b/code/addons/a11y/src/a11yRunner.test.ts @@ -16,9 +16,8 @@ describe('a11yRunner', () => { mockedAddons.getChannel.mockReturnValue(mockChannel as any); }); - it('should listen to events', () => { - // eslint-disable-next-line global-require - require('./a11yRunner'); + it('should listen to events', async () => { + await import('./a11yRunner'); expect(mockedAddons.getChannel).toHaveBeenCalled(); expect(mockChannel.on).toHaveBeenCalledWith(EVENTS.REQUEST, expect.any(Function)); diff --git a/code/frameworks/angular/package.json b/code/frameworks/angular/package.json index bbcf40425e37..8d40554cf560 100644 --- a/code/frameworks/angular/package.json +++ b/code/frameworks/angular/package.json @@ -83,7 +83,6 @@ "cross-spawn": "^7.0.3", "jest": "^29.3.1", "jest-preset-angular": "^13.0.1", - "jest-specific-snapshot": "^8.0.0", "tmp": "^0.2.1", "typescript": "^5.0.4", "webpack": "5", diff --git a/code/frameworks/angular/src/client/docs/angular-properties.test.ts b/code/frameworks/angular/src/client/docs/angular-properties.test.ts index b24bae9506b8..0a58ecde4836 100644 --- a/code/frameworks/angular/src/client/docs/angular-properties.test.ts +++ b/code/frameworks/angular/src/client/docs/angular-properties.test.ts @@ -1,4 +1,3 @@ -import 'jest-specific-snapshot'; import path from 'path'; import fs from 'fs'; import tmp from 'tmp'; @@ -50,14 +49,14 @@ describe('angular component properties', () => { // // snapshot the output of compodoc // const compodocOutput = runCompodoc(inputPath); // const compodocJson = JSON.parse(compodocOutput); - // expect(compodocJson).toMatchSpecificSnapshot( + // expect(compodocJson).toMatchFileSnapshot( // path.join(testDir, `compodoc-${SNAPSHOT_OS}.snapshot`) // ); // // snapshot the output of addon-docs angular-properties // const componentData = findComponentByName('InputComponent', compodocJson); // const argTypes = extractArgTypesFromData(componentData); - // expect(argTypes).toMatchSpecificSnapshot(path.join(testDir, 'argtypes.snapshot')); + // expect(argTypes).toMatchFileSnapshot(path.join(testDir, 'argtypes.snapshot')); // }); } } diff --git a/code/frameworks/react-webpack5/package.json b/code/frameworks/react-webpack5/package.json index aa5d15279ccf..c51becc1a0a3 100644 --- a/code/frameworks/react-webpack5/package.json +++ b/code/frameworks/react-webpack5/package.json @@ -52,9 +52,6 @@ "@storybook/react": "workspace:*", "@types/node": "^16.0.0" }, - "devDependencies": { - "jest-specific-snapshot": "^8.0.0" - }, "peerDependencies": { "@babel/core": "^7.22.0", "react": "^16.8.0 || ^17.0.0 || ^18.0.0", diff --git a/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts b/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts index ec07cc7af35a..68cf19796598 100644 --- a/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts +++ b/code/lib/cli/src/automigrate/helpers/getMigrationSummary.test.ts @@ -1,12 +1,11 @@ -import { describe, expect, vi } from 'vitest'; +import { describe, expect, vi, test } from 'vitest'; import { getMigrationSummary } from './getMigrationSummary'; import { FixStatus } from '../types'; import type { InstallationMetadata } from '../../js-package-manager/types'; -vi.mock('boxen', () => - // eslint-disable-next-line no-control-regex - vi.fn((str, { title = '' }) => `${title}\n\n${str.replace(/\x1b\[[0-9;]*[mG]/g, '')}`) -); +vi.mock('boxen', () => ({ + default: vi.fn((str, { title = '' }) => `${title}\n\n${str.replace(/\x1b\[[0-9;]*[mG]/g, '')}`), +})); describe('getMigrationSummary', () => { const fixResults = { diff --git a/code/lib/codemod/package.json b/code/lib/codemod/package.json index f33137ee2be7..13aaf0893ed3 100644 --- a/code/lib/codemod/package.json +++ b/code/lib/codemod/package.json @@ -71,7 +71,6 @@ "@types/jscodeshift": "^0.11.6", "ansi-regex": "^5.0.1", "jest": "^29.3.1", - "jest-specific-snapshot": "^8.0.0", "mdast-util-mdx-jsx": "^2.1.2", "mdast-util-mdxjs-esm": "^1.3.1", "remark": "^14.0.2", diff --git a/code/lib/codemod/src/transforms/__tests__/transforms.tests.js b/code/lib/codemod/src/transforms/__tests__/transforms.tests.js index 083db8987c35..0a12a581c654 100644 --- a/code/lib/codemod/src/transforms/__tests__/transforms.tests.js +++ b/code/lib/codemod/src/transforms/__tests__/transforms.tests.js @@ -1,7 +1,6 @@ import { describe, it, expect, vi } from 'vitest'; import path from 'path'; import fs from 'fs'; -import 'jest-specific-snapshot'; import { applyTransform } from 'jscodeshift/dist/testUtils'; vi.mock('@storybook/node-logger'); @@ -27,7 +26,7 @@ fs.readdirSync(fixturesDir).forEach((transformName) => { null, { path: inputPath, source: fs.readFileSync(inputPath, 'utf8') } ) - ).toMatchSpecificSnapshot(inputPath.replace(inputRegExp, '.output.snapshot'))); + ).toMatchFileSnapshot(inputPath.replace(inputRegExp, '.output.snapshot'))); }); }); }); diff --git a/code/lib/core-server/package.json b/code/lib/core-server/package.json index cf5c81447bc9..e02cc849ea0e 100644 --- a/code/lib/core-server/package.json +++ b/code/lib/core-server/package.json @@ -112,7 +112,6 @@ "@types/ws": "^8", "boxen": "^5.1.2", "jest-os-detection": "^1.3.1", - "jest-specific-snapshot": "^8.0.0", "node-fetch": "^3.3.1", "slash": "^5.0.0", "typescript": "~4.9.3" diff --git a/code/lib/docs-tools/package.json b/code/lib/docs-tools/package.json index 0b064903e599..12591c4ffa74 100644 --- a/code/lib/docs-tools/package.json +++ b/code/lib/docs-tools/package.json @@ -53,7 +53,6 @@ }, "devDependencies": { "@babel/core": "^7.22.9", - "jest-specific-snapshot": "^8.0.0", "require-from-string": "^2.0.2", "typescript": "~4.9.3" }, diff --git a/code/lib/postinstall/package.json b/code/lib/postinstall/package.json index 2bcd53b7e7f0..9f95f1e5bc3c 100644 --- a/code/lib/postinstall/package.json +++ b/code/lib/postinstall/package.json @@ -46,7 +46,6 @@ }, "devDependencies": { "jest": "^29.3.1", - "jest-specific-snapshot": "^8.0.0", "jscodeshift": "^0.14.0", "typescript": "~4.9.3" }, diff --git a/code/lib/postinstall/src/codemods.test.ts b/code/lib/postinstall/src/codemods.test.ts index 8936e007d430..bc7586c6881a 100644 --- a/code/lib/postinstall/src/codemods.test.ts +++ b/code/lib/postinstall/src/codemods.test.ts @@ -1,7 +1,6 @@ import { describe, it, expect, vi } from 'vitest'; import path from 'path'; import fs from 'fs'; -import 'jest-specific-snapshot'; // @ts-expect-error (broken types) import { applyTransform } from 'jscodeshift/dist/testUtils'; @@ -25,7 +24,7 @@ fs.readdirSync(fixturesDir).forEach((transformName) => { null, { path: inputPath, source: fs.readFileSync(inputPath, 'utf8') } ) - ).toMatchSpecificSnapshot(inputPath.replace(inputRegExp, '.output.snapshot'))); + ).toMatchFileSnapshot(inputPath.replace(inputRegExp, '.output.snapshot'))); }); }); }); diff --git a/code/lib/source-loader/package.json b/code/lib/source-loader/package.json index a006a63f4e76..d401fe78ae26 100644 --- a/code/lib/source-loader/package.json +++ b/code/lib/source-loader/package.json @@ -52,7 +52,6 @@ "prettier": "^2.8.0" }, "devDependencies": { - "jest-specific-snapshot": "^8.0.0", "typescript": "~4.9.3" }, "peerDependencies": { diff --git a/code/lib/source-loader/src/abstract-syntax-tree/inject-decorator.csf.test.js b/code/lib/source-loader/src/abstract-syntax-tree/inject-decorator.csf.test.js index f21638d1c8ce..808ca468a0d0 100644 --- a/code/lib/source-loader/src/abstract-syntax-tree/inject-decorator.csf.test.js +++ b/code/lib/source-loader/src/abstract-syntax-tree/inject-decorator.csf.test.js @@ -1,15 +1,12 @@ import { describe, it, expect } from 'vitest'; import { readFile } from 'fs/promises'; import path from 'path'; -import 'jest-specific-snapshot'; import injectDecorator from './inject-decorator'; import getParser from './parsers'; const regex = /\\r\\n|\r\n|\r|\n/g; describe('inject-decorator', () => { - const snapshotDir = path.join(__dirname, '__snapshots__'); - describe('positive - ts - csf', () => { it('includes storySource parameter in the default exported object', async () => { const mockFilePath = './__mocks__/inject-decorator.ts.csf.txt'; diff --git a/code/presets/server-webpack/package.json b/code/presets/server-webpack/package.json index 4f00bbbc15b3..85dcc430be59 100644 --- a/code/presets/server-webpack/package.json +++ b/code/presets/server-webpack/package.json @@ -65,7 +65,6 @@ }, "devDependencies": { "fs-extra": "^11.1.0", - "jest-specific-snapshot": "^8.0.0", "typescript": "~4.9.3", "yaml": "^2.3.1" }, diff --git a/code/presets/server-webpack/src/lib/compiler/json-to-csf-compiler.test.ts b/code/presets/server-webpack/src/lib/compiler/json-to-csf-compiler.test.ts index be3dc03e23e7..4f36bed0ad28 100644 --- a/code/presets/server-webpack/src/lib/compiler/json-to-csf-compiler.test.ts +++ b/code/presets/server-webpack/src/lib/compiler/json-to-csf-compiler.test.ts @@ -1,4 +1,3 @@ -import 'jest-specific-snapshot'; import path from 'path'; import fs from 'fs-extra'; import YAML from 'yaml'; @@ -21,7 +20,7 @@ async function generate(filePath: string) { it(`${fixtureFile}`, async () => { const inputPath = path.join(transformFixturesDir, fixtureFile); const code = await generate(inputPath); - expect(code).toMatchSpecificSnapshot(inputPath.replace(inputRegExp, '.snapshot')); + expect(code).toMatchFileSnapshot(inputPath.replace(inputRegExp, '.snapshot')); }); }); }); diff --git a/code/renderers/react/package.json b/code/renderers/react/package.json index cbcefcba281e..4a42e3fc38f4 100644 --- a/code/renderers/react/package.json +++ b/code/renderers/react/package.json @@ -79,7 +79,6 @@ "@babel/core": "^7.22.9", "@types/util-deprecate": "^1.0.0", "expect-type": "^0.15.0", - "jest-specific-snapshot": "^8.0.0", "require-from-string": "^2.0.2" }, "peerDependencies": { diff --git a/code/renderers/react/src/docs/extractArgTypes.test.ts b/code/renderers/react/src/docs/extractArgTypes.test.ts index 31ea19fd754c..83ce7fdc62f6 100644 --- a/code/renderers/react/src/docs/extractArgTypes.test.ts +++ b/code/renderers/react/src/docs/extractArgTypes.test.ts @@ -1,4 +1,3 @@ -import 'jest-specific-snapshot'; import path from 'path'; import fs from 'fs'; // @ts-expect-error (seems broken/missing) @@ -73,7 +72,7 @@ describe('react component properties', () => { // snapshot the output of babel-plugin-react-docgen const docgenPretty = annotateWithDocgen(inputPath); - expect(docgenPretty).toMatchSpecificSnapshot(path.join(testDir, 'docgen.snapshot')); + expect(docgenPretty).toMatchFileSnapshot(path.join(testDir, 'docgen.snapshot')); // transform into an uglier format that's works with require-from-string const docgenModule = transformToModule(docgenPretty); @@ -81,7 +80,7 @@ describe('react component properties', () => { // snapshot the output of component-properties/react const { component } = requireFromString(docgenModule, inputPath); const properties = extractProps(component); - expect(properties).toMatchSpecificSnapshot(path.join(testDir, 'properties.snapshot')); + expect(properties).toMatchFileSnapshot(path.join(testDir, 'properties.snapshot')); // snapshot the output of `extractArgTypes` const argTypes = extractArgTypes(component); @@ -90,7 +89,7 @@ describe('react component properties', () => { argTypes, parameters, } as unknown as StoryContext); - expect(rows).toMatchSpecificSnapshot(path.join(testDir, 'argTypes.snapshot')); + expect(rows).toMatchFileSnapshot(path.join(testDir, 'argTypes.snapshot')); }); } } diff --git a/code/renderers/web-components/src/docs/__testfixtures__/lit-element-demo-card/custom-elements.snapshot b/code/renderers/web-components/src/docs/__testfixtures__/lit-element-demo-card/custom-elements.snapshot index cbf4b8fa4254..2f365587bf83 100644 --- a/code/renderers/web-components/src/docs/__testfixtures__/lit-element-demo-card/custom-elements.snapshot +++ b/code/renderers/web-components/src/docs/__testfixtures__/lit-element-demo-card/custom-elements.snapshot @@ -1,78 +1,75 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`web-components component properties lit-element-demo-card 1`] = ` -Object { - "tags": Array [ - Object { - "attributes": Array [ - Object { +{ + "tags": [ + { + "attributes": [ + { "default": "false", "description": "Indicates that the back of the card is shown", "name": "back-side", "type": "boolean", }, - Object { - "default": "\\"Your Message\\"", + { + "default": "\"Your Message\"", "description": "Header message", "name": "header", "type": "string", }, - Object { + { "default": "[]", "description": "Data rows", "name": "rows", "type": "object", }, ], - "cssParts": Array [ - Object { + "cssParts": [ + { "description": "Front of the card", "name": "front", }, - Object { + { "description": "Back of the card", "name": "back", }, ], - "cssProperties": Array [ - Object { + "cssProperties": [ + { "description": "Header font size", "name": "--demo-wc-card-header-font-size", }, - Object { + { "description": "Font color for front", "name": "--demo-wc-card-front-color", }, - Object { + { "description": "Font color for back", "name": "--demo-wc-card-back-color", }, ], "description": "This is a container looking like a card with a back and front side you can switch", - "events": Array [ - Object { + "events": [ + { "description": "Fires whenever it switches between front/back", "name": "side-changed", }, ], "name": "input", "path": "dummy-path-to-component", - "properties": Array [ - Object { + "properties": [ + { "attribute": "back-side", "default": "false", "description": "Indicates that the back of the card is shown", "name": "backSide", "type": "boolean", }, - Object { + { "attribute": "header", - "default": "\\"Your Message\\"", + "default": "\"Your Message\"", "description": "Header message", "name": "header", "type": "string", }, - Object { + { "attribute": "rows", "default": "[]", "description": "Data rows", @@ -80,8 +77,8 @@ Object { "type": "object", }, ], - "slots": Array [ - Object { + "slots": [ + { "description": "This is an unnamed slot (the default slot)", "name": "", }, @@ -89,5 +86,4 @@ Object { }, ], "version": "experimental", -} -`; +} \ No newline at end of file diff --git a/code/renderers/web-components/src/docs/__testfixtures__/lit-element-demo-card/properties.snapshot b/code/renderers/web-components/src/docs/__testfixtures__/lit-element-demo-card/properties.snapshot index 7f1b194d16b6..6d20476125c7 100644 --- a/code/renderers/web-components/src/docs/__testfixtures__/lit-element-demo-card/properties.snapshot +++ b/code/renderers/web-components/src/docs/__testfixtures__/lit-element-demo-card/properties.snapshot @@ -1,185 +1,181 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`web-components component properties lit-element-demo-card 1`] = ` -Object { - "--demo-wc-card-back-color": Object { +{ + "--demo-wc-card-back-color": { "description": "Font color for back", "name": "--demo-wc-card-back-color", "required": false, - "table": Object { + "table": { "category": "css custom properties", - "defaultValue": Object { + "defaultValue": { "summary": undefined, }, - "type": Object { + "type": { "summary": undefined, }, }, - "type": Object { + "type": { "name": "void", }, }, - "--demo-wc-card-front-color": Object { + "--demo-wc-card-front-color": { "description": "Font color for front", "name": "--demo-wc-card-front-color", "required": false, - "table": Object { + "table": { "category": "css custom properties", - "defaultValue": Object { + "defaultValue": { "summary": undefined, }, - "type": Object { + "type": { "summary": undefined, }, }, - "type": Object { + "type": { "name": "void", }, }, - "--demo-wc-card-header-font-size": Object { + "--demo-wc-card-header-font-size": { "description": "Header font size", "name": "--demo-wc-card-header-font-size", "required": false, - "table": Object { + "table": { "category": "css custom properties", - "defaultValue": Object { + "defaultValue": { "summary": undefined, }, - "type": Object { + "type": { "summary": undefined, }, }, - "type": Object { + "type": { "name": "void", }, }, - "back": Object { + "back": { "description": "Back of the card", "name": "back", "required": false, - "table": Object { + "table": { "category": "css shadow parts", - "defaultValue": Object { + "defaultValue": { "summary": undefined, }, - "type": Object { + "type": { "summary": undefined, }, }, - "type": Object { + "type": { "name": "void", }, }, - "back-side": Object { + "back-side": { "description": "Indicates that the back of the card is shown", "name": "back-side", "required": false, - "table": Object { + "table": { "category": "attributes", - "defaultValue": Object { + "defaultValue": { "summary": "false", }, - "type": Object { + "type": { "summary": "boolean", }, }, - "type": Object { + "type": { "name": "boolean", }, }, - "backSide": Object { + "backSide": { "description": "Indicates that the back of the card is shown", "name": "backSide", "required": false, - "table": Object { + "table": { "category": "properties", - "defaultValue": Object { + "defaultValue": { "summary": "false", }, - "type": Object { + "type": { "summary": "boolean", }, }, - "type": Object { + "type": { "name": "boolean", }, }, - "front": Object { + "front": { "description": "Front of the card", "name": "front", "required": false, - "table": Object { + "table": { "category": "css shadow parts", - "defaultValue": Object { + "defaultValue": { "summary": undefined, }, - "type": Object { + "type": { "summary": undefined, }, }, - "type": Object { + "type": { "name": "void", }, }, - "header": Object { + "header": { "description": "Header message", "name": "header", "required": false, - "table": Object { + "table": { "category": "attributes", - "defaultValue": Object { - "summary": "\\"Your Message\\"", + "defaultValue": { + "summary": "\"Your Message\"", }, - "type": Object { + "type": { "summary": "string", }, }, - "type": Object { + "type": { "name": "string", }, }, - "onSideChanged": Object { - "action": Object { + "onSideChanged": { + "action": { "name": "side-changed", }, "name": "onSideChanged", - "table": Object { + "table": { "disable": true, }, }, - "rows": Object { + "rows": { "description": "Data rows", "name": "rows", "required": false, - "table": Object { + "table": { "category": "attributes", - "defaultValue": Object { + "defaultValue": { "summary": "[]", }, - "type": Object { + "type": { "summary": "object", }, }, - "type": Object { + "type": { "name": "object", }, }, - "side-changed": Object { + "side-changed": { "description": "Fires whenever it switches between front/back", "name": "side-changed", "required": false, - "table": Object { + "table": { "category": "events", - "defaultValue": Object { + "defaultValue": { "summary": undefined, }, - "type": Object { + "type": { "summary": undefined, }, }, - "type": Object { + "type": { "name": "void", }, }, -} -`; +} \ No newline at end of file diff --git a/code/renderers/web-components/src/docs/__testfixtures__/lit-html-welcome/custom-elements.snapshot b/code/renderers/web-components/src/docs/__testfixtures__/lit-html-welcome/custom-elements.snapshot index c1416386b1b1..81832c9edbed 100644 --- a/code/renderers/web-components/src/docs/__testfixtures__/lit-html-welcome/custom-elements.snapshot +++ b/code/renderers/web-components/src/docs/__testfixtures__/lit-html-welcome/custom-elements.snapshot @@ -1,13 +1,9 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`web-components component properties lit-html-welcome 1`] = ` -Object { - "tags": Array [ - Object { +{ + "tags": [ + { "name": "input", "path": "dummy-path-to-component", }, ], "version": "experimental", -} -`; +} \ No newline at end of file diff --git a/code/renderers/web-components/src/docs/__testfixtures__/lit-html-welcome/properties.snapshot b/code/renderers/web-components/src/docs/__testfixtures__/lit-html-welcome/properties.snapshot index a0d337eb0697..9e26dfeeb6e6 100644 --- a/code/renderers/web-components/src/docs/__testfixtures__/lit-html-welcome/properties.snapshot +++ b/code/renderers/web-components/src/docs/__testfixtures__/lit-html-welcome/properties.snapshot @@ -1,3 +1 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`web-components component properties lit-html-welcome 1`] = `Object {}`; +{} \ No newline at end of file diff --git a/code/renderers/web-components/src/docs/web-components-properties.test.ts b/code/renderers/web-components/src/docs/web-components-properties.test.ts index 7c61cdecd7cd..3b418464e152 100644 --- a/code/renderers/web-components/src/docs/web-components-properties.test.ts +++ b/code/renderers/web-components/src/docs/web-components-properties.test.ts @@ -1,9 +1,9 @@ -import 'jest-specific-snapshot'; import path from 'path'; import { vi, describe, it, expect } from 'vitest'; import fs from 'fs'; import tmp from 'tmp'; import { sync as spawnSync } from 'cross-spawn'; +import { extractArgTypesFromElements } from './custom-elements'; // File hierarchy: // __testfixtures__ / some-test-case / input.* @@ -33,10 +33,8 @@ describe('web-components component properties', () => { // we need to mock lit and dynamically require custom-elements // because lit is distributed as ESM not CJS // https://github.com/Polymer/lit-html/issues/516 - vi.mock('lit', () => {}); - vi.mock('lit/directive-helpers.js', () => {}); - // eslint-disable-next-line global-require - const { extractArgTypesFromElements } = require('./custom-elements'); + vi.mock('lit', () => ({ default: {} })); + vi.mock('lit/directive-helpers.js', () => ({ default: {} })); const fixturesDir = path.join(__dirname, '__testfixtures__'); fs.readdirSync(fixturesDir, { withFileTypes: true }).forEach((testEntry) => { @@ -54,13 +52,13 @@ describe('web-components component properties', () => { // eslint-disable-next-line no-param-reassign tag.path = 'dummy-path-to-component'; }); - expect(customElements).toMatchSpecificSnapshot( + expect(customElements).toMatchFileSnapshot( path.join(testDir, 'custom-elements.snapshot') ); // snapshot the properties const properties = extractArgTypesFromElements('input', customElements); - expect(properties).toMatchSpecificSnapshot(path.join(testDir, 'properties.snapshot')); + expect(properties).toMatchFileSnapshot(path.join(testDir, 'properties.snapshot')); }); } } diff --git a/code/ui/manager/src/components/sidebar/__tests__/Sidebar.test.tsx b/code/ui/manager/src/components/sidebar/__tests__/Sidebar.test.tsx index 78ebfb697ac7..e26907028951 100644 --- a/code/ui/manager/src/components/sidebar/__tests__/Sidebar.test.tsx +++ b/code/ui/manager/src/components/sidebar/__tests__/Sidebar.test.tsx @@ -1,3 +1,4 @@ +import { describe, test } from 'vitest'; import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import { ThemeProvider, ensure, themes } from '@storybook/theming'; diff --git a/code/yarn.lock b/code/yarn.lock index f06b5123b4c1..076af2f9fae5 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6584,7 +6584,6 @@ __metadata: cross-spawn: ^7.0.3 globby: ^11.0.2 jest: ^29.3.1 - jest-specific-snapshot: ^8.0.0 jscodeshift: ^0.14.0 lodash: ^4.17.21 mdast-util-mdx-jsx: ^2.1.2 @@ -6741,7 +6740,6 @@ __metadata: globby: ^11.0.2 ip: ^2.0.0 jest-os-detection: ^1.3.1 - jest-specific-snapshot: ^8.0.0 lodash: ^4.17.21 node-fetch: ^3.3.1 open: ^8.4.0 @@ -6884,7 +6882,6 @@ __metadata: "@storybook/types": "workspace:*" "@types/doctrine": ^0.0.3 doctrine: ^3.0.0 - jest-specific-snapshot: ^8.0.0 lodash: ^4.17.21 require-from-string: ^2.0.2 typescript: ~4.9.3 @@ -7216,7 +7213,6 @@ __metadata: resolution: "@storybook/postinstall@workspace:lib/postinstall" dependencies: jest: ^29.3.1 - jest-specific-snapshot: ^8.0.0 jscodeshift: ^0.14.0 typescript: ~4.9.3 languageName: unknown @@ -7366,7 +7362,6 @@ __metadata: "@storybook/server": "workspace:*" "@types/node": ^16.0.0 fs-extra: ^11.1.0 - jest-specific-snapshot: ^8.0.0 safe-identifier: ^0.4.1 ts-dedent: ^2.0.0 typescript: ~4.9.3 @@ -7604,7 +7599,6 @@ __metadata: escodegen: ^2.1.0 expect-type: ^0.15.0 html-tags: ^3.1.0 - jest-specific-snapshot: ^8.0.0 lodash: ^4.17.21 prop-types: ^15.7.2 react-element-to-jsx-string: ^15.0.0 @@ -7862,7 +7856,6 @@ __metadata: "@storybook/csf": ^0.1.0 "@storybook/types": "workspace:*" estraverse: ^5.2.0 - jest-specific-snapshot: ^8.0.0 lodash: ^4.17.21 prettier: ^2.8.0 typescript: ~4.9.3 From d1966b187f645958ded7733d1b8d7e48ac923522 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Thu, 14 Sep 2023 19:14:10 +0200 Subject: [PATCH 014/105] fix imports --- code/lib/cli/src/detect.ts | 2 +- code/lib/core-common/src/utils/normalize-stories.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/lib/cli/src/detect.ts b/code/lib/cli/src/detect.ts index b62288bc82e5..5a1baa6790cd 100644 --- a/code/lib/cli/src/detect.ts +++ b/code/lib/cli/src/detect.ts @@ -1,4 +1,4 @@ -import fs from 'fs'; +import * as fs from 'fs'; import findUp from 'find-up'; import semver from 'semver'; import { logger } from '@storybook/node-logger'; diff --git a/code/lib/core-common/src/utils/normalize-stories.ts b/code/lib/core-common/src/utils/normalize-stories.ts index 9801fbeae307..eb2f3eecfb73 100644 --- a/code/lib/core-common/src/utils/normalize-stories.ts +++ b/code/lib/core-common/src/utils/normalize-stories.ts @@ -1,4 +1,4 @@ -import fs from 'fs'; +import * as fs from 'fs'; import path from 'path'; import * as pico from 'picomatch'; import slash from 'slash'; From cb9ffb16091c74c46805a568f845bac7f73bb499 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Fri, 15 Sep 2023 09:08:30 +0200 Subject: [PATCH 015/105] more test fixes --- code/addons/jest/src/shared.test.ts | 2 +- .../builder-manager/src/utils/files.test.ts | 1 + .../plugins/external-globals-plugin.test.ts | 1 + .../src/utils/has-vite-plugins.test.ts | 1 + .../src/utils/without-vite-plugins.test.ts | 69 +- code/lib/cli/src/generators/configure.test.ts | 2 +- code/lib/core-webpack/src/to-importFn.test.ts | 2 +- .../src/argTypes/convert/convert.test.ts | 1 - .../lib/manager-api/src/tests/globals.test.ts | 4 +- .../manager-api/src/tests/shortcut.test.js | 2 +- code/lib/manager-api/src/tests/store.test.js | 18 +- code/lib/node-logger/src/index.test.ts | 30 +- .../modules/preview-web/PreviewWeb.test.ts | 92 +-- .../telemetry/src/get-monorepo-type.test.ts | 6 +- .../telemetry/src/storybook-metadata.test.ts | 2 +- .../__snapshots__/internals.test.tsx.snap | 231 +++++++ .../src/__test__/composeStories.test.tsx | 2 +- .../react/src/__test__/internals.test.tsx | 1 + .../react/src/docs/extractArgTypes.test.ts | 1 + .../react/src/docs/jsxDecorator.test.tsx | 2 +- .../docs/lib/inspection/acornParser.test.ts | 1 + .../propTypes/generateFuncSignature.test.ts | 1 + .../src/docs/propTypes/handleProp.test.tsx | 1 + .../src/docs/typeScript/handleProp.test.tsx | 1 + .../10017-ts-union/argTypes.snapshot | 26 +- .../10017-ts-union/docgen.snapshot | 42 +- .../10017-ts-union/properties.snapshot | 24 +- .../argTypes.snapshot | 18 +- .../docgen.snapshot | 48 +- .../properties.snapshot | 16 +- .../argTypes.snapshot | 70 +- .../8140-js-prop-types-oneof/docgen.snapshot | 106 ++- .../properties.snapshot | 48 +- .../8143-ts-imported-types/argTypes.snapshot | 18 +- .../8143-ts-imported-types/docgen.snapshot | 28 +- .../properties.snapshot | 16 +- .../argTypes.snapshot | 20 +- .../8143-ts-react-fc-generics/docgen.snapshot | 28 +- .../properties.snapshot | 16 +- .../argTypes.snapshot | 18 +- .../8428-js-static-prop-types/docgen.snapshot | 34 +- .../properties.snapshot | 16 +- .../8740-ts-multi-props/argTypes.snapshot | 20 +- .../8740-ts-multi-props/docgen.snapshot | 48 +- .../8740-ts-multi-props/properties.snapshot | 16 +- .../argTypes.snapshot | 32 +- .../8894-9511-ts-forward-ref/docgen.snapshot | 42 +- .../properties.snapshot | 22 +- .../9023-js-hoc/argTypes.snapshot | 52 +- .../9023-js-hoc/docgen.snapshot | 70 +- .../9023-js-hoc/properties.snapshot | 38 +- .../9399-js-proptypes-shape/argTypes.snapshot | 28 +- .../9399-js-proptypes-shape/docgen.snapshot | 48 +- .../properties.snapshot | 26 +- .../9465-ts-type-props/argTypes.snapshot | 20 +- .../9465-ts-type-props/docgen.snapshot | 34 +- .../9465-ts-type-props/properties.snapshot | 18 +- .../9493-ts-display-name/argTypes.snapshot | 38 +- .../9493-ts-display-name/docgen.snapshot | 60 +- .../9493-ts-display-name/properties.snapshot | 32 +- .../argTypes.snapshot | 20 +- .../docgen.snapshot | 34 +- .../properties.snapshot | 18 +- .../9575-ts-camel-case/argTypes.snapshot | 20 +- .../9575-ts-camel-case/docgen.snapshot | 38 +- .../9575-ts-camel-case/properties.snapshot | 18 +- .../9586-js-react-memo/argTypes.snapshot | 26 +- .../9586-js-react-memo/docgen.snapshot | 38 +- .../9586-js-react-memo/properties.snapshot | 22 +- .../9591-ts-import-types/argTypes.snapshot | 18 +- .../9591-ts-import-types/docgen.snapshot | 28 +- .../9591-ts-import-types/properties.snapshot | 16 +- .../9626-js-default-values/argTypes.snapshot | 20 +- .../9626-js-default-values/docgen.snapshot | 28 +- .../properties.snapshot | 16 +- .../argTypes.snapshot | 26 +- .../docgen.snapshot | 36 +- .../properties.snapshot | 22 +- .../argTypes.snapshot | 24 +- .../9721-ts-deprecated-jsdoc/docgen.snapshot | 50 +- .../properties.snapshot | 22 +- .../9764-ts-extend-props/argTypes.snapshot | 44 +- .../9764-ts-extend-props/docgen.snapshot | 54 +- .../9764-ts-extend-props/properties.snapshot | 34 +- .../9827-ts-default-values/argTypes.snapshot | 44 +- .../9827-ts-default-values/docgen.snapshot | 64 +- .../properties.snapshot | 34 +- .../9832-ts-enum-export/argTypes.snapshot | 4 +- .../9832-ts-enum-export/docgen.snapshot | 20 +- .../9832-ts-enum-export/properties.snapshot | 10 +- .../9922-ts-component-props/argTypes.snapshot | 18 +- .../9922-ts-component-props/docgen.snapshot | 32 +- .../properties.snapshot | 16 +- .../docgen-components/jsdoc/argTypes.snapshot | 604 +++++++++--------- .../docgen-components/jsdoc/docgen.snapshot | 460 +++++++------ .../jsdoc/properties.snapshot | 508 ++++++++------- .../ts-html/argTypes.snapshot | 4 +- .../docgen-components/ts-html/docgen.snapshot | 16 +- .../ts-html/properties.snapshot | 10 +- .../ts-jsdoc/argTypes.snapshot | 4 +- .../ts-jsdoc/docgen.snapshot | 20 +- .../ts-jsdoc/properties.snapshot | 10 +- .../ts-types/argTypes.snapshot | 378 ++++++----- .../ts-types/docgen.snapshot | 346 +++++----- .../ts-types/properties.snapshot | 194 +++--- .../syntaxhighlighter/formatter.test.ts | 1 + 106 files changed, 2554 insertions(+), 2625 deletions(-) diff --git a/code/addons/jest/src/shared.test.ts b/code/addons/jest/src/shared.test.ts index fd73321bf3b9..15689f8c777f 100644 --- a/code/addons/jest/src/shared.test.ts +++ b/code/addons/jest/src/shared.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, vi } from 'vitest'; +import { describe, expect, test } from 'vitest'; import { defineJestParameter } from './shared'; describe('defineJestParameter', () => { diff --git a/code/builders/builder-manager/src/utils/files.test.ts b/code/builders/builder-manager/src/utils/files.test.ts index 3a76234ec8d1..260eed7ec583 100644 --- a/code/builders/builder-manager/src/utils/files.test.ts +++ b/code/builders/builder-manager/src/utils/files.test.ts @@ -1,3 +1,4 @@ +import { test, expect } from 'vitest'; import type { OutputFile } from 'esbuild'; import { platform } from 'os'; import { sanitizePath } from './files'; diff --git a/code/builders/builder-vite/src/plugins/external-globals-plugin.test.ts b/code/builders/builder-vite/src/plugins/external-globals-plugin.test.ts index 2bd540ee9c29..8a6d59e5a1d8 100644 --- a/code/builders/builder-vite/src/plugins/external-globals-plugin.test.ts +++ b/code/builders/builder-vite/src/plugins/external-globals-plugin.test.ts @@ -1,3 +1,4 @@ +import { test, expect } from 'vitest'; import { rewriteImport } from './external-globals-plugin'; const packageName = '@storybook/package'; diff --git a/code/builders/builder-vite/src/utils/has-vite-plugins.test.ts b/code/builders/builder-vite/src/utils/has-vite-plugins.test.ts index d82211fba6b3..8070b69220be 100644 --- a/code/builders/builder-vite/src/utils/has-vite-plugins.test.ts +++ b/code/builders/builder-vite/src/utils/has-vite-plugins.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { hasVitePlugins } from './has-vite-plugins'; describe('hasVitePlugins', () => { diff --git a/code/builders/builder-vite/src/utils/without-vite-plugins.test.ts b/code/builders/builder-vite/src/utils/without-vite-plugins.test.ts index c53422cc69ed..dea82e6af9cb 100644 --- a/code/builders/builder-vite/src/utils/without-vite-plugins.test.ts +++ b/code/builders/builder-vite/src/utils/without-vite-plugins.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { withoutVitePlugins } from './without-vite-plugins'; describe('withoutVitePlugins', () => { @@ -7,8 +8,8 @@ describe('withoutVitePlugins', () => { const names = ['vite-plugin-root-to-remove']; expect(await withoutVitePlugins(plugins, names)).toMatchInlineSnapshot(` - Array [ - Object { + [ + { "name": "vite-plugin-root-keep", }, ] @@ -23,13 +24,13 @@ describe('withoutVitePlugins', () => { const names = ['vite-plugin-nested-to-remove']; expect(await withoutVitePlugins(plugins, names)).toMatchInlineSnapshot(` - Array [ - Array [ - Object { + [ + [ + { "name": "vite-plugin-nested-keep", }, ], - Object { + { "name": "vite-plugin-root-keep", }, ] @@ -46,9 +47,9 @@ describe('withoutVitePlugins', () => { const names = ['vite-plugin-nested-async-to-remove']; expect(await withoutVitePlugins(plugins, names)).toMatchInlineSnapshot(` - Array [ - Array [ - Object { + [ + [ + { "name": "vite-plugin-nested-async-keep", }, ], @@ -64,8 +65,8 @@ describe('withoutVitePlugins', () => { const names = ['vite-plugin-async-root-to-remove']; expect(await withoutVitePlugins(plugins, names)).toMatchInlineSnapshot(` - Array [ - Object { + [ + { "name": "vite-plugin-async-root-keep", }, ] @@ -83,13 +84,13 @@ describe('withoutVitePlugins', () => { const names = ['vite-plugin-async-nested-to-remove']; expect(await withoutVitePlugins(plugins, names)).toMatchInlineSnapshot(` - Array [ - Array [ - Object { + [ + [ + { "name": "vite-plugin-async-nested-keep", }, ], - Object { + { "name": "vite-plugin-async-root-keep", }, ] @@ -105,9 +106,9 @@ describe('withoutVitePlugins', () => { const names = ['vite-plugin-async-nested-async-to-remove']; expect(await withoutVitePlugins(plugins, names)).toMatchInlineSnapshot(` - Array [ - Array [ - Object { + [ + [ + { "name": "vite-plugin-async-nested-async-keep", }, ], @@ -124,8 +125,8 @@ describe('withoutVitePlugins', () => { const names = ['vite-plugin-root-first-to-remove', 'vite-plugin-root-second-to-remove']; expect(await withoutVitePlugins(plugins, names)).toMatchInlineSnapshot(` - Array [ - Object { + [ + { "name": "vite-plugin-root-keep", }, ] @@ -151,11 +152,11 @@ describe('withoutVitePlugins', () => { ]; expect(await withoutVitePlugins(plugins, names)).toMatchInlineSnapshot(` - Array [ - Array [], - Array [], - Array [], - Array [], + [ + [], + [], + [], + [], ] `); }); @@ -172,25 +173,25 @@ describe('withoutVitePlugins', () => { const names = ['vite-plugin-to-remove-first', 'vite-plugin-to-remove-second']; expect(await withoutVitePlugins(plugins, names)).toMatchInlineSnapshot(` - Array [ - Object { + [ + { "name": "vite-plugin-root", }, - Array [ - Object { + [ + { "name": "vite-plugin-in-nested-array", }, ], - Object { + { "name": "vite-plugin-async-root", }, - Array [ - Object { + [ + { "name": "vite-plugin-in-nested-async-array", }, ], - Array [ - Object { + [ + { "name": "vite-plugin-async-in-nested-async-array", }, ], diff --git a/code/lib/cli/src/generators/configure.test.ts b/code/lib/cli/src/generators/configure.test.ts index 5b591255109a..d816128b9bee 100644 --- a/code/lib/cli/src/generators/configure.test.ts +++ b/code/lib/cli/src/generators/configure.test.ts @@ -1,5 +1,5 @@ import type { Mock } from 'vitest'; -import { describe, beforeAll, expect, vi } from 'vitest'; +import { describe, beforeAll, expect, vi, test } from 'vitest'; import fse from 'fs-extra'; import dedent from 'ts-dedent'; import { SupportedLanguage } from '../project_types'; diff --git a/code/lib/core-webpack/src/to-importFn.test.ts b/code/lib/core-webpack/src/to-importFn.test.ts index 389f10db8dcd..d6cd4f8a0905 100644 --- a/code/lib/core-webpack/src/to-importFn.test.ts +++ b/code/lib/core-webpack/src/to-importFn.test.ts @@ -1,4 +1,4 @@ -import { describe, expect } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { normalizeStoriesEntry } from '@storybook/core-common'; import { webpackIncludeRegexp } from './to-importFn'; diff --git a/code/lib/docs-tools/src/argTypes/convert/convert.test.ts b/code/lib/docs-tools/src/argTypes/convert/convert.test.ts index 2a0237f0bae3..9f91065f7b62 100644 --- a/code/lib/docs-tools/src/argTypes/convert/convert.test.ts +++ b/code/lib/docs-tools/src/argTypes/convert/convert.test.ts @@ -1,5 +1,4 @@ import { describe, it, expect } from 'vitest'; -import 'jest-specific-snapshot'; import mapValues from 'lodash/mapValues.js'; import { transformSync } from '@babel/core'; import requireFromString from 'require-from-string'; diff --git a/code/lib/manager-api/src/tests/globals.test.ts b/code/lib/manager-api/src/tests/globals.test.ts index 69f7e46597a3..5e2a50fc5c34 100644 --- a/code/lib/manager-api/src/tests/globals.test.ts +++ b/code/lib/manager-api/src/tests/globals.test.ts @@ -2,13 +2,13 @@ import { describe, beforeEach, it, expect, vi } from 'vitest'; import { EventEmitter } from 'events'; import { SET_STORIES, SET_GLOBALS, UPDATE_GLOBALS, GLOBALS_UPDATED } from '@storybook/core-events'; +import { logger } from '@storybook/client-logger'; import type { API } from '../index'; import type { SubAPI } from '../modules/globals'; import { init as initModule } from '../modules/globals'; import type { ModuleArgs } from '../lib/types'; -const { logger } = require('@storybook/client-logger'); -const { getEventMetadata } = require('../lib/events'); +import { getEventMetadata } from '../lib/events'; vi.mock('@storybook/client-logger'); vi.mock('../lib/events'); diff --git a/code/lib/manager-api/src/tests/shortcut.test.js b/code/lib/manager-api/src/tests/shortcut.test.js index 068c938640c5..d8f24254b8b2 100644 --- a/code/lib/manager-api/src/tests/shortcut.test.js +++ b/code/lib/manager-api/src/tests/shortcut.test.js @@ -1,7 +1,7 @@ /** * @vitest-environment jsdom */ -import { describe, expect } from 'vitest'; +import { describe, expect, test } from 'vitest'; import { global } from '@storybook/global'; import { eventToShortcut, keyToSymbol } from '../lib/shortcut'; diff --git a/code/lib/manager-api/src/tests/store.test.js b/code/lib/manager-api/src/tests/store.test.js index 4543686815d7..5f87fc33e447 100644 --- a/code/lib/manager-api/src/tests/store.test.js +++ b/code/lib/manager-api/src/tests/store.test.js @@ -5,15 +5,17 @@ import flushPromises from 'flush-promises'; import Store, { STORAGE_KEY } from '../store'; vi.mock('store2', () => ({ - local: { - set: vi.fn(), - get: vi.fn(), + default: { + local: { + set: vi.fn(), + get: vi.fn(), + }, + session: { + set: vi.fn(), + get: vi.fn(), + }, + _: { fn: () => {} }, }, - session: { - set: vi.fn(), - get: vi.fn(), - }, - _: { fn: () => {} }, })); describe('store', () => { diff --git a/code/lib/node-logger/src/index.test.ts b/code/lib/node-logger/src/index.test.ts index 4ed4d119f83d..8402c2463f5a 100644 --- a/code/lib/node-logger/src/index.test.ts +++ b/code/lib/node-logger/src/index.test.ts @@ -5,21 +5,23 @@ import { logger } from '.'; globalThis.console = { log: vi.fn() } as any; vi.mock('npmlog', () => ({ - info: vi.fn(), - warn: vi.fn(), - error: vi.fn(), - levels: { - silly: -Infinity, - verbose: 1000, - info: 2000, - timing: 2500, - http: 3000, - notice: 3500, - warn: 4000, - error: 5000, - silent: Infinity, + default: { + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + levels: { + silly: -Infinity, + verbose: 1000, + info: 2000, + timing: 2500, + http: 3000, + notice: 3500, + warn: 4000, + error: 5000, + silent: Infinity, + }, + level: 'info', }, - level: 'info', })); // diff --git a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts index a67a5c93a240..858a25ee89ee 100644 --- a/code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts +++ b/code/lib/preview-api/src/modules/preview-web/PreviewWeb.test.ts @@ -3629,114 +3629,114 @@ describe('PreviewWeb', () => { expect(extracted).toBe(true); expect(await preview.extract()).toMatchInlineSnapshot(` - Object { - "component-one--a": Object { - "argTypes": Object { - "foo": Object { + { + "component-one--a": { + "argTypes": { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, - "one": Object { - "mapping": Object { + "one": { + "mapping": { "1": "mapped-1", }, "name": "one", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "a", "one": 1, }, "component": undefined, "componentId": "component-one", "id": "component-one--a", - "initialArgs": Object { + "initialArgs": { "foo": "a", "one": 1, }, "kind": "Component One", "name": "A", - "parameters": Object { + "parameters": { "__isArgsStory": false, - "docs": Object { - "container": [MockFunction], - "page": [MockFunction], + "docs": { + "container": [MockFunction spy], + "page": [MockFunction spy], "renderer": [Function], }, "fileName": "./src/ComponentOne.stories.js", }, "story": "A", "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component One", }, - "component-one--b": Object { - "argTypes": Object { - "foo": Object { + "component-one--b": { + "argTypes": { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, - "one": Object { - "mapping": Object { + "one": { + "mapping": { "1": "mapped-1", }, "name": "one", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "b", "one": 1, }, "component": undefined, "componentId": "component-one", "id": "component-one--b", - "initialArgs": Object { + "initialArgs": { "foo": "b", "one": 1, }, "kind": "Component One", "name": "B", - "parameters": Object { + "parameters": { "__isArgsStory": false, - "docs": Object { - "container": [MockFunction], - "page": [MockFunction], + "docs": { + "container": [MockFunction spy], + "page": [MockFunction spy], "renderer": [Function], }, "fileName": "./src/ComponentOne.stories.js", }, "story": "B", "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component One", }, - "component-one--e": Object { - "argTypes": Object {}, - "args": Object {}, + "component-one--e": { + "argTypes": {}, + "args": {}, "component": undefined, "componentId": "component-one", "id": "component-one--e", - "initialArgs": Object {}, + "initialArgs": {}, "kind": "Component One", "name": "E", - "parameters": Object { + "parameters": { "__isArgsStory": false, - "docs": Object { - "page": [MockFunction], + "docs": { + "page": [MockFunction spy], "renderer": [Function], }, "fileName": "./src/ExtraComponentOne.stories.js", @@ -3744,34 +3744,34 @@ describe('PreviewWeb', () => { "playFunction": undefined, "story": "E", "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component One", }, - "component-two--c": Object { - "argTypes": Object { - "foo": Object { + "component-two--c": { + "argTypes": { + "foo": { "name": "foo", - "type": Object { + "type": { "name": "string", }, }, }, - "args": Object { + "args": { "foo": "c", }, "component": undefined, "componentId": "component-two", "id": "component-two--c", - "initialArgs": Object { + "initialArgs": { "foo": "c", }, "kind": "Component Two", "name": "C", - "parameters": Object { + "parameters": { "__isArgsStory": false, - "docs": Object { + "docs": { "renderer": [Function], }, "fileName": "./src/ComponentTwo.stories.js", @@ -3779,7 +3779,7 @@ describe('PreviewWeb', () => { "playFunction": undefined, "story": "C", "subcomponents": undefined, - "tags": Array [ + "tags": [ "story", ], "title": "Component Two", diff --git a/code/lib/telemetry/src/get-monorepo-type.test.ts b/code/lib/telemetry/src/get-monorepo-type.test.ts index 1f66a4a288f8..a2e3984e10b6 100644 --- a/code/lib/telemetry/src/get-monorepo-type.test.ts +++ b/code/lib/telemetry/src/get-monorepo-type.test.ts @@ -10,8 +10,10 @@ vi.mock('fs-extra', () => require('../../../__mocks__/fs-extra')); vi.mock('@storybook/core-common', async () => { const coreCommon = await vi.importActual('@storybook/core-common'); return { - ...coreCommon, - getProjectRoot: () => 'root', + default: { + ...coreCommon, + getProjectRoot: () => 'root', + }, }; }); diff --git a/code/lib/telemetry/src/storybook-metadata.test.ts b/code/lib/telemetry/src/storybook-metadata.test.ts index da44e8d959af..a3f818c8961a 100644 --- a/code/lib/telemetry/src/storybook-metadata.test.ts +++ b/code/lib/telemetry/src/storybook-metadata.test.ts @@ -1,5 +1,5 @@ import type { SpyInstance } from 'vitest'; -import { describe, beforeEach, afterEach, expect, vi } from 'vitest'; +import { describe, beforeEach, afterEach, expect, vi, test } from 'vitest'; import type { PackageJson, StorybookConfig } from '@storybook/types'; import path from 'path'; diff --git a/code/renderers/react/src/__test__/__snapshots__/internals.test.tsx.snap b/code/renderers/react/src/__test__/__snapshots__/internals.test.tsx.snap index 2b92b1d68424..826471c764ae 100644 --- a/code/renderers/react/src/__test__/__snapshots__/internals.test.tsx.snap +++ b/code/renderers/react/src/__test__/__snapshots__/internals.test.tsx.snap @@ -2,6 +2,14 @@ exports[`Renders CSF2Secondary story 1`] = ` +
+ +
+
+
+ +
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +

+

+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+

+ I am a custom render function +

+ +
+
+
+ +
+
+ +
+
+ +
+
+ +
+ " `); }); @@ -65,71 +62,71 @@ describe('Extracting Arguments', () => { const results = createArgTypes(doc); expect(results).toMatchInlineSnapshot(` - Object { - "event_afterUpdate": Object { + { + "event_afterUpdate": { "action": "afterUpdate", "control": false, "description": "After Update", "name": "afterUpdate", - "table": Object { + "table": { "category": "events", }, }, - "event_click": Object { + "event_click": { "action": "click", "control": false, "description": "Click Event", "name": "click", - "table": Object { + "table": { "category": "events", }, }, - "rounded": Object { - "control": Object { + "rounded": { + "control": { "type": "boolean", }, "description": undefined, "name": "rounded", - "table": Object { + "table": { "category": "properties", - "defaultValue": Object { + "defaultValue": { "summary": true, }, - "type": Object { + "type": { "summary": "boolean", }, }, - "type": Object { + "type": { "name": "boolean", "required": false, }, }, - "slot_default": Object { + "slot_default": { "control": false, "description": "Default Slot \`{rounded}\`", "name": "default", - "table": Object { + "table": { "category": "slots", }, }, - "text": Object { - "control": Object { + "text": { + "control": { "type": "text", }, "description": undefined, "name": "text", - "table": Object { + "table": { "category": "properties", - "defaultValue": Object { + "defaultValue": { "summary": "", }, - "type": Object { + "type": { "summary": "string", }, }, - "type": Object { + "type": { "name": "string", "required": false, }, diff --git a/code/renderers/web-components/src/docs/custom-elements.test.ts b/code/renderers/web-components/src/docs/custom-elements.test.ts index edbffc37994b..a67e903492ab 100644 --- a/code/renderers/web-components/src/docs/custom-elements.test.ts +++ b/code/renderers/web-components/src/docs/custom-elements.test.ts @@ -1,4 +1,5 @@ /* eslint-disable no-underscore-dangle */ +import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { global } from '@storybook/global'; import { extractArgTypes } from './custom-elements'; import customElementsManifest from './__testfixtures__/custom-elements.json'; diff --git a/code/renderers/web-components/src/docs/sourceDecorator.test.ts b/code/renderers/web-components/src/docs/sourceDecorator.test.ts index b288aceb3601..0fa1f3b92c17 100644 --- a/code/renderers/web-components/src/docs/sourceDecorator.test.ts +++ b/code/renderers/web-components/src/docs/sourceDecorator.test.ts @@ -1,6 +1,6 @@ import { html, render } from 'lit'; -import type { Mocked } from 'vitest'; -import { describe, beforeEach, it, vi } from 'vitest'; +import type { Mocked, Mock } from 'vitest'; +import { describe, beforeEach, it, vi, expect } from 'vitest'; import { styleMap } from 'lit/directives/style-map.js'; import { addons, useEffect } from '@storybook/preview-api'; import { SNIPPET_RENDERED } from '@storybook/docs-tools'; @@ -9,7 +9,7 @@ import { sourceDecorator } from './sourceDecorator'; vi.mock('@storybook/preview-api'); const mockedAddons = addons as Mocked; -const mockedUseEffect = useEffect as Mocked; +const mockedUseEffect = vi.mocked(useEffect); expect.addSnapshotSerializer({ print: (val: any) => val, diff --git a/code/ui/blocks/src/blocks/DocsPage.test.ts b/code/ui/blocks/src/blocks/DocsPage.test.ts index 6acf3c09215f..99fb18a9c9ad 100644 --- a/code/ui/blocks/src/blocks/DocsPage.test.ts +++ b/code/ui/blocks/src/blocks/DocsPage.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { extractTitle } from './Title'; describe('defaultTitleSlot', () => { diff --git a/code/ui/blocks/src/controls/Date.test.ts b/code/ui/blocks/src/controls/Date.test.ts index 08ad139676df..b19fdafea602 100644 --- a/code/ui/blocks/src/controls/Date.test.ts +++ b/code/ui/blocks/src/controls/Date.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { parseDate, parseTime, formatDate, formatTime } from './Date'; describe('Date control', () => { diff --git a/code/ui/blocks/src/controls/helpers.test.ts b/code/ui/blocks/src/controls/helpers.test.ts index c902a025507e..21b3d7c95c8d 100644 --- a/code/ui/blocks/src/controls/helpers.test.ts +++ b/code/ui/blocks/src/controls/helpers.test.ts @@ -1,3 +1,4 @@ +import { describe, it, expect } from 'vitest'; import { getControlId, getControlSetterButtonId } from './helpers'; describe('getControlId', () => { From 6c272c9216ef706cad9dadab3823d000e471d82f Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Fri, 15 Sep 2023 12:03:50 +0200 Subject: [PATCH 017/105] more fixes --- code/lib/core-server/src/withTelemetry.test.ts | 2 -- code/lib/csf-tools/src/ConfigFile.test.ts | 2 -- code/lib/csf-tools/src/CsfFile.test.ts | 3 --- code/lib/csf-tools/src/enrichCsf.test.ts | 2 -- code/lib/instrumenter/src/instrumenter.test.ts | 3 +-- code/lib/telemetry/src/telemetry.test.ts | 1 - 6 files changed, 1 insertion(+), 12 deletions(-) diff --git a/code/lib/core-server/src/withTelemetry.test.ts b/code/lib/core-server/src/withTelemetry.test.ts index 1201e21cd894..400ab889e413 100644 --- a/code/lib/core-server/src/withTelemetry.test.ts +++ b/code/lib/core-server/src/withTelemetry.test.ts @@ -1,6 +1,4 @@ -/// /* eslint-disable local-rules/no-uncategorized-errors */ -import { describe, beforeEach, it, expect } from 'vitest'; import prompts from 'prompts'; import { describe, beforeEach, it, expect, vi } from 'vitest'; import { loadAllPresets, cache } from '@storybook/core-common'; diff --git a/code/lib/csf-tools/src/ConfigFile.test.ts b/code/lib/csf-tools/src/ConfigFile.test.ts index 83a4df393e27..7ec63575b08c 100644 --- a/code/lib/csf-tools/src/ConfigFile.test.ts +++ b/code/lib/csf-tools/src/ConfigFile.test.ts @@ -1,5 +1,3 @@ -/// -import { describe, it, expect } from 'vitest'; import { dedent } from 'ts-dedent'; import { describe, it, expect } from 'vitest'; import { loadConfig, printConfig } from './ConfigFile'; diff --git a/code/lib/csf-tools/src/CsfFile.test.ts b/code/lib/csf-tools/src/CsfFile.test.ts index 922efd0b4e0f..05ff59bc1c00 100644 --- a/code/lib/csf-tools/src/CsfFile.test.ts +++ b/code/lib/csf-tools/src/CsfFile.test.ts @@ -1,7 +1,4 @@ -/// /* eslint-disable no-underscore-dangle */ -import { describe, it, expect } from 'vitest'; - import { dedent } from 'ts-dedent'; import { describe, it, expect, vi } from 'vitest'; import yaml from 'js-yaml'; diff --git a/code/lib/csf-tools/src/enrichCsf.test.ts b/code/lib/csf-tools/src/enrichCsf.test.ts index 2dacbbbcc4f3..2fa95f651c51 100644 --- a/code/lib/csf-tools/src/enrichCsf.test.ts +++ b/code/lib/csf-tools/src/enrichCsf.test.ts @@ -1,6 +1,4 @@ -/// /* eslint-disable no-underscore-dangle */ -import { describe, it, expect } from 'vitest'; import { dedent } from 'ts-dedent'; import { describe, it, expect } from 'vitest'; import { formatCsf, loadCsf } from './CsfFile'; diff --git a/code/lib/instrumenter/src/instrumenter.test.ts b/code/lib/instrumenter/src/instrumenter.test.ts index 905c461c28c9..280c2d29ed91 100644 --- a/code/lib/instrumenter/src/instrumenter.test.ts +++ b/code/lib/instrumenter/src/instrumenter.test.ts @@ -1,6 +1,4 @@ -/// /* eslint-disable no-underscore-dangle */ -import { describe, beforeEach, afterEach, it, expect } from 'vitest'; import { addons, mockChannel } from '@storybook/preview-api'; import { describe, beforeEach, afterEach, it, expect, vi } from 'vitest'; import { logger } from '@storybook/client-logger'; @@ -413,6 +411,7 @@ describe('Instrumenter', () => { fn2(); }) ).toThrow('ignoredException'); + // VITEST_MIGRATION: TypeError: [Function fn1] is not a spy or a call to a spy! expect(fn1).toHaveBeenCalled(); expect(logger.warn).toHaveBeenCalledWith(new Error('Boom!')); expect((logger.warn as any).mock.calls[0][0].callId).toBe('kind--story [0] fn1 [0] fn2'); diff --git a/code/lib/telemetry/src/telemetry.test.ts b/code/lib/telemetry/src/telemetry.test.ts index a9b3f730b84a..787ed39076ad 100644 --- a/code/lib/telemetry/src/telemetry.test.ts +++ b/code/lib/telemetry/src/telemetry.test.ts @@ -1,4 +1,3 @@ -/// import fetch from 'node-fetch'; import type { Mock } from 'vitest'; From 6250ef34fab152ba878527671537889686a03425 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 15 Sep 2023 15:46:18 +0200 Subject: [PATCH 018/105] fix codemods test --- code/lib/codemod/package.json | 1 - .../basic.output.snapshot | 10 +- .../empty.output.snapshot | 10 +- .../presets-add-preset/basic.output.snapshot | 4 +- .../presets-add-preset/empty.output.snapshot | 4 +- code/lib/postinstall/src/codemods.test.ts | 46 +- code/lib/postinstall/tsconfig.json | 3 +- .../GlobalSetup.stories.ts | 3 - code/yarn.lock | 15 +- scripts/package.json | 10 - scripts/yarn.lock | 1855 +---------------- 11 files changed, 109 insertions(+), 1852 deletions(-) diff --git a/code/lib/codemod/package.json b/code/lib/codemod/package.json index 13aaf0893ed3..78b2168e57c7 100644 --- a/code/lib/codemod/package.json +++ b/code/lib/codemod/package.json @@ -70,7 +70,6 @@ "devDependencies": { "@types/jscodeshift": "^0.11.6", "ansi-regex": "^5.0.1", - "jest": "^29.3.1", "mdast-util-mdx-jsx": "^2.1.2", "mdast-util-mdxjs-esm": "^1.3.1", "remark": "^14.0.2", diff --git a/code/lib/postinstall/src/__testfixtures__/presets-add-preset-options/basic.output.snapshot b/code/lib/postinstall/src/__testfixtures__/presets-add-preset-options/basic.output.snapshot index 4a3d8bd7e284..db664bd72110 100644 --- a/code/lib/postinstall/src/__testfixtures__/presets-add-preset-options/basic.output.snapshot +++ b/code/lib/postinstall/src/__testfixtures__/presets-add-preset-options/basic.output.snapshot @@ -1,8 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`presets-add-preset-options transforms correctly using "basic.input.js" data 1`] = ` -"module.exports = ['foo', { +module.exports = ['foo', { name: 'test', - options: {\\"a\\":[1,2,3],\\"b\\":{\\"foo\\":\\"bar\\"},\\"c\\":\\"baz\\"} -}];" -`; + options: {"a":[1,2,3],"b":{"foo":"bar"},"c":"baz"} +}]; \ No newline at end of file diff --git a/code/lib/postinstall/src/__testfixtures__/presets-add-preset-options/empty.output.snapshot b/code/lib/postinstall/src/__testfixtures__/presets-add-preset-options/empty.output.snapshot index a28c9e8e6419..245a554ded5a 100644 --- a/code/lib/postinstall/src/__testfixtures__/presets-add-preset-options/empty.output.snapshot +++ b/code/lib/postinstall/src/__testfixtures__/presets-add-preset-options/empty.output.snapshot @@ -1,8 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`presets-add-preset-options transforms correctly using "empty.input.js" data 1`] = ` -"module.exports = [{ +module.exports = [{ name: 'test', - options: {\\"a\\":[1,2,3],\\"b\\":{\\"foo\\":\\"bar\\"},\\"c\\":\\"baz\\"} -}];" -`; + options: {"a":[1,2,3],"b":{"foo":"bar"},"c":"baz"} +}]; \ No newline at end of file diff --git a/code/lib/postinstall/src/__testfixtures__/presets-add-preset/basic.output.snapshot b/code/lib/postinstall/src/__testfixtures__/presets-add-preset/basic.output.snapshot index aaf16d58b3d8..60c223178bd9 100644 --- a/code/lib/postinstall/src/__testfixtures__/presets-add-preset/basic.output.snapshot +++ b/code/lib/postinstall/src/__testfixtures__/presets-add-preset/basic.output.snapshot @@ -1,3 +1 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`presets-add-preset transforms correctly using "basic.input.js" data 1`] = `"module.exports = ['foo', 'test'];"`; +module.exports = ['foo', 'test']; \ No newline at end of file diff --git a/code/lib/postinstall/src/__testfixtures__/presets-add-preset/empty.output.snapshot b/code/lib/postinstall/src/__testfixtures__/presets-add-preset/empty.output.snapshot index 9acaaca175c2..836a3cb6a2cf 100644 --- a/code/lib/postinstall/src/__testfixtures__/presets-add-preset/empty.output.snapshot +++ b/code/lib/postinstall/src/__testfixtures__/presets-add-preset/empty.output.snapshot @@ -1,3 +1 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`presets-add-preset transforms correctly using "empty.input.js" data 1`] = `"module.exports = ['test'];"`; +module.exports = ['test']; \ No newline at end of file diff --git a/code/lib/postinstall/src/codemods.test.ts b/code/lib/postinstall/src/codemods.test.ts index bc7586c6881a..6e5413790b05 100644 --- a/code/lib/postinstall/src/codemods.test.ts +++ b/code/lib/postinstall/src/codemods.test.ts @@ -1,30 +1,40 @@ -import { describe, it, expect, vi } from 'vitest'; -import path from 'path'; -import fs from 'fs'; +import { describe, it, expect } from 'vitest'; +import { join } from 'path'; +import { readFile } from 'fs/promises'; +import { readdirSync } from 'fs'; // @ts-expect-error (broken types) import { applyTransform } from 'jscodeshift/dist/testUtils'; -vi.mock('@storybook/node-logger'); - const inputRegExp = /\.input\.js$/; -const fixturesDir = path.resolve(__dirname, './__testfixtures__'); -fs.readdirSync(fixturesDir).forEach((transformName) => { - const transformFixturesDir = path.join(fixturesDir, transformName); +const ROOT = __dirname; +const fixturesDir = join(ROOT, '__testfixtures__'); +const fixturesDirectories = readdirSync(fixturesDir); + +fixturesDirectories.forEach((transformName) => { + const transformFixturesDir = join(fixturesDir, transformName); + describe(`${transformName}`, () => { - fs.readdirSync(transformFixturesDir) + const files = readdirSync(transformFixturesDir); + + files .filter((fileName) => inputRegExp.test(fileName)) .forEach((fileName) => { - const inputPath = path.join(transformFixturesDir, fileName); - it(`transforms correctly using "${fileName}" data`, () => + it(`transforms correctly using "${fileName}" data`, async () => { + const pathToInput = join(transformFixturesDir, fileName); + const pathToOutput = pathToInput.replace(inputRegExp, '.output.snapshot'); + const pathToTransformer = join(ROOT, '__testtransforms__', transformName); + + const { default: transformer } = await import(pathToTransformer); + const source = await readFile(pathToInput, 'utf8'); + expect( - applyTransform( - // eslint-disable-next-line global-require,import/no-dynamic-require - require(path.join(__dirname, '__testtransforms__', transformName)), - null, - { path: inputPath, source: fs.readFileSync(inputPath, 'utf8') } - ) - ).toMatchFileSnapshot(inputPath.replace(inputRegExp, '.output.snapshot'))); + applyTransform(transformer, null, { + path: pathToInput, + source, + }) + ).toMatchFileSnapshot(pathToOutput); + }); }); }); }); diff --git a/code/lib/postinstall/tsconfig.json b/code/lib/postinstall/tsconfig.json index ff4f0ce4aea6..ef10f2bb3010 100644 --- a/code/lib/postinstall/tsconfig.json +++ b/code/lib/postinstall/tsconfig.json @@ -2,7 +2,8 @@ "extends": "../../tsconfig.json", "compilerOptions": { "types": ["node"], - "strict": true + "strict": true, + "allowJs": true }, "include": ["src/**/*"] } diff --git a/code/renderers/vue3/template/stories_vue3-vite-default-ts/GlobalSetup.stories.ts b/code/renderers/vue3/template/stories_vue3-vite-default-ts/GlobalSetup.stories.ts index 2c0319724491..f3403375c924 100644 --- a/code/renderers/vue3/template/stories_vue3-vite-default-ts/GlobalSetup.stories.ts +++ b/code/renderers/vue3/template/stories_vue3-vite-default-ts/GlobalSetup.stories.ts @@ -1,6 +1,3 @@ -/// -/// - import { expect } from '@storybook/jest'; import type { Meta, StoryObj } from '@storybook/vue3'; import { within } from '@storybook/testing-library'; diff --git a/code/yarn.lock b/code/yarn.lock index 076af2f9fae5..4d70fbc9b50f 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6183,7 +6183,6 @@ __metadata: find-up: ^5.0.0 jest: ^29.3.1 jest-preset-angular: ^13.0.1 - jest-specific-snapshot: ^8.0.0 read-pkg-up: ^7.0.1 semver: ^7.3.7 telejson: ^7.2.0 @@ -7563,7 +7562,6 @@ __metadata: "@storybook/preset-react-webpack": "workspace:*" "@storybook/react": "workspace:*" "@types/node": ^16.0.0 - jest-specific-snapshot: ^8.0.0 peerDependencies: "@babel/core": ^7.22.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -20194,7 +20192,7 @@ __metadata: languageName: node linkType: hard -"jest-snapshot@npm:^29.0.0, jest-snapshot@npm:^29.7.0": +"jest-snapshot@npm:^29.7.0": version: 29.7.0 resolution: "jest-snapshot@npm:29.7.0" dependencies: @@ -20222,17 +20220,6 @@ __metadata: languageName: node linkType: hard -"jest-specific-snapshot@npm:^8.0.0": - version: 8.0.0 - resolution: "jest-specific-snapshot@npm:8.0.0" - dependencies: - jest-snapshot: ^29.0.0 - peerDependencies: - jest: ">= 29.0.0" - checksum: c2417340c3f085536441f499b7606f9c22527d0da83ab6ba9a9cdd47427e89fde0a1d41a53a4538b0c169237dd5fc4f13abcc31a2c18c48d2419dd152808071d - languageName: node - linkType: hard - "jest-util@npm:^29.0.0, jest-util@npm:^29.7.0": version: 29.7.0 resolution: "jest-util@npm:29.7.0" diff --git a/scripts/package.json b/scripts/package.json index 3b355f931872..76bda7656813 100644 --- a/scripts/package.json +++ b/scripts/package.json @@ -68,9 +68,7 @@ "@babel/preset-react": "^7.22.0", "@babel/preset-typescript": "^7.21.0", "@babel/types": "^7.22.0", - "@emotion/jest": "^11.10.5", "@google-cloud/bigquery": "^6.2.0", - "@jest/globals": "^29.3.1", "@nx/workspace": "16.2.1", "@octokit/graphql": "^5.0.5", "@storybook/eslint-config-storybook": "^3.1.2", @@ -135,14 +133,6 @@ "glob": "^10.0.0", "http-server": "^14.1.1", "husky": "^4.3.7", - "jest": "^29.3.1", - "jest-environment-jsdom": "^29.3.1", - "jest-image-snapshot": "^6.0.0", - "jest-junit": "^14.0.1", - "jest-mock-extended": "^3.0.4", - "jest-os-detection": "^1.3.1", - "jest-serializer-html": "^7.1.0", - "jest-watch-typeahead": "^2.2.1", "json5": "^2.2.3", "junit-xml": "^1.2.0", "lint-staged": "^10.5.4", diff --git a/scripts/yarn.lock b/scripts/yarn.lock index 22b54156645c..f9d58cd4cf01 100644 --- a/scripts/yarn.lock +++ b/scripts/yarn.lock @@ -65,7 +65,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.22.0": +"@babel/core@npm:^7.22.0": version: 7.22.17 resolution: "@babel/core@npm:7.22.17" dependencies: @@ -88,7 +88,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.22.15, @babel/generator@npm:^7.7.2": +"@babel/generator@npm:^7.22.15": version: 7.22.15 resolution: "@babel/generator@npm:7.22.15" dependencies: @@ -360,7 +360,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.22.16, @babel/parser@npm:^7.7.0": +"@babel/parser@npm:^7.22.15, @babel/parser@npm:^7.22.16, @babel/parser@npm:^7.7.0": version: 7.22.16 resolution: "@babel/parser@npm:7.22.16" bin: @@ -440,18 +440,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-bigint@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-bigint@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": ^7.8.0 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 686891b81af2bc74c39013655da368a480f17dd237bf9fbc32048e5865cb706d5a8f65438030da535b332b1d6b22feba336da8fa931f663b6b34e13147d12dde - languageName: node - linkType: hard - -"@babel/plugin-syntax-class-properties@npm:^7.12.13, @babel/plugin-syntax-class-properties@npm:^7.8.3": +"@babel/plugin-syntax-class-properties@npm:^7.12.13": version: 7.12.13 resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" dependencies: @@ -528,7 +517,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-import-meta@npm:^7.10.4, @babel/plugin-syntax-import-meta@npm:^7.8.3": +"@babel/plugin-syntax-import-meta@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" dependencies: @@ -550,7 +539,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.21.0, @babel/plugin-syntax-jsx@npm:^7.22.5, @babel/plugin-syntax-jsx@npm:^7.7.2": +"@babel/plugin-syntax-jsx@npm:^7.21.0, @babel/plugin-syntax-jsx@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-syntax-jsx@npm:7.22.5" dependencies: @@ -561,7 +550,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4, @babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": +"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" dependencies: @@ -583,7 +572,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-numeric-separator@npm:^7.10.4, @babel/plugin-syntax-numeric-separator@npm:^7.8.3": +"@babel/plugin-syntax-numeric-separator@npm:^7.10.4": version: 7.10.4 resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" dependencies: @@ -638,7 +627,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-top-level-await@npm:^7.14.5, @babel/plugin-syntax-top-level-await@npm:^7.8.3": +"@babel/plugin-syntax-top-level-await@npm:^7.14.5": version: 7.14.5 resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5" dependencies: @@ -649,7 +638,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.21.0, @babel/plugin-syntax-typescript@npm:^7.22.5, @babel/plugin-syntax-typescript@npm:^7.7.2": +"@babel/plugin-syntax-typescript@npm:^7.21.0, @babel/plugin-syntax-typescript@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-syntax-typescript@npm:7.22.5" dependencies: @@ -1456,7 +1445,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2": version: 7.22.15 resolution: "@babel/runtime@npm:7.22.15" dependencies: @@ -1465,7 +1454,7 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.22.15, @babel/template@npm:^7.22.5, @babel/template@npm:^7.3.3": +"@babel/template@npm:^7.22.15, @babel/template@npm:^7.22.5": version: 7.22.15 resolution: "@babel/template@npm:7.22.15" dependencies: @@ -1494,7 +1483,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.0, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.17, @babel/types@npm:^7.22.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.7.0, @babel/types@npm:^7.8.3": +"@babel/types@npm:^7.22.0, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.17, @babel/types@npm:^7.22.5, @babel/types@npm:^7.4.4, @babel/types@npm:^7.7.0, @babel/types@npm:^7.8.3": version: 7.22.17 resolution: "@babel/types@npm:7.22.17" dependencies: @@ -1505,13 +1494,6 @@ __metadata: languageName: node linkType: hard -"@bcoe/v8-coverage@npm:^0.2.3": - version: 0.2.3 - resolution: "@bcoe/v8-coverage@npm:0.2.3" - checksum: 6b80ae4cb3db53f486da2dc63b6e190a74c8c3cca16bb2733f234a0b6a9382b09b146488ae08e2b22cf00f6c83e20f3e040a2f7894f05c045c946d6a090b1d52 - languageName: node - linkType: hard - "@cspotcode/source-map-support@npm:^0.8.0": version: 0.8.1 resolution: "@cspotcode/source-map-support@npm:0.8.1" @@ -1521,44 +1503,6 @@ __metadata: languageName: node linkType: hard -"@emotion/css-prettifier@npm:^1.1.3": - version: 1.1.3 - resolution: "@emotion/css-prettifier@npm:1.1.3" - dependencies: - "@emotion/memoize": ^0.8.1 - stylis: 4.2.0 - checksum: 9ce3d7e5851054a24ca68cca4f6973de47d64567d03b6be730aa83f1cf9ae15e4da8c4611e68620e7b972f7a9fb7c36099fdf7e26b78589eb64f094fce46ce1b - languageName: node - linkType: hard - -"@emotion/jest@npm:^11.10.5": - version: 11.11.0 - resolution: "@emotion/jest@npm:11.11.0" - dependencies: - "@babel/runtime": ^7.18.3 - "@emotion/css-prettifier": ^1.1.3 - chalk: ^4.1.0 - specificity: ^0.4.1 - stylis: 4.2.0 - peerDependencies: - "@types/jest": ^26.0.14 || ^27.0.0 || ^28.0.0 || ^29.0.0 - enzyme-to-json: ^3.2.1 - peerDependenciesMeta: - "@types/jest": - optional: true - enzyme-to-json: - optional: true - checksum: 919def636000234c4af8447a6cdf7f9675146bb020074fd06cf3c6eb42c365e727354ae79b2a7cdccb472d38da8ed8d6fd57f4235cab2e1b7605a2c6672a0fc5 - languageName: node - linkType: hard - -"@emotion/memoize@npm:^0.8.1": - version: 0.8.1 - resolution: "@emotion/memoize@npm:0.8.1" - checksum: dffed372fc3b9fa2ba411e76af22b6bb686fb0cb07694fdfaa6dd2baeb0d5e4968c1a7caa472bfcf06a5997d5e7c7d16b90e993f9a6ffae79a2c3dbdc76dfe78 - languageName: node - linkType: hard - "@esbuild/android-arm64@npm:0.18.20": version: 0.18.20 resolution: "@esbuild/android-arm64@npm:0.18.20" @@ -1920,93 +1864,6 @@ __metadata: languageName: node linkType: hard -"@istanbuljs/load-nyc-config@npm:^1.0.0": - version: 1.1.0 - resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" - dependencies: - camelcase: ^5.3.1 - find-up: ^4.1.0 - get-package-type: ^0.1.0 - js-yaml: ^3.13.1 - resolve-from: ^5.0.0 - checksum: dd2a8b094887da5a1a2339543a4933d06db2e63cbbc2e288eb6431bd832065df0c099d091b6a67436e71b7d6bf85f01ce7c15f9253b4cbebcc3b9a496165ba42 - languageName: node - linkType: hard - -"@istanbuljs/schema@npm:^0.1.2": - version: 0.1.3 - resolution: "@istanbuljs/schema@npm:0.1.3" - checksum: 61c5286771676c9ca3eb2bd8a7310a9c063fb6e0e9712225c8471c582d157392c88f5353581c8c9adbe0dff98892317d2fdfc56c3499aa42e0194405206a963a - languageName: node - linkType: hard - -"@jest/console@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/console@npm:29.7.0" - dependencies: - "@jest/types": ^29.6.3 - "@types/node": "*" - chalk: ^4.0.0 - jest-message-util: ^29.7.0 - jest-util: ^29.7.0 - slash: ^3.0.0 - checksum: 7be408781d0a6f657e969cbec13b540c329671819c2f57acfad0dae9dbfe2c9be859f38fe99b35dba9ff1536937dc6ddc69fdcd2794812fa3c647a1619797f6c - languageName: node - linkType: hard - -"@jest/core@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/core@npm:29.7.0" - dependencies: - "@jest/console": ^29.7.0 - "@jest/reporters": ^29.7.0 - "@jest/test-result": ^29.7.0 - "@jest/transform": ^29.7.0 - "@jest/types": ^29.6.3 - "@types/node": "*" - ansi-escapes: ^4.2.1 - chalk: ^4.0.0 - ci-info: ^3.2.0 - exit: ^0.1.2 - graceful-fs: ^4.2.9 - jest-changed-files: ^29.7.0 - jest-config: ^29.7.0 - jest-haste-map: ^29.7.0 - jest-message-util: ^29.7.0 - jest-regex-util: ^29.6.3 - jest-resolve: ^29.7.0 - jest-resolve-dependencies: ^29.7.0 - jest-runner: ^29.7.0 - jest-runtime: ^29.7.0 - jest-snapshot: ^29.7.0 - jest-util: ^29.7.0 - jest-validate: ^29.7.0 - jest-watcher: ^29.7.0 - micromatch: ^4.0.4 - pretty-format: ^29.7.0 - slash: ^3.0.0 - strip-ansi: ^6.0.0 - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: 934f7bf73190f029ac0f96662c85cd276ec460d407baf6b0dbaec2872e157db4d55a7ee0b1c43b18874602f662b37cb973dda469a4e6d88b4e4845b521adeeb2 - languageName: node - linkType: hard - -"@jest/environment@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/environment@npm:29.7.0" - dependencies: - "@jest/fake-timers": ^29.7.0 - "@jest/types": ^29.6.3 - "@types/node": "*" - jest-mock: ^29.7.0 - checksum: c7b1b40c618f8baf4d00609022d2afa086d9c6acc706f303a70bb4b67275868f620ad2e1a9efc5edd418906157337cce50589a627a6400bbdf117d351b91ef86 - languageName: node - linkType: hard - "@jest/expect-utils@npm:^29.7.0": version: 29.7.0 resolution: "@jest/expect-utils@npm:29.7.0" @@ -2016,79 +1873,6 @@ __metadata: languageName: node linkType: hard -"@jest/expect@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/expect@npm:29.7.0" - dependencies: - expect: ^29.7.0 - jest-snapshot: ^29.7.0 - checksum: b41f193fb697d3ced134349250aed6ccea075e48c4f803159db102b826a4e473397c68c31118259868fd69a5cba70e97e1c26d2c2ff716ca39dc73a2ccec037e - languageName: node - linkType: hard - -"@jest/fake-timers@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/fake-timers@npm:29.7.0" - dependencies: - "@jest/types": ^29.6.3 - "@sinonjs/fake-timers": ^10.0.2 - "@types/node": "*" - jest-message-util: ^29.7.0 - jest-mock: ^29.7.0 - jest-util: ^29.7.0 - checksum: cf0a8bcda801b28dc2e2b2ba36302200ee8104a45ad7a21e6c234148932f826cb3bc57c8df3b7b815aeea0861d7b6ca6f0d4778f93b9219398ef28749e03595c - languageName: node - linkType: hard - -"@jest/globals@npm:^29.3.1, @jest/globals@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/globals@npm:29.7.0" - dependencies: - "@jest/environment": ^29.7.0 - "@jest/expect": ^29.7.0 - "@jest/types": ^29.6.3 - jest-mock: ^29.7.0 - checksum: a385c99396878fe6e4460c43bd7bb0a5cc52befb462cc6e7f2a3810f9e7bcce7cdeb51908fd530391ee452dc856c98baa2c5f5fa8a5b30b071d31ef7f6955cea - languageName: node - linkType: hard - -"@jest/reporters@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/reporters@npm:29.7.0" - dependencies: - "@bcoe/v8-coverage": ^0.2.3 - "@jest/console": ^29.7.0 - "@jest/test-result": ^29.7.0 - "@jest/transform": ^29.7.0 - "@jest/types": ^29.6.3 - "@jridgewell/trace-mapping": ^0.3.18 - "@types/node": "*" - chalk: ^4.0.0 - collect-v8-coverage: ^1.0.0 - exit: ^0.1.2 - glob: ^7.1.3 - graceful-fs: ^4.2.9 - istanbul-lib-coverage: ^3.0.0 - istanbul-lib-instrument: ^6.0.0 - istanbul-lib-report: ^3.0.0 - istanbul-lib-source-maps: ^4.0.0 - istanbul-reports: ^3.1.3 - jest-message-util: ^29.7.0 - jest-util: ^29.7.0 - jest-worker: ^29.7.0 - slash: ^3.0.0 - string-length: ^4.0.1 - strip-ansi: ^6.0.0 - v8-to-istanbul: ^9.0.1 - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - checksum: a754402a799541c6e5aff2c8160562525e2a47e7d568f01ebfc4da66522de39cbb809bbb0a841c7052e4270d79214e70aec3c169e4eae42a03bc1a8a20cb9fa2 - languageName: node - linkType: hard - "@jest/schemas@npm:^28.1.3": version: 28.1.3 resolution: "@jest/schemas@npm:28.1.3" @@ -2107,64 +1891,6 @@ __metadata: languageName: node linkType: hard -"@jest/source-map@npm:^29.6.3": - version: 29.6.3 - resolution: "@jest/source-map@npm:29.6.3" - dependencies: - "@jridgewell/trace-mapping": ^0.3.18 - callsites: ^3.0.0 - graceful-fs: ^4.2.9 - checksum: a2f177081830a2e8ad3f2e29e20b63bd40bade294880b595acf2fc09ec74b6a9dd98f126a2baa2bf4941acd89b13a4ade5351b3885c224107083a0059b60a219 - languageName: node - linkType: hard - -"@jest/test-result@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/test-result@npm:29.7.0" - dependencies: - "@jest/console": ^29.7.0 - "@jest/types": ^29.6.3 - "@types/istanbul-lib-coverage": ^2.0.0 - collect-v8-coverage: ^1.0.0 - checksum: 7de54090e54a674ca173470b55dc1afdee994f2d70d185c80236003efd3fa2b753fff51ffcdda8e2890244c411fd2267529d42c4a50a8303755041ee493e6a04 - languageName: node - linkType: hard - -"@jest/test-sequencer@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/test-sequencer@npm:29.7.0" - dependencies: - "@jest/test-result": ^29.7.0 - graceful-fs: ^4.2.9 - jest-haste-map: ^29.7.0 - slash: ^3.0.0 - checksum: 593a8c4272797bb5628984486080cbf57aed09c7cfdc0a634e8c06c38c6bef329c46c0016e84555ee55d1cd1f381518cf1890990ff845524c1123720c8c1481b - languageName: node - linkType: hard - -"@jest/transform@npm:^29.7.0": - version: 29.7.0 - resolution: "@jest/transform@npm:29.7.0" - dependencies: - "@babel/core": ^7.11.6 - "@jest/types": ^29.6.3 - "@jridgewell/trace-mapping": ^0.3.18 - babel-plugin-istanbul: ^6.1.1 - chalk: ^4.0.0 - convert-source-map: ^2.0.0 - fast-json-stable-stringify: ^2.1.0 - graceful-fs: ^4.2.9 - jest-haste-map: ^29.7.0 - jest-regex-util: ^29.6.3 - jest-util: ^29.7.0 - micromatch: ^4.0.4 - pirates: ^4.0.4 - slash: ^3.0.0 - write-file-atomic: ^4.0.2 - checksum: 7f4a7f73dcf45dfdf280c7aa283cbac7b6e5a904813c3a93ead7e55873761fc20d5c4f0191d2019004fac6f55f061c82eb3249c2901164ad80e362e7a7ede5a6 - languageName: node - linkType: hard - "@jest/types@npm:^27.5.1": version: 27.5.1 resolution: "@jest/types@npm:27.5.1" @@ -2234,7 +1960,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.9": +"@jridgewell/trace-mapping@npm:^0.3.17, @jridgewell/trace-mapping@npm:^0.3.9": version: 0.3.19 resolution: "@jridgewell/trace-mapping@npm:0.3.19" dependencies: @@ -2802,24 +2528,6 @@ __metadata: languageName: node linkType: hard -"@sinonjs/commons@npm:^3.0.0": - version: 3.0.0 - resolution: "@sinonjs/commons@npm:3.0.0" - dependencies: - type-detect: 4.0.8 - checksum: 1df9cd257942f4e4960dfb9fd339d9e97b6a3da135f3d5b8646562918e863809cb8e00268535f4f4723535d2097881c8fc03d545c414d8555183376cfc54ee84 - languageName: node - linkType: hard - -"@sinonjs/fake-timers@npm:^10.0.2": - version: 10.3.0 - resolution: "@sinonjs/fake-timers@npm:10.3.0" - dependencies: - "@sinonjs/commons": ^3.0.0 - checksum: 2e2fb6cc57f227912814085b7b01fede050cd4746ea8d49a1e44d5a0e56a804663b0340ae2f11af7559ea9bf4d087a11f2f646197a660ea3cb04e19efc04aa63 - languageName: node - linkType: hard - "@storybook/csf@npm:^0.0.1": version: 0.0.1 resolution: "@storybook/csf@npm:0.0.1" @@ -2901,9 +2609,7 @@ __metadata: "@babel/preset-react": ^7.22.0 "@babel/preset-typescript": ^7.21.0 "@babel/types": ^7.22.0 - "@emotion/jest": ^11.10.5 "@google-cloud/bigquery": ^6.2.0 - "@jest/globals": ^29.3.1 "@nx/workspace": 16.2.1 "@octokit/graphql": ^5.0.5 "@storybook/eslint-config-storybook": ^3.1.2 @@ -2969,14 +2675,6 @@ __metadata: glob: ^10.0.0 http-server: ^14.1.1 husky: ^4.3.7 - jest: ^29.3.1 - jest-environment-jsdom: ^29.3.1 - jest-image-snapshot: ^6.0.0 - jest-junit: ^14.0.1 - jest-mock-extended: ^3.0.4 - jest-os-detection: ^1.3.1 - jest-serializer-html: ^7.1.0 - jest-watch-typeahead: ^2.2.1 json5: ^2.2.3 junit-xml: ^1.2.0 lint-staged: ^10.5.4 @@ -3296,47 +2994,6 @@ __metadata: languageName: node linkType: hard -"@types/babel__core@npm:^7.1.14": - version: 7.20.1 - resolution: "@types/babel__core@npm:7.20.1" - dependencies: - "@babel/parser": ^7.20.7 - "@babel/types": ^7.20.7 - "@types/babel__generator": "*" - "@types/babel__template": "*" - "@types/babel__traverse": "*" - checksum: c83402fc7ef8abd1f94ffe350b8bde9a35ccb6c3624bc8e39b6a7e1a675d112f6b70ac1b05391a579ca3b126baffe66b0b94f954edef086c4482b97d293c3659 - languageName: node - linkType: hard - -"@types/babel__generator@npm:*": - version: 7.6.4 - resolution: "@types/babel__generator@npm:7.6.4" - dependencies: - "@babel/types": ^7.0.0 - checksum: e0051b450e4ba2df0a7e386f08df902a4e920f6f8d6f185d69ddbe9b0e2e2d3ae434bb51e437bc0fca2a9a0f5dc4ca44d3a1941ef75e74371e8be5bf64416fe4 - languageName: node - linkType: hard - -"@types/babel__template@npm:*": - version: 7.4.1 - resolution: "@types/babel__template@npm:7.4.1" - dependencies: - "@babel/parser": ^7.1.0 - "@babel/types": ^7.0.0 - checksum: 6f180e96c39765487f27e861d43eebed341ec7a2fc06cdf5a52c22872fae67f474ca165d149c708f4fd9d5482beb66c0a92f77411b234bb30262ed2303e50b1a - languageName: node - linkType: hard - -"@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.0.6": - version: 7.20.1 - resolution: "@types/babel__traverse@npm:7.20.1" - dependencies: - "@babel/types": ^7.20.7 - checksum: 5a6a3a26be090573309527184a31f1b82ef55f3d73d811c15f181d323e471305f2390651a04d49d4cd4ca41bbeabb53c9f7862a8e09eab5a0f8910a6aec6e867 - languageName: node - linkType: hard - "@types/body-parser@npm:*": version: 1.19.2 resolution: "@types/body-parser@npm:1.19.2" @@ -3492,15 +3149,6 @@ __metadata: languageName: node linkType: hard -"@types/graceful-fs@npm:^4.1.3": - version: 4.1.6 - resolution: "@types/graceful-fs@npm:4.1.6" - dependencies: - "@types/node": "*" - checksum: b1d32c5ae7bd52cf60e29df20407904c4312a39612e7ec2ee23c1e3731c1cfe31d97c6941bf6cb52f5f929d50d86d92dd506436b63fafa833181d439b628885e - languageName: node - linkType: hard - "@types/hast@npm:^2.0.0": version: 2.3.5 resolution: "@types/hast@npm:2.3.5" @@ -3540,7 +3188,7 @@ __metadata: languageName: node linkType: hard -"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1": +"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0": version: 2.0.4 resolution: "@types/istanbul-lib-coverage@npm:2.0.4" checksum: af5f6b64e788331ed3f7b2e2613cb6ca659c58b8500be94bbda8c995ad3da9216c006f1cfe6f66b321c39392b1bda18b16e63cef090a77d24a00b4bd5ba3b018 @@ -3585,17 +3233,6 @@ __metadata: languageName: node linkType: hard -"@types/jsdom@npm:^20.0.0": - version: 20.0.1 - resolution: "@types/jsdom@npm:20.0.1" - dependencies: - "@types/node": "*" - "@types/tough-cookie": "*" - parse5: ^7.0.0 - checksum: 3d4b2a3eab145674ee6da482607c5e48977869109f0f62560bf91ae1a792c9e847ac7c6aaf243ed2e97333cb3c51aef314ffa54a19ef174b8f9592dfcb836b25 - languageName: node - linkType: hard - "@types/json-schema@npm:^7.0.9": version: 7.0.12 resolution: "@types/json-schema@npm:7.0.12" @@ -3864,13 +3501,6 @@ __metadata: languageName: node linkType: hard -"@types/tough-cookie@npm:*": - version: 4.0.2 - resolution: "@types/tough-cookie@npm:4.0.2" - checksum: 38d01fc79a9a87166253b8c548bb401599424c57a818bea1b47a68be6dcd37fc3bff381f978354e00221f284937d5066bb92d58bf79952f9d21deb934e8ec9a7 - languageName: node - linkType: hard - "@types/unist@npm:^2, @types/unist@npm:^2.0.0, @types/unist@npm:^2.0.2": version: 2.0.8 resolution: "@types/unist@npm:2.0.8" @@ -4346,13 +3976,6 @@ __metadata: languageName: node linkType: hard -"abab@npm:^2.0.6": - version: 2.0.6 - resolution: "abab@npm:2.0.6" - checksum: 0b245c3c3ea2598fe0025abf7cc7bb507b06949d51e8edae5d12c1b847a0a0c09639abcb94788332b4e2044ac4491c1e8f571b51c7826fd4b0bda1685ad4a278 - languageName: node - linkType: hard - "abbrev@npm:^1.0.0": version: 1.1.1 resolution: "abbrev@npm:1.1.1" @@ -4386,16 +4009,6 @@ __metadata: languageName: node linkType: hard -"acorn-globals@npm:^7.0.0": - version: 7.0.1 - resolution: "acorn-globals@npm:7.0.1" - dependencies: - acorn: ^8.1.0 - acorn-walk: ^8.0.2 - checksum: 7437f58e92d99292dbebd0e79531af27d706c9f272f31c675d793da6c82d897e75302a8744af13c7f7978a8399840f14a353b60cf21014647f71012982456d2b - languageName: node - linkType: hard - "acorn-jsx@npm:^5.3.2": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" @@ -4423,7 +4036,7 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.0.2, acorn-walk@npm:^8.1.1, acorn-walk@npm:^8.2.0": +"acorn-walk@npm:^8.1.1, acorn-walk@npm:^8.2.0": version: 8.2.0 resolution: "acorn-walk@npm:8.2.0" checksum: dbe92f5b2452c93e960c5594e666dd1fae141b965ff2cb4a1e1d0381e3e4db4274c5ce4ffa3d681a86ca2a8d4e29d5efc0670a08e23fd2800051ea387df56ca2 @@ -4439,7 +4052,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.1.0, acorn@npm:^8.10.0, acorn@npm:^8.4.1, acorn@npm:^8.8.1, acorn@npm:^8.9.0": +"acorn@npm:^8.10.0, acorn@npm:^8.4.1, acorn@npm:^8.9.0": version: 8.10.0 resolution: "acorn@npm:8.10.0" bin: @@ -4557,7 +4170,7 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0": +"ansi-escapes@npm:^4.3.0": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" dependencies: @@ -4566,15 +4179,6 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^6.0.0": - version: 6.2.0 - resolution: "ansi-escapes@npm:6.2.0" - dependencies: - type-fest: ^3.0.0 - checksum: 3eec75deedd8b10192c5f98e4cd9715cc3ff268d33fc463c24b7d22446668bfcd4ad1803993ea89c0f51f88b5a3399572bacb7c8cb1a067fc86e189c5f3b0c7e - languageName: node - linkType: hard - "ansi-regex@npm:^5.0.0, ansi-regex@npm:^5.0.1": version: 5.0.1 resolution: "ansi-regex@npm:5.0.1" @@ -4628,7 +4232,7 @@ __metadata: languageName: node linkType: hard -"anymatch@npm:^3.0.3, anymatch@npm:~3.1.2": +"anymatch@npm:~3.1.2": version: 3.1.3 resolution: "anymatch@npm:3.1.3" dependencies: @@ -5037,23 +4641,6 @@ __metadata: languageName: node linkType: hard -"babel-jest@npm:^29.7.0": - version: 29.7.0 - resolution: "babel-jest@npm:29.7.0" - dependencies: - "@jest/transform": ^29.7.0 - "@types/babel__core": ^7.1.14 - babel-plugin-istanbul: ^6.1.1 - babel-preset-jest: ^29.6.3 - chalk: ^4.0.0 - graceful-fs: ^4.2.9 - slash: ^3.0.0 - peerDependencies: - "@babel/core": ^7.8.0 - checksum: 2eda9c1391e51936ca573dd1aedfee07b14c59b33dbe16ef347873ddd777bcf6e2fc739681e9e9661ab54ef84a3109a03725be2ac32cd2124c07ea4401cbe8c1 - languageName: node - linkType: hard - "babel-loader@npm:^9.1.2": version: 9.1.3 resolution: "babel-loader@npm:9.1.3" @@ -5067,31 +4654,6 @@ __metadata: languageName: node linkType: hard -"babel-plugin-istanbul@npm:^6.1.1": - version: 6.1.1 - resolution: "babel-plugin-istanbul@npm:6.1.1" - dependencies: - "@babel/helper-plugin-utils": ^7.0.0 - "@istanbuljs/load-nyc-config": ^1.0.0 - "@istanbuljs/schema": ^0.1.2 - istanbul-lib-instrument: ^5.0.4 - test-exclude: ^6.0.0 - checksum: 1075657feb705e00fd9463b329921856d3775d9867c5054b449317d39153f8fbcebd3e02ebf00432824e647faff3683a9ca0a941325ef1afe9b3c4dd51b24beb - languageName: node - linkType: hard - -"babel-plugin-jest-hoist@npm:^29.6.3": - version: 29.6.3 - resolution: "babel-plugin-jest-hoist@npm:29.6.3" - dependencies: - "@babel/template": ^7.3.3 - "@babel/types": ^7.3.3 - "@types/babel__core": ^7.1.14 - "@types/babel__traverse": ^7.0.6 - checksum: 7e6451caaf7dce33d010b8aafb970e62f1b0c0b57f4978c37b0d457bbcf0874d75a395a102daf0bae0bd14eafb9f6e9a165ee5e899c0a4f1f3bb2e07b304ed2e - languageName: node - linkType: hard - "babel-plugin-polyfill-corejs2@npm:^0.4.5": version: 0.4.5 resolution: "babel-plugin-polyfill-corejs2@npm:0.4.5" @@ -5128,40 +4690,6 @@ __metadata: languageName: node linkType: hard -"babel-preset-current-node-syntax@npm:^1.0.0": - version: 1.0.1 - resolution: "babel-preset-current-node-syntax@npm:1.0.1" - dependencies: - "@babel/plugin-syntax-async-generators": ^7.8.4 - "@babel/plugin-syntax-bigint": ^7.8.3 - "@babel/plugin-syntax-class-properties": ^7.8.3 - "@babel/plugin-syntax-import-meta": ^7.8.3 - "@babel/plugin-syntax-json-strings": ^7.8.3 - "@babel/plugin-syntax-logical-assignment-operators": ^7.8.3 - "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 - "@babel/plugin-syntax-numeric-separator": ^7.8.3 - "@babel/plugin-syntax-object-rest-spread": ^7.8.3 - "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 - "@babel/plugin-syntax-optional-chaining": ^7.8.3 - "@babel/plugin-syntax-top-level-await": ^7.8.3 - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 5ba39a3a0e6c37d25e56a4fb843be632dac98d54706d8a0933f9bcb1a07987a96d55c2b5a6c11788a74063fb2534fe68c1f1dbb6c93626850c785e0938495627 - languageName: node - linkType: hard - -"babel-preset-jest@npm:^29.6.3": - version: 29.6.3 - resolution: "babel-preset-jest@npm:29.6.3" - dependencies: - babel-plugin-jest-hoist: ^29.6.3 - babel-preset-current-node-syntax: ^1.0.0 - peerDependencies: - "@babel/core": ^7.0.0 - checksum: ec5fd0276b5630b05f0c14bb97cc3815c6b31600c683ebb51372e54dcb776cff790bdeeabd5b8d01ede375a040337ccbf6a3ccd68d3a34219125945e167ad943 - languageName: node - linkType: hard - "bail@npm:^1.0.0": version: 1.0.5 resolution: "bail@npm:1.0.5" @@ -5357,15 +4885,6 @@ __metadata: languageName: node linkType: hard -"bser@npm:2.1.1": - version: 2.1.1 - resolution: "bser@npm:2.1.1" - dependencies: - node-int64: ^0.4.0 - checksum: 24d8dfb7b6d457d73f32744e678a60cc553e4ec0e9e1a01cf614b44d85c3c87e188d3cc78ef0442ce5032ee6818de20a0162ba1074725c0d08908f62ea979227 - languageName: node - linkType: hard - "buffer-alloc-unsafe@npm:^1.1.0": version: 1.1.0 resolution: "buffer-alloc-unsafe@npm:1.1.0" @@ -5522,7 +5041,7 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:^5.0.0, camelcase@npm:^5.3.1": +"camelcase@npm:^5.0.0": version: 5.3.1 resolution: "camelcase@npm:5.3.1" checksum: 92ff9b443bfe8abb15f2b1513ca182d16126359ad4f955ebc83dc4ddcc4ef3fdd2c078bc223f2673dc223488e75c99b16cc4d056624374b799e6a1555cf61b23 @@ -5603,27 +5122,13 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^5.0.0, chalk@npm:^5.2.0": +"chalk@npm:^5.0.0": version: 5.3.0 resolution: "chalk@npm:5.3.0" checksum: 8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09 languageName: node linkType: hard -"char-regex@npm:^1.0.2": - version: 1.0.2 - resolution: "char-regex@npm:1.0.2" - checksum: 57a09a86371331e0be35d9083ba429e86c4f4648ecbe27455dbfb343037c16ee6fdc7f6b61f433a57cc5ded5561d71c56a150e018f40c2ffb7bc93a26dae341e - languageName: node - linkType: hard - -"char-regex@npm:^2.0.0": - version: 2.0.1 - resolution: "char-regex@npm:2.0.1" - checksum: ec592229ac3ef18f2ea1f5676ae9a829c37150db55fd7f709edce1bcdc9f506de22ae19388d853704806e51af71fe9239bcb7e7be583296951bfbf2a9a9763a2 - languageName: node - linkType: hard - "character-entities-legacy@npm:^1.0.0": version: 1.1.4 resolution: "character-entities-legacy@npm:1.1.4" @@ -5706,13 +5211,6 @@ __metadata: languageName: node linkType: hard -"cjs-module-lexer@npm:^1.0.0": - version: 1.2.3 - resolution: "cjs-module-lexer@npm:1.2.3" - checksum: 0de9a9c3fad03a46804c0d38e7b712fb282584a9c7ef1ed44cae22fb71d9bb600309d66a9711ac36a596fd03422f5bb03e021e8f369c12a39fa1786ae531baab - languageName: node - linkType: hard - "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -5816,13 +5314,6 @@ __metadata: languageName: node linkType: hard -"co@npm:^4.6.0": - version: 4.6.0 - resolution: "co@npm:4.6.0" - checksum: c0e85ea0ca8bf0a50cbdca82efc5af0301240ca88ebe3644a6ffb8ffe911f34d40f8fbcf8f1d52c5ddd66706abd4d3bfcd64259f1e8e2371d4f47573b0dc8c28 - languageName: node - linkType: hard - "codecov@npm:^3.8.1": version: 3.8.2 resolution: "codecov@npm:3.8.2" @@ -5845,13 +5336,6 @@ __metadata: languageName: node linkType: hard -"collect-v8-coverage@npm:^1.0.0": - version: 1.0.2 - resolution: "collect-v8-coverage@npm:1.0.2" - checksum: ed7008e2e8b6852c5483b444a3ae6e976e088d4335a85aa0a9db2861c5f1d31bd2d7ff97a60469b3388deeba661a619753afbe201279fb159b4b9548ab8269a1 - languageName: node - linkType: hard - "color-convert@npm:^1.9.0": version: 1.9.3 resolution: "color-convert@npm:1.9.3" @@ -6024,20 +5508,13 @@ __metadata: languageName: node linkType: hard -"convert-source-map@npm:^1.6.0, convert-source-map@npm:^1.7.0": +"convert-source-map@npm:^1.7.0": version: 1.9.0 resolution: "convert-source-map@npm:1.9.0" checksum: 281da55454bf8126cbc6625385928c43479f2060984180c42f3a86c8b8c12720a24eac260624a7d1e090004028d2dee78602330578ceec1a08e27cb8bb0a8a5b languageName: node linkType: hard -"convert-source-map@npm:^2.0.0": - version: 2.0.0 - resolution: "convert-source-map@npm:2.0.0" - checksum: 8f2f7a27a1a011cc6cc88cc4da2d7d0cfa5ee0369508baae3d98c260bb3ac520691464e5bbe4ae7cdf09860c1d69ecc6f70c63c6e7c7f7e3f18ec08484dc7d9b - languageName: node - linkType: hard - "cookie-signature@npm:1.0.6": version: 1.0.6 resolution: "cookie-signature@npm:1.0.6" @@ -6129,23 +5606,6 @@ __metadata: languageName: node linkType: hard -"create-jest@npm:^29.7.0": - version: 29.7.0 - resolution: "create-jest@npm:29.7.0" - dependencies: - "@jest/types": ^29.6.3 - chalk: ^4.0.0 - exit: ^0.1.2 - graceful-fs: ^4.2.9 - jest-config: ^29.7.0 - jest-util: ^29.7.0 - prompts: ^2.0.1 - bin: - create-jest: bin/create-jest.js - checksum: e7e54c280692470d3398f62a6238fd396327e01c6a0757002833f06d00afc62dd7bfe04ff2b9cd145264460e6b4d1eb8386f2925b7e567f97939843b7b0e812f - languageName: node - linkType: hard - "create-require@npm:^1.1.0": version: 1.1.1 resolution: "create-require@npm:1.1.1" @@ -6203,29 +5663,6 @@ __metadata: languageName: node linkType: hard -"cssom@npm:^0.5.0": - version: 0.5.0 - resolution: "cssom@npm:0.5.0" - checksum: 8c4121c243baf0678c65dcac29b201ff0067dfecf978de9d5c83b2ff127a8fdefd2bfd54577f5ad8c80ed7d2c8b489ae01c82023545d010c4ecb87683fb403dd - languageName: node - linkType: hard - -"cssom@npm:~0.3.6": - version: 0.3.8 - resolution: "cssom@npm:0.3.8" - checksum: d74017b209440822f9e24d8782d6d2e808a8fdd58fa626a783337222fe1c87a518ba944d4c88499031b4786e68772c99dfae616638d71906fe9f203aeaf14411 - languageName: node - linkType: hard - -"cssstyle@npm:^2.3.0": - version: 2.3.0 - resolution: "cssstyle@npm:2.3.0" - dependencies: - cssom: ~0.3.6 - checksum: 863400da2a458f73272b9a55ba7ff05de40d850f22eb4f37311abebd7eff801cf1cd2fb04c4c92b8c3daed83fe766e52e4112afb7bc88d86c63a9c2256a7d178 - languageName: node - linkType: hard - "csstype@npm:^3.0.2": version: 3.1.2 resolution: "csstype@npm:3.1.2" @@ -6304,17 +5741,6 @@ __metadata: languageName: node linkType: hard -"data-urls@npm:^3.0.2": - version: 3.0.2 - resolution: "data-urls@npm:3.0.2" - dependencies: - abab: ^2.0.6 - whatwg-mimetype: ^3.0.0 - whatwg-url: ^11.0.0 - checksum: 051c3aaaf3e961904f136aab095fcf6dff4db23a7fc759dd8ba7b3e6ba03fc07ef608086caad8ab910d864bd3b5e57d0d2f544725653d77c96a2c971567045f4 - languageName: node - linkType: hard - "dataloader@npm:^2.2.2": version: 2.2.2 resolution: "dataloader@npm:2.2.2" @@ -6359,13 +5785,6 @@ __metadata: languageName: node linkType: hard -"decimal.js@npm:^10.4.2": - version: 10.4.3 - resolution: "decimal.js@npm:10.4.3" - checksum: 6d60206689ff0911f0ce968d40f163304a6c1bc739927758e6efc7921cfa630130388966f16bf6ef6b838cb33679fbe8e7a78a2f3c478afce841fd55ac8fb8ee - languageName: node - linkType: hard - "decode-named-character-reference@npm:^1.0.0": version: 1.0.2 resolution: "decode-named-character-reference@npm:1.0.2" @@ -6461,18 +5880,6 @@ __metadata: languageName: node linkType: hard -"dedent@npm:^1.0.0": - version: 1.5.1 - resolution: "dedent@npm:1.5.1" - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - checksum: f8612cd5b00aab58b18bb95572dca08dc2d49720bfa7201a444c3dae430291e8a06d4928614a6ec8764d713927f44bce9c990d3b8238fca2f430990ddc17c070 - languageName: node - linkType: hard - "deep-eql@npm:^4.1.2": version: 4.1.3 resolution: "deep-eql@npm:4.1.3" @@ -6515,13 +5922,6 @@ __metadata: languageName: node linkType: hard -"deepmerge@npm:^4.2.2": - version: 4.3.1 - resolution: "deepmerge@npm:4.3.1" - checksum: e53481aaf1aa2c4082b5342be6b6d8ad9dfe387bc92ce197a66dea08bd4265904a087e75e464f14d1347cf2ac8afe1e4c16b266e0561cc5df29382d3c5f80044 - languageName: node - linkType: hard - "defaults@npm:^1.0.3": version: 1.0.4 resolution: "defaults@npm:1.0.4" @@ -6636,7 +6036,7 @@ __metadata: languageName: node linkType: hard -"detect-newline@npm:3.1.0, detect-newline@npm:^3.0.0": +"detect-newline@npm:3.1.0": version: 3.1.0 resolution: "detect-newline@npm:3.1.0" checksum: c38cfc8eeb9fda09febb44bcd85e467c970d4e3bf526095394e5a4f18bc26dd0cf6b22c69c1fa9969261521c593836db335c2795218f6d781a512aea2fb8209d @@ -6691,15 +6091,6 @@ __metadata: languageName: node linkType: hard -"diffable-html@npm:^4.1.0": - version: 4.1.0 - resolution: "diffable-html@npm:4.1.0" - dependencies: - htmlparser2: ^3.9.2 - checksum: 4224133455312e03dd5b84cec0a7d7390552ae30fc5ceb24256c4973e7b51ab2ba69f8b8dbeaaa3feb2b92d3fdd57476dcb7afeada793130ab340720c6a553c7 - languageName: node - linkType: hard - "dir-glob@npm:^2.0.0": version: 2.2.2 resolution: "dir-glob@npm:2.2.2" @@ -6743,16 +6134,6 @@ __metadata: languageName: node linkType: hard -"dom-serializer@npm:0": - version: 0.2.2 - resolution: "dom-serializer@npm:0.2.2" - dependencies: - domelementtype: ^2.0.1 - entities: ^2.0.0 - checksum: 5cb595fb77e1a23eca56742f47631e6f4af66ce1982c7ed28b3d0ef21f1f50304c067adc29d3eaf824c572be022cee88627d0ac9b929408f24e923f3c7bed37b - languageName: node - linkType: hard - "dom-serializer@npm:^1.0.1": version: 1.4.1 resolution: "dom-serializer@npm:1.4.1" @@ -6764,13 +6145,6 @@ __metadata: languageName: node linkType: hard -"domelementtype@npm:1, domelementtype@npm:^1.3.1": - version: 1.3.1 - resolution: "domelementtype@npm:1.3.1" - checksum: 6d4f5761060a21eaf3c96545501e9d188745c7e1c31b8d141bf15d8748feeadba868f4ea32877751b8678b286fb1afbe6ae905ca3fb8f0214d8322e482cdbec0 - languageName: node - linkType: hard - "domelementtype@npm:^2.0.1, domelementtype@npm:^2.2.0": version: 2.3.0 resolution: "domelementtype@npm:2.3.0" @@ -6778,24 +6152,6 @@ __metadata: languageName: node linkType: hard -"domexception@npm:^4.0.0": - version: 4.0.0 - resolution: "domexception@npm:4.0.0" - dependencies: - webidl-conversions: ^7.0.0 - checksum: 774277cd9d4df033f852196e3c0077a34dbd15a96baa4d166e0e47138a80f4c0bdf0d94e4703e6ff5883cec56bb821a6fff84402d8a498e31de7c87eb932a294 - languageName: node - linkType: hard - -"domhandler@npm:^2.3.0": - version: 2.4.2 - resolution: "domhandler@npm:2.4.2" - dependencies: - domelementtype: 1 - checksum: 6670cab73e97e3c6771dcf22b537db3f6a0be0ad6b370f03bb5f1b585d3b563d326787fdabe1190b7ca9d81c804e9b3f8a1431159c27c44f6c05f94afa92be2d - languageName: node - linkType: hard - "domhandler@npm:^4.2.0, domhandler@npm:^4.2.2": version: 4.3.1 resolution: "domhandler@npm:4.3.1" @@ -6805,16 +6161,6 @@ __metadata: languageName: node linkType: hard -"domutils@npm:^1.5.1": - version: 1.7.0 - resolution: "domutils@npm:1.7.0" - dependencies: - dom-serializer: 0 - domelementtype: 1 - checksum: 437fcd2d6d6be03f488152e73c6f953e289c58496baa22be9626b2b46f9cfd40486ae77d144487ff6b102929a3231cdb9a8bf8ef485fb7b7c30c985daedc77eb - languageName: node - linkType: hard - "domutils@npm:^2.8.0": version: 2.8.0 resolution: "domutils@npm:2.8.0" @@ -6939,13 +6285,6 @@ __metadata: languageName: node linkType: hard -"emittery@npm:^0.13.1": - version: 0.13.1 - resolution: "emittery@npm:0.13.1" - checksum: 1573d0ae29ab34661b6c63251ff8f5facd24ccf6a823f19417ae8ba8c88ea450325788c67f16c99edec8de4b52ce93a10fe441ece389fd156e88ee7dab9bfa35 - languageName: node - linkType: hard - "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" @@ -7021,13 +6360,6 @@ __metadata: languageName: node linkType: hard -"entities@npm:^1.1.1": - version: 1.1.2 - resolution: "entities@npm:1.1.2" - checksum: 5b12fa8c4fb942f88af6f8791bbe7be0a59ebd91c8933cee091d94455efd1eeb200418c7b1bc8dd0f74cdd4db8cf4538eb043db14cfd1919130c25d8c6095215 - languageName: node - linkType: hard - "entities@npm:^2.0.0": version: 2.2.0 resolution: "entities@npm:2.2.0" @@ -7042,13 +6374,6 @@ __metadata: languageName: node linkType: hard -"entities@npm:^4.4.0": - version: 4.5.0 - resolution: "entities@npm:4.5.0" - checksum: 5b039739f7621f5d1ad996715e53d964035f75ad3b9a4d38c6b3804bb226e282ffeae2443624d8fdd9c47d8e926ae9ac009c54671243f0c3294c26af7cc85250 - languageName: node - linkType: hard - "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -7328,24 +6653,6 @@ __metadata: languageName: node linkType: hard -"escodegen@npm:^2.0.0": - version: 2.1.0 - resolution: "escodegen@npm:2.1.0" - dependencies: - esprima: ^4.0.1 - estraverse: ^5.2.0 - esutils: ^2.0.2 - source-map: ~0.6.1 - dependenciesMeta: - source-map: - optional: true - bin: - escodegen: bin/escodegen.js - esgenerate: bin/esgenerate.js - checksum: e1450a1f75f67d35c061bf0d60888b15f62ab63aef9df1901cffc81cffbbb9e8b3de237c5502cf8613a017c1df3a3003881307c78835a1ab54d8c8d2206e01d3 - languageName: node - linkType: hard - "eslint-config-airbnb-base@npm:^14.2.0, eslint-config-airbnb-base@npm:^14.2.1": version: 14.2.1 resolution: "eslint-config-airbnb-base@npm:14.2.1" @@ -7699,7 +7006,7 @@ __metadata: languageName: node linkType: hard -"esprima@npm:^4.0.0, esprima@npm:^4.0.1, esprima@npm:~4.0.0": +"esprima@npm:^4.0.0, esprima@npm:~4.0.0": version: 4.0.1 resolution: "esprima@npm:4.0.1" bin: @@ -7859,13 +7166,6 @@ __metadata: languageName: node linkType: hard -"exit@npm:^0.1.2": - version: 0.1.2 - resolution: "exit@npm:0.1.2" - checksum: 71d2ad9b36bc25bb8b104b17e830b40a08989be7f7d100b13269aaae7c3784c3e6e1e88a797e9e87523993a25ba27c8958959a554535370672cfb4d824af8989 - languageName: node - linkType: hard - "expand-tilde@npm:^2.0.2": version: 2.0.2 resolution: "expand-tilde@npm:2.0.2" @@ -7875,7 +7175,7 @@ __metadata: languageName: node linkType: hard -"expect@npm:^29.0.0, expect@npm:^29.7.0": +"expect@npm:^29.0.0": version: 29.7.0 resolution: "expect@npm:29.7.0" dependencies: @@ -8030,7 +7330,7 @@ __metadata: languageName: node linkType: hard -"fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": +"fast-json-stable-stringify@npm:^2.0.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" checksum: 7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b @@ -8092,15 +7392,6 @@ __metadata: languageName: node linkType: hard -"fb-watchman@npm:^2.0.0": - version: 2.0.2 - resolution: "fb-watchman@npm:2.0.2" - dependencies: - bser: 2.1.1 - checksum: feae89ac148adb8f6ae8ccd87632e62b13563e6fb114cacb5265c51f585b17e2e268084519fb2edd133872f1d47a18e6bfd7e5e08625c0d41b93149694187581 - languageName: node - linkType: hard - "fd-slicer@npm:~1.1.0": version: 1.1.0 resolution: "fd-slicer@npm:1.1.0" @@ -8215,7 +7506,7 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^4.0.0, find-up@npm:^4.1.0": +"find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" dependencies: @@ -8421,7 +7712,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": +"fsevents@npm:~2.3.2": version: 2.3.3 resolution: "fsevents@npm:2.3.3" dependencies: @@ -8431,7 +7722,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@^2.3.2#~builtin, fsevents@patch:fsevents@~2.3.2#~builtin": +"fsevents@patch:fsevents@~2.3.2#~builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=df0bf1" dependencies: @@ -8561,20 +7852,6 @@ __metadata: languageName: node linkType: hard -"get-package-type@npm:^0.1.0": - version: 0.1.0 - resolution: "get-package-type@npm:0.1.0" - checksum: e34cdf447fdf1902a1f6d5af737eaadf606d2ee3518287abde8910e04159368c268568174b2e71102b87b26c2020486f126bfca9c4fb1ceb986ff99b52ecd1be - languageName: node - linkType: hard - -"get-stdin@npm:^5.0.1": - version: 5.0.1 - resolution: "get-stdin@npm:5.0.1" - checksum: 309f933f08a4d6783681674451027802299124e596324cd628c5e5138bbc5de843bbaa345a8ce0fc72304869f9de3b50086407aca551e292b13f7cb02351479e - languageName: node - linkType: hard - "get-stdin@npm:^6.0.0": version: 6.0.0 resolution: "get-stdin@npm:6.0.0" @@ -8863,13 +8140,6 @@ __metadata: languageName: node linkType: hard -"glur@npm:^1.1.2": - version: 1.1.2 - resolution: "glur@npm:1.1.2" - checksum: 756fcbc7f1a8576755811e31367feeaffbd13b7f20d788672bccbd65956839065e256621a7576f4ab321352b28a0aea442d64567bca23882526b891767ffbe3e - languageName: node - linkType: hard - "google-auth-library@npm:^8.0.2": version: 8.9.0 resolution: "google-auth-library@npm:8.9.0" @@ -9112,27 +8382,6 @@ __metadata: languageName: node linkType: hard -"html-escaper@npm:^2.0.0": - version: 2.0.2 - resolution: "html-escaper@npm:2.0.2" - checksum: 208e8a12de1a6569edbb14544f4567e6ce8ecc30b9394fcaa4e7bb1e60c12a7c9a1ed27e31290817157e8626f3a4f29e76c8747030822eb84a6abb15c255f0a0 - languageName: node - linkType: hard - -"htmlparser2@npm:^3.9.2": - version: 3.10.1 - resolution: "htmlparser2@npm:3.10.1" - dependencies: - domelementtype: ^1.3.1 - domhandler: ^2.3.0 - domutils: ^1.5.1 - entities: ^1.1.1 - inherits: ^2.0.1 - readable-stream: ^3.1.1 - checksum: b1424536ff062088501efa06a2afd478545d3134a5ad2e28bbe02dc2d092784982286b90f1c87fa3d86692958dbfb8936352dfd71d1cb2ff7cb61208c00fcdb1 - languageName: node - linkType: hard - "htmlparser2@npm:^7.1.2": version: 7.2.0 resolution: "htmlparser2@npm:7.2.0" @@ -9385,18 +8634,6 @@ __metadata: languageName: node linkType: hard -"import-local@npm:^3.0.2": - version: 3.1.0 - resolution: "import-local@npm:3.1.0" - dependencies: - pkg-dir: ^4.2.0 - resolve-cwd: ^3.0.0 - bin: - import-local-fixture: fixtures/cli.js - checksum: c67ecea72f775fe8684ca3d057e54bdb2ae28c14bf261d2607c269c18ea0da7b730924c06262eca9aed4b8ab31e31d65bc60b50e7296c85908a56e2f7d41ecd2 - languageName: node - linkType: hard - "import-meta-resolve@npm:^2.0.0": version: 2.2.2 resolution: "import-meta-resolve@npm:2.2.2" @@ -9428,7 +8665,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 @@ -9677,13 +8914,6 @@ __metadata: languageName: node linkType: hard -"is-generator-fn@npm:^2.0.0": - version: 2.1.0 - resolution: "is-generator-fn@npm:2.1.0" - checksum: 2957cab387997a466cd0bf5c1b6047bd21ecb32bdcfd8996b15747aa01002c1c88731802f1b3d34ac99f4f6874b626418bd118658cf39380fe5fff32a3af9c4d - languageName: node - linkType: hard - "is-generator-function@npm:^1.0.10, is-generator-function@npm:^1.0.7": version: 1.0.10 resolution: "is-generator-function@npm:1.0.10" @@ -9821,13 +9051,6 @@ __metadata: languageName: node linkType: hard -"is-potential-custom-element-name@npm:^1.0.1": - version: 1.0.1 - resolution: "is-potential-custom-element-name@npm:1.0.1" - checksum: b73e2f22bc863b0939941d369486d308b43d7aef1f9439705e3582bfccaa4516406865e32c968a35f97a99396dac84e2624e67b0a16b0a15086a785e16ce7db9 - languageName: node - linkType: hard - "is-promise@npm:^2.1.0": version: 2.2.2 resolution: "is-promise@npm:2.2.2" @@ -10000,71 +9223,6 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": - version: 3.2.0 - resolution: "istanbul-lib-coverage@npm:3.2.0" - checksum: 10ecb00a50cac2f506af8231ce523ffa1ac1310db0435c8ffaabb50c1d72539906583aa13c84f8835dc103998b9989edc3c1de989d2e2a96a91a9ba44e5db6b9 - languageName: node - linkType: hard - -"istanbul-lib-instrument@npm:^5.0.4": - version: 5.2.1 - resolution: "istanbul-lib-instrument@npm:5.2.1" - dependencies: - "@babel/core": ^7.12.3 - "@babel/parser": ^7.14.7 - "@istanbuljs/schema": ^0.1.2 - istanbul-lib-coverage: ^3.2.0 - semver: ^6.3.0 - checksum: 8a1bdf3e377dcc0d33ec32fe2b6ecacdb1e4358fd0eb923d4326bb11c67622c0ceb99600a680f3dad5d29c66fc1991306081e339b4d43d0b8a2ab2e1d910a6ee - languageName: node - linkType: hard - -"istanbul-lib-instrument@npm:^6.0.0": - version: 6.0.0 - resolution: "istanbul-lib-instrument@npm:6.0.0" - dependencies: - "@babel/core": ^7.12.3 - "@babel/parser": ^7.14.7 - "@istanbuljs/schema": ^0.1.2 - istanbul-lib-coverage: ^3.2.0 - semver: ^7.5.4 - checksum: ee86777f3692f95c3ae35c5cbc9aa979b551241da2de1284f75c507a2bdef948cc56ca90214c3bb47b5dc2ebe748610eb4f7c4d39b304f24a933bcd0867a05e8 - languageName: node - linkType: hard - -"istanbul-lib-report@npm:^3.0.0": - version: 3.0.1 - resolution: "istanbul-lib-report@npm:3.0.1" - dependencies: - istanbul-lib-coverage: ^3.0.0 - make-dir: ^4.0.0 - supports-color: ^7.1.0 - checksum: 84323afb14392de8b6a5714bd7e9af845cfbd56cfe71ed276cda2f5f1201aea673c7111901227ee33e68e4364e288d73861eb2ed48f6679d1e69a43b6d9b3ba7 - languageName: node - linkType: hard - -"istanbul-lib-source-maps@npm:^4.0.0": - version: 4.0.1 - resolution: "istanbul-lib-source-maps@npm:4.0.1" - dependencies: - debug: ^4.1.1 - istanbul-lib-coverage: ^3.0.0 - source-map: ^0.6.1 - checksum: 19e4cc405016f2c906dff271a76715b3e881fa9faeb3f09a86cb99b8512b3a5ed19cadfe0b54c17ca0e54c1142c9c6de9330d65506e35873994e06634eebeb66 - languageName: node - linkType: hard - -"istanbul-reports@npm:^3.1.3": - version: 3.1.6 - resolution: "istanbul-reports@npm:3.1.6" - dependencies: - html-escaper: ^2.0.0 - istanbul-lib-report: ^3.0.0 - checksum: ec3f1bdbc51b3e0b325a5b9f4ad31a247697f31001df4e81075f7980413f14da1b5adfec574fd156efd3b0464023f61320f6718efc66ee72b32d89611cef99dd - languageName: node - linkType: hard - "iterator.prototype@npm:^1.1.0": version: 1.1.1 resolution: "iterator.prototype@npm:1.1.1" @@ -10104,109 +9262,6 @@ __metadata: languageName: node linkType: hard -"jest-changed-files@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-changed-files@npm:29.7.0" - dependencies: - execa: ^5.0.0 - jest-util: ^29.7.0 - p-limit: ^3.1.0 - checksum: e071384d9e2f6bb462231ac53f29bff86f0e12394c1b49ccafbad225ce2ab7da226279a8a94f421949920bef9be7ef574fd86aee22e8adfa149be73554ab828b - languageName: node - linkType: hard - -"jest-circus@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-circus@npm:29.7.0" - dependencies: - "@jest/environment": ^29.7.0 - "@jest/expect": ^29.7.0 - "@jest/test-result": ^29.7.0 - "@jest/types": ^29.6.3 - "@types/node": "*" - chalk: ^4.0.0 - co: ^4.6.0 - dedent: ^1.0.0 - is-generator-fn: ^2.0.0 - jest-each: ^29.7.0 - jest-matcher-utils: ^29.7.0 - jest-message-util: ^29.7.0 - jest-runtime: ^29.7.0 - jest-snapshot: ^29.7.0 - jest-util: ^29.7.0 - p-limit: ^3.1.0 - pretty-format: ^29.7.0 - pure-rand: ^6.0.0 - slash: ^3.0.0 - stack-utils: ^2.0.3 - checksum: 8d15344cf7a9f14e926f0deed64ed190c7a4fa1ed1acfcd81e4cc094d3cc5bf7902ebb7b874edc98ada4185688f90c91e1747e0dfd7ac12463b097968ae74b5e - languageName: node - linkType: hard - -"jest-cli@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-cli@npm:29.7.0" - dependencies: - "@jest/core": ^29.7.0 - "@jest/test-result": ^29.7.0 - "@jest/types": ^29.6.3 - chalk: ^4.0.0 - create-jest: ^29.7.0 - exit: ^0.1.2 - import-local: ^3.0.2 - jest-config: ^29.7.0 - jest-util: ^29.7.0 - jest-validate: ^29.7.0 - yargs: ^17.3.1 - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - bin: - jest: bin/jest.js - checksum: a658fd55050d4075d65c1066364595962ead7661711495cfa1dfeecf3d6d0a8ffec532f3dbd8afbb3e172dd5fd2fb2e813c5e10256e7cf2fea766314942fb43a - languageName: node - linkType: hard - -"jest-config@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-config@npm:29.7.0" - dependencies: - "@babel/core": ^7.11.6 - "@jest/test-sequencer": ^29.7.0 - "@jest/types": ^29.6.3 - babel-jest: ^29.7.0 - chalk: ^4.0.0 - ci-info: ^3.2.0 - deepmerge: ^4.2.2 - glob: ^7.1.3 - graceful-fs: ^4.2.9 - jest-circus: ^29.7.0 - jest-environment-node: ^29.7.0 - jest-get-type: ^29.6.3 - jest-regex-util: ^29.6.3 - jest-resolve: ^29.7.0 - jest-runner: ^29.7.0 - jest-util: ^29.7.0 - jest-validate: ^29.7.0 - micromatch: ^4.0.4 - parse-json: ^5.2.0 - pretty-format: ^29.7.0 - slash: ^3.0.0 - strip-json-comments: ^3.1.1 - peerDependencies: - "@types/node": "*" - ts-node: ">=9.0.0" - peerDependenciesMeta: - "@types/node": - optional: true - ts-node: - optional: true - checksum: bab23c2eda1fff06e0d104b00d6adfb1d1aabb7128441899c9bff2247bd26710b050a5364281ce8d52b46b499153bf7e3ee88b19831a8f3451f1477a0246a0f1 - languageName: node - linkType: hard - "jest-diff@npm:^28.1.3": version: 28.1.3 resolution: "jest-diff@npm:28.1.3" @@ -10231,63 +9286,6 @@ __metadata: languageName: node linkType: hard -"jest-docblock@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-docblock@npm:29.7.0" - dependencies: - detect-newline: ^3.0.0 - checksum: d932a8272345cf6b6142bb70a2bb63e0856cc0093f082821577ea5bdf4643916a98744dfc992189d2b1417c38a11fa42466f6111526bc1fb81366f56410f3be9 - languageName: node - linkType: hard - -"jest-each@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-each@npm:29.7.0" - dependencies: - "@jest/types": ^29.6.3 - chalk: ^4.0.0 - jest-get-type: ^29.6.3 - jest-util: ^29.7.0 - pretty-format: ^29.7.0 - checksum: f7f9a90ebee80cc688e825feceb2613627826ac41ea76a366fa58e669c3b2403d364c7c0a74d862d469b103c843154f8456d3b1c02b487509a12afa8b59edbb4 - languageName: node - linkType: hard - -"jest-environment-jsdom@npm:^29.3.1": - version: 29.7.0 - resolution: "jest-environment-jsdom@npm:29.7.0" - dependencies: - "@jest/environment": ^29.7.0 - "@jest/fake-timers": ^29.7.0 - "@jest/types": ^29.6.3 - "@types/jsdom": ^20.0.0 - "@types/node": "*" - jest-mock: ^29.7.0 - jest-util: ^29.7.0 - jsdom: ^20.0.0 - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true - checksum: 139b94e2c8ec1bb5a46ce17df5211da65ce867354b3fd4e00fa6a0d1da95902df4cf7881273fc6ea937e5c325d39d6773f0d41b6c469363334de9d489d2c321f - languageName: node - linkType: hard - -"jest-environment-node@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-environment-node@npm:29.7.0" - dependencies: - "@jest/environment": ^29.7.0 - "@jest/fake-timers": ^29.7.0 - "@jest/types": ^29.6.3 - "@types/node": "*" - jest-mock: ^29.7.0 - jest-util: ^29.7.0 - checksum: 61f04fec077f8b1b5c1a633e3612fc0c9aa79a0ab7b05600683428f1e01a4d35346c474bde6f439f9fcc1a4aa9a2861ff852d079a43ab64b02105d1004b2592b - languageName: node - linkType: hard - "jest-get-type@npm:^28.0.2": version: 28.0.2 resolution: "jest-get-type@npm:28.0.2" @@ -10302,72 +9300,6 @@ __metadata: languageName: node linkType: hard -"jest-haste-map@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-haste-map@npm:29.7.0" - dependencies: - "@jest/types": ^29.6.3 - "@types/graceful-fs": ^4.1.3 - "@types/node": "*" - anymatch: ^3.0.3 - fb-watchman: ^2.0.0 - fsevents: ^2.3.2 - graceful-fs: ^4.2.9 - jest-regex-util: ^29.6.3 - jest-util: ^29.7.0 - jest-worker: ^29.7.0 - micromatch: ^4.0.4 - walker: ^1.0.8 - dependenciesMeta: - fsevents: - optional: true - checksum: 2683a8f29793c75a4728787662972fedd9267704c8f7ef9d84f2beed9a977f1cf5e998c07b6f36ba5603f53cb010c911fe8cd0ac9886e073fe28ca66beefd30c - languageName: node - linkType: hard - -"jest-image-snapshot@npm:^6.0.0": - version: 6.2.0 - resolution: "jest-image-snapshot@npm:6.2.0" - dependencies: - chalk: ^4.0.0 - get-stdin: ^5.0.1 - glur: ^1.1.2 - lodash: ^4.17.4 - pixelmatch: ^5.1.0 - pngjs: ^3.4.0 - rimraf: ^2.6.2 - ssim.js: ^3.1.1 - peerDependencies: - jest: ">=20 <=29" - peerDependenciesMeta: - jest: - optional: true - checksum: 62e415f86f2bed30fe126520519014beed61a38a678285de44c6544d10eed7381b28958d3406f131a60c05715f42ab7bf7ea4ecfdab4f55946cec6739de23924 - languageName: node - linkType: hard - -"jest-junit@npm:^14.0.1": - version: 14.0.1 - resolution: "jest-junit@npm:14.0.1" - dependencies: - mkdirp: ^1.0.4 - strip-ansi: ^6.0.1 - uuid: ^8.3.2 - xml: ^1.0.1 - checksum: ec06ffad0326f037e62637b0c9935f2668c4657bebf4b81ab3b14867482b754f479c93cd13fe8915b763a7196a3dbc3edf323f062026763e4a79891b617e5945 - languageName: node - linkType: hard - -"jest-leak-detector@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-leak-detector@npm:29.7.0" - dependencies: - jest-get-type: ^29.6.3 - pretty-format: ^29.7.0 - checksum: 71bb9f77fc489acb842a5c7be030f2b9acb18574dc9fb98b3100fc57d422b1abc55f08040884bd6e6dbf455047a62f7eaff12aa4058f7cbdc11558718ca6a395 - languageName: node - linkType: hard - "jest-matcher-utils@npm:^28.0.0": version: 28.1.3 resolution: "jest-matcher-utils@npm:28.1.3" @@ -10382,304 +9314,54 @@ __metadata: "jest-matcher-utils@npm:^29.7.0": version: 29.7.0 - resolution: "jest-matcher-utils@npm:29.7.0" - dependencies: - chalk: ^4.0.0 - jest-diff: ^29.7.0 - jest-get-type: ^29.6.3 - pretty-format: ^29.7.0 - checksum: 0d0e70b28fa5c7d4dce701dc1f46ae0922102aadc24ed45d594dd9b7ae0a8a6ef8b216718d1ab79e451291217e05d4d49a82666e1a3cc2b428b75cd9c933244e - languageName: node - linkType: hard - -"jest-message-util@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-message-util@npm:29.7.0" - dependencies: - "@babel/code-frame": ^7.12.13 - "@jest/types": ^29.6.3 - "@types/stack-utils": ^2.0.0 - chalk: ^4.0.0 - graceful-fs: ^4.2.9 - micromatch: ^4.0.4 - pretty-format: ^29.7.0 - slash: ^3.0.0 - stack-utils: ^2.0.3 - checksum: 850ae35477f59f3e6f27efac5215f706296e2104af39232bb14e5403e067992afb5c015e87a9243ec4d9df38525ef1ca663af9f2f4766aa116f127247008bd22 - languageName: node - linkType: hard - -"jest-mock-extended@npm:^3.0.4": - version: 3.0.5 - resolution: "jest-mock-extended@npm:3.0.5" - dependencies: - ts-essentials: ^7.0.3 - peerDependencies: - jest: ^24.0.0 || ^25.0.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0 - typescript: ^3.0.0 || ^4.0.0 || ^5.0.0 - checksum: cbe46aa7bb05c4d57ba82d09003359071e3794ef9ad2835192bec605d78e1d3cc0a7252dcc6db1004a8377be167f05e16795c67edf6d5c9b5a8544ccd3e92ac5 - languageName: node - linkType: hard - -"jest-mock@npm:^27.3.0": - version: 27.5.1 - resolution: "jest-mock@npm:27.5.1" - dependencies: - "@jest/types": ^27.5.1 - "@types/node": "*" - checksum: 6ad58454b37ee3f726930b07efbf40a7c79d2d2d9c7b226708b4b550bc0904de93bcacf714105d11952a5c0bc855e5d59145c8c9dbbb4e69b46e7367abf53b52 - languageName: node - linkType: hard - -"jest-mock@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-mock@npm:29.7.0" - dependencies: - "@jest/types": ^29.6.3 - "@types/node": "*" - jest-util: ^29.7.0 - checksum: 7b9f8349ee87695a309fe15c46a74ab04c853369e5c40952d68061d9dc3159a0f0ed73e215f81b07ee97a9faaf10aebe5877a9d6255068a0977eae6a9ff1d5ac - languageName: node - linkType: hard - -"jest-os-detection@npm:^1.3.1": - version: 1.3.1 - resolution: "jest-os-detection@npm:1.3.1" - checksum: 0fd540b9518d443fe037bd74c3413869e23b167faa3c3f2653c652eb9b0f4acf5448df92344bdf67f4d0d6e994294513e3ba6b0507c245e5d9d31e83541ac621 - languageName: node - linkType: hard - -"jest-pnp-resolver@npm:^1.2.2": - version: 1.2.3 - resolution: "jest-pnp-resolver@npm:1.2.3" - peerDependencies: - jest-resolve: "*" - peerDependenciesMeta: - jest-resolve: - optional: true - checksum: 86eec0c78449a2de733a6d3e316d49461af6a858070e113c97f75fb742a48c2396ea94150cbca44159ffd4a959f743a47a8b37a792ef6fdad2cf0a5cba973fac - languageName: node - linkType: hard - -"jest-regex-util@npm:^29.0.0, jest-regex-util@npm:^29.6.3": - version: 29.6.3 - resolution: "jest-regex-util@npm:29.6.3" - checksum: 4e33fb16c4f42111159cafe26397118dcfc4cf08bc178a67149fb05f45546a91928b820894572679d62559839d0992e21080a1527faad65daaae8743a5705a3b - languageName: node - linkType: hard - -"jest-resolve-dependencies@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-resolve-dependencies@npm:29.7.0" - dependencies: - jest-regex-util: ^29.6.3 - jest-snapshot: ^29.7.0 - checksum: b6e9ad8ae5b6049474118ea6441dfddd385b6d1fc471db0136f7c8fbcfe97137a9665e4f837a9f49f15a29a1deb95a14439b7aec812f3f99d08f228464930f0d - languageName: node - linkType: hard - -"jest-resolve@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-resolve@npm:29.7.0" - dependencies: - chalk: ^4.0.0 - graceful-fs: ^4.2.9 - jest-haste-map: ^29.7.0 - jest-pnp-resolver: ^1.2.2 - jest-util: ^29.7.0 - jest-validate: ^29.7.0 - resolve: ^1.20.0 - resolve.exports: ^2.0.0 - slash: ^3.0.0 - checksum: 59da5c9c5b50563e959a45e09e2eace783d7f9ac0b5dcc6375dea4c0db938d2ebda97124c8161310082760e8ebbeff9f6b177c15ca2f57fb424f637a5d2adb47 - languageName: node - linkType: hard - -"jest-runner@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-runner@npm:29.7.0" - dependencies: - "@jest/console": ^29.7.0 - "@jest/environment": ^29.7.0 - "@jest/test-result": ^29.7.0 - "@jest/transform": ^29.7.0 - "@jest/types": ^29.6.3 - "@types/node": "*" - chalk: ^4.0.0 - emittery: ^0.13.1 - graceful-fs: ^4.2.9 - jest-docblock: ^29.7.0 - jest-environment-node: ^29.7.0 - jest-haste-map: ^29.7.0 - jest-leak-detector: ^29.7.0 - jest-message-util: ^29.7.0 - jest-resolve: ^29.7.0 - jest-runtime: ^29.7.0 - jest-util: ^29.7.0 - jest-watcher: ^29.7.0 - jest-worker: ^29.7.0 - p-limit: ^3.1.0 - source-map-support: 0.5.13 - checksum: 2194b4531068d939f14c8d3274fe5938b77fa73126aedf9c09ec9dec57d13f22c72a3b5af01ac04f5c1cf2e28d0ac0b4a54212a61b05f10b5d6b47f2a1097bb4 - languageName: node - linkType: hard - -"jest-runtime@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-runtime@npm:29.7.0" - dependencies: - "@jest/environment": ^29.7.0 - "@jest/fake-timers": ^29.7.0 - "@jest/globals": ^29.7.0 - "@jest/source-map": ^29.6.3 - "@jest/test-result": ^29.7.0 - "@jest/transform": ^29.7.0 - "@jest/types": ^29.6.3 - "@types/node": "*" - chalk: ^4.0.0 - cjs-module-lexer: ^1.0.0 - collect-v8-coverage: ^1.0.0 - glob: ^7.1.3 - graceful-fs: ^4.2.9 - jest-haste-map: ^29.7.0 - jest-message-util: ^29.7.0 - jest-mock: ^29.7.0 - jest-regex-util: ^29.6.3 - jest-resolve: ^29.7.0 - jest-snapshot: ^29.7.0 - jest-util: ^29.7.0 - slash: ^3.0.0 - strip-bom: ^4.0.0 - checksum: 7cd89a1deda0bda7d0941835434e44f9d6b7bd50b5c5d9b0fc9a6c990b2d4d2cab59685ab3cb2850ed4cc37059f6de903af5a50565d7f7f1192a77d3fd6dd2a6 - languageName: node - linkType: hard - -"jest-serializer-html@npm:^7.1.0": - version: 7.1.0 - resolution: "jest-serializer-html@npm:7.1.0" - dependencies: - diffable-html: ^4.1.0 - checksum: e8383431fbacd5ebb9a7c053c849a0d1e0a183e625aba1ede726260186931b229468dc6456b9b821a137123a88ea3b4325884a5c01c5d78b39c106c3d5c18fcc - languageName: node - linkType: hard - -"jest-snapshot@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-snapshot@npm:29.7.0" - dependencies: - "@babel/core": ^7.11.6 - "@babel/generator": ^7.7.2 - "@babel/plugin-syntax-jsx": ^7.7.2 - "@babel/plugin-syntax-typescript": ^7.7.2 - "@babel/types": ^7.3.3 - "@jest/expect-utils": ^29.7.0 - "@jest/transform": ^29.7.0 - "@jest/types": ^29.6.3 - babel-preset-current-node-syntax: ^1.0.0 - chalk: ^4.0.0 - expect: ^29.7.0 - graceful-fs: ^4.2.9 - jest-diff: ^29.7.0 - jest-get-type: ^29.6.3 - jest-matcher-utils: ^29.7.0 - jest-message-util: ^29.7.0 - jest-util: ^29.7.0 - natural-compare: ^1.4.0 - pretty-format: ^29.7.0 - semver: ^7.5.3 - checksum: 6e9003c94ec58172b4a62864a91c0146513207bedf4e0a06e1e2ac70a4484088a2683e3a0538d8ea913bcfd53dc54a9b98a98cdfa562e7fe1d1339aeae1da570 - languageName: node - linkType: hard - -"jest-util@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-util@npm:29.7.0" - dependencies: - "@jest/types": ^29.6.3 - "@types/node": "*" - chalk: ^4.0.0 - ci-info: ^3.2.0 - graceful-fs: ^4.2.9 - picomatch: ^2.2.3 - checksum: bc55a8f49fdbb8f51baf31d2a4f312fb66c9db1483b82f602c9c990e659cdd7ec529c8e916d5a89452ecbcfae4949b21b40a7a59d4ffc0cd813a973ab08c8150 - languageName: node - linkType: hard - -"jest-validate@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-validate@npm:29.7.0" + resolution: "jest-matcher-utils@npm:29.7.0" dependencies: - "@jest/types": ^29.6.3 - camelcase: ^6.2.0 chalk: ^4.0.0 + jest-diff: ^29.7.0 jest-get-type: ^29.6.3 - leven: ^3.1.0 pretty-format: ^29.7.0 - checksum: a20b930480c1ed68778c739f4739dce39423131bc070cd2505ddede762a5570a256212e9c2401b7ae9ba4d7b7c0803f03c5b8f1561c62348213aba18d9dbece2 - languageName: node - linkType: hard - -"jest-watch-typeahead@npm:^2.2.1": - version: 2.2.2 - resolution: "jest-watch-typeahead@npm:2.2.2" - dependencies: - ansi-escapes: ^6.0.0 - chalk: ^5.2.0 - jest-regex-util: ^29.0.0 - jest-watcher: ^29.0.0 - slash: ^5.0.0 - string-length: ^5.0.1 - strip-ansi: ^7.0.1 - peerDependencies: - jest: ^27.0.0 || ^28.0.0 || ^29.0.0 - checksum: 5a55a571d616958cd6c6b52c4bf57cfaa97132cd9681af8ebfa8ebde9fa1d829426ff36f4ef2eaa867142ee97577fdad1735c58c3db62cbb33a39ad97125ee00 + checksum: 0d0e70b28fa5c7d4dce701dc1f46ae0922102aadc24ed45d594dd9b7ae0a8a6ef8b216718d1ab79e451291217e05d4d49a82666e1a3cc2b428b75cd9c933244e languageName: node linkType: hard -"jest-watcher@npm:^29.0.0, jest-watcher@npm:^29.7.0": +"jest-message-util@npm:^29.7.0": version: 29.7.0 - resolution: "jest-watcher@npm:29.7.0" + resolution: "jest-message-util@npm:29.7.0" dependencies: - "@jest/test-result": ^29.7.0 + "@babel/code-frame": ^7.12.13 "@jest/types": ^29.6.3 - "@types/node": "*" - ansi-escapes: ^4.2.1 + "@types/stack-utils": ^2.0.0 chalk: ^4.0.0 - emittery: ^0.13.1 - jest-util: ^29.7.0 - string-length: ^4.0.1 - checksum: ec6c75030562fc8f8c727cb8f3b94e75d831fc718785abfc196e1f2a2ebc9a2e38744a15147170039628a853d77a3b695561ce850375ede3a4ee6037a2574567 + graceful-fs: ^4.2.9 + micromatch: ^4.0.4 + pretty-format: ^29.7.0 + slash: ^3.0.0 + stack-utils: ^2.0.3 + checksum: 850ae35477f59f3e6f27efac5215f706296e2104af39232bb14e5403e067992afb5c015e87a9243ec4d9df38525ef1ca663af9f2f4766aa116f127247008bd22 languageName: node linkType: hard -"jest-worker@npm:^29.7.0": - version: 29.7.0 - resolution: "jest-worker@npm:29.7.0" +"jest-mock@npm:^27.3.0": + version: 27.5.1 + resolution: "jest-mock@npm:27.5.1" dependencies: + "@jest/types": ^27.5.1 "@types/node": "*" - jest-util: ^29.7.0 - merge-stream: ^2.0.0 - supports-color: ^8.0.0 - checksum: 5570a3a005b16f46c131968b8a5b56d291f9bbb85ff4217e31c80bd8a02e7de799e59a54b95ca28d5c302f248b54cbffde2d177c2f0f52ffcee7504c6eabf660 + checksum: 6ad58454b37ee3f726930b07efbf40a7c79d2d2d9c7b226708b4b550bc0904de93bcacf714105d11952a5c0bc855e5d59145c8c9dbbb4e69b46e7367abf53b52 languageName: node linkType: hard -"jest@npm:^29.3.1": +"jest-util@npm:^29.7.0": version: 29.7.0 - resolution: "jest@npm:29.7.0" + resolution: "jest-util@npm:29.7.0" dependencies: - "@jest/core": ^29.7.0 "@jest/types": ^29.6.3 - import-local: ^3.0.2 - jest-cli: ^29.7.0 - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - bin: - jest: bin/jest.js - checksum: f40eb8171cf147c617cc6ada49d062fbb03b4da666cb8d39cdbfb739a7d75eea4c3ca150fb072d0d273dce0c753db4d0467d54906ad0293f59c54f9db4a09d8b + "@types/node": "*" + chalk: ^4.0.0 + ci-info: ^3.2.0 + graceful-fs: ^4.2.9 + picomatch: ^2.2.3 + checksum: bc55a8f49fdbb8f51baf31d2a4f312fb66c9db1483b82f602c9c990e659cdd7ec529c8e916d5a89452ecbcfae4949b21b40a7a59d4ffc0cd813a973ab08c8150 languageName: node linkType: hard @@ -10717,7 +9399,7 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:3.14.1, js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.1, js-yaml@npm:^3.6.1": +"js-yaml@npm:3.14.1, js-yaml@npm:^3.10.0, js-yaml@npm:^3.6.1": version: 3.14.1 resolution: "js-yaml@npm:3.14.1" dependencies: @@ -10747,45 +9429,6 @@ __metadata: languageName: node linkType: hard -"jsdom@npm:^20.0.0": - version: 20.0.3 - resolution: "jsdom@npm:20.0.3" - dependencies: - abab: ^2.0.6 - acorn: ^8.8.1 - acorn-globals: ^7.0.0 - cssom: ^0.5.0 - cssstyle: ^2.3.0 - data-urls: ^3.0.2 - decimal.js: ^10.4.2 - domexception: ^4.0.0 - escodegen: ^2.0.0 - form-data: ^4.0.0 - html-encoding-sniffer: ^3.0.0 - http-proxy-agent: ^5.0.0 - https-proxy-agent: ^5.0.1 - is-potential-custom-element-name: ^1.0.1 - nwsapi: ^2.2.2 - parse5: ^7.1.1 - saxes: ^6.0.0 - symbol-tree: ^3.2.4 - tough-cookie: ^4.1.2 - w3c-xmlserializer: ^4.0.0 - webidl-conversions: ^7.0.0 - whatwg-encoding: ^2.0.0 - whatwg-mimetype: ^3.0.0 - whatwg-url: ^11.0.0 - ws: ^8.11.0 - xml-name-validator: ^4.0.0 - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true - checksum: b109073bb826a966db7828f46cb1d7371abecd30f182b143c52be5fe1ed84513bbbe995eb3d157241681fcd18331381e61e3dc004d4949f3a63bca02f6214902 - languageName: node - linkType: hard - "jsesc@npm:^2.5.1": version: 2.5.2 resolution: "jsesc@npm:2.5.2" @@ -11104,7 +9747,7 @@ __metadata: languageName: node linkType: hard -"leven@npm:^3.1.0, leven@npm:^3.1.0 < 4": +"leven@npm:^3.1.0 < 4": version: 3.1.0 resolution: "leven@npm:3.1.0" checksum: cd778ba3fbab0f4d0500b7e87d1f6e1f041507c56fdcd47e8256a3012c98aaee371d4c15e0a76e0386107af2d42e2b7466160a2d80688aaa03e66e49949f42df @@ -11398,7 +10041,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:4, lodash@npm:4.17.21, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.21, lodash@npm:^4.17.4": +"lodash@npm:4, lodash@npm:4.17.21, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.21": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c @@ -11556,15 +10199,6 @@ __metadata: languageName: node linkType: hard -"make-dir@npm:^4.0.0": - version: 4.0.0 - resolution: "make-dir@npm:4.0.0" - dependencies: - semver: ^7.5.3 - checksum: 69b98a6c0b8e5c4fe9acb61608a9fbcfca1756d910f51e5dbe7a9e5cfb74fca9b8a0c8a0ffdf1294a740826c1ab4871d5bf3f62f72a3049e5eac6541ddffed68 - languageName: node - linkType: hard - "make-error@npm:^1.1.1": version: 1.3.6 resolution: "make-error@npm:1.3.6" @@ -11595,15 +10229,6 @@ __metadata: languageName: node linkType: hard -"makeerror@npm:1.0.12": - version: 1.0.12 - resolution: "makeerror@npm:1.0.12" - dependencies: - tmpl: 1.0.5 - checksum: b0e6e599780ce6bab49cc413eba822f7d1f0dfebd1c103eaa3785c59e43e22c59018323cf9e1708f0ef5329e94a745d163fcbb6bff8e4c6742f9be9e86f3500c - languageName: node - linkType: hard - "map-or-similar@npm:^1.5.0": version: 1.5.0 resolution: "map-or-similar@npm:1.5.0" @@ -12274,7 +10899,7 @@ __metadata: languageName: node linkType: hard -"mkdirp@npm:1.0.4, mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4": +"mkdirp@npm:1.0.4, mkdirp@npm:^1.0.3": version: 1.0.4 resolution: "mkdirp@npm:1.0.4" bin: @@ -12519,13 +11144,6 @@ __metadata: languageName: node linkType: hard -"node-int64@npm:^0.4.0": - version: 0.4.0 - resolution: "node-int64@npm:0.4.0" - checksum: a6a4d8369e2f2720e9c645255ffde909c0fbd41c92ea92a5607fc17055955daac99c1ff589d421eee12a0d24e99f7bfc2aabfeb1a4c14742f6c099a51863f31a - languageName: node - linkType: hard - "node-machine-id@npm:^1.1.12": version: 1.1.12 resolution: "node-machine-id@npm:1.1.12" @@ -12655,13 +11273,6 @@ __metadata: languageName: node linkType: hard -"nwsapi@npm:^2.2.2": - version: 2.2.7 - resolution: "nwsapi@npm:2.2.7" - checksum: 44be198adae99208487a1c886c0a3712264f7bbafa44368ad96c003512fed2753d4e22890ca1e6edb2690c3456a169f2a3c33bfacde1905cf3bf01c7722464db - languageName: node - linkType: hard - "nx-cloud@npm:16.0.5": version: 16.0.5 resolution: "nx-cloud@npm:16.0.5" @@ -13161,7 +11772,7 @@ __metadata: languageName: node linkType: hard -"parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": +"parse-json@npm:^5.0.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" dependencies: @@ -13208,15 +11819,6 @@ __metadata: languageName: node linkType: hard -"parse5@npm:^7.0.0, parse5@npm:^7.1.1": - version: 7.1.2 - resolution: "parse5@npm:7.1.2" - dependencies: - entities: ^4.4.0 - checksum: 297d7af8224f4b5cb7f6617ecdae98eeaed7f8cbd78956c42785e230505d5a4f07cef352af10d3006fa5c1544b76b57784d3a22d861ae071bbc460c649482bf4 - languageName: node - linkType: hard - "parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" @@ -13440,33 +12042,13 @@ __metadata: languageName: node linkType: hard -"pirates@npm:^4.0.1, pirates@npm:^4.0.4": +"pirates@npm:^4.0.1": version: 4.0.6 resolution: "pirates@npm:4.0.6" checksum: 00d5fa51f8dded94d7429700fb91a0c1ead00ae2c7fd27089f0c5b63e6eca36197fe46384631872690a66f390c5e27198e99006ab77ae472692ab9c2ca903f36 languageName: node linkType: hard -"pixelmatch@npm:^5.1.0": - version: 5.3.0 - resolution: "pixelmatch@npm:5.3.0" - dependencies: - pngjs: ^6.0.0 - bin: - pixelmatch: bin/pixelmatch - checksum: 30850661db29b57cefbe6cf36e930b7517aea4e0ed129e85fcc8ec04a7e6e7648a822a972f8e01d2d3db268ca3c735555caf6b8099a164d8b64d105986d682d2 - languageName: node - linkType: hard - -"pkg-dir@npm:^4.2.0": - version: 4.2.0 - resolution: "pkg-dir@npm:4.2.0" - dependencies: - find-up: ^4.0.0 - checksum: c56bda7769e04907a88423feb320babaed0711af8c436ce3e56763ab1021ba107c7b0cafb11cde7529f669cfc22bffcaebffb573645cbd63842ea9fb17cd7728 - languageName: node - linkType: hard - "pkg-dir@npm:^5.0.0": version: 5.0.0 resolution: "pkg-dir@npm:5.0.0" @@ -13539,20 +12121,6 @@ __metadata: languageName: node linkType: hard -"pngjs@npm:^3.4.0": - version: 3.4.0 - resolution: "pngjs@npm:3.4.0" - checksum: 88ee73e2ad3f736e0b2573722309eb80bd2aa28916f0862379b4fd0f904751b4f61bb6bd1ecd7d4242d331f2b5c28c13309dd4b7d89a9b78306e35122fdc5011 - languageName: node - linkType: hard - -"pngjs@npm:^6.0.0": - version: 6.0.0 - resolution: "pngjs@npm:6.0.0" - checksum: ac23ea329b1881d1a10575aff58116dc27b894ec3f5b84ba15c7f527d21e609fbce7ba16d48f8ccb86c7ce45ceed622472765476ab2875949d4bec55e153f87a - languageName: node - linkType: hard - "portfinder@npm:^1.0.28": version: 1.0.32 resolution: "portfinder@npm:1.0.32" @@ -13725,7 +12293,7 @@ __metadata: languageName: node linkType: hard -"prompts@npm:^2.0.1, prompts@npm:^2.4.0": +"prompts@npm:^2.4.0": version: 2.4.2 resolution: "prompts@npm:2.4.2" dependencies: @@ -13770,7 +12338,7 @@ __metadata: languageName: node linkType: hard -"psl@npm:^1.1.28, psl@npm:^1.1.33": +"psl@npm:^1.1.28": version: 1.9.0 resolution: "psl@npm:1.9.0" checksum: 6a3f805fdab9442f44de4ba23880c4eba26b20c8e8e0830eff1cb31007f6825dace61d17203c58bfe36946842140c97a1ba7f67bc63ca2d88a7ee052b65d97ab @@ -13794,13 +12362,6 @@ __metadata: languageName: node linkType: hard -"pure-rand@npm:^6.0.0": - version: 6.0.3 - resolution: "pure-rand@npm:6.0.3" - checksum: f8bf59c29ef7fa6302e462cae3aa47932fb364e1bf8f095667b542d77c6fa26e52068eefa5c39b2e715a6c92d41fd8dd321bf81c07077f45e9373fc33f80e0ed - languageName: node - linkType: hard - "qs@npm:6.11.0": version: 6.11.0 resolution: "qs@npm:6.11.0" @@ -13838,13 +12399,6 @@ __metadata: languageName: node linkType: hard -"querystringify@npm:^2.1.1": - version: 2.2.0 - resolution: "querystringify@npm:2.2.0" - checksum: 3258bc3dbdf322ff2663619afe5947c7926a6ef5fb78ad7d384602974c467fadfc8272af44f5eb8cddd0d011aae8fabf3a929a8eee4b86edcc0a21e6bd10f9aa - languageName: node - linkType: hard - "queue-microtask@npm:^1.2.2": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" @@ -14785,15 +13339,6 @@ __metadata: languageName: node linkType: hard -"resolve-cwd@npm:^3.0.0": - version: 3.0.0 - resolution: "resolve-cwd@npm:3.0.0" - dependencies: - resolve-from: ^5.0.0 - checksum: e608a3ebd15356264653c32d7ecbc8fd702f94c6703ea4ac2fb81d9c359180cba0ae2e6b71faa446631ed6145454d5a56b227efc33a2d40638ac13f8beb20ee4 - languageName: node - linkType: hard - "resolve-from@npm:^4.0.0": version: 4.0.0 resolution: "resolve-from@npm:4.0.0" @@ -14808,14 +13353,7 @@ __metadata: languageName: node linkType: hard -"resolve.exports@npm:^2.0.0": - version: 2.0.2 - resolution: "resolve.exports@npm:2.0.2" - checksum: cc4cffdc25447cf34730f388dca5021156ba9302a3bad3d7f168e790dc74b2827dff603f1bc6ad3d299bac269828dca96dd77e036dc9fba6a2a1807c47ab5c98 - languageName: node - linkType: hard - -"resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.14.2, resolve@npm:^1.20.0, resolve@npm:^1.22.4": +"resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.14.2, resolve@npm:^1.22.4": version: 1.22.4 resolution: "resolve@npm:1.22.4" dependencies: @@ -14841,7 +13379,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.20.0#~builtin, resolve@patch:resolve@^1.22.4#~builtin": +"resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.22.4#~builtin": version: 1.22.4 resolution: "resolve@patch:resolve@npm%3A1.22.4#~builtin::version=1.22.4&hash=c3c19d" dependencies: @@ -14924,17 +13462,6 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:^2.6.2": - version: 2.7.1 - resolution: "rimraf@npm:2.7.1" - dependencies: - glob: ^7.1.3 - bin: - rimraf: ./bin.js - checksum: 4eef73d406c6940927479a3a9dee551e14a54faf54b31ef861250ac815172bade86cc6f7d64a4dc5e98b65e4b18a2e1c9ff3b68d296be0c748413f092bb0dd40 - languageName: node - linkType: hard - "rimraf@npm:^3.0.0, rimraf@npm:^3.0.2": version: 3.0.2 resolution: "rimraf@npm:3.0.2" @@ -15049,15 +13576,6 @@ __metadata: languageName: node linkType: hard -"saxes@npm:^6.0.0": - version: 6.0.0 - resolution: "saxes@npm:6.0.0" - dependencies: - xmlchars: ^2.2.0 - checksum: 3847b839f060ef3476eb8623d099aa502ad658f5c40fd60c105ebce86d244389b0d76fcae30f4d0c728d7705ceb2f7e9b34bb54717b6a7dbedaf5dad2d9a4b74 - languageName: node - linkType: hard - "scheduler@npm:^0.19.1": version: 0.19.1 resolution: "scheduler@npm:0.19.1" @@ -15133,7 +13651,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.5.4, semver@npm:^7.0.0, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.3, semver@npm:^7.5.4": +"semver@npm:7.5.4, semver@npm:^7.0.0, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.3.8, semver@npm:^7.5.4": version: 7.5.4 resolution: "semver@npm:7.5.4" dependencies: @@ -15432,16 +13950,6 @@ __metadata: languageName: node linkType: hard -"source-map-support@npm:0.5.13": - version: 0.5.13 - resolution: "source-map-support@npm:0.5.13" - dependencies: - buffer-from: ^1.0.0 - source-map: ^0.6.0 - checksum: 137539f8c453fa0f496ea42049ab5da4569f96781f6ac8e5bfda26937be9494f4e8891f523c5f98f0e85f71b35d74127a00c46f83f6a4f54672b58d53202565e - languageName: node - linkType: hard - "source-map@npm:0.8.0-beta.0": version: 0.8.0-beta.0 resolution: "source-map@npm:0.8.0-beta.0" @@ -15451,7 +13959,7 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.1": +"source-map@npm:^0.6.1, source-map@npm:~0.6.1": version: 0.6.1 resolution: "source-map@npm:0.6.1" checksum: ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 @@ -15492,15 +14000,6 @@ __metadata: languageName: node linkType: hard -"specificity@npm:^0.4.1": - version: 0.4.1 - resolution: "specificity@npm:0.4.1" - bin: - specificity: ./bin/specificity - checksum: 5da85a05052b55e344cb0f5bce5d07cbabbbe8945da176a481589db5a13e9fbcfa879ceb075cf564b94e680fae0a2ab14ea55cc87496b86a6d5122545946d7c2 - languageName: node - linkType: hard - "split-on-first@npm:^1.0.0": version: 1.1.0 resolution: "split-on-first@npm:1.1.0" @@ -15543,13 +14042,6 @@ __metadata: languageName: node linkType: hard -"ssim.js@npm:^3.1.1": - version: 3.5.0 - resolution: "ssim.js@npm:3.5.0" - checksum: 9e7101da17395d3acbd417aac712d8f156522e79059a27cb38882eedd5a8868e31871c8f58bec3a150f8cf0660883cf22310cbd2fd63b408c1fd0ab02fda9fbc - languageName: node - linkType: hard - "ssri@npm:^10.0.0": version: 10.0.5 resolution: "ssri@npm:10.0.5" @@ -15637,26 +14129,6 @@ __metadata: languageName: node linkType: hard -"string-length@npm:^4.0.1": - version: 4.0.2 - resolution: "string-length@npm:4.0.2" - dependencies: - char-regex: ^1.0.2 - strip-ansi: ^6.0.0 - checksum: 1cd77409c3d7db7bc59406f6bcc9ef0783671dcbabb23597a1177c166906ef2ee7c8290f78cae73a8aec858768f189d2cb417797df5e15ec4eb5e16b3346340c - languageName: node - linkType: hard - -"string-length@npm:^5.0.1": - version: 5.0.1 - resolution: "string-length@npm:5.0.1" - dependencies: - char-regex: ^2.0.0 - strip-ansi: ^7.0.1 - checksum: 311fa5758d397bd616be17150dfefaab4755ed292a3112237924d10ba5122f606064ad4880a293387401c1d7aa20d79f7936728bac2abed17a5e48f5b317cbc8 - languageName: node - linkType: hard - "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.0.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.2, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -15782,13 +14254,6 @@ __metadata: languageName: node linkType: hard -"strip-bom@npm:^4.0.0": - version: 4.0.0 - resolution: "strip-bom@npm:4.0.0" - checksum: 26abad1172d6bc48985ab9a5f96c21e440f6e7e476686de49be813b5a59b3566dccb5c525b831ec54fe348283b47f3ffb8e080bc3f965fde12e84df23f6bb7ef - languageName: node - linkType: hard - "strip-dirs@npm:^2.0.0": version: 2.1.0 resolution: "strip-dirs@npm:2.1.0" @@ -15864,13 +14329,6 @@ __metadata: languageName: node linkType: hard -"stylis@npm:4.2.0": - version: 4.2.0 - resolution: "stylis@npm:4.2.0" - checksum: a7128ad5a8ed72652c6eba46bed4f416521bc9745a460ef5741edc725252cebf36ee45e33a8615a7057403c93df0866ab9ee955960792db210bb80abd5ac6543 - languageName: node - linkType: hard - "sucrase@npm:^3.20.3": version: 3.34.0 resolution: "sucrase@npm:3.34.0" @@ -15916,15 +14374,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.0.0": - version: 8.1.1 - resolution: "supports-color@npm:8.1.1" - dependencies: - has-flag: ^4.0.0 - checksum: ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89 - languageName: node - linkType: hard - "supports-color@npm:^9.0.0": version: 9.4.0 resolution: "supports-color@npm:9.4.0" @@ -15949,13 +14398,6 @@ __metadata: languageName: node linkType: hard -"symbol-tree@npm:^3.2.4": - version: 3.2.4 - resolution: "symbol-tree@npm:3.2.4" - checksum: dfbe201ae09ac6053d163578778c53aa860a784147ecf95705de0cd23f42c851e1be7889241495e95c37cabb058edb1052f141387bef68f705afc8f9dd358509 - languageName: node - linkType: hard - "syntax-error@npm:^1.1.6": version: 1.4.0 resolution: "syntax-error@npm:1.4.0" @@ -16074,17 +14516,6 @@ __metadata: languageName: node linkType: hard -"test-exclude@npm:^6.0.0": - version: 6.0.0 - resolution: "test-exclude@npm:6.0.0" - dependencies: - "@istanbuljs/schema": ^0.1.2 - glob: ^7.1.4 - minimatch: ^3.0.4 - checksum: 019d33d81adff3f9f1bfcff18125fb2d3c65564f437d9be539270ee74b994986abb8260c7c2ce90e8f30162178b09dbbce33c6389273afac4f36069c48521f57 - languageName: node - linkType: hard - "text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" @@ -16163,13 +14594,6 @@ __metadata: languageName: node linkType: hard -"tmpl@npm:1.0.5": - version: 1.0.5 - resolution: "tmpl@npm:1.0.5" - checksum: f935537799c2d1922cb5d6d3805f594388f75338fe7a4a9dac41504dd539704ca4db45b883b52e7b0aa5b2fd5ddadb1452bf95cd23a69da2f793a843f9451cc9 - languageName: node - linkType: hard - "to-buffer@npm:^1.1.1": version: 1.1.1 resolution: "to-buffer@npm:1.1.1" @@ -16227,18 +14651,6 @@ __metadata: languageName: node linkType: hard -"tough-cookie@npm:^4.1.2": - version: 4.1.3 - resolution: "tough-cookie@npm:4.1.3" - dependencies: - psl: ^1.1.33 - punycode: ^2.1.1 - universalify: ^0.2.0 - url-parse: ^1.5.3 - checksum: 4fc0433a0cba370d57c4b240f30440c848906dee3180bb6e85033143c2726d322e7e4614abb51d42d111ebec119c4876ed8d7247d4113563033eebbc1739c831 - languageName: node - linkType: hard - "tough-cookie@npm:~2.5.0": version: 2.5.0 resolution: "tough-cookie@npm:2.5.0" @@ -16258,15 +14670,6 @@ __metadata: languageName: node linkType: hard -"tr46@npm:^3.0.0": - version: 3.0.0 - resolution: "tr46@npm:3.0.0" - dependencies: - punycode: ^2.1.1 - checksum: cdc47cad3a9d0b6cb293e39ccb1066695ae6fdd39b9e4f351b010835a1f8b4f3a6dc3a55e896b421371187f22b48d7dac1b693de4f6551bdef7b6ab6735dfe3b - languageName: node - linkType: hard - "tr46@npm:~0.0.3": version: 0.0.3 resolution: "tr46@npm:0.0.3" @@ -16327,15 +14730,6 @@ __metadata: languageName: node linkType: hard -"ts-essentials@npm:^7.0.3": - version: 7.0.3 - resolution: "ts-essentials@npm:7.0.3" - peerDependencies: - typescript: ">=3.7.0" - checksum: ea1919534ec6ce4ca4d9cb0ff1ab8e053509237da8d4298762ab3bfba4e78ca5649a599ce78a5c7c2624f3a7a971f62b265b7b0c3c881336e4fa6acaf6f37544 - languageName: node - linkType: hard - "ts-essentials@npm:^9.3.2": version: 9.4.0 resolution: "ts-essentials@npm:9.4.0" @@ -16538,7 +14932,7 @@ __metadata: languageName: node linkType: hard -"type-detect@npm:4.0.8, type-detect@npm:^4.0.0, type-detect@npm:^4.0.5": +"type-detect@npm:^4.0.0, type-detect@npm:^4.0.5": version: 4.0.8 resolution: "type-detect@npm:4.0.8" checksum: 8fb9a51d3f365a7de84ab7f73b653534b61b622aa6800aecdb0f1095a4a646d3f5eb295322127b6573db7982afcd40ab492d038cf825a42093a58b1e1353e0bd @@ -17064,13 +15458,6 @@ __metadata: languageName: node linkType: hard -"universalify@npm:^0.2.0": - version: 0.2.0 - resolution: "universalify@npm:0.2.0" - checksum: cedbe4d4ca3967edf24c0800cfc161c5a15e240dac28e3ce575c689abc11f2c81ccc6532c8752af3b40f9120fb5e454abecd359e164f4f6aa44c29cd37e194fe - languageName: node - linkType: hard - "universalify@npm:^2.0.0": version: 2.0.0 resolution: "universalify@npm:2.0.0" @@ -17122,16 +15509,6 @@ __metadata: languageName: node linkType: hard -"url-parse@npm:^1.5.3": - version: 1.5.10 - resolution: "url-parse@npm:1.5.10" - dependencies: - querystringify: ^2.1.1 - requires-port: ^1.0.0 - checksum: bd5aa9389f896974beb851c112f63b466505a04b4807cea2e5a3b7092f6fbb75316f0491ea84e44f66fed55f1b440df5195d7e3a8203f64fcefa19d182f5be87 - languageName: node - linkType: hard - "urlgrey@npm:0.4.4": version: 0.4.4 resolution: "urlgrey@npm:0.4.4" @@ -17230,17 +15607,6 @@ __metadata: languageName: node linkType: hard -"v8-to-istanbul@npm:^9.0.1": - version: 9.1.0 - resolution: "v8-to-istanbul@npm:9.1.0" - dependencies: - "@jridgewell/trace-mapping": ^0.3.12 - "@types/istanbul-lib-coverage": ^2.0.1 - convert-source-map: ^1.6.0 - checksum: 657ef7c52a514c1a0769663f96dd6f2cd11d2d3f6c8272d1035f4a543dca0b52c84b005beb7f0ca215eb98425c8bc4aa92a62826b1fc76abc1f7228d33ccbc60 - languageName: node - linkType: hard - "validate-npm-package-license@npm:^3.0.1": version: 3.0.4 resolution: "validate-npm-package-license@npm:3.0.4" @@ -17703,15 +16069,6 @@ __metadata: languageName: node linkType: hard -"w3c-xmlserializer@npm:^4.0.0": - version: 4.0.0 - resolution: "w3c-xmlserializer@npm:4.0.0" - dependencies: - xml-name-validator: ^4.0.0 - checksum: 02cc66d6efc590bd630086cd88252444120f5feec5c4043932b0d0f74f8b060512f79dc77eb093a7ad04b4f02f39da79ce4af47ceb600f2bf9eacdc83204b1a8 - languageName: node - linkType: hard - "wait-on@npm:^7.0.1": version: 7.0.1 resolution: "wait-on@npm:7.0.1" @@ -17734,15 +16091,6 @@ __metadata: languageName: node linkType: hard -"walker@npm:^1.0.8": - version: 1.0.8 - resolution: "walker@npm:1.0.8" - dependencies: - makeerror: 1.0.12 - checksum: a17e037bccd3ca8a25a80cb850903facdfed0de4864bd8728f1782370715d679fa72e0a0f5da7c1c1379365159901e5935f35be531229da53bbfc0efdabdb48e - languageName: node - linkType: hard - "wcwidth@npm:^1.0.1": version: 1.0.1 resolution: "wcwidth@npm:1.0.1" @@ -17766,13 +16114,6 @@ __metadata: languageName: node linkType: hard -"webidl-conversions@npm:^7.0.0": - version: 7.0.0 - resolution: "webidl-conversions@npm:7.0.0" - checksum: 228d8cb6d270c23b0720cb2d95c579202db3aaf8f633b4e9dd94ec2000a04e7e6e43b76a94509cdb30479bd00ae253ab2371a2da9f81446cc313f89a4213a2c4 - languageName: node - linkType: hard - "whatwg-encoding@npm:^2.0.0": version: 2.0.0 resolution: "whatwg-encoding@npm:2.0.0" @@ -17782,23 +16123,6 @@ __metadata: languageName: node linkType: hard -"whatwg-mimetype@npm:^3.0.0": - version: 3.0.0 - resolution: "whatwg-mimetype@npm:3.0.0" - checksum: 323895a1cda29a5fb0b9ca82831d2c316309fede0365047c4c323073e3239067a304a09a1f4b123b9532641ab604203f33a1403b5ca6a62ef405bcd7a204080f - languageName: node - linkType: hard - -"whatwg-url@npm:^11.0.0": - version: 11.0.0 - resolution: "whatwg-url@npm:11.0.0" - dependencies: - tr46: ^3.0.0 - webidl-conversions: ^7.0.0 - checksum: f7ec264976d7c725e0696fcaf9ebe056e14422eacbf92fdbb4462034609cba7d0c85ffa1aab05e9309d42969bcf04632ba5ed3f3882c516d7b093053315bf4c1 - languageName: node - linkType: hard - "whatwg-url@npm:^5.0.0": version: 5.0.0 resolution: "whatwg-url@npm:5.0.0" @@ -18015,31 +16339,6 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:^4.0.2": - version: 4.0.2 - resolution: "write-file-atomic@npm:4.0.2" - dependencies: - imurmurhash: ^0.1.4 - signal-exit: ^3.0.7 - checksum: a2c282c95ef5d8e1c27b335ae897b5eca00e85590d92a3fd69a437919b7b93ff36a69ea04145da55829d2164e724bc62202cdb5f4b208b425aba0807889375c7 - languageName: node - linkType: hard - -"ws@npm:^8.11.0": - version: 8.14.1 - resolution: "ws@npm:8.14.1" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 71b819d1ea00f8a345dd445f72821df64f5892b497d23deb47707cc09e98035902a7cff9b77a911b1af0dcc0a2fbf61f1f50f25ba4ab684e054dc08877e6095d - languageName: node - linkType: hard - "xcase@npm:^2.0.1": version: 2.0.1 resolution: "xcase@npm:2.0.1" @@ -18066,13 +16365,6 @@ __metadata: languageName: node linkType: hard -"xml-name-validator@npm:^4.0.0": - version: 4.0.0 - resolution: "xml-name-validator@npm:4.0.0" - checksum: c1bfa219d64e56fee265b2bd31b2fcecefc063ee802da1e73bad1f21d7afd89b943c9e2c97af2942f60b1ad46f915a4c81e00039c7d398b53cf410e29d3c30bd - languageName: node - linkType: hard - "xml@npm:^1.0.1": version: 1.0.1 resolution: "xml@npm:1.0.1" @@ -18080,13 +16372,6 @@ __metadata: languageName: node linkType: hard -"xmlchars@npm:^2.2.0": - version: 2.2.0 - resolution: "xmlchars@npm:2.2.0" - checksum: b64b535861a6f310c5d9bfa10834cf49127c71922c297da9d4d1b45eeaae40bf9b4363275876088fbe2667e5db028d2cd4f8ee72eed9bede840a67d57dab7593 - languageName: node - linkType: hard - "xtend@npm:^4.0.0, xtend@npm:^4.0.2, xtend@npm:~4.0.1": version: 4.0.2 resolution: "xtend@npm:4.0.2" @@ -18136,7 +16421,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.0.0, yargs@npm:^17.3.1, yargs@npm:^17.6.2": +"yargs@npm:^17.0.0, yargs@npm:^17.6.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: From ab77c3ec54a9abdc1aeb71d4de8d6368919a86f9 Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 15 Sep 2023 17:05:17 +0200 Subject: [PATCH 019/105] improve test --- .../StoryIndexGenerator.deprecated.test.ts | 98 ++++++++++--------- 1 file changed, 52 insertions(+), 46 deletions(-) diff --git a/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts b/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts index abbf94141bcc..1eaee4bf8d79 100644 --- a/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts +++ b/code/lib/core-server/src/utils/StoryIndexGenerator.deprecated.test.ts @@ -1,53 +1,44 @@ /* eslint-disable @typescript-eslint/no-shadow */ -/** - * @vitest-environment node - */ -import type { Mock } from 'vitest'; import { describe, beforeEach, it, expect, vi } from 'vitest'; -import path from 'path'; +import { join } from 'path'; import fs from 'fs-extra'; import { normalizeStoriesEntry } from '@storybook/core-common'; import type { NormalizedStoriesSpecifier, StoryIndexEntry } from '@storybook/types'; -import { loadCsf, getStorySortParameter } from '@storybook/csf-tools'; -import { toId } from '@storybook/csf'; +import * as csfToolsMod from '@storybook/csf-tools'; +import * as csfMod from '@storybook/csf'; import { logger, once } from '@storybook/node-logger'; import type { StoryIndexGeneratorOptions } from './StoryIndexGenerator'; import { StoryIndexGenerator } from './StoryIndexGenerator'; -vi.mock('@storybook/csf-tools'); +vi.mock('@storybook/node-logger'); vi.mock('@storybook/csf', async () => { - const csf = await vi.importActual('@storybook/csf'); + const csf: typeof csfMod = vi.mocked(await vi.importActual('@storybook/csf')); return { ...csf, toId: vi.fn(csf.toId), }; }); -vi.mock('@storybook/node-logger'); - -const toIdMock = toId as Mock>; -const loadCsfMock = loadCsf as Mock>; -const getStorySortParameterMock = getStorySortParameter as Mock< - ReturnType ->; +const toId = vi.spyOn(csfMod, 'toId'); +const loadCsf = vi.spyOn(csfToolsMod, 'loadCsf'); const csfIndexer = async (fileName: string, opts: any) => { const code = (await fs.readFile(fileName, 'utf-8')).toString(); - return loadCsf(code, { ...opts, fileName }).parse(); + return csfToolsMod.loadCsf(code, { ...opts, fileName }).parse(); }; const storiesMdxIndexer = async (fileName: string, opts: any) => { let code = (await fs.readFile(fileName, 'utf-8')).toString(); const { compile } = await import('@storybook/mdx2-csf'); code = await compile(code, {}); - return loadCsf(code, { ...opts, fileName }).parse(); + return csfToolsMod.loadCsf(code, { ...opts, fileName }).parse(); }; const options: StoryIndexGeneratorOptions = { - configDir: path.join(__dirname, '__mockdata__'), - workingDir: path.join(__dirname, '__mockdata__'), + configDir: join(__dirname, '__mockdata__'), + workingDir: join(__dirname, '__mockdata__'), storyIndexers: [ { test: /\.stories\.mdx$/, indexer: storiesMdxIndexer }, { test: /\.stories\.(m?js|ts)x?$/, indexer: csfIndexer }, @@ -60,10 +51,11 @@ const options: StoryIndexGeneratorOptions = { describe('StoryIndexGenerator with deprecated indexer API', () => { beforeEach(async () => { - const actual = await vi.importActual('@storybook/csf-tools'); - loadCsfMock.mockImplementation(actual.loadCsf); - vi.mocked(logger.warn).mockClear(); - vi.mocked(once.warn).mockClear(); + // const actual: typeof csfToolsMod = await vi.importActual('@storybook/csf-tools'); + // loadCsf.mockImplementation(actual.loadCsf); + vi.clearAllMocks(); + // vi.mocked(logger.warn).mockClear(); + // vi.mocked(once.warn).mockClear(); }); describe('extraction', () => { const storiesSpecifier: NormalizedStoriesSpecifier = normalizeStoriesEntry( @@ -1210,8 +1202,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { const generator = new StoryIndexGenerator([docsSpecifier, storiesSpecifier], options); await generator.initialize(); - - (getStorySortParameter as Mock).mockReturnValueOnce({ + vi.spyOn(csfToolsMod, 'getStorySortParameter').mockReturnValueOnce({ order: ['docs2', 'D', 'B', 'nested', 'A', 'second-nested', 'first-nested/deeply'], }); @@ -1242,15 +1233,15 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { options ); - loadCsfMock.mockClear(); + loadCsf.mockClear(); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); await generator.getIndex(); - expect(loadCsfMock).toHaveBeenCalledTimes(7); + expect(loadCsf).toHaveBeenCalledTimes(7); - loadCsfMock.mockClear(); + loadCsf.mockClear(); await generator.getIndex(); - expect(loadCsfMock).not.toHaveBeenCalled(); + expect(loadCsf).not.toHaveBeenCalled(); }); it('does not extract docs files a second time', async () => { @@ -1268,7 +1259,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { await generator.getIndex(); expect(toId).toHaveBeenCalledTimes(6); - toIdMock.mockClear(); + toId.mockClear(); await generator.getIndex(); expect(toId).not.toHaveBeenCalled(); }); @@ -1280,7 +1271,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { ); const sortFn = vi.fn(); - getStorySortParameterMock.mockReturnValue(sortFn); + vi.spyOn(csfToolsMod, 'getStorySortParameter').mockReturnValue(sortFn); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); await generator.getIndex(); @@ -1299,17 +1290,17 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { options ); - loadCsfMock.mockClear(); + loadCsf.mockClear(); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); await generator.getIndex(); - expect(loadCsfMock).toHaveBeenCalledTimes(7); + expect(loadCsf).toHaveBeenCalledTimes(7); generator.invalidate(specifier, './src/B.stories.ts', false); - loadCsfMock.mockClear(); + loadCsf.mockClear(); await generator.getIndex(); - expect(loadCsfMock).toHaveBeenCalledTimes(1); + expect(loadCsf).toHaveBeenCalledTimes(1); }); it('calls extract docs file for just the one file', async () => { @@ -1329,7 +1320,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { generator.invalidate(docsSpecifier, './src/docs2/Title.mdx', false); - toIdMock.mockClear(); + toId.mockClear(); await generator.getIndex(); expect(toId).toHaveBeenCalledTimes(1); }); @@ -1351,7 +1342,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { generator.invalidate(storiesSpecifier, './src/A.stories.js', false); - toIdMock.mockClear(); + toId.mockClear(); await generator.getIndex(); expect(toId).toHaveBeenCalledTimes(3); }); @@ -1363,7 +1354,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { ); const sortFn = vi.fn(); - getStorySortParameterMock.mockReturnValue(sortFn); + vi.spyOn(csfToolsMod, 'getStorySortParameter').mockReturnValue(sortFn); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); await generator.getIndex(); @@ -1384,17 +1375,17 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { options ); - loadCsfMock.mockClear(); + loadCsf.mockClear(); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); await generator.getIndex(); - expect(loadCsfMock).toHaveBeenCalledTimes(7); + expect(loadCsf).toHaveBeenCalledTimes(7); generator.invalidate(specifier, './src/B.stories.ts', true); - loadCsfMock.mockClear(); + loadCsf.mockClear(); await generator.getIndex(); - expect(loadCsfMock).not.toHaveBeenCalled(); + expect(loadCsf).not.toHaveBeenCalled(); }); it('does call the sort function a second time', async () => { @@ -1404,7 +1395,7 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { ); const sortFn = vi.fn(); - getStorySortParameterMock.mockReturnValue(sortFn); + vi.spyOn(csfToolsMod, 'getStorySortParameter').mockReturnValue(sortFn); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); await generator.getIndex(); @@ -1423,11 +1414,11 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { options ); - loadCsfMock.mockClear(); + loadCsf.mockClear(); const generator = new StoryIndexGenerator([specifier], options); await generator.initialize(); await generator.getIndex(); - expect(loadCsfMock).toHaveBeenCalledTimes(7); + expect(loadCsf).toHaveBeenCalledTimes(7); generator.invalidate(specifier, './src/B.stories.ts', true); @@ -1469,6 +1460,21 @@ describe('StoryIndexGenerator with deprecated indexer API', () => { const generator = new StoryIndexGenerator([docsSpecifier, storiesSpecifier], options); await generator.initialize(); await generator.getIndex(); + console.log(toId.mock.calls); + // MAIN: + // [ 'A', 'Story One' ], + // [ 'ComponentReference', 'docs' ], + // [ 'A', 'MetaOf' ], + // [ 'NoTitle', 'docs' ], + // [ 'docs2/Yabbadabbadooo', 'docs' ], + // [ 'A', 'Second Docs' ] + + // THIS BRANCH + // [ 'A', 'MetaOf' ], + // [ 'A', 'Second Docs' ], + // [ 'ComponentReference', 'docs' ], + // [ 'NoTitle', 'docs' ], + // [ 'docs2/Yabbadabbadooo', 'docs' ] expect(toId).toHaveBeenCalledTimes(6); expect(Object.keys((await generator.getIndex()).entries)).toContain('a--metaof'); From 2ae51af076c61397f74aeb304bd9ef3f3ea4e76c Mon Sep 17 00:00:00 2001 From: Norbert de Langen Date: Fri, 15 Sep 2023 17:18:58 +0200 Subject: [PATCH 020/105] fix a test --- .../upgrade-deprecated-types.test.ts.snap | 72 +++++++++++++++++++ .../upgrade-deprecated-types.test.ts | 71 ++---------------- 2 files changed, 76 insertions(+), 67 deletions(-) create mode 100644 code/lib/codemod/src/transforms/__tests__/__snapshots__/upgrade-deprecated-types.test.ts.snap diff --git a/code/lib/codemod/src/transforms/__tests__/__snapshots__/upgrade-deprecated-types.test.ts.snap b/code/lib/codemod/src/transforms/__tests__/__snapshots__/upgrade-deprecated-types.test.ts.snap new file mode 100644 index 000000000000..bd1ef757d52f --- /dev/null +++ b/code/lib/codemod/src/transforms/__tests__/__snapshots__/upgrade-deprecated-types.test.ts.snap @@ -0,0 +1,72 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`upgrade-deprecated-types > typescript > upgrade imports with conflicting local names 1`] = ` +This codemod does not support local imports that are called the same as a storybook import. +Rename this local import and try again. +> 1 | import { ComponentMeta as Meta, ComponentStory as StoryFn } from '@storybook/react'; + | ^^^^^^^^^^^^^^^^^^^^^ + 2 | import { Cat } from './Cat'; + 3 | + 4 | const meta = { title: 'Cat', component: Cat } satisfies Meta +`; + +exports[`upgrade-deprecated-types > typescript > upgrade imports with local names 1`] = ` +import { + StoryFn as Story_, + Meta as ComponentMeta_, + StoryObj as ComponentStoryObj_, +} from '@storybook/react'; +import { Cat } from './Cat'; + +const meta = { title: 'Cat', component: Cat } satisfies ComponentMeta_; +const meta2: ComponentMeta_ = { title: 'Cat', component: Cat }; +export default meta; + +export const A: Story__ = (args) => ; +export const B: any = (args) => -
-
-
- -
-
-
- -
-
- -
-
-
- -
-
- -
-
- -
-
- -
-
-
- -
-
- -
-
- -
-
- -
-
- -

-

- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
-
-

- I am a custom render function -

- -
-
-
- -
-
- -
-
- -
-
- -