diff --git a/packages/svelte/tests/server-side-rendering/samples/async-context-throws-after-await/_config.js b/packages/svelte/tests/server-side-rendering/samples/async-context-throws-after-await/_config.js new file mode 100644 index 0000000000..a1b52a2df9 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/async-context-throws-after-await/_config.js @@ -0,0 +1,6 @@ +import { test } from '../../test'; + +export default test({ + mode: ['async'], + error: 'lifecycle_outside_component' +}); diff --git a/packages/svelte/tests/server-side-rendering/samples/async-context-throws-after-await/main.svelte b/packages/svelte/tests/server-side-rendering/samples/async-context-throws-after-await/main.svelte new file mode 100644 index 0000000000..d3feb5aa79 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/async-context-throws-after-await/main.svelte @@ -0,0 +1,10 @@ + + + + diff --git a/packages/svelte/tests/server-side-rendering/samples/context/Child.svelte b/packages/svelte/tests/server-side-rendering/samples/context/Child.svelte new file mode 100644 index 0000000000..e25aa2f4f1 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/context/Child.svelte @@ -0,0 +1,11 @@ + + +
{getContext('key')}
+ + + diff --git a/packages/svelte/tests/server-side-rendering/samples/context/_config.js b/packages/svelte/tests/server-side-rendering/samples/context/_config.js new file mode 100644 index 0000000000..05de37a8bd --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/context/_config.js @@ -0,0 +1,5 @@ +import { test } from '../../test'; + +export default test({ + mode: ['async'] +}); diff --git a/packages/svelte/tests/server-side-rendering/samples/context/_expected.html b/packages/svelte/tests/server-side-rendering/samples/context/_expected.html new file mode 100644 index 0000000000..554133d8d9 --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/context/_expected.html @@ -0,0 +1,3 @@ +
value
+
value
+
child value
\ No newline at end of file diff --git a/packages/svelte/tests/server-side-rendering/samples/context/main.svelte b/packages/svelte/tests/server-side-rendering/samples/context/main.svelte new file mode 100644 index 0000000000..300c20e5ba --- /dev/null +++ b/packages/svelte/tests/server-side-rendering/samples/context/main.svelte @@ -0,0 +1,15 @@ + + +
{getContext('key')}
+
{(await Promise.resolve(true)) && getContext('key')}
+ + + + + diff --git a/packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/_config.js b/packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/_config.js index 71edff6a68..6325ea7d0e 100644 --- a/packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/_config.js +++ b/packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/_config.js @@ -4,8 +4,6 @@ export default test({ compileOptions: { dev: true }, - - errors: [ + error: 'node_invalid_placement_ssr: `

` (packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/main.svelte:2:1) cannot be a child of `

` (packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/main.svelte:1:0)\n\nThis can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.' - ] }); diff --git a/packages/svelte/tests/server-side-rendering/test.ts b/packages/svelte/tests/server-side-rendering/test.ts index f1326ae6b4..09a8aebb53 100644 --- a/packages/svelte/tests/server-side-rendering/test.ts +++ b/packages/svelte/tests/server-side-rendering/test.ts @@ -7,23 +7,19 @@ import * as fs from 'node:fs'; import { assert } from 'vitest'; import { render, renderAsync } from 'svelte/server'; -import { - async_mode, - compile_directory, - should_update_expected, - try_read_file -} from '../helpers.js'; +import { compile_directory, should_update_expected, try_read_file } from '../helpers.js'; import { assert_html_equal_with_options } from '../html_equal.js'; -import { suite, type BaseTest } from '../suite.js'; +import { suite_with_variants, type BaseTest } from '../suite.js'; import type { CompileOptions } from '#compiler'; interface SSRTest extends BaseTest { + mode?: ('sync' | 'async')[]; compileOptions?: Partial; load_compiled?: boolean; props?: Record; id_prefix?: string; withoutNormalizeHtml?: boolean; - errors?: string[]; + error?: string; } // TODO remove this shim when we can @@ -40,86 +36,101 @@ Promise.withResolvers = () => { return { promise, resolve, reject }; }; -// eslint-disable-next-line no-console -let console_error = console.error; +const { test, run } = suite_with_variants( + ['sync', 'async'], + (variant, config, test_name) => { + if (config.mode && !config.mode.includes(variant)) { + return 'no-test'; + } -const { test, run } = suite(async (config, test_dir) => { - const compile_options = { - experimental: { - async: async_mode, - ...config.compileOptions?.experimental - }, - ...config.compileOptions - }; + if (test_name.startsWith('async') && variant === 'sync') { + return 'no-test'; + } - if (!config.load_compiled) { - await compile_directory(test_dir, 'server', compile_options); - } + return false; + }, + async (config, test_dir) => { + const compile_options = { + experimental: { + async: true, + ...config.compileOptions?.experimental + }, + ...config.compileOptions + }; + + if (!config.load_compiled) { + await compile_directory(test_dir, 'server', compile_options); + } - const errors: string[] = []; - - console.error = (...args) => { - errors.push(...args); - }; - - const Component = (await import(`${test_dir}/_output/server/main.svelte.js`)).default; - const expected_html = try_read_file(`${test_dir}/_expected.html`); - const rendered = async_mode - ? await renderAsync(Component, { - props: config.props || {}, - idPrefix: config.id_prefix - }) - : render(Component, { - props: config.props || {}, - idPrefix: config.id_prefix - }); - const { body, head } = rendered; + return compile_options; + }, + async (config, test_dir, variant, compile_options) => { + const Component = (await import(`${test_dir}/_output/server/main.svelte.js`)).default; + const expected_html = try_read_file(`${test_dir}/_expected.html`); + let rendered; + try { + rendered = + variant === 'async' + ? await renderAsync(Component, { + props: config.props || {}, + idPrefix: config.id_prefix + }) + : render(Component, { + props: config.props || {}, + idPrefix: config.id_prefix + }); + } catch (error) { + if (config.error) { + assert.deepEqual((error as Error).message, config.error); + return; + } else { + throw error; + } + } - fs.writeFileSync(`${test_dir}/_output/rendered.html`, body); + const { body, head } = rendered; - if (head) { - fs.writeFileSync(`${test_dir}/_output/rendered_head.html`, head); - } + const prefix = variant === 'async' ? 'async_' : ''; + fs.writeFileSync(`${test_dir}/_output/${prefix}rendered.html`, body); - try { - assert_html_equal_with_options(body, expected_html || '', { - preserveComments: compile_options.preserveComments, - withoutNormalizeHtml: config.withoutNormalizeHtml - }); - } catch (error: any) { - if (should_update_expected()) { - fs.writeFileSync(`${test_dir}/_expected.html`, body); - console.log(`Updated ${test_dir}/_expected.html.`); - } else { - error.message += '\n' + `${test_dir}/main.svelte`; - throw error; + if (head) { + fs.writeFileSync(`${test_dir}/_output/${prefix}rendered_head.html`, head); } - } - if (fs.existsSync(`${test_dir}/_expected_head.html`)) { try { - assert_html_equal_with_options( - head, - fs.readFileSync(`${test_dir}/_expected_head.html`, 'utf-8'), - {} - ); + assert_html_equal_with_options(body, expected_html || '', { + preserveComments: compile_options.preserveComments, + withoutNormalizeHtml: config.withoutNormalizeHtml + }); } catch (error: any) { if (should_update_expected()) { - fs.writeFileSync(`${test_dir}/_expected_head.html`, head); - console.log(`Updated ${test_dir}/_expected_head.html.`); - error.message += '\n' + `${test_dir}/main.svelte`; + fs.writeFileSync(`${test_dir}/_expected.html`, body); + console.log(`Updated ${test_dir}/_expected.html.`); } else { + error.message += '\n' + `${test_dir}/main.svelte`; throw error; } } - } - if (errors.length > 0) { - assert.deepEqual(config.errors, errors); + if (fs.existsSync(`${test_dir}/_expected_head.html`)) { + try { + assert_html_equal_with_options( + head, + fs.readFileSync(`${test_dir}/_expected_head.html`, 'utf-8'), + {} + ); + } catch (error: any) { + if (should_update_expected()) { + fs.writeFileSync(`${test_dir}/_expected_head.html`, head); + console.log(`Updated ${test_dir}/_expected_head.html.`); + error.message += '\n' + `${test_dir}/main.svelte`; + } else { + throw error; + } + } + } } - - console.error = console_error; -}); +); export { test };