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 };