Skip to content

Commit c75c429

Browse files
committed
chore: run test suite on both functional and string templating
1 parent 8424395 commit c75c429

File tree

36 files changed

+975
-68
lines changed

36 files changed

+975
-68
lines changed

packages/svelte/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,9 @@
149149
"dependencies": {
150150
"@ampproject/remapping": "^2.3.0",
151151
"@jridgewell/sourcemap-codec": "^1.5.0",
152+
"@sveltejs/acorn-typescript": "^1.0.5",
152153
"@types/estree": "^1.0.5",
153154
"acorn": "^8.12.1",
154-
"@sveltejs/acorn-typescript": "^1.0.5",
155155
"aria-query": "^5.3.1",
156156
"axobject-query": "^4.1.0",
157157
"clsx": "^2.1.1",

packages/svelte/src/internal/server/dev.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { current_component } from './context.js';
2222
let parent = null;
2323

2424
/** @type {Set<string>} */
25-
let seen;
25+
export let seen;
2626

2727
/**
2828
* @param {Element} element

packages/svelte/tests/helpers.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,17 @@ export function create_deferred() {
5858
* @param {Partial<CompileOptions>} compileOptions
5959
* @param {boolean} [output_map]
6060
* @param {any} [preprocessor]
61+
* @param {import('./suite').TemplatingMode} [templating_mode]
6162
*/
6263
export async function compile_directory(
6364
cwd,
6465
generate,
6566
compileOptions = {},
6667
output_map = false,
67-
preprocessor
68+
preprocessor,
69+
templating_mode
6870
) {
69-
const output_dir = `${cwd}/_output/${generate}`;
71+
const output_dir = `${cwd}/_output/${generate}${templating_mode === 'functional' ? `-${templating_mode}` : ''}`;
7072

7173
fs.rmSync(output_dir, { recursive: true, force: true });
7274

@@ -77,7 +79,8 @@ export async function compile_directory(
7779
let opts = {
7880
filename: path.join(cwd, file),
7981
...compileOptions,
80-
generate
82+
generate,
83+
preventTemplateCloning: templating_mode === 'functional'
8184
};
8285

8386
if (file.endsWith('.js')) {

packages/svelte/tests/hydration/test.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,24 @@ function read(path: string): string | void {
4141
return fs.existsSync(path) ? fs.readFileSync(path, 'utf-8') : undefined;
4242
}
4343

44-
const { test, run } = suite<HydrationTest>(async (config, cwd) => {
44+
const { test, run } = suite<HydrationTest>(async (config, cwd, templating_mode) => {
4545
if (!config.load_compiled) {
46-
await compile_directory(cwd, 'client', { accessors: true, ...config.compileOptions });
47-
await compile_directory(cwd, 'server', config.compileOptions);
46+
await compile_directory(
47+
cwd,
48+
'client',
49+
{ accessors: true, ...config.compileOptions },
50+
undefined,
51+
undefined,
52+
templating_mode
53+
);
54+
await compile_directory(
55+
cwd,
56+
'server',
57+
config.compileOptions,
58+
undefined,
59+
undefined,
60+
templating_mode
61+
);
4862
}
4963

5064
const target = window.document.body;
@@ -102,7 +116,11 @@ const { test, run } = suite<HydrationTest>(async (config, cwd) => {
102116
};
103117

104118
const component = createClassComponent({
105-
component: (await import(`${cwd}/_output/client/main.svelte.js`)).default,
119+
component: (
120+
await import(
121+
`${cwd}/_output/client${templating_mode === 'functional' ? '-functional' : ''}/main.svelte.js`
122+
)
123+
).default,
106124
target,
107125
hydrate: true,
108126
props: config.props,
@@ -169,4 +187,5 @@ const { test, run } = suite<HydrationTest>(async (config, cwd) => {
169187
});
170188
export { test, assert_ok };
171189

172-
await run(__dirname);
190+
await run(__dirname, 'string');
191+
await run(__dirname, 'functional');

packages/svelte/tests/runtime-browser/test.ts

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as fs from 'node:fs';
44
import * as path from 'node:path';
55
import { compile } from 'svelte/compiler';
66
import { afterAll, assert, beforeAll, describe } from 'vitest';
7-
import { suite, suite_with_variants } from '../suite';
7+
import { suite, suite_with_variants, type TemplatingMode } from '../suite';
88
import { write } from '../helpers';
99
import type { Warning } from '#compiler';
1010

@@ -35,35 +35,50 @@ const { run: run_browser_tests } = suite_with_variants<
3535
return false;
3636
},
3737
() => {},
38-
async (config, test_dir, variant) => {
39-
await run_test(test_dir, config, variant === 'hydrate');
38+
async (config, test_dir, variant, _, templating_mode) => {
39+
await run_test(test_dir, config, variant === 'hydrate', templating_mode);
4040
}
4141
);
4242

4343
describe.concurrent(
4444
'runtime-browser',
45-
() => run_browser_tests(__dirname),
45+
() => run_browser_tests(__dirname, 'string'),
46+
// Browser tests are brittle and slow on CI
47+
{ timeout: 20000, retry: process.env.CI ? 1 : 0 }
48+
);
49+
50+
describe.concurrent(
51+
'runtime-browser-functional',
52+
() => run_browser_tests(__dirname, 'functional'),
4653
// Browser tests are brittle and slow on CI
4754
{ timeout: 20000, retry: process.env.CI ? 1 : 0 }
4855
);
4956

5057
const { run: run_ce_tests } = suite<ReturnType<typeof import('./assert').test>>(
51-
async (config, test_dir) => {
52-
await run_test(test_dir, config, false);
58+
async (config, test_dir, templating_mode) => {
59+
await run_test(test_dir, config, false, templating_mode);
5360
}
5461
);
5562

5663
describe.concurrent(
5764
'custom-elements',
58-
() => run_ce_tests(__dirname, 'custom-elements-samples'),
65+
() => run_ce_tests(__dirname, 'string', 'custom-elements-samples'),
66+
// Browser tests are brittle and slow on CI
67+
{ timeout: 20000, retry: process.env.CI ? 1 : 0 }
68+
);
69+
70+
describe.concurrent(
71+
'custom-elements',
72+
() => run_ce_tests(__dirname, 'functional', 'custom-elements-samples'),
5973
// Browser tests are brittle and slow on CI
6074
{ timeout: 20000, retry: process.env.CI ? 1 : 0 }
6175
);
6276

6377
async function run_test(
6478
test_dir: string,
6579
config: ReturnType<typeof import('./assert').test>,
66-
hydrate: boolean
80+
hydrate: boolean,
81+
templating_mode: TemplatingMode
6782
) {
6883
const warnings: any[] = [];
6984

@@ -90,10 +105,14 @@ async function run_test(
90105
...config.compileOptions,
91106
immutable: config.immutable,
92107
customElement: test_dir.includes('custom-elements-samples'),
93-
accessors: 'accessors' in config ? config.accessors : true
108+
accessors: 'accessors' in config ? config.accessors : true,
109+
preventTemplateCloning: templating_mode === 'functional'
94110
});
95111

96-
write(`${test_dir}/_output/client/${path.basename(args.path)}.js`, compiled.js.code);
112+
write(
113+
`${test_dir}/_output/client${templating_mode === 'functional' ? '-functional' : ''}/${path.basename(args.path)}.js`,
114+
compiled.js.code
115+
);
97116

98117
compiled.warnings.forEach((warning) => {
99118
if (warning.code === 'options_deprecated_accessors') return;
@@ -103,7 +122,7 @@ async function run_test(
103122
if (compiled.css !== null) {
104123
compiled.js.code += `document.head.innerHTML += \`<style>${compiled.css.code}</style>\``;
105124
write(
106-
`${test_dir}/_output/client/${path.basename(args.path)}.css`,
125+
`${test_dir}/_output/${templating_mode === 'functional' ? '-functional' : ''}/${path.basename(args.path)}.css`,
107126
compiled.css.code
108127
);
109128
}
@@ -151,7 +170,8 @@ async function run_test(
151170
...config.compileOptions,
152171
immutable: config.immutable,
153172
customElement: test_dir.includes('custom-elements-samples'),
154-
accessors: 'accessors' in config ? config.accessors : true
173+
accessors: 'accessors' in config ? config.accessors : true,
174+
preventTemplateCloning: templating_mode === 'functional'
155175
});
156176

157177
return {

packages/svelte/tests/runtime-legacy/samples/attribute-casing-custom-element/main.svelte

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
this.innerHTML = 'Hello ' + this._obj.text + '!';
1919
}
2020
}
21-
22-
window.customElements.define('my-custom-element', MyCustomElement);
21+
if(!window.customElements.get('my-custom-element')) {
22+
window.customElements.define('my-custom-element', MyCustomElement);
23+
}
2324
</script>
2425

2526
<my-custom-element camelCase={{ text: 'World' }} />

packages/svelte/tests/runtime-legacy/samples/attribute-custom-element-inheritance/main.svelte

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
}
2727
2828
class Extended extends MyCustomElement {}
29-
30-
window.customElements.define('my-custom-inheritance-element', Extended);
29+
30+
if(!window.customElements.get('my-custom-inheritance-element')) {
31+
window.customElements.define('my-custom-inheritance-element', Extended);
32+
}
3133
</script>
3234

3335
<my-custom-inheritance-element camelCase={{ text: 'World' }} text="!" />

packages/svelte/tests/runtime-legacy/samples/window-binding-scroll-store/_config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ export default test({
99
Object.defineProperties(window, {
1010
scrollY: {
1111
value: 0,
12-
configurable: true
12+
configurable: true,
13+
writable: true
1314
}
1415
});
1516
original_scrollTo = window.scrollTo;

packages/svelte/tests/runtime-legacy/shared.ts

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import { compile_directory } from '../helpers.js';
1010
import { setup_html_equal } from '../html_equal.js';
1111
import { raf } from '../animation-helpers.js';
1212
import type { CompileOptions } from '#compiler';
13-
import { suite_with_variants, type BaseTest } from '../suite.js';
13+
import { suite_with_variants, type BaseTest, type TemplatingMode } from '../suite.js';
14+
import { seen } from '../../src/internal/server/dev.js';
1415

1516
type Assert = typeof import('vitest').assert & {
1617
htmlEqual(a: string, b: string, description?: string): void;
@@ -141,16 +142,21 @@ export function runtime_suite(runes: boolean) {
141142

142143
return false;
143144
},
144-
(config, cwd) => {
145-
return common_setup(cwd, runes, config);
145+
(config, cwd, templating_mode) => {
146+
return common_setup(cwd, runes, config, templating_mode);
146147
},
147-
async (config, cwd, variant, common) => {
148-
await run_test_variant(cwd, config, variant, common, runes);
148+
async (config, cwd, variant, common, templating_mode) => {
149+
await run_test_variant(cwd, config, variant, common, runes, templating_mode);
149150
}
150151
);
151152
}
152153

153-
async function common_setup(cwd: string, runes: boolean | undefined, config: RuntimeTest) {
154+
async function common_setup(
155+
cwd: string,
156+
runes: boolean | undefined,
157+
config: RuntimeTest,
158+
templating_mode: TemplatingMode
159+
) {
154160
const force_hmr = process.env.HMR && config.compileOptions?.dev !== false && !config.error;
155161

156162
const compileOptions: CompileOptions = {
@@ -161,13 +167,14 @@ async function common_setup(cwd: string, runes: boolean | undefined, config: Run
161167
...config.compileOptions,
162168
immutable: config.immutable,
163169
accessors: 'accessors' in config ? config.accessors : true,
164-
runes
170+
runes,
171+
preventTemplateCloning: templating_mode === 'functional'
165172
};
166173

167174
// load_compiled can be used for debugging a test. It means the compiler will not run on the input
168175
// so you can manipulate the output manually to see what fixes it, adding console.logs etc.
169176
if (!config.load_compiled) {
170-
await compile_directory(cwd, 'client', compileOptions);
177+
await compile_directory(cwd, 'client', compileOptions, undefined, undefined, templating_mode);
171178
await compile_directory(cwd, 'server', compileOptions);
172179
}
173180

@@ -179,7 +186,8 @@ async function run_test_variant(
179186
config: RuntimeTest,
180187
variant: 'dom' | 'hydrate' | 'ssr',
181188
compileOptions: CompileOptions,
182-
runes: boolean
189+
runes: boolean,
190+
templating_mode: TemplatingMode
183191
) {
184192
let unintended_error = false;
185193

@@ -257,8 +265,15 @@ async function run_test_variant(
257265
raf.reset();
258266

259267
// Put things we need on window for testing
260-
const styles = globSync('**/*.css', { cwd: `${cwd}/_output/client` })
261-
.map((file) => fs.readFileSync(`${cwd}/_output/client/${file}`, 'utf-8'))
268+
const styles = globSync('**/*.css', {
269+
cwd: `${cwd}/_output/client${templating_mode === 'functional' ? '-functional' : ''}`
270+
})
271+
.map((file) =>
272+
fs.readFileSync(
273+
`${cwd}/_output/client${templating_mode === 'functional' ? '-functional' : ''}/${file}`,
274+
'utf-8'
275+
)
276+
)
262277
.join('\n')
263278
.replace(/\/\*<\/?style>\*\//g, '');
264279

@@ -274,26 +289,36 @@ async function run_test_variant(
274289

275290
globalThis.requestAnimationFrame = globalThis.setTimeout;
276291

277-
let mod = await import(`${cwd}/_output/client/main.svelte.js`);
292+
let mod = await import(
293+
`${cwd}/_output/client${templating_mode === 'functional' ? '-functional' : ''}/main.svelte.js`
294+
);
278295

279296
const target = window.document.querySelector('main') as HTMLElement;
280297

281298
let snapshot = undefined;
282299

283300
if (variant === 'hydrate' || variant === 'ssr') {
284301
config.before_test?.();
302+
// we need to clear the seen messages between tests
303+
seen?.clear?.();
285304
// ssr into target
286305
const SsrSvelteComponent = (await import(`${cwd}/_output/server/main.svelte.js`)).default;
287306
const { html, head } = render(SsrSvelteComponent, {
288307
props: config.server_props ?? config.props ?? {},
289308
idPrefix: config.id_prefix
290309
});
291310

292-
fs.writeFileSync(`${cwd}/_output/rendered.html`, html);
311+
fs.writeFileSync(
312+
`${cwd}/_output/rendered${templating_mode === 'functional' ? '-functional' : ''}.html`,
313+
html
314+
);
293315
target.innerHTML = html;
294316

295317
if (head) {
296-
fs.writeFileSync(`${cwd}/_output/rendered_head.html`, head);
318+
fs.writeFileSync(
319+
`${cwd}/_output/rendered_head${templating_mode === 'functional' ? '-functional' : ''}.html`,
320+
head
321+
);
297322
window.document.head.innerHTML = window.document.head.innerHTML + head;
298323
}
299324

packages/svelte/tests/runtime-legacy/test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ const { test, run } = runtime_suite(false);
1111

1212
export { test, ok };
1313

14-
await run(__dirname);
14+
await run(__dirname, 'string');
15+
await run(__dirname, 'functional');

0 commit comments

Comments
 (0)