From eb4926c6381b24a7117c5669653ec2a6f3e6fe39 Mon Sep 17 00:00:00 2001 From: feugy Date: Sat, 11 Nov 2023 14:50:58 +0100 Subject: [PATCH 1/3] chore: updates all dependencies, migrates to vitest, adds examples --- .changeset/config.json | 11 +- .eslintignore | 3 +- .eslintrc.cjs | 22 + .eslintrc.js | 34 - .prettierrc.yml | 2 + TODO.md | 3 + docs/releasing.md | 2 +- examples/svelte/atelier/Button.tools.svelte | 16 + examples/svelte/index.html | 14 + examples/svelte/package.json | 20 + examples/svelte/src/Button.svelte | 29 + examples/svelte/src/main.js | 8 + examples/svelte/vite.config.js | 7 + examples/sveltekit/README.md | 38 + .../atelier/routes/+page.tools.svelte | 9 + examples/sveltekit/jsconfig.json | 17 + examples/sveltekit/package.json | 31 + examples/sveltekit/src/app.d.ts | 12 + examples/sveltekit/src/app.html | 12 + examples/sveltekit/src/routes/+page.svelte | 10 + examples/sveltekit/src/stores/locale.js | 10 + examples/sveltekit/static/favicon.png | Bin 0 -> 1571 bytes examples/sveltekit/svelte.config.js | 13 + examples/sveltekit/vite.config.js | 7 + package.json | 36 +- packages/svelte/package.json | 15 +- packages/svelte/src/components/Tool.svelte | 15 +- packages/svelte/src/stores.js | 2 +- packages/svelte/tests/components/Tool.test.js | 32 +- .../svelte/tests/components/ToolBox.test.js | 1 + .../svelte/tests/components/Workbench.test.js | 3 +- packages/svelte/tests/setup.js | 8 +- packages/svelte/tests/stores.test.js | 15 +- .../svelte/tests/test-components/Tool.svelte | 1 + .../svelte/tests/workframe-content.test.js | 3 +- packages/toolshot/package.json | 22 +- packages/toolshot/src/index.js | 25 +- packages/toolshot/src/matcher.js | 59 +- packages/toolshot/tests/toolshot.test.js | 150 +- packages/toolshot/vite.config.js | 9 +- packages/ui/index.html | 24 +- packages/ui/package.json | 27 +- packages/ui/src/common.js | 4 +- packages/ui/src/components/EventLogger.svelte | 1 + .../src/components/Explorer/Explorer.svelte | 1 + .../src/components/Explorer/ToolGroup.svelte | 1 + packages/ui/src/components/Frame.svelte | 1 + .../ui/src/components/PaneContainer.svelte | 1 + packages/ui/src/components/SizePicker.svelte | 1 + .../ui/src/connected-components/App.svelte | 14 +- .../connected-components/ErrorDialogue.svelte | 1 + .../connected-components/EventsPane.svelte | 2 +- packages/ui/src/stores/settings.js | 2 +- packages/ui/src/stores/tools.js | 3 +- .../ui/tests/components/Aside.tools.svelte | 1 + .../tests/components/BackgroundPicker.test.js | 4 +- .../components/BackgroundPicker.tools.svelte | 1 + .../ui/tests/components/Button.tools.svelte | 1 + .../ui/tests/components/Dialogue.tools.svelte | 1 + .../tests/components/EventLogger.tools.svelte | 1 + packages/ui/tests/components/Explorer.test.js | 51 +- .../ui/tests/components/Explorer.tools.svelte | 1 + packages/ui/tests/components/Frame.test.js | 4 +- .../ui/tests/components/Frame.tools.svelte | 1 + .../ui/tests/components/Loader.tools.svelte | 1 + .../ui/tests/components/PaneContainer.test.js | 25 +- .../components/PaneContainer.tools.svelte | 1 + .../tests/components/Properties.tools.svelte | 1 + .../ui/tests/components/SizePicker.test.js | 23 +- .../tests/components/SizePicker.tools.svelte | 1 + .../ui/tests/connected-components/App.test.js | 6 +- .../ErrorDialogue.test.js | 4 +- .../connected-components/EventsPane.test.js | 10 +- .../PropertiesPane.test.js | 20 +- packages/ui/tests/setup.js | 10 +- packages/ui/tests/stores/settings.test.js | 8 +- packages/ui/tests/stores/tools.test.js | 14 +- packages/ui/tests/utils/names.test.js | 4 +- packages/ui/vite.config.js | 14 +- packages/vite-plugin-atelier/package.json | 10 +- packages/vite-plugin-atelier/src/index.js | 2 +- .../vite-plugin-atelier/src/workframe.html | 20 +- .../tests/fixtures/custom-path/index.html | 2 +- .../tests/fixtures/public-dirs/index.html | 2 +- .../tests/fixtures/simple/index.html | 2 +- .../vite-plugin-atelier/tests/plugin.test.js | 104 +- pnpm-lock.yaml | 3351 +++++++++-------- 87 files changed, 2572 insertions(+), 1938 deletions(-) create mode 100644 .eslintrc.cjs delete mode 100644 .eslintrc.js create mode 100644 examples/svelte/atelier/Button.tools.svelte create mode 100644 examples/svelte/index.html create mode 100644 examples/svelte/package.json create mode 100644 examples/svelte/src/Button.svelte create mode 100644 examples/svelte/src/main.js create mode 100644 examples/svelte/vite.config.js create mode 100644 examples/sveltekit/README.md create mode 100644 examples/sveltekit/atelier/routes/+page.tools.svelte create mode 100644 examples/sveltekit/jsconfig.json create mode 100644 examples/sveltekit/package.json create mode 100644 examples/sveltekit/src/app.d.ts create mode 100644 examples/sveltekit/src/app.html create mode 100644 examples/sveltekit/src/routes/+page.svelte create mode 100644 examples/sveltekit/src/stores/locale.js create mode 100644 examples/sveltekit/static/favicon.png create mode 100644 examples/sveltekit/svelte.config.js create mode 100644 examples/sveltekit/vite.config.js diff --git a/.changeset/config.json b/.changeset/config.json index 7fcf973..4b52cda 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -2,10 +2,17 @@ "$schema": "https://unpkg.com/@changesets/config@2.2.0/schema.json", "changelog": "@changesets/cli/changelog", "commit": false, - "fixed": [], + "fixed": [ + [ + "@atelier-wb/svelte", + "@atelier-wb/ui", + "@atelier-wb/toolshot", + "@atelier-wb/vite-plugin-atelier" + ] + ], "linked": [], "access": "restricted", "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": [] + "ignore": ["@atelier-wb/example-svelte", "@atelier-wb/example-sveltekit"] } diff --git a/.eslintignore b/.eslintignore index 4636378..c25cd06 100644 --- a/.eslintignore +++ b/.eslintignore @@ -2,4 +2,5 @@ coverage/ dist/ node_modules/ fixtures/ -dist-atelier/ \ No newline at end of file +dist-atelier/ +*.tools.svelte \ No newline at end of file diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..206effc --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,22 @@ +module.exports = { + extends: [ + 'eslint:recommended', + 'plugin:svelte/recommended', + 'plugin:vitest/recommended', + 'plugin:testing-library/dom' + ], + env: { + browser: true, + es2020: true, + node: true + }, + plugins: ['simple-import-sort'], + parserOptions: { + sourceType: 'module' + }, + rules: { + 'simple-import-sort/imports': 'error', + 'vitest/valid-expect': 'off', + 'testing-library/no-node-access': 'off' + } +} diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 7693b13..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,34 +0,0 @@ -module.exports = { - extends: [ - 'eslint:recommended', - 'plugin:testing-library/dom', - 'plugin:jest-dom/recommended' - ], - env: { - browser: true, - es2020: true, - node: true, - jest: true - }, - globals: { - vi: true - }, - plugins: ['svelte3'], - overrides: [ - { - files: ['*.svelte'], - processor: 'svelte3/svelte3' - }, - { - files: ['*.js'], - extends: ['prettier'] - } - ], - parserOptions: { - sourceType: 'module' - }, - settings: { - // unfortunately, eslint-plugin-svelte can not work with preprocessors, like postcss - 'svelte3/ignore-styles': () => true - } -} diff --git a/.prettierrc.yml b/.prettierrc.yml index 5a352f3..2441418 100644 --- a/.prettierrc.yml +++ b/.prettierrc.yml @@ -2,3 +2,5 @@ semi: false singleQuote: true trailingComma: none arrowParens: avoid +plugins: + - prettier-plugin-svelte diff --git a/TODO.md b/TODO.md index 6c4decb..b0bfb33 100644 --- a/TODO.md +++ b/TODO.md @@ -1,5 +1,8 @@ # Features +bug: toolshot name do not include the toolbox's name +bug: how to inject unocss global styles? + ## UI - warn on tool name collisions diff --git a/docs/releasing.md b/docs/releasing.md index aa3ed49..a3cbb3c 100644 --- a/docs/releasing.md +++ b/docs/releasing.md @@ -28,7 +28,7 @@ Since the tool is not opinionated, here are the conventions we use. ## How to -1. At root level, `npm run release:bump` +1. At root level, `pnpm release` It generates CHANGELOG.md, bumps versions in packages.json files, creates a git tag. diff --git a/examples/svelte/atelier/Button.tools.svelte b/examples/svelte/atelier/Button.tools.svelte new file mode 100644 index 0000000..878e1bf --- /dev/null +++ b/examples/svelte/atelier/Button.tools.svelte @@ -0,0 +1,16 @@ + + + + + + + diff --git a/examples/svelte/index.html b/examples/svelte/index.html new file mode 100644 index 0000000..5a2ee20 --- /dev/null +++ b/examples/svelte/index.html @@ -0,0 +1,14 @@ + + + + + + + Vite + Svelte + + + +
+ + + diff --git a/examples/svelte/package.json b/examples/svelte/package.json new file mode 100644 index 0000000..ed7fc44 --- /dev/null +++ b/examples/svelte/package.json @@ -0,0 +1,20 @@ +{ + "name": "@atelier-wb/example-svelte", + "version": "1.0.0", + "description": "Example of Atelier for plain Svelte projects", + "license": "MIT", + "private": true, + "type": "module", + "scripts": { + "build": "vite build --mode export-atelier", + "dev": "vite dev --open", + "preview": "serve dist-atelier" + }, + "devDependencies": { + "@atelier-wb/vite-plugin-atelier": "workspace:*", + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "serve": "^14.2.1", + "svelte": "^4.2.8", + "vite": "^5.0.4" + } +} diff --git a/examples/svelte/src/Button.svelte b/examples/svelte/src/Button.svelte new file mode 100644 index 0000000..943a264 --- /dev/null +++ b/examples/svelte/src/Button.svelte @@ -0,0 +1,29 @@ + + + + + diff --git a/examples/svelte/src/main.js b/examples/svelte/src/main.js new file mode 100644 index 0000000..0ee579e --- /dev/null +++ b/examples/svelte/src/main.js @@ -0,0 +1,8 @@ +import Button from './Button.svelte' + +const app = new Button({ + target: document.getElementById('app'), + props: { text: 'Hello!' } +}) + +export default app diff --git a/examples/svelte/vite.config.js b/examples/svelte/vite.config.js new file mode 100644 index 0000000..31402bb --- /dev/null +++ b/examples/svelte/vite.config.js @@ -0,0 +1,7 @@ +import atelier from '@atelier-wb/vite-plugin-atelier' +import { svelte } from '@sveltejs/vite-plugin-svelte' +import { defineConfig } from 'vite' + +export default defineConfig({ + plugins: [svelte(), atelier()] +}) diff --git a/examples/sveltekit/README.md b/examples/sveltekit/README.md new file mode 100644 index 0000000..5c91169 --- /dev/null +++ b/examples/sveltekit/README.md @@ -0,0 +1,38 @@ +# create-svelte + +Everything you need to build a Svelte project, powered by [`create-svelte`](https://github.com/sveltejs/kit/tree/master/packages/create-svelte). + +## Creating a project + +If you're seeing this, you've probably already done this step. Congrats! + +```bash +# create a new project in the current directory +npm create svelte@latest + +# create a new project in my-app +npm create svelte@latest my-app +``` + +## Developing + +Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: + +```bash +npm run dev + +# or start the server and open the app in a new browser tab +npm run dev -- --open +``` + +## Building + +To create a production version of your app: + +```bash +npm run build +``` + +You can preview the production build with `npm run preview`. + +> To deploy your app, you may need to install an [adapter](https://kit.svelte.dev/docs/adapters) for your target environment. diff --git a/examples/sveltekit/atelier/routes/+page.tools.svelte b/examples/sveltekit/atelier/routes/+page.tools.svelte new file mode 100644 index 0000000..719f619 --- /dev/null +++ b/examples/sveltekit/atelier/routes/+page.tools.svelte @@ -0,0 +1,9 @@ + + + + + diff --git a/examples/sveltekit/jsconfig.json b/examples/sveltekit/jsconfig.json new file mode 100644 index 0000000..f1da068 --- /dev/null +++ b/examples/sveltekit/jsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "./.svelte-kit/tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true + } + // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias and https://kit.svelte.dev/docs/configuration#files + // + // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes + // from the referenced tsconfig.json - TypeScript does not merge them in +} diff --git a/examples/sveltekit/package.json b/examples/sveltekit/package.json new file mode 100644 index 0000000..d2f2697 --- /dev/null +++ b/examples/sveltekit/package.json @@ -0,0 +1,31 @@ +{ + "name": "@atelier-wb/example-sveltekit", + "version": "0.0.1", + "description": "Example of Atelier for plain Svelte projects", + "license": "MIT", + "private": true, + "type": "module", + "scripts": { + "atelier": "vite build --mode export-atelier", + "atelier:preview": "serve dist-atelier", + "build": "vite build", + "check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json", + "check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch", + "dev": "vite dev --open", + "preview": "vite preview" + }, + "devDependencies": { + "@atelier-wb/vite-plugin-atelier": "workspace:*", + "@sveltejs/adapter-auto": "^2.1.1", + "@sveltejs/kit": "^1.27.6", + "serve": "^14.2.1", + "svelte": "^4.2.8", + "svelte-check": "^3.6.2", + "typescript": "^5.3.2", + "vite": "^5.0.4" + }, + "dependencies": { + "format-message": "^6.2.4", + "svelte-intl": "^1.1.4" + } +} diff --git a/examples/sveltekit/src/app.d.ts b/examples/sveltekit/src/app.d.ts new file mode 100644 index 0000000..0425013 --- /dev/null +++ b/examples/sveltekit/src/app.d.ts @@ -0,0 +1,12 @@ +// See https://kit.svelte.dev/docs/types#app +// for information about these interfaces +declare global { + namespace App { + // interface Error {} + // interface Locals {} + // interface PageData {} + // interface Platform {} + } +} + +export {} diff --git a/examples/sveltekit/src/app.html b/examples/sveltekit/src/app.html new file mode 100644 index 0000000..b009ee2 --- /dev/null +++ b/examples/sveltekit/src/app.html @@ -0,0 +1,12 @@ + + + + + + + %sveltekit.head% + + +
%sveltekit.body%
+ + diff --git a/examples/sveltekit/src/routes/+page.svelte b/examples/sveltekit/src/routes/+page.svelte new file mode 100644 index 0000000..9e10dce --- /dev/null +++ b/examples/sveltekit/src/routes/+page.svelte @@ -0,0 +1,10 @@ + + +

Welcome to SvelteKit

+{#each terms.sort($comparator$.compare) as term} +

{term}

+{/each} diff --git a/examples/sveltekit/src/stores/locale.js b/examples/sveltekit/src/stores/locale.js new file mode 100644 index 0000000..7f6d9be --- /dev/null +++ b/examples/sveltekit/src/stores/locale.js @@ -0,0 +1,10 @@ +import { derived } from 'svelte/store' +import { locale } from 'svelte-intl' + +const defaultLocale = 'fr' +const locale$ = derived(locale, value => value || defaultLocale) + +export const comparator$ = derived( + locale$, + locale => new Intl.Collator(locale, { numeric: true, usage: 'sort' }) +) diff --git a/examples/sveltekit/static/favicon.png b/examples/sveltekit/static/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..825b9e65af7c104cfb07089bb28659393b4f2097 GIT binary patch literal 1571 zcmV+;2Hg3HP)Px)-AP12RCwC$UE6KzI1p6{F2N z1VK2vi|pOpn{~#djwYcWXTI_im_u^TJgMZ4JMOsSj!0ma>B?-(Hr@X&W@|R-$}W@Z zgj#$x=!~7LGqHW?IO8+*oE1MyDp!G=L0#^lUx?;!fXv@l^6SvTnf^ac{5OurzC#ZMYc20lI%HhX816AYVs1T3heS1*WaWH z%;x>)-J}YB5#CLzU@GBR6sXYrD>Vw(Fmt#|JP;+}<#6b63Ike{Fuo!?M{yEffez;| zp!PfsuaC)>h>-AdbnwN13g*1LowNjT5?+lFVd#9$!8Z9HA|$*6dQ8EHLu}U|obW6f z2%uGv?vr=KNq7YYa2Roj;|zooo<)lf=&2yxM@e`kM$CmCR#x>gI>I|*Ubr({5Y^rb zghxQU22N}F51}^yfDSt786oMTc!W&V;d?76)9KXX1 z+6Okem(d}YXmmOiZq$!IPk5t8nnS{%?+vDFz3BevmFNgpIod~R{>@#@5x9zJKEHLHv!gHeK~n)Ld!M8DB|Kfe%~123&Hz1Z(86nU7*G5chmyDe ziV7$pB7pJ=96hpxHv9rCR29%bLOXlKU<_13_M8x)6;P8E1Kz6G<&P?$P^%c!M5`2` zfY2zg;VK5~^>TJGQzc+33-n~gKt{{of8GzUkWmU110IgI0DLxRIM>0US|TsM=L|@F z0Bun8U!cRB7-2apz=y-7*UxOxz@Z0)@QM)9wSGki1AZ38ceG7Q72z5`i;i=J`ILzL z@iUO?SBBG-0cQuo+an4TsLy-g-x;8P4UVwk|D8{W@U1Zi z!M)+jqy@nQ$p?5tsHp-6J304Q={v-B>66$P0IDx&YT(`IcZ~bZfmn11#rXd7<5s}y zBi9eim&zQc0Dk|2>$bs0PnLmDfMP5lcXRY&cvJ=zKxI^f0%-d$tD!`LBf9^jMSYUA zI8U?CWdY@}cRq6{5~y+)#h1!*-HcGW@+gZ4B};0OnC~`xQOyH19z*TA!!BJ%9s0V3F?CAJ{hTd#*tf+ur-W9MOURF-@B77_-OshsY}6 zOXRY=5%C^*26z?l)1=$bz30!so5tfABdSYzO+H=CpV~aaUefmjvfZ3Ttu9W&W3Iu6 zROlh0MFA5h;my}8lB0tAV-Rvc2Zs_CCSJnx@d`**$idgy-iMob4dJWWw|21b4NB=LfsYp0Aeh{Ov)yztQi;eL4y5 zMi>8^SzKqk8~k?UiQK^^-5d8c%bV?$F8%X~czyiaKCI2=UH=3.44.3" }, "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^2.4.2", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/svelte": "^4.0.1", - "jsdom": "^22.1.0", - "svelte": "^4.0.0", + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "@testing-library/jest-dom": "^6.1.5", + "@testing-library/svelte": "^4.0.5", + "jsdom": "^23.0.1", + "svelte": "^4.2.8", "svelte-htm": "^1.2.0", - "vite": "^4.3.9" + "vite": "^5.0.4", + "vitest-dom": "^0.1.1" }, "files": [ "src/**/*", diff --git a/packages/svelte/src/components/Tool.svelte b/packages/svelte/src/components/Tool.svelte index 5f25a99..375c187 100644 --- a/packages/svelte/src/components/Tool.svelte +++ b/packages/svelte/src/components/Tool.svelte @@ -7,14 +7,15 @@ onMount, tick } from 'svelte' - import * as ToolBox from './ToolBox.svelte' + import { - registerTool, + currentTool, recordError, recordEvent, - currentTool, - recordVisibility + recordVisibility, + registerTool } from '../stores' + import * as ToolBox from './ToolBox.svelte' export let name = '' export let props = {} @@ -141,14 +142,14 @@ {:else if !usesSlot} {:else} {#if visible} @@ -162,7 +163,7 @@ display: none; flex-direction: column; } - .tool.visible { + .tool.current { display: flex; } diff --git a/packages/svelte/src/stores.js b/packages/svelte/src/stores.js index 61abbe4..511620d 100644 --- a/packages/svelte/src/stores.js +++ b/packages/svelte/src/stores.js @@ -1,4 +1,4 @@ -import { writable, derived } from 'svelte/store' +import { derived, writable } from 'svelte/store' const isJsdom = navigator.userAgent?.includes('jsdom') ?? false diff --git a/packages/svelte/tests/components/Tool.test.js b/packages/svelte/tests/components/Tool.test.js index 0f0b03b..4e5bee5 100644 --- a/packages/svelte/tests/components/Tool.test.js +++ b/packages/svelte/tests/components/Tool.test.js @@ -7,9 +7,10 @@ import { waitFor } from '@testing-library/svelte' import { tick } from 'svelte' -import html from 'svelte-htm' import { get, writable } from 'svelte/store' +import html from 'svelte-htm' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + import { Tool, ToolBox } from '../../src' import { currentTool, @@ -32,7 +33,7 @@ vi.mock('../../src/stores', async () => { }) describe('Tool component', () => { - beforeEach(vi.resetAllMocks) + beforeEach(() => vi.resetAllMocks()) afterEach(cleanup) describe('given no toolbox', () => { @@ -285,10 +286,10 @@ describe('Tool component', () => { expect(button).toBeInTheDocument() expect(recordEvent).not.toHaveBeenCalled() - await fireEvent.click(button) + fireEvent.click(button) expect(recordEvent).toHaveBeenCalledWith('click', expect.any(MouseEvent)) - await fireEvent.mouseEnter(button) + fireEvent.mouseEnter(button) expect(recordEvent).toHaveBeenCalledWith('enter', expect.any(CustomEvent)) expect(recordEvent).toHaveBeenCalledTimes(2) }) @@ -557,8 +558,7 @@ describe('Tool component', () => { }) expect(registerTool).toHaveBeenCalledTimes(1) expect(recordEvent).not.toHaveBeenCalled() - const tool = screen.getByRole('button').parentElement - expect(tool).toHaveClass('tool') + expect(screen.getByRole('button').parentElement).toHaveClass('tool') }) it('registers tool and renders nothing', async () => { @@ -769,10 +769,10 @@ describe('Tool component', () => { expect(button).toBeInTheDocument() expect(recordEvent).not.toHaveBeenCalled() - await fireEvent.click(button) + fireEvent.click(button) expect(recordEvent).toHaveBeenCalledWith('click', expect.any(MouseEvent)) - await fireEvent.mouseEnter(button) + fireEvent.mouseEnter(button) expect(recordEvent).toHaveBeenCalledWith('enter', expect.any(CustomEvent)) expect(recordEvent).toHaveBeenCalledTimes(2) }) @@ -807,8 +807,8 @@ describe('Tool component', () => { setup=${setup} > <${Tool} name=${name} props=${{ - disabled: props.disabled - }} setup=${toolSetup} /> + disabled: props.disabled + }} setup=${toolSetup} /> `) await tick() @@ -850,8 +850,8 @@ describe('Tool component', () => { setup=${setup} > <${Tool} name=${name} props=${{ - disabled: props.disabled - }} setup=${toolSetup} /> + disabled: props.disabled + }} setup=${toolSetup} /> `) await waitFor(() => expect(recordVisibility).toHaveBeenCalledWith({ @@ -891,11 +891,11 @@ describe('Tool component', () => { setup=${setup} > <${Tool} name=${name1} props=${{ - disabled: props1.disabled - }} setup=${toolSetup1} /> + disabled: props1.disabled + }} setup=${toolSetup1} /> <${Tool} name=${name2} props=${{ - disabled: props2.disabled - }} setup=${toolSetup2} /> + disabled: props2.disabled + }} setup=${toolSetup2} /> `) await tick() diff --git a/packages/svelte/tests/components/ToolBox.test.js b/packages/svelte/tests/components/ToolBox.test.js index d351abf..d984f12 100644 --- a/packages/svelte/tests/components/ToolBox.test.js +++ b/packages/svelte/tests/components/ToolBox.test.js @@ -2,6 +2,7 @@ import { faker } from '@faker-js/faker' import { cleanup, render } from '@testing-library/svelte' import html from 'svelte-htm' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + import { ToolBox } from '../../src' import { Tool } from '../test-components' diff --git a/packages/svelte/tests/components/Workbench.test.js b/packages/svelte/tests/components/Workbench.test.js index b1dc752..b9757d9 100644 --- a/packages/svelte/tests/components/Workbench.test.js +++ b/packages/svelte/tests/components/Workbench.test.js @@ -1,6 +1,7 @@ import { cleanup, render, screen } from '@testing-library/svelte' import html from 'svelte-htm' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + import { Workbench } from '../../src' import { currentTool } from '../../src/stores' import { Button } from '../test-components' @@ -13,7 +14,7 @@ vi.mock('../../src/stores', async () => { }) describe('Workbench component', () => { - beforeEach(vi.resetAllMocks) + beforeEach(() => vi.resetAllMocks()) afterEach(cleanup) it('can handle no tools', () => { diff --git a/packages/svelte/tests/setup.js b/packages/svelte/tests/setup.js index d263e51..5a36275 100644 --- a/packages/svelte/tests/setup.js +++ b/packages/svelte/tests/setup.js @@ -1,4 +1,6 @@ -import matchers from '@testing-library/jest-dom/matchers' -import { expect } from 'vitest' +import 'vitest-dom/extend-expect' -expect.extend(matchers) +import { cleanup } from '@testing-library/svelte' +import { afterEach } from 'vitest' + +afterEach(() => cleanup()) diff --git a/packages/svelte/tests/stores.test.js b/packages/svelte/tests/stores.test.js index a577392..ce06445 100644 --- a/packages/svelte/tests/stores.test.js +++ b/packages/svelte/tests/stores.test.js @@ -1,6 +1,7 @@ import { faker } from '@faker-js/faker' import { get } from 'svelte/store' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + import { currentTool, recordError, @@ -19,7 +20,7 @@ describe('stores', () => { const postMessage = vi.spyOn(window.parent, 'postMessage') const origin = new URL(window.parent.location.href).origin - beforeEach(vi.resetAllMocks) + beforeEach(() => vi.resetAllMocks()) describe('recordVisibility()', () => { it('records visibility change through postMessage', () => { @@ -446,12 +447,12 @@ describe('stores', () => { describe('currentTool', () => { it('is empty by default', () => { - expect(get(currentTool)).not.toBeDefined() + expect(get(currentTool)).toBeUndefined() }) it('ignores message from a different origin', () => { const data = faker.string.uuid() - expect(get(currentTool)).not.toBeDefined() + expect(get(currentTool)).toBeUndefined() window.dispatchEvent( new MessageEvent('message', { @@ -459,12 +460,12 @@ describe('stores', () => { data: { type: 'selectTool', data } }) ) - expect(get(currentTool)).not.toBeDefined() + expect(get(currentTool)).toBeUndefined() }) it('ignores message with unsupported types', () => { const data = faker.string.uuid() - expect(get(currentTool)).not.toBeDefined() + expect(get(currentTool)).toBeUndefined() window.dispatchEvent( new MessageEvent('message', { @@ -472,12 +473,12 @@ describe('stores', () => { data: { type: faker.lorem.word(), data } }) ) - expect(get(currentTool)).not.toBeDefined() + expect(get(currentTool)).toBeUndefined() }) it('updates when receiving selectTool message', () => { const data = faker.string.uuid() - expect(get(currentTool)).not.toBeDefined() + expect(get(currentTool)).toBeUndefined() window.dispatchEvent( new MessageEvent('message', { diff --git a/packages/svelte/tests/test-components/Tool.svelte b/packages/svelte/tests/test-components/Tool.svelte index f706a79..8b6e11b 100644 --- a/packages/svelte/tests/test-components/Tool.svelte +++ b/packages/svelte/tests/test-components/Tool.svelte @@ -1,5 +1,6 @@ - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/ui/package.json b/packages/ui/package.json index a38a85f..88a8ddb 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@atelier-wb/ui", - "version": "0.11.0", + "version": "0.12.0", "description": "Atelier UI component and workbench page", "main": "index.html", "type": "module", @@ -14,26 +14,27 @@ "test:dev": "vitest dev" }, "devDependencies": { - "@rollup/plugin-yaml": "^4.1.1", - "@sveltejs/vite-plugin-svelte": "^2.4.2", - "@testing-library/dom": "^9.3.1", - "@testing-library/jest-dom": "^5.16.5", - "@testing-library/svelte": "^4.0.1", - "@testing-library/user-event": "^14.4.3", + "@rollup/plugin-yaml": "^4.1.2", + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "@testing-library/dom": "^9.3.3", + "@testing-library/jest-dom": "^6.1.5", + "@testing-library/svelte": "^4.0.5", + "@testing-library/user-event": "^14.5.1", "ajv": "^8.12.0", "format-message": "^6.2.4", "js-yaml": "^4.1.0", - "jsdom": "^22.1.0", + "jsdom": "^23.0.1", "material-design-icons-iconfont": "^6.7.0", "rxjs": "^7.8.1", - "serve": "^14.2.0", - "svelte": "^4.0.0", + "serve": "^14.2.1", + "svelte": "^4.2.8", "svelte-htm": "^1.2.0", "svelte-intl": "^1.1.4", "svelte-portal": "^2.2.0", - "svelte-preprocess": "^5.0.4", - "vite": "^4.3.9", - "vite-plugin-windicss": "^1.9.0", + "svelte-preprocess": "^5.1.1", + "vite": "^5.0.4", + "vite-plugin-windicss": "^1.9.2", + "vitest-dom": "^0.1.1", "windicss": "^3.5.6" }, "files": [ diff --git a/packages/ui/src/common.js b/packages/ui/src/common.js index 9a0c0fd..e80e71c 100644 --- a/packages/ui/src/common.js +++ b/packages/ui/src/common.js @@ -1,6 +1,8 @@ -import { locale, translations, getBrowserLocale } from 'svelte-intl' import 'virtual:windi.css' import './styles.postcss' + +import { getBrowserLocale, locale, translations } from 'svelte-intl' + import fr from './locales/fr.yaml' import en from './locales/fr.yaml' diff --git a/packages/ui/src/components/EventLogger.svelte b/packages/ui/src/components/EventLogger.svelte index 538dcab..7cc65ea 100644 --- a/packages/ui/src/components/EventLogger.svelte +++ b/packages/ui/src/components/EventLogger.svelte @@ -2,6 +2,7 @@ import { createEventDispatcher } from 'svelte' import { fade } from 'svelte/transition' import { _ } from 'svelte-intl' + import Button from './Button.svelte' import PaneDisclaimer from './PaneDisclaimer.svelte' diff --git a/packages/ui/src/components/Explorer/Explorer.svelte b/packages/ui/src/components/Explorer/Explorer.svelte index b59e392..d525380 100644 --- a/packages/ui/src/components/Explorer/Explorer.svelte +++ b/packages/ui/src/components/Explorer/Explorer.svelte @@ -1,5 +1,6 @@ diff --git a/packages/ui/src/connected-components/EventsPane.svelte b/packages/ui/src/connected-components/EventsPane.svelte index 8657c07..72b4516 100644 --- a/packages/ui/src/connected-components/EventsPane.svelte +++ b/packages/ui/src/connected-components/EventsPane.svelte @@ -5,7 +5,7 @@ diff --git a/packages/ui/src/stores/settings.js b/packages/ui/src/stores/settings.js index 10d735c..4192eb1 100644 --- a/packages/ui/src/stores/settings.js +++ b/packages/ui/src/stores/settings.js @@ -1,5 +1,5 @@ -import { BehaviorSubject, map, tap } from 'rxjs' import Ajv from 'ajv' +import { BehaviorSubject, map, tap } from 'rxjs' const ajv = new Ajv() const settings$ = new BehaviorSubject() diff --git a/packages/ui/src/stores/tools.js b/packages/ui/src/stores/tools.js index 49b1819..8c443a0 100644 --- a/packages/ui/src/stores/tools.js +++ b/packages/ui/src/stores/tools.js @@ -1,4 +1,5 @@ -import { BehaviorSubject, Subject, map, scan, shareReplay } from 'rxjs' +import { BehaviorSubject, map, scan, shareReplay, Subject } from 'rxjs' + import { groupByName } from '../utils' let workframe = null diff --git a/packages/ui/tests/components/Aside.tools.svelte b/packages/ui/tests/components/Aside.tools.svelte index 5d0dd05..b392c26 100644 --- a/packages/ui/tests/components/Aside.tools.svelte +++ b/packages/ui/tests/components/Aside.tools.svelte @@ -1,5 +1,6 @@ diff --git a/packages/ui/tests/components/BackgroundPicker.test.js b/packages/ui/tests/components/BackgroundPicker.test.js index 38fc46f..a057303 100644 --- a/packages/ui/tests/components/BackgroundPicker.test.js +++ b/packages/ui/tests/components/BackgroundPicker.test.js @@ -1,5 +1,7 @@ import { fireEvent, render, screen } from '@testing-library/svelte' import html from 'svelte-htm' +import { beforeEach, describe, expect, it } from 'vitest' + import { BackgroundPicker } from '../../src/components' describe('BackgroundPicker component', () => { @@ -35,7 +37,7 @@ describe('BackgroundPicker component', () => { for (const [i, background] of backgrounds.entries()) { if (background) { // we're not testing DOM elements, but svelte bindings. - expect(items[i].style.cssText).toEqual(`--background: ${background};`) // eslint-disable-line jest-dom/prefer-to-have-style + expect(items[i].style.cssText).toBe(`--background: ${background};`) } } }) diff --git a/packages/ui/tests/components/BackgroundPicker.tools.svelte b/packages/ui/tests/components/BackgroundPicker.tools.svelte index 3475164..6885bcc 100644 --- a/packages/ui/tests/components/BackgroundPicker.tools.svelte +++ b/packages/ui/tests/components/BackgroundPicker.tools.svelte @@ -1,5 +1,6 @@ diff --git a/packages/ui/tests/components/Dialogue.tools.svelte b/packages/ui/tests/components/Dialogue.tools.svelte index e15d2c1..f2fd912 100644 --- a/packages/ui/tests/components/Dialogue.tools.svelte +++ b/packages/ui/tests/components/Dialogue.tools.svelte @@ -1,5 +1,6 @@ diff --git a/packages/ui/tests/components/EventLogger.tools.svelte b/packages/ui/tests/components/EventLogger.tools.svelte index 114466f..80facda 100644 --- a/packages/ui/tests/components/EventLogger.tools.svelte +++ b/packages/ui/tests/components/EventLogger.tools.svelte @@ -1,5 +1,6 @@ diff --git a/packages/ui/tests/components/Explorer.test.js b/packages/ui/tests/components/Explorer.test.js index 3945c4d..0c973db 100644 --- a/packages/ui/tests/components/Explorer.test.js +++ b/packages/ui/tests/components/Explorer.test.js @@ -1,5 +1,8 @@ import { fireEvent, render, screen, within } from '@testing-library/svelte' +import { tick } from 'svelte' import html from 'svelte-htm' +import { describe, expect, it, vi } from 'vitest' + import { Explorer } from '../../src/components' import { groupByName } from '../../src/utils' @@ -40,7 +43,8 @@ describe('Explorer components', () => { expect(within(breadcrumb).queryByText('home')).not.toBeInTheDocument() expect(within(breadcrumb).queryByText('a')).not.toBeInTheDocument() - await fireEvent.click(within(tree).getByText('a')) + fireEvent.click(within(tree).getByText('a')) + await tick() expect(within(tree).getByText('tool1')).toBeInTheDocument() expect(within(tree).getByText('c')).toBeInTheDocument() @@ -49,7 +53,8 @@ describe('Explorer components', () => { expect(within(breadcrumb).queryByText('c')).not.toBeInTheDocument() expect(within(tree).queryByText('a')).not.toBeInTheDocument() - await fireEvent.click(within(tree).getByText('c')) + fireEvent.click(within(tree).getByText('c')) + await tick() expect(within(tree).getByText('tool3')).toBeInTheDocument() expect(within(breadcrumb).getByText('home')).toBeInTheDocument() @@ -64,8 +69,10 @@ describe('Explorer components', () => { const breadcrumb = screen.getByRole('navigation') const tree = screen.getAllByRole('list')[1] - await fireEvent.click(within(tree).getByText('a')) - await fireEvent.click(within(tree).getByText('c')) + fireEvent.click(within(tree).getByText('a')) + await tick() + fireEvent.click(within(tree).getByText('c')) + await tick() expect(within(tree).getByText('tool3')).toBeInTheDocument() expect(within(tree).queryByText('tool1')).not.toBeInTheDocument() expect(within(tree).queryByText('c')).not.toBeInTheDocument() @@ -73,7 +80,8 @@ describe('Explorer components', () => { expect(within(breadcrumb).getByText('a')).toBeInTheDocument() expect(within(breadcrumb).getByText('c')).toBeInTheDocument() - await fireEvent.click(within(breadcrumb).getByText('a')) + fireEvent.click(within(breadcrumb).getByText('a')) + await tick() expect(within(tree).getByText('tool1')).toBeInTheDocument() expect(within(tree).getByText('c')).toBeInTheDocument() expect(within(tree).queryByText('a')).not.toBeInTheDocument() @@ -81,7 +89,8 @@ describe('Explorer components', () => { expect(within(tree).queryByText('b')).not.toBeInTheDocument() expect(within(breadcrumb).queryByText('c')).not.toBeInTheDocument() - await fireEvent.click(within(breadcrumb).getByText('home')) + fireEvent.click(within(breadcrumb).getByText('home')) + await tick() expect(screen.getByText('a')).toBeInTheDocument() expect(screen.getByText('tool2')).toBeInTheDocument() expect(screen.getByText('b')).toBeInTheDocument() @@ -93,8 +102,10 @@ describe('Explorer components', () => { const breadcrumb = screen.getByRole('navigation') const tree = screen.getAllByRole('list')[1] - await fireEvent.click(within(tree).getByText('a')) - await fireEvent.click(within(tree).getByText('c')) + fireEvent.click(within(tree).getByText('a')) + await tick() + fireEvent.click(within(tree).getByText('c')) + await tick() expect(within(tree).getByText('tool3')).toBeInTheDocument() expect(within(tree).queryByText('tool1')).not.toBeInTheDocument() expect(within(tree).queryByText('c')).not.toBeInTheDocument() @@ -102,7 +113,8 @@ describe('Explorer components', () => { expect(within(breadcrumb).getByText('a')).toBeInTheDocument() expect(within(breadcrumb).getByText('c')).toBeInTheDocument() - await fireEvent.click(within(breadcrumb).getByText('home')) + fireEvent.click(within(breadcrumb).getByText('home')) + await tick() expect(screen.getByText('a')).toBeInTheDocument() expect(screen.getByText('tool2')).toBeInTheDocument() expect(screen.getByText('b')).toBeInTheDocument() @@ -136,18 +148,21 @@ describe('Explorer components', () => { it('selects a different tool', async () => { const handleSelect = vi.fn() - render(html`<${Explorer} - tools=${groupByName(tools)} - current=${tools[3]} - on:select=${handleSelect} - />`) + render( + html`<${Explorer} + tools=${groupByName(tools)} + current=${tools[3]} + on:select=${handleSelect} + />` + ) const tree = screen.getAllByRole('list')[1] expect(within(tree).getByText('tool4')).toHaveClass('current') expect(within(tree).getByText('tool5')).not.toHaveClass('current') expect(handleSelect).not.toHaveBeenCalled() - await fireEvent.click(within(tree).getByText('tool5')) + fireEvent.click(within(tree).getByText('tool5')) + await tick() expect(handleSelect).toHaveBeenCalledWith( expect.objectContaining({ detail: tools[4] }) ) @@ -204,8 +219,10 @@ describe('Explorer components', () => { const { component } = render(Explorer, { props: { current: tools[2], tools: groupByName(tools) } }) - await fireEvent.click(screen.getByText('home')) - await fireEvent.click(screen.getByText('b')) + fireEvent.click(screen.getByText('home')) + await tick() + fireEvent.click(screen.getByText('b')) + await tick() expect(screen.getByText('tool4')).toBeInTheDocument() expect(screen.getByText('tool5')).toBeInTheDocument() diff --git a/packages/ui/tests/components/Explorer.tools.svelte b/packages/ui/tests/components/Explorer.tools.svelte index bae6940..280dca5 100644 --- a/packages/ui/tests/components/Explorer.tools.svelte +++ b/packages/ui/tests/components/Explorer.tools.svelte @@ -1,5 +1,6 @@ diff --git a/packages/ui/tests/components/Frame.test.js b/packages/ui/tests/components/Frame.test.js index ac0c4ad..d5b3bd5 100644 --- a/packages/ui/tests/components/Frame.test.js +++ b/packages/ui/tests/components/Frame.test.js @@ -1,6 +1,8 @@ import { render, screen, waitFor } from '@testing-library/svelte' -import html from 'svelte-htm' import { get, writable } from 'svelte/store' +import html from 'svelte-htm' +import { describe, expect, it } from 'vitest' + import { Frame } from '../../src/components' describe('Frame components', () => { diff --git a/packages/ui/tests/components/Frame.tools.svelte b/packages/ui/tests/components/Frame.tools.svelte index 9d0dac4..a09abcb 100644 --- a/packages/ui/tests/components/Frame.tools.svelte +++ b/packages/ui/tests/components/Frame.tools.svelte @@ -1,5 +1,6 @@ diff --git a/packages/ui/tests/components/PaneContainer.test.js b/packages/ui/tests/components/PaneContainer.test.js index 2a9f1ea..2925bed 100644 --- a/packages/ui/tests/components/PaneContainer.test.js +++ b/packages/ui/tests/components/PaneContainer.test.js @@ -1,10 +1,13 @@ import { faker } from '@faker-js/faker' import { fireEvent, render, screen, within } from '@testing-library/svelte' +import { tick } from 'svelte' import { readable } from 'svelte/store' import html from 'svelte-htm' -import { translate } from '../test-utils' -import { Pane1, Pane2, Pane3 } from '../test-components' +import { describe, expect, it } from 'vitest' + import { PaneContainer } from '../../src/components' +import { Pane1, Pane2, Pane3 } from '../test-components' +import { translate } from '../test-utils' describe('PaneContainer component', () => { it('display tabs and can switch between them', async () => { @@ -40,7 +43,8 @@ describe('PaneContainer component', () => { const main = screen.getByRole('main') expect(main).toHaveTextContent('This is pane #1') - await fireEvent.click(tabItems[2]) + fireEvent.click(tabItems[2]) + await tick() expect(main).toHaveTextContent('This is pane #3') }) @@ -75,7 +79,8 @@ describe('PaneContainer component', () => { const main = screen.getByRole('main') expect(main).toHaveTextContent('This is pane #2') - await fireEvent.click(tabItems[1]) + fireEvent.click(tabItems[1]) + await tick() expect(main).toHaveTextContent('This is pane #3') }) @@ -122,16 +127,20 @@ describe('PaneContainer component', () => { const main = screen.getByRole('main') expect(main).not.toHaveClass('collapsed') - await fireEvent.click(collapseButton) + fireEvent.click(collapseButton) + await tick() expect(main).toHaveClass('collapsed') - await fireEvent.click(collapseButton) + fireEvent.click(collapseButton) + await tick() expect(main).not.toHaveClass('collapsed') - await fireEvent.dblClick(tabBar) + fireEvent.dblClick(tabBar) + await tick() expect(main).toHaveClass('collapsed') - await fireEvent.dblClick(tabBar) + fireEvent.dblClick(tabBar) + await tick() expect(main).not.toHaveClass('collapsed') }) }) diff --git a/packages/ui/tests/components/PaneContainer.tools.svelte b/packages/ui/tests/components/PaneContainer.tools.svelte index 2778a75..a4497d6 100644 --- a/packages/ui/tests/components/PaneContainer.tools.svelte +++ b/packages/ui/tests/components/PaneContainer.tools.svelte @@ -1,6 +1,7 @@ diff --git a/packages/ui/tests/components/SizePicker.test.js b/packages/ui/tests/components/SizePicker.test.js index db19b59..dee1ac4 100644 --- a/packages/ui/tests/components/SizePicker.test.js +++ b/packages/ui/tests/components/SizePicker.test.js @@ -1,12 +1,13 @@ import { fireEvent, render, screen } from '@testing-library/svelte' import { tick } from 'svelte' import html from 'svelte-htm' +import { beforeEach, describe, expect, it, vi } from 'vitest' + import { SizePicker } from '../../src/components' describe('SizePicker component', () => { const viewport = { // we're not testing DOM elements, but assignments to mock object. - /* eslint-disable jest-dom/prefer-to-have-style */ style: {}, parentElement: { classList: { add: vi.fn(), remove: vi.fn() } } } @@ -61,8 +62,8 @@ describe('SizePicker component', () => { const rank = 1 fireEvent.click(screen.getAllByRole('button')[rank]) await tick() - expect(viewport.style.width).toEqual(`${sizes[rank].width}px`) - expect(viewport.style.height).toEqual(`${sizes[rank].height}px`) + expect(viewport.style.width).toBe(`${sizes[rank].width}px`) + expect(viewport.style.height).toBe(`${sizes[rank].height}px`) expect(viewport.parentElement.classList.add).toHaveBeenCalledWith('frame') let buttons = screen.getAllByRole('button') expect(buttons).toHaveLength(sizes.length + 2) @@ -79,8 +80,8 @@ describe('SizePicker component', () => { for (const [i, { icon }] of sizes.entries()) { expect(buttons[i]).toHaveTextContent(icon) } - expect(viewport.style.width).toEqual('100%') - expect(viewport.style.height).toEqual('100%') + expect(viewport.style.width).toBe('100%') + expect(viewport.style.height).toBe('100%') expect(viewport.parentElement.classList.remove).toHaveBeenCalledWith( 'frame' ) @@ -97,8 +98,8 @@ describe('SizePicker component', () => { let rank = 0 fireEvent.click(screen.getAllByRole('button')[rank]) await tick() - expect(viewport.style.width).toEqual(`${sizes[rank].width}px`) - expect(viewport.style.height).toEqual(`${sizes[rank].height}px`) + expect(viewport.style.width).toBe(`${sizes[rank].width}px`) + expect(viewport.style.height).toBe(`${sizes[rank].height}px`) expect(viewport.parentElement.classList.add).toHaveBeenNthCalledWith( 1, 'frame' @@ -106,14 +107,14 @@ describe('SizePicker component', () => { fireEvent.click(screen.getAllByRole('button')[1]) await tick() - expect(viewport.style.width).toEqual(`${sizes[rank].height}px`) - expect(viewport.style.height).toEqual(`${sizes[rank].width}px`) + expect(viewport.style.width).toBe(`${sizes[rank].height}px`) + expect(viewport.style.height).toBe(`${sizes[rank].width}px`) rank = 1 fireEvent.click(screen.getAllByRole('button')[rank + 2]) await tick() - expect(viewport.style.width).toEqual(`${sizes[rank].height}px`) - expect(viewport.style.height).toEqual(`${sizes[rank].width}px`) + expect(viewport.style.width).toBe(`${sizes[rank].height}px`) + expect(viewport.style.height).toBe(`${sizes[rank].width}px`) expect(viewport.parentElement.classList.add).toHaveBeenNthCalledWith( 2, 'frame' diff --git a/packages/ui/tests/components/SizePicker.tools.svelte b/packages/ui/tests/components/SizePicker.tools.svelte index c3cfdbb..5d6cd31 100644 --- a/packages/ui/tests/components/SizePicker.tools.svelte +++ b/packages/ui/tests/components/SizePicker.tools.svelte @@ -2,6 +2,7 @@ import { Tool, ToolBox } from '@atelier-wb/svelte' import { tick } from 'svelte' import { _ } from 'svelte-intl' + import SizePicker from '../../src/components/SizePicker.svelte' let viewport diff --git a/packages/ui/tests/connected-components/App.test.js b/packages/ui/tests/connected-components/App.test.js index dafb85c..1892679 100644 --- a/packages/ui/tests/connected-components/App.test.js +++ b/packages/ui/tests/connected-components/App.test.js @@ -1,11 +1,13 @@ import { render, screen, waitFor, within } from '@testing-library/svelte' import html from 'svelte-htm' -import { translate } from '../test-utils' +import { beforeEach, describe, expect, it, vi } from 'vitest' + import { App } from '../../src/connected-components' import { reloadSettings } from '../../src/stores' +import { translate } from '../test-utils' describe('App connected component', () => { - beforeEach(vi.resetAllMocks) + beforeEach(() => vi.resetAllMocks()) it('displays explorer, pane container with default pickers and loader', () => { const { container } = render(html`<${App} />`) diff --git a/packages/ui/tests/connected-components/ErrorDialogue.test.js b/packages/ui/tests/connected-components/ErrorDialogue.test.js index 58c3b00..98416ef 100644 --- a/packages/ui/tests/connected-components/ErrorDialogue.test.js +++ b/packages/ui/tests/connected-components/ErrorDialogue.test.js @@ -1,8 +1,10 @@ import { render, screen, within } from '@testing-library/svelte' import html from 'svelte-htm' -import { translate } from '../test-utils' +import { beforeEach, describe, expect, it, vi } from 'vitest' + import ErrorDialogue from '../../src/connected-components/ErrorDialogue.svelte' import { lastError } from '../../src/stores' +import { translate } from '../test-utils' vi.mock('../../src/stores/tools', () => ({ lastError: new (require('rxjs').BehaviorSubject)() diff --git a/packages/ui/tests/connected-components/EventsPane.test.js b/packages/ui/tests/connected-components/EventsPane.test.js index 0184d0a..f0ee928 100644 --- a/packages/ui/tests/connected-components/EventsPane.test.js +++ b/packages/ui/tests/connected-components/EventsPane.test.js @@ -1,12 +1,14 @@ import { faker } from '@faker-js/faker' import { fireEvent, render, screen } from '@testing-library/svelte' import html from 'svelte-htm' -import { translate } from '../test-utils' +import { beforeEach, describe, expect, it, vi } from 'vitest' + import { default as EventsPane, isEnabled } from '../../src/connected-components/EventsPane.svelte' -import { events, clearEvents } from '../../src/stores' +import { clearEvents, events } from '../../src/stores' +import { translate } from '../test-utils' vi.mock('../../src/stores/tools', () => ({ events: new (require('rxjs').BehaviorSubject)(), @@ -14,7 +16,7 @@ vi.mock('../../src/stores/tools', () => ({ })) describe('EventLogger connected component', () => { - beforeEach(vi.resetAllMocks) + beforeEach(() => vi.resetAllMocks()) it('handles no events', () => { events.next([]) @@ -52,7 +54,7 @@ describe('EventLogger connected component', () => { render(html`<${EventsPane} />`) expect(clearEvents).not.toHaveBeenCalled() - await fireEvent.click(screen.queryByRole('button')) + fireEvent.click(screen.queryByRole('button')) expect(clearEvents).toHaveBeenCalledTimes(1) }) diff --git a/packages/ui/tests/connected-components/PropertiesPane.test.js b/packages/ui/tests/connected-components/PropertiesPane.test.js index f0b14fd..33e30ba 100644 --- a/packages/ui/tests/connected-components/PropertiesPane.test.js +++ b/packages/ui/tests/connected-components/PropertiesPane.test.js @@ -1,6 +1,8 @@ import { faker } from '@faker-js/faker' import { fireEvent, render, screen } from '@testing-library/svelte' import html from 'svelte-htm' +import { beforeEach, describe, expect, it, vi } from 'vitest' + import { PropertiesPane } from '../../src/connected-components' import { currentTool, updateProperty } from '../../src/stores' @@ -13,7 +15,7 @@ vi.mock('../../src/stores/tools', () => { }) describe('PropertiesPane connected component', () => { - beforeEach(vi.resetAllMocks) + beforeEach(() => vi.resetAllMocks()) it('can edit a text property', async () => { const name = faker.lorem.word() @@ -26,7 +28,7 @@ describe('PropertiesPane connected component', () => { expect(updateProperty).not.toHaveBeenCalled() const newValue = faker.lorem.words() - await fireEvent.input(input, { target: { value: newValue } }) + fireEvent.input(input, { target: { value: newValue } }) expect(updateProperty).toHaveBeenCalledWith( expect.objectContaining({ detail: { name, value: newValue } }) ) @@ -43,12 +45,12 @@ describe('PropertiesPane connected component', () => { expect(input).toBeChecked(value) expect(updateProperty).not.toHaveBeenCalled() - await fireEvent.change(input, { target: { checked: false } }) + fireEvent.change(input, { target: { checked: false } }) expect(updateProperty).toHaveBeenCalledWith( expect.objectContaining({ detail: { name, value: false } }) ) - await fireEvent.change(input, { target: { checked: true } }) + fireEvent.change(input, { target: { checked: true } }) expect(updateProperty).toHaveBeenCalledWith( expect.objectContaining({ detail: { name, value: true } }) ) @@ -66,7 +68,7 @@ describe('PropertiesPane connected component', () => { expect(updateProperty).not.toHaveBeenCalled() const newValue = faker.number.int(999) - await fireEvent.change(input, { target: { value: newValue } }) + fireEvent.change(input, { target: { value: newValue } }) expect(updateProperty).toHaveBeenCalledWith( expect.objectContaining({ detail: { name, value: newValue } }) ) @@ -83,13 +85,13 @@ describe('PropertiesPane connected component', () => { expect(input).toHaveValue(JSON.stringify(value, null, 2)) expect(updateProperty).not.toHaveBeenCalled() - await fireEvent.input(input, { + fireEvent.input(input, { target: { value: `does not parse as array` } }) expect(updateProperty).not.toHaveBeenCalled() const newValue = [4, 6] - await fireEvent.input(input, { + fireEvent.input(input, { target: { value: JSON.stringify(newValue) } }) expect(updateProperty).toHaveBeenCalledWith( @@ -108,13 +110,13 @@ describe('PropertiesPane connected component', () => { expect(input).toHaveValue(JSON.stringify(value, null, 2)) expect(updateProperty).not.toHaveBeenCalled() - await fireEvent.input(input, { + fireEvent.input(input, { target: { value: `does not parse as object` } }) expect(updateProperty).not.toHaveBeenCalled() const newValue = { baz: { bar: 'foo' } } - await fireEvent.input(input, { + fireEvent.input(input, { target: { value: JSON.stringify(newValue) } }) expect(updateProperty).toHaveBeenCalledWith( diff --git a/packages/ui/tests/setup.js b/packages/ui/tests/setup.js index dbaebe3..6ea0b62 100644 --- a/packages/ui/tests/setup.js +++ b/packages/ui/tests/setup.js @@ -1,8 +1,8 @@ -import matchers from '@testing-library/jest-dom/matchers' -import formatMessage from 'format-message' -import { expect } from 'vitest' +import 'vitest-dom/extend-expect' -expect.extend(matchers) +import { cleanup } from '@testing-library/svelte' +import formatMessage from 'format-message' +import { afterEach } from 'vitest' const { date, time } = formatMessage.setup().formats for (const key in date) { @@ -11,3 +11,5 @@ for (const key in date) { for (const key in time) { time[key].timeZone = 'UTC' } + +afterEach(() => cleanup()) diff --git a/packages/ui/tests/stores/settings.test.js b/packages/ui/tests/stores/settings.test.js index 206db09..2b7eb92 100644 --- a/packages/ui/tests/stores/settings.test.js +++ b/packages/ui/tests/stores/settings.test.js @@ -1,7 +1,9 @@ import { faker } from '@faker-js/faker' import { firstValueFrom } from 'rxjs' import { get } from 'svelte/store' -import { reloadSettings, getSettings } from '../../src/stores' +import { beforeEach, describe, expect, it, vi } from 'vitest' + +import { getSettings, reloadSettings } from '../../src/stores' describe('settings store', () => { beforeEach(() => { @@ -26,8 +28,8 @@ describe('settings store', () => { window.uiSettings = { foo: 'enabled', bar: 10, [key]: value } reloadSettings() - expect(get(getSettings('foo'))).toEqual('enabled') - expect(get(getSettings('bar'))).toEqual(10) + expect(get(getSettings('foo'))).toBe('enabled') + expect(get(getSettings('bar'))).toBe(10) expect(get(getSettings(key))).toEqual(value) }) diff --git a/packages/ui/tests/stores/tools.test.js b/packages/ui/tests/stores/tools.test.js index b664b04..439430a 100644 --- a/packages/ui/tests/stores/tools.test.js +++ b/packages/ui/tests/stores/tools.test.js @@ -1,20 +1,22 @@ import { faker } from '@faker-js/faker' import { get } from 'svelte/store' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' + import { clearEvents, - events, - tools, currentTool, + events, lastError, selectTool, setWorkbenchFrame, + tools, updateProperty } from '../../src/stores' describe('tools store', () => { const subscriptions = [] - beforeEach(vi.resetAllMocks) + beforeEach(() => vi.resetAllMocks()) afterEach(() => { for (const subscription of subscriptions) { @@ -32,7 +34,7 @@ describe('tools store', () => { data: { type: 'registerTool', data: {} } }) ) - expect(get(currentTool)).not.toBeDefined() + expect(get(currentTool)).toBeUndefined() expect(get(tools)).toEqual([]) expect(get(events)).toEqual([]) }) @@ -46,7 +48,7 @@ describe('tools store', () => { data: { type: faker.lorem.word(), data: {} } }) ) - expect(get(currentTool)).not.toBeDefined() + expect(get(currentTool)).toBeUndefined() expect(get(tools)).toEqual([]) expect(get(events)).toEqual([]) }) @@ -57,7 +59,7 @@ describe('tools store', () => { const tool2 = { fullName: faker.commerce.productName() } const tool3 = { fullName: faker.commerce.productName() } setWorkbenchFrame({ src }) - expect(get(currentTool)).not.toBeDefined() + expect(get(currentTool)).toBeUndefined() window.dispatchEvent( new MessageEvent('message', { diff --git a/packages/ui/tests/utils/names.test.js b/packages/ui/tests/utils/names.test.js index 781be6f..18d3bcd 100644 --- a/packages/ui/tests/utils/names.test.js +++ b/packages/ui/tests/utils/names.test.js @@ -1,6 +1,8 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest' + import { groupByName } from '../../src/utils' -beforeEach(vi.resetAllMocks) +beforeEach(() => vi.resetAllMocks()) describe('groupByName() utility', () => { it('handles no tools', () => { diff --git a/packages/ui/vite.config.js b/packages/ui/vite.config.js index 00953cd..a4d78a9 100644 --- a/packages/ui/vite.config.js +++ b/packages/ui/vite.config.js @@ -1,10 +1,11 @@ -import { svelte } from '@sveltejs/vite-plugin-svelte' import yaml from '@rollup/plugin-yaml' -import atelier from '../vite-plugin-atelier' +import { svelte } from '@sveltejs/vite-plugin-svelte' import sveltePreprocess from 'svelte-preprocess' import { defineConfig } from 'vite' import windi from 'vite-plugin-windicss' +import atelier from '../vite-plugin-atelier' + export default defineConfig(({ mode }) => { return { base: '', // allows embedded deployments @@ -36,8 +37,13 @@ export default defineConfig(({ mode }) => { test: { // https://github.com/vitest-dev/vitest/issues/2834 alias: [{ find: /^svelte$/, replacement: 'svelte/internal' }], - deps: { inline: ['svelte-hyperscript'] }, - globals: true, + deps: { + optimizer: { + web: { + include: ['svelte-hyperscript'] + } + } + }, environment: 'jsdom', setupFiles: 'tests/setup' } diff --git a/packages/vite-plugin-atelier/package.json b/packages/vite-plugin-atelier/package.json index 9439989..7c80767 100644 --- a/packages/vite-plugin-atelier/package.json +++ b/packages/vite-plugin-atelier/package.json @@ -1,6 +1,6 @@ { "name": "@atelier-wb/vite-plugin-atelier", - "version": "0.11.1", + "version": "0.12.0", "description": "Helps you buildind Component Driven UIs with Atelier and Vite", "main": "src/index.js", "type": "module", @@ -17,11 +17,11 @@ "vite": ">=3.1.0" }, "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^2.4.2", + "@sveltejs/vite-plugin-svelte": "^3.0.1", "connect": "^3.7.0", - "svelte": "^4.0.0", - "undici": "^5.22.1", - "vite": "^4.3.9" + "svelte": "^4.2.8", + "undici": "^5.28.2", + "vite": "^5.0.4" }, "files": [ "src/**/*" diff --git a/packages/vite-plugin-atelier/src/index.js b/packages/vite-plugin-atelier/src/index.js index f16ae67..b0aee51 100644 --- a/packages/vite-plugin-atelier/src/index.js +++ b/packages/vite-plugin-atelier/src/index.js @@ -1,6 +1,6 @@ import Ajv from 'ajv' import { createReadStream } from 'fs' -import { cp, readdir, readFile, rm, writeFile, stat } from 'fs/promises' +import { cp, readdir, readFile, rm, stat, writeFile } from 'fs/promises' import { createRequire } from 'module' import { dirname, resolve } from 'path' import sirv from 'sirv' diff --git a/packages/vite-plugin-atelier/src/workframe.html b/packages/vite-plugin-atelier/src/workframe.html index 428ed16..a047bc8 100644 --- a/packages/vite-plugin-atelier/src/workframe.html +++ b/packages/vite-plugin-atelier/src/workframe.html @@ -1,12 +1,14 @@ - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/packages/vite-plugin-atelier/tests/fixtures/custom-path/index.html b/packages/vite-plugin-atelier/tests/fixtures/custom-path/index.html index b3cff51..50ac984 100644 --- a/packages/vite-plugin-atelier/tests/fixtures/custom-path/index.html +++ b/packages/vite-plugin-atelier/tests/fixtures/custom-path/index.html @@ -1,4 +1,4 @@ - + diff --git a/packages/vite-plugin-atelier/tests/fixtures/public-dirs/index.html b/packages/vite-plugin-atelier/tests/fixtures/public-dirs/index.html index b3cff51..50ac984 100644 --- a/packages/vite-plugin-atelier/tests/fixtures/public-dirs/index.html +++ b/packages/vite-plugin-atelier/tests/fixtures/public-dirs/index.html @@ -1,4 +1,4 @@ - + diff --git a/packages/vite-plugin-atelier/tests/fixtures/simple/index.html b/packages/vite-plugin-atelier/tests/fixtures/simple/index.html index b3cff51..50ac984 100644 --- a/packages/vite-plugin-atelier/tests/fixtures/simple/index.html +++ b/packages/vite-plugin-atelier/tests/fixtures/simple/index.html @@ -1,4 +1,4 @@ - + diff --git a/packages/vite-plugin-atelier/tests/plugin.test.js b/packages/vite-plugin-atelier/tests/plugin.test.js index 5f2d762..9f4decf 100644 --- a/packages/vite-plugin-atelier/tests/plugin.test.js +++ b/packages/vite-plugin-atelier/tests/plugin.test.js @@ -17,6 +17,7 @@ import { it, vi } from 'vitest' + import builder from '../src' const defaultWorkframeId = '@atelier-wb/workframe' @@ -51,7 +52,7 @@ async function preparePlugin( } describe('plugin builder', () => { - beforeEach(vi.resetAllMocks) + beforeEach(() => vi.resetAllMocks()) it('validates path option', () => { expect(() => builder({ path: true })).toThrow( @@ -147,9 +148,9 @@ describe('plugin builder', () => { describe('given some files', () => { it('does not handle other ids than workframeId', async () => { const plugin = await preparePlugin() - expect(plugin.resolveId(faker.lorem.word())).not.toBeDefined() - expect(await plugin.load(faker.lorem.word())).not.toBeDefined() - expect(plugin.resolveId(`${defaultUrl}${defaultWorkframeId}`)).toEqual( + expect(plugin.resolveId(faker.lorem.word())).toBeUndefined() + expect(await plugin.load(faker.lorem.word())).toBeUndefined() + expect(plugin.resolveId(`${defaultUrl}${defaultWorkframeId}`)).toBe( `${defaultUrl}${defaultWorkframeId}` ) }) @@ -157,9 +158,9 @@ describe('plugin builder', () => { it('supports custom workframeId', async () => { const workframeId = faker.lorem.word() const plugin = await preparePlugin({ workframeId }) - expect(plugin.resolveId(faker.lorem.word())).not.toBeDefined() - expect(await plugin.load(faker.lorem.word())).not.toBeDefined() - expect(plugin.resolveId(`${defaultUrl}${workframeId}`)).toEqual( + expect(plugin.resolveId(faker.lorem.word())).toBeUndefined() + expect(await plugin.load(faker.lorem.word())).toBeUndefined() + expect(plugin.resolveId(`${defaultUrl}${workframeId}`)).toBe( `${defaultUrl}${workframeId}` ) }) @@ -177,7 +178,7 @@ describe('plugin builder', () => { it('finds tool files and generates workframe content', async () => { const plugin = await preparePlugin({ path }) expect(await plugin.load(`${defaultUrl}${defaultWorkframeId}`)) - .toEqual(`import { Workbench } from '@atelier-wb/svelte' + .toBe(`import { Workbench } from '@atelier-wb/svelte' import tool1 from '${path}/a.tools.svelte' import tool2 from '${path}/b.tools.svelte' @@ -200,7 +201,7 @@ new Workbench({ toolRegexp: '\\.custom\\.svelte$' }) expect(await plugin.load(`${defaultUrl}${defaultWorkframeId}`)) - .toEqual(`import { Workbench } from '@atelier-wb/svelte' + .toBe(`import { Workbench } from '@atelier-wb/svelte' import tool1 from '${path}/c.custom.svelte' import tool2 from '${path}/folder1/a.custom.svelte' @@ -218,7 +219,7 @@ new Workbench({ const setupPath = faker.lorem.word() const plugin = await preparePlugin({ path, setupPath }) expect(await plugin.load(`${defaultUrl}${defaultWorkframeId}`)) - .toEqual(`import { Workbench } from '@atelier-wb/svelte' + .toBe(`import { Workbench } from '@atelier-wb/svelte' import '${setupPath}' import tool1 from '${path}/a.tools.svelte' @@ -239,7 +240,7 @@ new Workbench({ const setupPath = faker.lorem.word() const plugin = await preparePlugin({ path, setupPath: `./${setupPath}` }) expect(await plugin.load(`${defaultUrl}${defaultWorkframeId}`)) - .toEqual(`import { Workbench } from '@atelier-wb/svelte' + .toBe(`import { Workbench } from '@atelier-wb/svelte' import '${resolve(path, setupPath).replace(/\\/g, '/')}' import tool1 from '${path}/a.tools.svelte' @@ -260,7 +261,7 @@ new Workbench({ const setupPath = resolve(path, faker.lorem.word()).replace(/\\/g, '/') const plugin = await preparePlugin({ path, setupPath }) expect(await plugin.load(`${defaultUrl}${defaultWorkframeId}`)) - .toEqual(`import { Workbench } from '@atelier-wb/svelte' + .toBe(`import { Workbench } from '@atelier-wb/svelte' import '${setupPath}' import tool1 from '${path}/a.tools.svelte' @@ -307,7 +308,7 @@ new Workbench({ }) }) - describe('given a configured and started server', () => { + describe('given a started server', () => { let server afterEach(() => server?.close()) @@ -326,11 +327,11 @@ new Workbench({ })) const response = await fetch(`${address}${url}ui-settings.js`) - expect(response.status).toEqual(200) - expect(response.headers.get('content-type')).toEqual( + expect(response.status).toBe(200) + expect(response.headers.get('content-type')).toBe( 'application/javascript;charset=utf-8' ) - expect(await response.text()).toEqual( + expect(await response.text()).toBe( `window.uiSettings = ${JSON.stringify(uiSettings)};` ) }) @@ -357,8 +358,8 @@ new Workbench({ it(`serves atelier's main html file`, async () => { const response = await fetch(`${address}${url}`) - expect(response.status).toEqual(200) - expect(response.headers.get('content-type')).toEqual( + expect(response.status).toBe(200) + expect(response.headers.get('content-type')).toBe( 'text/html;charset=utf-8' ) const body = await response.text() @@ -368,56 +369,59 @@ new Workbench({ ) ) expect(body).toEqual( - expect.stringContaining(' - - - - - - - - - - - " + + + + + + + + + + + + " `) }) @@ -486,10 +490,12 @@ new Workbench({ }) }) + // eslint-disable-next-line vitest/expect-expect -- expectWorkframeAndAssets contains expectations it(`generated workframe file with its assets`, async () => { await expectWorkframeAndAssets(atelierOut) }) + // eslint-disable-next-line vitest/expect-expect -- expectWorkframeAndAssets contains expectations it(`included ui distribution`, async () => { await expectUiDistribution(atelierOut) }) @@ -497,7 +503,7 @@ new Workbench({ it(`generated ui-settings file`, async () => { const settingsPath = resolve(atelierOut, 'ui-settings.js') await expect(stat(settingsPath)).resolves.toBeDefined() - expect(await readFile(settingsPath, 'utf-8')).toEqual( + expect(await readFile(settingsPath, 'utf-8')).toBe( `window.uiSettings = ${JSON.stringify(uiSettings)};` ) }) @@ -517,10 +523,12 @@ new Workbench({ }) }) + // eslint-disable-next-line vitest/expect-expect -- expectWorkframeAndAssets contains expectations it(`generated workframe file with its assets`, async () => { await expectWorkframeAndAssets(atelierOut) }) + // eslint-disable-next-line vitest/expect-expect -- expectWorkframeAndAssets contains expectations it(`included ui distribution`, async () => { await expectUiDistribution(atelierOut) }) @@ -540,10 +548,12 @@ new Workbench({ }) }) + // eslint-disable-next-line vitest/expect-expect -- expectWorkframeAndAssets contains expectations it(`generated workframe file with its assets`, async () => { await expectWorkframeAndAssets(atelierOut) }) + // eslint-disable-next-line vitest/expect-expect -- expectWorkframeAndAssets contains expectations it(`included ui distribution`, async () => { await expectUiDistribution(atelierOut) }) @@ -563,10 +573,12 @@ new Workbench({ }) }) + // eslint-disable-next-line vitest/expect-expect -- expectWorkframeAndAssets contains expectations it(`generated workframe file with its assets`, async () => { await expectWorkframeAndAssets(atelierOut) }) + // eslint-disable-next-line vitest/expect-expect -- expectWorkframeAndAssets contains expectations it(`included ui distribution`, async () => { await expectUiDistribution(atelierOut) }) @@ -627,9 +639,9 @@ new Workbench({ async function expectWorkframeAndAssets(atelierOut) { const workframeHtmlPath = resolve(atelierOut, 'workframe.html') const workframeJsRegExp = - /