run ssr on sync and async

pull/16781/head
S. Elliott Johnson 4 weeks ago
parent b63a56a67e
commit 5a42efb99b

@ -0,0 +1,6 @@
import { test } from '../../test';
export default test({
mode: ['async'],
error: 'lifecycle_outside_component'
});

@ -0,0 +1,10 @@
<script>
import { setContext } from 'svelte';
await Promise.resolve('hi');
setContext('key', 'value');
</script>

@ -0,0 +1,11 @@
<script>
import { setContext, getContext } from 'svelte';
setContext('key', 'child value');
await Promise.resolve();
</script>
<div>{getContext('key')}</div>

@ -0,0 +1,5 @@
import { test } from '../../test';
export default test({
mode: ['async']
});

@ -0,0 +1,3 @@
<div>value</div>
<div>value</div>
<div>child value</div>

@ -0,0 +1,15 @@
<script>
import { getContext, setContext } from 'svelte';
import Child from './Child.svelte';
setContext('key', 'value');
await Promise.resolve();
</script>
<div>{getContext('key')}</div>
<div>{(await Promise.resolve(true)) && getContext('key')}</div>
<Child />

@ -4,8 +4,6 @@ export default test({
compileOptions: { compileOptions: {
dev: true dev: true
}, },
error:
errors: [
'node_invalid_placement_ssr: `<p>` (packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/main.svelte:2:1) cannot be a child of `<p>` (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.' 'node_invalid_placement_ssr: `<p>` (packages/svelte/tests/server-side-rendering/samples/invalid-nested-svelte-element/main.svelte:2:1) cannot be a child of `<p>` (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.'
]
}); });

@ -7,23 +7,19 @@
import * as fs from 'node:fs'; import * as fs from 'node:fs';
import { assert } from 'vitest'; import { assert } from 'vitest';
import { render, renderAsync } from 'svelte/server'; import { render, renderAsync } from 'svelte/server';
import { import { compile_directory, should_update_expected, try_read_file } from '../helpers.js';
async_mode,
compile_directory,
should_update_expected,
try_read_file
} from '../helpers.js';
import { assert_html_equal_with_options } from '../html_equal.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'; import type { CompileOptions } from '#compiler';
interface SSRTest extends BaseTest { interface SSRTest extends BaseTest {
mode?: ('sync' | 'async')[];
compileOptions?: Partial<CompileOptions>; compileOptions?: Partial<CompileOptions>;
load_compiled?: boolean; load_compiled?: boolean;
props?: Record<string, any>; props?: Record<string, any>;
id_prefix?: string; id_prefix?: string;
withoutNormalizeHtml?: boolean; withoutNormalizeHtml?: boolean;
errors?: string[]; error?: string;
} }
// TODO remove this shim when we can // TODO remove this shim when we can
@ -40,86 +36,101 @@ Promise.withResolvers = () => {
return { promise, resolve, reject }; return { promise, resolve, reject };
}; };
// eslint-disable-next-line no-console const { test, run } = suite_with_variants<SSRTest, 'sync' | 'async', CompileOptions>(
let console_error = console.error; ['sync', 'async'],
(variant, config, test_name) => {
if (config.mode && !config.mode.includes(variant)) {
return 'no-test';
}
const { test, run } = suite<SSRTest>(async (config, test_dir) => { if (test_name.startsWith('async') && variant === 'sync') {
const compile_options = { return 'no-test';
experimental: { }
async: async_mode,
...config.compileOptions?.experimental
},
...config.compileOptions
};
if (!config.load_compiled) { return false;
await compile_directory(test_dir, 'server', compile_options); },
} 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[] = []; return compile_options;
},
console.error = (...args) => { async (config, test_dir, variant, compile_options) => {
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`);
let rendered;
const Component = (await import(`${test_dir}/_output/server/main.svelte.js`)).default; try {
const expected_html = try_read_file(`${test_dir}/_expected.html`); rendered =
const rendered = async_mode variant === 'async'
? await renderAsync(Component, { ? await renderAsync(Component, {
props: config.props || {}, props: config.props || {},
idPrefix: config.id_prefix idPrefix: config.id_prefix
}) })
: render(Component, { : render(Component, {
props: config.props || {}, props: config.props || {},
idPrefix: config.id_prefix idPrefix: config.id_prefix
}); });
const { body, head } = rendered; } 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) { const prefix = variant === 'async' ? 'async_' : '';
fs.writeFileSync(`${test_dir}/_output/rendered_head.html`, head); fs.writeFileSync(`${test_dir}/_output/${prefix}rendered.html`, body);
}
try { if (head) {
assert_html_equal_with_options(body, expected_html || '', { fs.writeFileSync(`${test_dir}/_output/${prefix}rendered_head.html`, head);
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 (fs.existsSync(`${test_dir}/_expected_head.html`)) {
try { try {
assert_html_equal_with_options( assert_html_equal_with_options(body, expected_html || '', {
head, preserveComments: compile_options.preserveComments,
fs.readFileSync(`${test_dir}/_expected_head.html`, 'utf-8'), withoutNormalizeHtml: config.withoutNormalizeHtml
{} });
);
} catch (error: any) { } catch (error: any) {
if (should_update_expected()) { if (should_update_expected()) {
fs.writeFileSync(`${test_dir}/_expected_head.html`, head); fs.writeFileSync(`${test_dir}/_expected.html`, body);
console.log(`Updated ${test_dir}/_expected_head.html.`); console.log(`Updated ${test_dir}/_expected.html.`);
error.message += '\n' + `${test_dir}/main.svelte`;
} else { } else {
error.message += '\n' + `${test_dir}/main.svelte`;
throw error; throw error;
} }
} }
}
if (errors.length > 0) { if (fs.existsSync(`${test_dir}/_expected_head.html`)) {
assert.deepEqual(config.errors, errors); 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 }; export { test };

Loading…
Cancel
Save