From c75c42949b3364d74089f1912900a7901f4079b4 Mon Sep 17 00:00:00 2001 From: paoloricciuti <ricciutipaolo@gmail.com> Date: Thu, 20 Mar 2025 14:45:32 +0100 Subject: [PATCH] chore: run test suite on both `functional` and `string` templating --- packages/svelte/package.json | 2 +- packages/svelte/src/internal/server/dev.js | 2 +- packages/svelte/tests/helpers.js | 9 +- packages/svelte/tests/hydration/test.ts | 29 +- packages/svelte/tests/runtime-browser/test.ts | 44 ++- .../main.svelte | 5 +- .../main.svelte | 6 +- .../window-binding-scroll-store/_config.js | 3 +- .../svelte/tests/runtime-legacy/shared.ts | 53 +++- packages/svelte/tests/runtime-legacy/test.ts | 3 +- .../custom-element-attributes/main.svelte | 26 +- packages/svelte/tests/runtime-runes/test.ts | 3 +- .../client-functional/index.svelte.js | 52 ++++ .../client-functional/index.svelte.js | 45 +++ .../client-functional/index.svelte.js | 7 + .../client-functional/index.svelte.js | 27 ++ .../client-functional/index.svelte.js | 16 + .../client-functional/main.svelte.js | 53 ++++ .../client-functional/index.svelte.js | 19 ++ .../client-functional/index.svelte.js | 4 + .../client-functional/index.svelte.js | 27 ++ .../client-functional/index.svelte.js | 21 ++ .../client-functional/index.svelte.js | 32 ++ .../_expected/client-functional/export.js | 1 + .../client-functional/index.svelte.js | 8 + .../client-functional/module.svelte.js | 5 + .../client-functional/index.svelte.js | 54 ++++ .../client-functional/index.svelte.js | 17 ++ .../client-functional/index.svelte.js | 34 +++ .../client-functional/index.svelte.js | 283 ++++++++++++++++++ .../client-functional/index.svelte.js | 50 ++++ .../client-functional/index.svelte.js | 11 + .../client-functional/index.svelte.js | 34 +++ packages/svelte/tests/snapshot/test.ts | 14 +- packages/svelte/tests/suite.ts | 42 ++- pnpm-lock.yaml | 2 +- 36 files changed, 975 insertions(+), 68 deletions(-) create mode 100644 packages/svelte/tests/snapshot/samples/await-block-scope/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/bind-this/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/destructured-assignments/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/dynamic-attributes-casing/_expected/client-functional/main.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/each-string-template/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/export-state/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/hello-world/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/hmr/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/imports-in-modules/_expected/client-functional/export.js create mode 100644 packages/svelte/tests/snapshot/samples/imports-in-modules/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/imports-in-modules/_expected/client-functional/module.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/nullish-coallescence-omittance/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/props-identifier/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/purity/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/state-proxy-literal/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/svelte-element/_expected/client-functional/index.svelte.js create mode 100644 packages/svelte/tests/snapshot/samples/text-nodes-deriveds/_expected/client-functional/index.svelte.js diff --git a/packages/svelte/package.json b/packages/svelte/package.json index 6f10b2a9ea..9e9f5c8a8d 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -149,9 +149,9 @@ "dependencies": { "@ampproject/remapping": "^2.3.0", "@jridgewell/sourcemap-codec": "^1.5.0", + "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", - "@sveltejs/acorn-typescript": "^1.0.5", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", diff --git a/packages/svelte/src/internal/server/dev.js b/packages/svelte/src/internal/server/dev.js index ecf4e67429..6ff5426818 100644 --- a/packages/svelte/src/internal/server/dev.js +++ b/packages/svelte/src/internal/server/dev.js @@ -22,7 +22,7 @@ import { current_component } from './context.js'; let parent = null; /** @type {Set<string>} */ -let seen; +export let seen; /** * @param {Element} element diff --git a/packages/svelte/tests/helpers.js b/packages/svelte/tests/helpers.js index 87bcb473e7..164d855e89 100644 --- a/packages/svelte/tests/helpers.js +++ b/packages/svelte/tests/helpers.js @@ -58,15 +58,17 @@ export function create_deferred() { * @param {Partial<CompileOptions>} compileOptions * @param {boolean} [output_map] * @param {any} [preprocessor] + * @param {import('./suite').TemplatingMode} [templating_mode] */ export async function compile_directory( cwd, generate, compileOptions = {}, output_map = false, - preprocessor + preprocessor, + templating_mode ) { - const output_dir = `${cwd}/_output/${generate}`; + const output_dir = `${cwd}/_output/${generate}${templating_mode === 'functional' ? `-${templating_mode}` : ''}`; fs.rmSync(output_dir, { recursive: true, force: true }); @@ -77,7 +79,8 @@ export async function compile_directory( let opts = { filename: path.join(cwd, file), ...compileOptions, - generate + generate, + preventTemplateCloning: templating_mode === 'functional' }; if (file.endsWith('.js')) { diff --git a/packages/svelte/tests/hydration/test.ts b/packages/svelte/tests/hydration/test.ts index 266ac07bff..0fc5187733 100644 --- a/packages/svelte/tests/hydration/test.ts +++ b/packages/svelte/tests/hydration/test.ts @@ -41,10 +41,24 @@ function read(path: string): string | void { return fs.existsSync(path) ? fs.readFileSync(path, 'utf-8') : undefined; } -const { test, run } = suite<HydrationTest>(async (config, cwd) => { +const { test, run } = suite<HydrationTest>(async (config, cwd, templating_mode) => { if (!config.load_compiled) { - await compile_directory(cwd, 'client', { accessors: true, ...config.compileOptions }); - await compile_directory(cwd, 'server', config.compileOptions); + await compile_directory( + cwd, + 'client', + { accessors: true, ...config.compileOptions }, + undefined, + undefined, + templating_mode + ); + await compile_directory( + cwd, + 'server', + config.compileOptions, + undefined, + undefined, + templating_mode + ); } const target = window.document.body; @@ -102,7 +116,11 @@ const { test, run } = suite<HydrationTest>(async (config, cwd) => { }; const component = createClassComponent({ - component: (await import(`${cwd}/_output/client/main.svelte.js`)).default, + component: ( + await import( + `${cwd}/_output/client${templating_mode === 'functional' ? '-functional' : ''}/main.svelte.js` + ) + ).default, target, hydrate: true, props: config.props, @@ -169,4 +187,5 @@ const { test, run } = suite<HydrationTest>(async (config, cwd) => { }); export { test, assert_ok }; -await run(__dirname); +await run(__dirname, 'string'); +await run(__dirname, 'functional'); diff --git a/packages/svelte/tests/runtime-browser/test.ts b/packages/svelte/tests/runtime-browser/test.ts index 582a10edf7..0f7b259715 100644 --- a/packages/svelte/tests/runtime-browser/test.ts +++ b/packages/svelte/tests/runtime-browser/test.ts @@ -4,7 +4,7 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import { compile } from 'svelte/compiler'; import { afterAll, assert, beforeAll, describe } from 'vitest'; -import { suite, suite_with_variants } from '../suite'; +import { suite, suite_with_variants, type TemplatingMode } from '../suite'; import { write } from '../helpers'; import type { Warning } from '#compiler'; @@ -35,27 +35,41 @@ const { run: run_browser_tests } = suite_with_variants< return false; }, () => {}, - async (config, test_dir, variant) => { - await run_test(test_dir, config, variant === 'hydrate'); + async (config, test_dir, variant, _, templating_mode) => { + await run_test(test_dir, config, variant === 'hydrate', templating_mode); } ); describe.concurrent( 'runtime-browser', - () => run_browser_tests(__dirname), + () => run_browser_tests(__dirname, 'string'), + // Browser tests are brittle and slow on CI + { timeout: 20000, retry: process.env.CI ? 1 : 0 } +); + +describe.concurrent( + 'runtime-browser-functional', + () => run_browser_tests(__dirname, 'functional'), // Browser tests are brittle and slow on CI { timeout: 20000, retry: process.env.CI ? 1 : 0 } ); const { run: run_ce_tests } = suite<ReturnType<typeof import('./assert').test>>( - async (config, test_dir) => { - await run_test(test_dir, config, false); + async (config, test_dir, templating_mode) => { + await run_test(test_dir, config, false, templating_mode); } ); describe.concurrent( 'custom-elements', - () => run_ce_tests(__dirname, 'custom-elements-samples'), + () => run_ce_tests(__dirname, 'string', 'custom-elements-samples'), + // Browser tests are brittle and slow on CI + { timeout: 20000, retry: process.env.CI ? 1 : 0 } +); + +describe.concurrent( + 'custom-elements', + () => run_ce_tests(__dirname, 'functional', 'custom-elements-samples'), // Browser tests are brittle and slow on CI { timeout: 20000, retry: process.env.CI ? 1 : 0 } ); @@ -63,7 +77,8 @@ describe.concurrent( async function run_test( test_dir: string, config: ReturnType<typeof import('./assert').test>, - hydrate: boolean + hydrate: boolean, + templating_mode: TemplatingMode ) { const warnings: any[] = []; @@ -90,10 +105,14 @@ async function run_test( ...config.compileOptions, immutable: config.immutable, customElement: test_dir.includes('custom-elements-samples'), - accessors: 'accessors' in config ? config.accessors : true + accessors: 'accessors' in config ? config.accessors : true, + preventTemplateCloning: templating_mode === 'functional' }); - write(`${test_dir}/_output/client/${path.basename(args.path)}.js`, compiled.js.code); + write( + `${test_dir}/_output/client${templating_mode === 'functional' ? '-functional' : ''}/${path.basename(args.path)}.js`, + compiled.js.code + ); compiled.warnings.forEach((warning) => { if (warning.code === 'options_deprecated_accessors') return; @@ -103,7 +122,7 @@ async function run_test( if (compiled.css !== null) { compiled.js.code += `document.head.innerHTML += \`<style>${compiled.css.code}</style>\``; write( - `${test_dir}/_output/client/${path.basename(args.path)}.css`, + `${test_dir}/_output/${templating_mode === 'functional' ? '-functional' : ''}/${path.basename(args.path)}.css`, compiled.css.code ); } @@ -151,7 +170,8 @@ async function run_test( ...config.compileOptions, immutable: config.immutable, customElement: test_dir.includes('custom-elements-samples'), - accessors: 'accessors' in config ? config.accessors : true + accessors: 'accessors' in config ? config.accessors : true, + preventTemplateCloning: templating_mode === 'functional' }); return { diff --git a/packages/svelte/tests/runtime-legacy/samples/attribute-casing-custom-element/main.svelte b/packages/svelte/tests/runtime-legacy/samples/attribute-casing-custom-element/main.svelte index 6433d0dc76..81c855676a 100644 --- a/packages/svelte/tests/runtime-legacy/samples/attribute-casing-custom-element/main.svelte +++ b/packages/svelte/tests/runtime-legacy/samples/attribute-casing-custom-element/main.svelte @@ -18,8 +18,9 @@ this.innerHTML = 'Hello ' + this._obj.text + '!'; } } - - window.customElements.define('my-custom-element', MyCustomElement); + if(!window.customElements.get('my-custom-element')) { + window.customElements.define('my-custom-element', MyCustomElement); + } </script> <my-custom-element camelCase={{ text: 'World' }} /> diff --git a/packages/svelte/tests/runtime-legacy/samples/attribute-custom-element-inheritance/main.svelte b/packages/svelte/tests/runtime-legacy/samples/attribute-custom-element-inheritance/main.svelte index 1324bcc4b1..04ac58435a 100644 --- a/packages/svelte/tests/runtime-legacy/samples/attribute-custom-element-inheritance/main.svelte +++ b/packages/svelte/tests/runtime-legacy/samples/attribute-custom-element-inheritance/main.svelte @@ -26,8 +26,10 @@ } class Extended extends MyCustomElement {} - - window.customElements.define('my-custom-inheritance-element', Extended); + + if(!window.customElements.get('my-custom-inheritance-element')) { + window.customElements.define('my-custom-inheritance-element', Extended); + } </script> <my-custom-inheritance-element camelCase={{ text: 'World' }} text="!" /> diff --git a/packages/svelte/tests/runtime-legacy/samples/window-binding-scroll-store/_config.js b/packages/svelte/tests/runtime-legacy/samples/window-binding-scroll-store/_config.js index 115c3cfd38..b9ea2fb27b 100644 --- a/packages/svelte/tests/runtime-legacy/samples/window-binding-scroll-store/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/window-binding-scroll-store/_config.js @@ -9,7 +9,8 @@ export default test({ Object.defineProperties(window, { scrollY: { value: 0, - configurable: true + configurable: true, + writable: true } }); original_scrollTo = window.scrollTo; diff --git a/packages/svelte/tests/runtime-legacy/shared.ts b/packages/svelte/tests/runtime-legacy/shared.ts index fc748ce6b2..8acac668f9 100644 --- a/packages/svelte/tests/runtime-legacy/shared.ts +++ b/packages/svelte/tests/runtime-legacy/shared.ts @@ -10,7 +10,8 @@ import { compile_directory } from '../helpers.js'; import { setup_html_equal } from '../html_equal.js'; import { raf } from '../animation-helpers.js'; import type { CompileOptions } from '#compiler'; -import { suite_with_variants, type BaseTest } from '../suite.js'; +import { suite_with_variants, type BaseTest, type TemplatingMode } from '../suite.js'; +import { seen } from '../../src/internal/server/dev.js'; type Assert = typeof import('vitest').assert & { htmlEqual(a: string, b: string, description?: string): void; @@ -141,16 +142,21 @@ export function runtime_suite(runes: boolean) { return false; }, - (config, cwd) => { - return common_setup(cwd, runes, config); + (config, cwd, templating_mode) => { + return common_setup(cwd, runes, config, templating_mode); }, - async (config, cwd, variant, common) => { - await run_test_variant(cwd, config, variant, common, runes); + async (config, cwd, variant, common, templating_mode) => { + await run_test_variant(cwd, config, variant, common, runes, templating_mode); } ); } -async function common_setup(cwd: string, runes: boolean | undefined, config: RuntimeTest) { +async function common_setup( + cwd: string, + runes: boolean | undefined, + config: RuntimeTest, + templating_mode: TemplatingMode +) { const force_hmr = process.env.HMR && config.compileOptions?.dev !== false && !config.error; const compileOptions: CompileOptions = { @@ -161,13 +167,14 @@ async function common_setup(cwd: string, runes: boolean | undefined, config: Run ...config.compileOptions, immutable: config.immutable, accessors: 'accessors' in config ? config.accessors : true, - runes + runes, + preventTemplateCloning: templating_mode === 'functional' }; // load_compiled can be used for debugging a test. It means the compiler will not run on the input // so you can manipulate the output manually to see what fixes it, adding console.logs etc. if (!config.load_compiled) { - await compile_directory(cwd, 'client', compileOptions); + await compile_directory(cwd, 'client', compileOptions, undefined, undefined, templating_mode); await compile_directory(cwd, 'server', compileOptions); } @@ -179,7 +186,8 @@ async function run_test_variant( config: RuntimeTest, variant: 'dom' | 'hydrate' | 'ssr', compileOptions: CompileOptions, - runes: boolean + runes: boolean, + templating_mode: TemplatingMode ) { let unintended_error = false; @@ -257,8 +265,15 @@ async function run_test_variant( raf.reset(); // Put things we need on window for testing - const styles = globSync('**/*.css', { cwd: `${cwd}/_output/client` }) - .map((file) => fs.readFileSync(`${cwd}/_output/client/${file}`, 'utf-8')) + const styles = globSync('**/*.css', { + cwd: `${cwd}/_output/client${templating_mode === 'functional' ? '-functional' : ''}` + }) + .map((file) => + fs.readFileSync( + `${cwd}/_output/client${templating_mode === 'functional' ? '-functional' : ''}/${file}`, + 'utf-8' + ) + ) .join('\n') .replace(/\/\*<\/?style>\*\//g, ''); @@ -274,7 +289,9 @@ async function run_test_variant( globalThis.requestAnimationFrame = globalThis.setTimeout; - let mod = await import(`${cwd}/_output/client/main.svelte.js`); + let mod = await import( + `${cwd}/_output/client${templating_mode === 'functional' ? '-functional' : ''}/main.svelte.js` + ); const target = window.document.querySelector('main') as HTMLElement; @@ -282,6 +299,8 @@ async function run_test_variant( if (variant === 'hydrate' || variant === 'ssr') { config.before_test?.(); + // we need to clear the seen messages between tests + seen?.clear?.(); // ssr into target const SsrSvelteComponent = (await import(`${cwd}/_output/server/main.svelte.js`)).default; const { html, head } = render(SsrSvelteComponent, { @@ -289,11 +308,17 @@ async function run_test_variant( idPrefix: config.id_prefix }); - fs.writeFileSync(`${cwd}/_output/rendered.html`, html); + fs.writeFileSync( + `${cwd}/_output/rendered${templating_mode === 'functional' ? '-functional' : ''}.html`, + html + ); target.innerHTML = html; if (head) { - fs.writeFileSync(`${cwd}/_output/rendered_head.html`, head); + fs.writeFileSync( + `${cwd}/_output/rendered_head${templating_mode === 'functional' ? '-functional' : ''}.html`, + head + ); window.document.head.innerHTML = window.document.head.innerHTML + head; } diff --git a/packages/svelte/tests/runtime-legacy/test.ts b/packages/svelte/tests/runtime-legacy/test.ts index c4617a571c..d422d8a336 100644 --- a/packages/svelte/tests/runtime-legacy/test.ts +++ b/packages/svelte/tests/runtime-legacy/test.ts @@ -11,4 +11,5 @@ const { test, run } = runtime_suite(false); export { test, ok }; -await run(__dirname); +await run(__dirname, 'string'); +await run(__dirname, 'functional'); diff --git a/packages/svelte/tests/runtime-runes/samples/custom-element-attributes/main.svelte b/packages/svelte/tests/runtime-runes/samples/custom-element-attributes/main.svelte index 4c98245e5b..82774f160d 100644 --- a/packages/svelte/tests/runtime-runes/samples/custom-element-attributes/main.svelte +++ b/packages/svelte/tests/runtime-runes/samples/custom-element-attributes/main.svelte @@ -1,18 +1,20 @@ <script module> - customElements.define('value-element', class extends HTMLElement { + if(!customElements.get('value-element')) { + customElements.define('value-element', class extends HTMLElement { - constructor() { - super(); - this.attachShadow({ mode: 'open' }); - } + constructor() { + super(); + this.attachShadow({ mode: 'open' }); + } - set value(v) { - if (this.__value !== v) { - this.__value = v; - this.shadowRoot.innerHTML = `<span>${v}</span>`; - } - } - }); + set value(v) { + if (this.__value !== v) { + this.__value = v; + this.shadowRoot.innerHTML = `<span>${v}</span>`; + } + } + }); + } </script> <my-element string="test" object={{ test: true }}></my-element> diff --git a/packages/svelte/tests/runtime-runes/test.ts b/packages/svelte/tests/runtime-runes/test.ts index 0806864060..5dafe62ad2 100644 --- a/packages/svelte/tests/runtime-runes/test.ts +++ b/packages/svelte/tests/runtime-runes/test.ts @@ -5,4 +5,5 @@ const { test, run } = runtime_suite(true); export { test, ok }; -await run(__dirname); +await run(__dirname, 'string'); +await run(__dirname, 'functional'); diff --git a/packages/svelte/tests/snapshot/samples/await-block-scope/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/await-block-scope/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..262454e9c3 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/await-block-scope/_expected/client-functional/index.svelte.js @@ -0,0 +1,52 @@ +import 'svelte/internal/disclose-version'; +import * as $ from 'svelte/internal/client'; + +function increment(_, counter) { + counter.count += 1; +} + +var root = $.template_fn( + () => { + var button = document.createElement('button'); + var text = document.createTextNode(' '); + + button.insertBefore(text, undefined) + + var text_1 = document.createTextNode(' '); + var comment = document.createComment(''); + var text_2 = document.createTextNode(' '); + var fragment = document.createDocumentFragment(); + + fragment.append(button, text_1, comment, text_2) + return fragment; + }, + 1 +); + +export default function Await_block_scope($$anchor) { + let counter = $.proxy({ count: 0 }); + const promise = $.derived(() => Promise.resolve(counter)); + var fragment = root(); + var button = $.first_child(fragment); + + button.__click = [increment, counter]; + + var text = $.child(button); + + $.reset(button); + + var node = $.sibling(button, 2); + + $.await(node, () => $.get(promise), null, ($$anchor, counter) => {}); + + var text_1 = $.sibling(node); + + $.template_effect(() => { + $.set_text(text, `clicks: ${counter.count ?? ''}`); + $.set_text(text_1, ` ${counter.count ?? ''}`); + }); + + $.append($$anchor, fragment); +} + +$.delegate(['click']); \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..e4b1e2d1e0 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/bind-component-snippet/_expected/client-functional/index.svelte.js @@ -0,0 +1,45 @@ +import 'svelte/internal/disclose-version'; +import * as $ from 'svelte/internal/client'; +import TextInput from './Child.svelte'; + +const snippet = ($$anchor) => { + $.next(); + + var text = $.text('Something'); + + $.append($$anchor, text); +}; + +var root = $.template_fn( + () => { + var comment = document.createComment(''); + var comment_1 = document.createComment(''); + var text = document.createTextNode(' '); + var fragment = document.createDocumentFragment(); + + fragment.append(comment, comment_1, text) + return fragment; + }, + 1 +); + +export default function Bind_component_snippet($$anchor) { + let value = $.state(''); + const _snippet = snippet; + var fragment = root(); + var node = $.first_child(fragment); + + TextInput(node, { + get value() { + return $.get(value); + }, + set value($$value) { + $.set(value, $.proxy($$value)); + } + }); + + var text_1 = $.sibling(node); + + $.template_effect(() => $.set_text(text_1, ` value: ${$.get(value) ?? ''}`)); + $.append($$anchor, fragment); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/bind-this/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/bind-this/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..dfd32a04e5 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/bind-this/_expected/client-functional/index.svelte.js @@ -0,0 +1,7 @@ +import 'svelte/internal/disclose-version'; +import 'svelte/internal/flags/legacy'; +import * as $ from 'svelte/internal/client'; + +export default function Bind_this($$anchor) { + $.bind_this(Foo($$anchor, { $$legacy: true }), ($$value) => foo = $$value, () => foo); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..2898f31a6f --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/class-state-field-constructor-assignment/_expected/client-functional/index.svelte.js @@ -0,0 +1,27 @@ +import 'svelte/internal/disclose-version'; +import * as $ from 'svelte/internal/client'; + +export default function Class_state_field_constructor_assignment($$anchor, $$props) { + $.push($$props, true); + + class Foo { + #a = $.state(); + + get a() { + return $.get(this.#a); + } + + set a(value) { + $.set(this.#a, $.proxy(value)); + } + + #b = $.state(); + + constructor() { + this.a = 1; + this.#b.v = 2; + } + } + + $.pop(); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/destructured-assignments/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/destructured-assignments/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..9651713c52 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/destructured-assignments/_expected/client-functional/index.svelte.js @@ -0,0 +1,16 @@ +/* index.svelte.js generated by Svelte VERSION */ +import * as $ from 'svelte/internal/client'; + +let a = $.state(1); +let b = $.state(2); +let c = 3; +let d = 4; + +export function update(array) { + ( + $.set(a, $.proxy(array[0])), + $.set(b, $.proxy(array[1])) + ); + + [c, d] = array; +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/dynamic-attributes-casing/_expected/client-functional/main.svelte.js b/packages/svelte/tests/snapshot/samples/dynamic-attributes-casing/_expected/client-functional/main.svelte.js new file mode 100644 index 0000000000..c05184f1f8 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/dynamic-attributes-casing/_expected/client-functional/main.svelte.js @@ -0,0 +1,53 @@ +import 'svelte/internal/disclose-version'; +import * as $ from 'svelte/internal/client'; + +var root = $.template_fn( + () => { + var div = document.createElement('div'); + var text = document.createTextNode(' '); + var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + var text_1 = document.createTextNode(' '); + var custom_element = document.createElement('custom-element'); + var text_2 = document.createTextNode(' '); + var div_1 = document.createElement('div'); + var text_3 = document.createTextNode(' '); + var svg_1 = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + var text_4 = document.createTextNode(' '); + var custom_element_1 = document.createElement('custom-element'); + var fragment = document.createDocumentFragment(); + + fragment.append(div, text, svg, text_1, custom_element, text_2, div_1, text_3, svg_1, text_4, custom_element_1) + return fragment; + }, + 3 +); + +export default function Main($$anchor) { + // needs to be a snapshot test because jsdom does auto-correct the attribute casing + let x = 'test'; + let y = () => 'test'; + var fragment = root(); + var div = $.first_child(fragment); + var svg = $.sibling(div, 2); + var custom_element = $.sibling(svg, 2); + + $.template_effect(() => $.set_custom_element_data(custom_element, 'fooBar', x)); + + var div_1 = $.sibling(custom_element, 2); + var svg_1 = $.sibling(div_1, 2); + var custom_element_1 = $.sibling(svg_1, 2); + + $.template_effect(() => $.set_custom_element_data(custom_element_1, 'fooBar', y())); + + $.template_effect( + ($0, $1) => { + $.set_attribute(div, 'foobar', x); + $.set_attribute(svg, 'viewBox', x); + $.set_attribute(div_1, 'foobar', $0); + $.set_attribute(svg_1, 'viewBox', $1); + }, + [y, y] + ); + + $.append($$anchor, fragment); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/each-string-template/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/each-string-template/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..c0626bd416 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/each-string-template/_expected/client-functional/index.svelte.js @@ -0,0 +1,19 @@ +import 'svelte/internal/disclose-version'; +import 'svelte/internal/flags/legacy'; +import * as $ from 'svelte/internal/client'; + +export default function Each_string_template($$anchor) { + var fragment = $.comment(); + var node = $.first_child(fragment); + + $.each(node, 0, () => ['foo', 'bar', 'baz'], $.index, ($$anchor, thing) => { + $.next(); + + var text = $.text(); + + $.template_effect(() => $.set_text(text, `${thing ?? ''}, `)); + $.append($$anchor, text); + }); + + $.append($$anchor, fragment); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/export-state/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/export-state/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..c2a6054bc6 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/export-state/_expected/client-functional/index.svelte.js @@ -0,0 +1,4 @@ +/* index.svelte.js generated by Svelte VERSION */ +import * as $ from 'svelte/internal/client'; + +export const object = $.proxy({ ok: true }); \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..c545608bca --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/function-prop-no-getter/_expected/client-functional/index.svelte.js @@ -0,0 +1,27 @@ +import 'svelte/internal/disclose-version'; +import * as $ from 'svelte/internal/client'; + +export default function Function_prop_no_getter($$anchor) { + let count = $.state(0); + + function onmouseup() { + $.set(count, $.get(count) + 2); + } + + const plusOne = (num) => num + 1; + + Button($$anchor, { + onmousedown: () => $.set(count, $.get(count) + 1), + onmouseup, + onmouseenter: () => $.set(count, $.proxy(plusOne($.get(count)))), + children: ($$anchor, $$slotProps) => { + $.next(); + + var text = $.text(); + + $.template_effect(() => $.set_text(text, `clicks: ${$.get(count) ?? ''}`)); + $.append($$anchor, text); + }, + $$slots: { default: true } + }); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/hello-world/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/hello-world/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..5f55a12c20 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/hello-world/_expected/client-functional/index.svelte.js @@ -0,0 +1,21 @@ +import 'svelte/internal/disclose-version'; +import 'svelte/internal/flags/legacy'; +import * as $ from 'svelte/internal/client'; + +var root = $.template_fn(() => { + var h1 = document.createElement('h1'); + var text = document.createTextNode('hello world'); + + h1.insertBefore(text, undefined) + + var fragment = document.createDocumentFragment(); + + fragment.append(h1) + return fragment; +}); + +export default function Hello_world($$anchor) { + var h1 = root(); + + $.append($$anchor, h1); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/hmr/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/hmr/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..6196ed18bb --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/hmr/_expected/client-functional/index.svelte.js @@ -0,0 +1,32 @@ +import 'svelte/internal/disclose-version'; +import 'svelte/internal/flags/legacy'; +import * as $ from 'svelte/internal/client'; + +var root = $.template_fn(() => { + var h1 = document.createElement('h1'); + var text = document.createTextNode('hello world'); + + h1.insertBefore(text, undefined) + + var fragment = document.createDocumentFragment(); + + fragment.append(h1) + return fragment; +}); + +function Hmr($$anchor) { + var h1 = root(); + + $.append($$anchor, h1); +} + +if (import.meta.hot) { + Hmr = $.hmr(Hmr, () => Hmr[$.HMR].source); + + import.meta.hot.accept((module) => { + module.default[$.HMR].source = Hmr[$.HMR].source; + $.set(Hmr[$.HMR].source, module.default[$.HMR].original); + }); +} + +export default Hmr; \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/imports-in-modules/_expected/client-functional/export.js b/packages/svelte/tests/snapshot/samples/imports-in-modules/_expected/client-functional/export.js new file mode 100644 index 0000000000..b4bb7075da --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/imports-in-modules/_expected/client-functional/export.js @@ -0,0 +1 @@ +export * from '../../export.js'; \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/imports-in-modules/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/imports-in-modules/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..ebbe191dcb --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/imports-in-modules/_expected/client-functional/index.svelte.js @@ -0,0 +1,8 @@ +import 'svelte/internal/disclose-version'; +import 'svelte/internal/flags/legacy'; +import * as $ from 'svelte/internal/client'; +import { random } from './module.svelte'; + +export default function Imports_in_modules($$anchor) { + +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/imports-in-modules/_expected/client-functional/module.svelte.js b/packages/svelte/tests/snapshot/samples/imports-in-modules/_expected/client-functional/module.svelte.js new file mode 100644 index 0000000000..0d366e6258 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/imports-in-modules/_expected/client-functional/module.svelte.js @@ -0,0 +1,5 @@ +/* module.svelte.js generated by Svelte VERSION */ +import * as $ from 'svelte/internal/client'; +import { random } from './export'; + +export { random }; \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/nullish-coallescence-omittance/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/nullish-coallescence-omittance/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..6b48b03635 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/nullish-coallescence-omittance/_expected/client-functional/index.svelte.js @@ -0,0 +1,54 @@ +import 'svelte/internal/disclose-version'; +import * as $ from 'svelte/internal/client'; + +var on_click = (_, count) => $.update(count); + +var root = $.template_fn( + () => { + var h1 = document.createElement('h1'); + var text = document.createTextNode(' '); + var b = document.createElement('b'); + var text_1 = document.createTextNode(' '); + var button = document.createElement('button'); + var text_2 = document.createTextNode(' '); + + button.insertBefore(text_2, undefined) + + var text_3 = document.createTextNode(' '); + var h1_1 = document.createElement('h1'); + var fragment = document.createDocumentFragment(); + + fragment.append(h1, text, b, text_1, button, text_3, h1_1) + return fragment; + }, + 1 +); + +export default function Nullish_coallescence_omittance($$anchor) { + let name = 'world'; + let count = $.state(0); + var fragment = root(); + var h1 = $.first_child(fragment); + + h1.textContent = `Hello, ${name ?? ''}!`; + + var b = $.sibling(h1, 2); + + b.textContent = `${1 ?? 'stuff'}${2 ?? 'more stuff'}${3 ?? 'even more stuff'}`; + + var button = $.sibling(b, 2); + + button.__click = [on_click, count]; + + var text = $.child(button); + + $.reset(button); + + var h1_1 = $.sibling(button, 2); + + h1_1.textContent = `Hello, ${name ?? 'earth' ?? ''}`; + $.template_effect(() => $.set_text(text, `Count is ${$.get(count) ?? ''}`)); + $.append($$anchor, fragment); +} + +$.delegate(['click']); \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/props-identifier/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/props-identifier/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..5a46b9bbef --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/props-identifier/_expected/client-functional/index.svelte.js @@ -0,0 +1,17 @@ +import 'svelte/internal/disclose-version'; +import * as $ from 'svelte/internal/client'; + +export default function Props_identifier($$anchor, $$props) { + $.push($$props, true); + + let props = $.rest_props($$props, ['$$slots', '$$events', '$$legacy']); + + $$props.a; + props[a]; + $$props.a.b; + $$props.a.b = true; + props.a = true; + props[a] = true; + props; + $.pop(); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/purity/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/purity/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..409a0d93aa --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/purity/_expected/client-functional/index.svelte.js @@ -0,0 +1,34 @@ +import 'svelte/internal/disclose-version'; +import 'svelte/internal/flags/legacy'; +import * as $ from 'svelte/internal/client'; + +var root = $.template_fn( + () => { + var p = document.createElement('p'); + var text = document.createTextNode(' '); + var p_1 = document.createElement('p'); + var text_1 = document.createTextNode(' '); + var comment = document.createComment(''); + var fragment = document.createDocumentFragment(); + + fragment.append(p, text, p_1, text_1, comment) + return fragment; + }, + 1 +); + +export default function Purity($$anchor) { + var fragment = root(); + var p = $.first_child(fragment); + + p.textContent = Math.max(0, Math.min(0, 100)); + + var p_1 = $.sibling(p, 2); + + p_1.textContent = location.href; + + var node = $.sibling(p_1, 2); + + Child(node, { prop: encodeURIComponent('hello') }); + $.append($$anchor, fragment); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..8023738996 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/client-functional/index.svelte.js @@ -0,0 +1,283 @@ +import 'svelte/internal/disclose-version'; +import * as $ from 'svelte/internal/client'; + +var root = $.template_fn( + () => { + var header = document.createElement('header'); + var nav = document.createElement('nav'); + + header.insertBefore(nav, undefined) + + var a = document.createElement('a'); + + nav.insertBefore(a, undefined) + a.setAttribute('href', '/') + + var text = document.createTextNode('Home'); + + a.insertBefore(text, undefined) + + var text_1 = document.createTextNode(' '); + + nav.insertBefore(text_1, undefined) + + var a_1 = document.createElement('a'); + + nav.insertBefore(a_1, undefined) + a_1.setAttribute('href', '/away') + + var text_2 = document.createTextNode('Away'); + + a_1.insertBefore(text_2, undefined) + + var text_3 = document.createTextNode(' '); + var main = document.createElement('main'); + var h1 = document.createElement('h1'); + + main.insertBefore(h1, undefined) + + var text_4 = document.createTextNode(' '); + + h1.insertBefore(text_4, undefined) + + var text_5 = document.createTextNode(' '); + + main.insertBefore(text_5, undefined) + + var div = document.createElement('div'); + + main.insertBefore(div, undefined) + div.setAttribute('class', 'static') + + var p = document.createElement('p'); + + div.insertBefore(p, undefined) + + var text_6 = document.createTextNode('we don\'t need to traverse these nodes'); + + p.insertBefore(text_6, undefined) + + var text_7 = document.createTextNode(' '); + + main.insertBefore(text_7, undefined) + + var p_1 = document.createElement('p'); + + main.insertBefore(p_1, undefined) + + var text_8 = document.createTextNode('or'); + + p_1.insertBefore(text_8, undefined) + + var text_9 = document.createTextNode(' '); + + main.insertBefore(text_9, undefined) + + var p_2 = document.createElement('p'); + + main.insertBefore(p_2, undefined) + + var text_10 = document.createTextNode('these'); + + p_2.insertBefore(text_10, undefined) + + var text_11 = document.createTextNode(' '); + + main.insertBefore(text_11, undefined) + + var p_3 = document.createElement('p'); + + main.insertBefore(p_3, undefined) + + var text_12 = document.createTextNode('ones'); + + p_3.insertBefore(text_12, undefined) + + var text_13 = document.createTextNode(' '); + + main.insertBefore(text_13, undefined) + + var comment = document.createComment(''); + + main.insertBefore(comment, undefined) + + var text_14 = document.createTextNode(' '); + + main.insertBefore(text_14, undefined) + + var p_4 = document.createElement('p'); + + main.insertBefore(p_4, undefined) + + var text_15 = document.createTextNode('these'); + + p_4.insertBefore(text_15, undefined) + + var text_16 = document.createTextNode(' '); + + main.insertBefore(text_16, undefined) + + var p_5 = document.createElement('p'); + + main.insertBefore(p_5, undefined) + + var text_17 = document.createTextNode('trailing'); + + p_5.insertBefore(text_17, undefined) + + var text_18 = document.createTextNode(' '); + + main.insertBefore(text_18, undefined) + + var p_6 = document.createElement('p'); + + main.insertBefore(p_6, undefined) + + var text_19 = document.createTextNode('nodes'); + + p_6.insertBefore(text_19, undefined) + + var text_20 = document.createTextNode(' '); + + main.insertBefore(text_20, undefined) + + var p_7 = document.createElement('p'); + + main.insertBefore(p_7, undefined) + + var text_21 = document.createTextNode('can'); + + p_7.insertBefore(text_21, undefined) + + var text_22 = document.createTextNode(' '); + + main.insertBefore(text_22, undefined) + + var p_8 = document.createElement('p'); + + main.insertBefore(p_8, undefined) + + var text_23 = document.createTextNode('be'); + + p_8.insertBefore(text_23, undefined) + + var text_24 = document.createTextNode(' '); + + main.insertBefore(text_24, undefined) + + var p_9 = document.createElement('p'); + + main.insertBefore(p_9, undefined) + + var text_25 = document.createTextNode('completely'); + + p_9.insertBefore(text_25, undefined) + + var text_26 = document.createTextNode(' '); + + main.insertBefore(text_26, undefined) + + var p_10 = document.createElement('p'); + + main.insertBefore(p_10, undefined) + + var text_27 = document.createTextNode('ignored'); + + p_10.insertBefore(text_27, undefined) + + var text_28 = document.createTextNode(' '); + var cant_skip = document.createElement('cant-skip'); + var custom_elements = document.createElement('custom-elements'); + + cant_skip.insertBefore(custom_elements, undefined) + + var text_29 = document.createTextNode(' '); + var div_1 = document.createElement('div'); + var input = document.createElement('input'); + + div_1.insertBefore(input, undefined) + + var text_30 = document.createTextNode(' '); + var div_2 = document.createElement('div'); + var source = document.createElement('source'); + + div_2.insertBefore(source, undefined) + + var text_31 = document.createTextNode(' '); + var select = document.createElement('select'); + var option = document.createElement('option'); + + select.insertBefore(option, undefined) + + var text_32 = document.createTextNode('a'); + + option.insertBefore(text_32, undefined) + + var text_33 = document.createTextNode(' '); + var img = document.createElement('img'); + + img.setAttribute('src', '...') + img.setAttribute('alt', '') + img.setAttribute('loading', 'lazy') + + var text_34 = document.createTextNode(' '); + var div_3 = document.createElement('div'); + var img_1 = document.createElement('img'); + + div_3.insertBefore(img_1, undefined) + img_1.setAttribute('src', '...') + img_1.setAttribute('alt', '') + img_1.setAttribute('loading', 'lazy') + + var fragment = document.createDocumentFragment(); + + fragment.append(header, text_3, main, text_28, cant_skip, text_29, div_1, text_30, div_2, text_31, select, text_33, img, text_34, div_3) + return fragment; + }, + 3 +); + +export default function Skip_static_subtree($$anchor, $$props) { + var fragment = root(); + var main = $.sibling($.first_child(fragment), 2); + var h1 = $.child(main); + var text = $.child(h1, true); + + $.reset(h1); + + var node = $.sibling(h1, 10); + + $.html(node, () => $$props.content, false, false); + $.next(14); + $.reset(main); + + var cant_skip = $.sibling(main, 2); + var custom_elements = $.child(cant_skip); + + $.set_custom_element_data(custom_elements, 'with', 'attributes'); + $.reset(cant_skip); + + var div = $.sibling(cant_skip, 2); + var input = $.child(div); + + $.autofocus(input, true); + $.reset(div); + + var div_1 = $.sibling(div, 2); + var source = $.child(div_1); + + source.muted = true; + $.reset(div_1); + + var select = $.sibling(div_1, 2); + var option = $.child(select); + + option.value = null == (option.__value = 'a') ? '' : 'a'; + $.reset(select); + + var img = $.sibling(select, 2); + + $.next(2); + $.template_effect(() => $.set_text(text, $$props.title)); + $.append($$anchor, fragment); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/state-proxy-literal/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/state-proxy-literal/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..4247dcfda3 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/state-proxy-literal/_expected/client-functional/index.svelte.js @@ -0,0 +1,50 @@ +import 'svelte/internal/disclose-version'; +import * as $ from 'svelte/internal/client'; + +function reset(_, str, tpl) { + $.set(str, ''); + $.set(str, ``); + $.set(tpl, ''); + $.set(tpl, ``); +} + +var root = $.template_fn( + () => { + var input = document.createElement('input'); + var text = document.createTextNode(' '); + var input_1 = document.createElement('input'); + var text_1 = document.createTextNode(' '); + var button = document.createElement('button'); + var text_2 = document.createTextNode('reset'); + + button.insertBefore(text_2, undefined) + + var fragment = document.createDocumentFragment(); + + fragment.append(input, text, input_1, text_1, button) + return fragment; + }, + 1 +); + +export default function State_proxy_literal($$anchor) { + let str = $.state(''); + let tpl = $.state(``); + var fragment = root(); + var input = $.first_child(fragment); + + $.remove_input_defaults(input); + + var input_1 = $.sibling(input, 2); + + $.remove_input_defaults(input_1); + + var button = $.sibling(input_1, 2); + + button.__click = [reset, str, tpl]; + $.bind_value(input, () => $.get(str), ($$value) => $.set(str, $$value)); + $.bind_value(input_1, () => $.get(tpl), ($$value) => $.set(tpl, $$value)); + $.append($$anchor, fragment); +} + +$.delegate(['click']); \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..2270005ee0 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/svelte-element/_expected/client-functional/index.svelte.js @@ -0,0 +1,11 @@ +import 'svelte/internal/disclose-version'; +import * as $ from 'svelte/internal/client'; + +export default function Svelte_element($$anchor, $$props) { + let tag = $.prop($$props, 'tag', 3, 'hr'); + var fragment = $.comment(); + var node = $.first_child(fragment); + + $.element(node, tag, false); + $.append($$anchor, fragment); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/text-nodes-deriveds/_expected/client-functional/index.svelte.js b/packages/svelte/tests/snapshot/samples/text-nodes-deriveds/_expected/client-functional/index.svelte.js new file mode 100644 index 0000000000..5163dc3509 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/text-nodes-deriveds/_expected/client-functional/index.svelte.js @@ -0,0 +1,34 @@ +import 'svelte/internal/disclose-version'; +import * as $ from 'svelte/internal/client'; + +var root = $.template_fn(() => { + var p = document.createElement('p'); + var text = document.createTextNode(' '); + + p.insertBefore(text, undefined) + + var fragment = document.createDocumentFragment(); + + fragment.append(p) + return fragment; +}); + +export default function Text_nodes_deriveds($$anchor) { + let count1 = 0; + let count2 = 0; + + function text1() { + return count1; + } + + function text2() { + return count2; + } + + var p = root(); + var text = $.child(p); + + $.reset(p); + $.template_effect(($0, $1) => $.set_text(text, `${$0 ?? ''}${$1 ?? ''}`), [text1, text2]); + $.append($$anchor, p); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/test.ts b/packages/svelte/tests/snapshot/test.ts index 0a591c6e2a..bbcee10d85 100644 --- a/packages/svelte/tests/snapshot/test.ts +++ b/packages/svelte/tests/snapshot/test.ts @@ -9,8 +9,15 @@ interface SnapshotTest extends BaseTest { compileOptions?: Partial<import('#compiler').CompileOptions>; } -const { test, run } = suite<SnapshotTest>(async (config, cwd) => { - await compile_directory(cwd, 'client', config.compileOptions); +const { test, run } = suite<SnapshotTest>(async (config, cwd, templating_mode) => { + await compile_directory( + cwd, + 'client', + config.compileOptions, + undefined, + undefined, + templating_mode + ); await compile_directory(cwd, 'server', config.compileOptions); // run `UPDATE_SNAPSHOTS=true pnpm test snapshot` to update snapshot tests @@ -41,4 +48,5 @@ const { test, run } = suite<SnapshotTest>(async (config, cwd) => { export { test }; -await run(__dirname); +await run(__dirname, 'string'); +await run(__dirname, 'functional'); diff --git a/packages/svelte/tests/suite.ts b/packages/svelte/tests/suite.ts index 0ae06e727f..c2e7743f2b 100644 --- a/packages/svelte/tests/suite.ts +++ b/packages/svelte/tests/suite.ts @@ -6,6 +6,8 @@ export interface BaseTest { solo?: boolean; } +export type TemplatingMode = 'string' | 'functional'; + /** * To filter tests, run one of these: * @@ -20,14 +22,22 @@ const filter = process.env.FILTER ) : /./; -export function suite<Test extends BaseTest>(fn: (config: Test, test_dir: string) => void) { +export function suite<Test extends BaseTest>( + fn: (config: Test, test_dir: string, templating_mode: TemplatingMode) => void +) { return { test: (config: Test) => config, - run: async (cwd: string, samples_dir = 'samples') => { + run: async ( + cwd: string, + templating_mode: TemplatingMode = 'string', + samples_dir = 'samples' + ) => { await for_each_dir<Test>(cwd, samples_dir, (config, dir) => { let it_fn = config.skip ? it.skip : config.solo ? it.only : it; - it_fn(dir, () => fn(config, `${cwd}/${samples_dir}/${dir}`)); + it_fn(`${dir} (${templating_mode})`, () => + fn(config, `${cwd}/${samples_dir}/${dir}`, templating_mode) + ); }); } }; @@ -36,12 +46,26 @@ export function suite<Test extends BaseTest>(fn: (config: Test, test_dir: string export function suite_with_variants<Test extends BaseTest, Variants extends string, Common>( variants: Variants[], should_skip_variant: (variant: Variants, config: Test) => boolean | 'no-test', - common_setup: (config: Test, test_dir: string) => Promise<Common> | Common, - fn: (config: Test, test_dir: string, variant: Variants, common: Common) => void + common_setup: ( + config: Test, + test_dir: string, + templating_mode: TemplatingMode + ) => Promise<Common> | Common, + fn: ( + config: Test, + test_dir: string, + variant: Variants, + common: Common, + templating_mode: TemplatingMode + ) => void ) { return { test: (config: Test) => config, - run: async (cwd: string, samples_dir = 'samples') => { + run: async ( + cwd: string, + templating_mode: TemplatingMode = 'string', + samples_dir = 'samples' + ) => { await for_each_dir<Test>(cwd, samples_dir, (config, dir) => { let called_common = false; let common: any = undefined; @@ -54,12 +78,12 @@ export function suite_with_variants<Test extends BaseTest, Variants extends stri const solo = config.solo; let it_fn = skip ? it.skip : solo ? it.only : it; - it_fn(`${dir} (${variant})`, async () => { + it_fn(`${dir} (${templating_mode}-${variant})`, async () => { if (!called_common) { called_common = true; - common = await common_setup(config, `${cwd}/${samples_dir}/${dir}`); + common = await common_setup(config, `${cwd}/${samples_dir}/${dir}`, templating_mode); } - return fn(config, `${cwd}/${samples_dir}/${dir}`, variant, common); + return fn(config, `${cwd}/${samples_dir}/${dir}`, variant, common, templating_mode); }); } }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c687db12d4..420e0e90fd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -916,7 +916,7 @@ packages: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} concat-map@0.0.1: - resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==}