replace skip_if_ssr and skip_if_hydrate with modes (#10956)

pull/10965/head
Rich Harris 7 months ago committed by GitHub
parent 326e2b4840
commit 2079e675ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -111,9 +111,9 @@ function normalize_children(node) {
* @template Props
* @param {{
* skip?: boolean;
* skip_if_ssr?: boolean | 'permanent';
* skip_if_hydrate?: boolean | 'permanent';
* solo?: boolean;
* mode?: Array<'server' | 'client' | 'hydrate'>;
* skip_mode?: Array<'server' | 'client' | 'hydrate'>;
* html?: string;
* ssrHtml?: string;
* props?: Props;

@ -1,8 +1,8 @@
import { test } from '../../assert';
export default test({
skip_if_ssr: 'permanent',
skip_if_hydrate: 'permanent',
mode: ['client'],
props: {
tag: /** @type {string | null} */ ('my-custom-element'),
name: /** @type {string | null | undefined} */ (null)

@ -4,6 +4,5 @@ export default test({
// Test that @html does not execute scripts when instantiated in the client.
// Needs to be in this test suite because JSDOM does not quite get this right.
html: `<div></div><script>document.body.innerHTML = 'this should not be executed'</script>`,
skip_if_ssr: 'permanent',
skip_if_hydrate: 'permanent'
mode: ['client']
});

@ -46,7 +46,8 @@ export async function run_ssr_test(
}
const { run } = suite<ReturnType<typeof import('./assert').test>>(async (config, test_dir) => {
if (config.skip_if_ssr) return;
if (config.mode && !config.mode.includes('server')) return;
if (config.skip_mode?.includes('server')) return;
await run_ssr_test(config, test_dir);
});

@ -28,7 +28,11 @@ const { run: run_browser_tests } = suite_with_variants<
>(
['dom', 'hydrate'],
(variant, config) => {
if (variant === 'hydrate' && config.skip_if_hydrate) return true;
if (variant === 'hydrate') {
if (config.mode && !config.mode.includes('hydrate')) return 'no-test';
if (config.skip_mode?.includes('hydrate')) return true;
}
return false;
},
() => {},

@ -1,7 +1,7 @@
import { ok, test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // unnecessary to test this in ssr mode
mode: ['client', 'hydrate'],
html: '<button>10</button>',

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: true,
skip_mode: ['server'],
get props() {
return { value: 'hello!' };

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: true,
skip_mode: ['server'],
get props() {
return { value: 'hello!' };

@ -1,8 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent',
skip_if_hydrate: 'permanent',
mode: ['client'],
html: `
<my-custom-element>Hello World!</my-custom-element>
`

@ -9,11 +9,11 @@ export default test({
<text wordWrap="true"></text>
</page>
`,
skip_if_hydrate: true,
compileOptions: {
namespace: 'foreign'
},
test({ assert, target }) {
// @ts-ignore
const attr = (/** @type {string} */ sel) => target.querySelector(sel).attributes[0].name;

@ -8,7 +8,6 @@ export default test({
<button textWrap="true" text="button">
</page>
`,
skip_if_hydrate: true,
test({ assert, target }) {
// @ts-ignore

@ -3,8 +3,6 @@ import { test } from '../../test';
export default test({
skip: true, // TODO: needs fixing
skip_if_ssr: true,
skip_if_hydrate: true,
html: `
<my-custom-inheritance-element>Hello World!</my-custom-inheritance-element>
`

@ -3,8 +3,6 @@ import { test } from '../../test';
export default test({
skip: true, // TODO: needs fixing
skip_if_ssr: true,
html: `
<span>3</span>
<span>2</span>

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: true,
skip_mode: ['server'],
get props() {
return { value: 'hello!' };

@ -5,7 +5,7 @@ import { flushSync } from 'svelte';
let tasks = [];
export default test({
skip_if_ssr: 'permanent', // unnecessary to test this in ssr mode
mode: ['client', 'hydrate'], // unnecessary to test this in ssr mode
get props() {
tasks = [

@ -1,7 +1,7 @@
import { ok, test } from '../../test';
export default test({
skip_if_ssr: 'permanent',
mode: ['client', 'hydrate'],
html: `
<p>selected: b</p>

@ -1,7 +1,7 @@
import { ok, test } from '../../test';
export default test({
skip_if_ssr: 'permanent',
mode: ['client', 'hydrate'],
html: `
<p>selected: a</p>

@ -1,7 +1,7 @@
import { ok, test } from '../../test';
export default test({
skip_if_ssr: 'permanent',
mode: ['client', 'hydrate'],
html: `
<p>selected: a</p>

@ -2,7 +2,7 @@ import { ok, test } from '../../test';
// test select binding behavior when a selected option is removed
export default test({
skip_if_ssr: 'permanent',
mode: ['client', 'hydrate'],
html: `<p>selected: a</p><select><option value="a">a</option><option value="b">b</option><option value="c">c</option></select>`,

@ -1,7 +1,7 @@
import { ok, test } from '../../test';
export default test({
skip_if_ssr: 'permanent',
mode: ['client', 'hydrate'],
html: `
<input type="checkbox">
<input type="checkbox">

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // there's no class instance to retrieve in SSR mode
mode: ['client', 'hydrate'], // there's no class instance to retrieve in SSR mode
html: `
<div>foo</div>

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // there's no class instance to retrieve in SSR mode
mode: ['client', 'hydrate'], // there's no class instance to retrieve in SSR mode
html: `
<div>foo</div>
<div>first has foo: true</div>

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // there's no class instance to retrieve in SSR mode
mode: ['client', 'hydrate'], // there's no class instance to retrieve in SSR mode
html: `
<div>foo</div>

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // there's no class instance to retrieve in SSR mode
mode: ['client', 'hydrate'], // there's no class instance to retrieve in SSR mode
html: `
<div>foo</div>

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // there's no class instance to retrieve in SSR mode
mode: ['client', 'hydrate'], // there's no class instance to retrieve in SSR mode
get props() {
return { visible: true };
},

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // there's no class instance to retrieve in SSR mode
mode: ['client', 'hydrate'], // there's no class instance to retrieve in SSR mode
html: '<div>has div: true</div>'
});

@ -1,6 +1,6 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // doesn't work in SSR
mode: ['client', 'hydrate'], // doesn't work in SSR
html: '<div>object</div>'
});

@ -2,7 +2,7 @@ import { ok, test } from '../../test';
import { flushSync } from 'svelte';
export default test({
skip_if_ssr: 'permanent', // relies on onMount firing, which does not happen in SSR mode
mode: ['client', 'hydrate'], // relies on onMount firing, which does not happen in SSR mode
get props() {
return { count: 3 };

@ -2,7 +2,7 @@ import { ok, test } from '../../test';
import { flushSync } from 'svelte';
export default test({
skip_if_ssr: 'permanent', // relies on onMount firing, which does not happen in SSR mode
mode: ['client', 'hydrate'], // relies on onMount firing, which does not happen in SSR mode
get props() {
return { count: 3 };

@ -1,10 +1,11 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent',
skip_if_hydrate: 'permanent',
mode: ['client'],
compileOptions: {
dev: true
},
error: 'this={...} of <svelte:component> should specify a Svelte component.'
});

@ -1,8 +1,8 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent',
skip_if_hydrate: 'permanent',
mode: ['client'],
get props() {
return { selected: false };
},

@ -1,7 +1,8 @@
import { test } from '../../test';
export default test({
skip_if_ssr: true,
skip_mode: ['server'],
html: `
<div><div>Value in child component: </div></div>
`

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent',
mode: ['client', 'hydrate'],
html: `
<p>Reactive: foo</p>

@ -9,7 +9,7 @@ let originalSpanGetBoundingClientRect;
let originalParagraphGetBoundingClientRect;
export default test({
skip_if_ssr: 'permanent', // no animations in SSR
mode: ['client', 'hydrate'], // no animations in SSR
get props() {
return {
things: [

@ -1,12 +1,15 @@
import { test } from '../../test';
export default test({
skip_if_hydrate: 'permanent', // SSR errors on render already
mode: ['client', 'server'], // SSR errors on render already
compileOptions: {
dev: true
},
get props() {
return { tag: 123 };
},
error: '<svelte:element> expects "this" attribute to be a string.'
});

@ -1,6 +1,6 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent',
mode: ['client', 'hydrate'],
html: '<div>object</div>'
});

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // uses oncreate
mode: ['client', 'hydrate'], // uses oncreate
html: '<div><p>true</p>\n<p>true</p></div>'
});

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // uses oncreate
mode: ['client', 'hydrate'], // uses oncreate
html: '<div><p>true</p></div>',

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_hydrate: 'permanent', // output is correct, but test suite chokes on the extra ssr comment which is harmless
mode: ['client', 'server'], // output is correct, but test suite chokes on the extra ssr comment which is harmless
withoutNormalizeHtml: true,
html: get_html(false),
ssrHtml: get_html(true)

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // a separate SSR test exists
mode: ['client', 'hydrate'], // a separate SSR test exists
compileOptions: {
preserveComments: true

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // uses oncreate
mode: ['client', 'hydrate'], // uses oncreate
html: '<p>2</p>'
});

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // DOM and SSR output is different, a separate SSR test exists
mode: ['client', 'hydrate'], // DOM and SSR output is different, a separate SSR test exists
html: '<input form="qux" list="quu" />',
test({ assert, target }) {

@ -1,10 +1,12 @@
import { test } from '../../test';
export default test({
skip_if_ssr: true,
skip_mode: ['server'],
compileOptions: {
cssHash: () => 'svelte-xyz'
},
async test({ assert, component, window }) {
assert.htmlEqual(
window.document.head.innerHTML,

@ -1,10 +1,12 @@
import { test } from '../../test';
export default test({
skip_if_ssr: true,
skip_mode: ['server'],
compileOptions: {
cssHash: () => 'svelte-xyz'
},
async test({ assert, component, window }) {
assert.htmlEqual(
window.document.head.innerHTML,

@ -1,10 +1,12 @@
import { test } from '../../test';
export default test({
skip_if_ssr: true,
skip_mode: ['server'],
compileOptions: {
cssHash: () => 'svelte-xyz'
},
async test({ assert, component, window }) {
assert.htmlEqual(
window.document.head.innerHTML,

@ -1,7 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent', // SSR behaviour is awkwardly different
mode: ['client', 'hydrate'], // SSR behaviour is awkwardly different
get props() {
return { foo: 42 };

@ -3,7 +3,7 @@ import { test } from '../../test';
export default test({
intro: true,
skip_if_hydrate: 'permanent',
mode: ['client', 'server'],
test({ assert, target, raf }) {
const div = /** @type {HTMLDivElement & { foo: number }} */ (target.querySelector('div'));

@ -20,7 +20,7 @@ export default test({
});
},
skip_if_ssr: 'permanent',
mode: ['client', 'hydrate'],
async test({ assert, target, window }) {
const event = new window.Event('resize');

@ -27,10 +27,10 @@ type Assert = typeof import('vitest').assert & {
export interface RuntimeTest<Props extends Record<string, any> = Record<string, any>>
extends BaseTest {
/** Use `true` to signal a temporary skip, and `"permanent"` to signal that this test is never intended to run in ssr mode */
skip_if_ssr?: boolean | 'permanent';
/** Use `true` to signal a temporary skip, and `"permanent"` to signal that this test is never intended to run in hydration mode */
skip_if_hydrate?: boolean | 'permanent';
/** Use e.g. `mode: ['client']` to indicate that this test should never run in server/hydrate modes */
mode?: Array<'server' | 'client' | 'hydrate'>;
/** Temporarily skip specific modes, without skipping the entire test */
skip_mode?: Array<'server' | 'client' | 'hydrate'>;
html?: string;
ssrHtml?: string;
compileOptions?: Partial<CompileOptions>;
@ -96,12 +96,13 @@ export function runtime_suite(runes: boolean) {
['dom', 'hydrate', 'ssr'],
(variant, config) => {
if (variant === 'hydrate') {
if (config.skip_if_hydrate === 'permanent') return 'no-test';
if (config.skip_if_hydrate) return true;
if (config.mode && !config.mode.includes('hydrate')) return 'no-test';
if (config.skip_mode?.includes('hydrate')) return true;
}
if (variant === 'ssr') {
if (
config.skip_if_ssr === 'permanent' ||
(config.mode && !config.mode.includes('server')) ||
(!config.test_ssr &&
config.html === undefined &&
config.ssrHtml === undefined &&
@ -109,7 +110,7 @@ export function runtime_suite(runes: boolean) {
) {
return 'no-test';
}
if (config.skip_if_ssr) return true;
if (config.skip_mode?.includes('server')) return true;
}
return false;

@ -4,7 +4,7 @@ import { log } from './log.js';
export default test({
// The component context class instance gets shared between tests, strangely, causing hydration to fail?
skip_if_hydrate: 'permanent',
mode: ['client', 'server'],
before_test() {
log.length = 0;

@ -1,8 +1,9 @@
import { test } from '../../test';
export default test({
mode: ['client', 'server'],
html: '<div>d2: 3</div><div>d3: 3</div><div>d4: 3</div>',
skip_if_hydrate: 'permanent',
async test({ assert, target }) {
await Promise.resolve();

@ -2,7 +2,8 @@ import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
skip_if_hydrate: 'permanent',
mode: ['client', 'server'],
async test({ assert, target }) {
let [btn1, btn2] = target.querySelectorAll('button');
const input = target.querySelector('input');

@ -2,9 +2,9 @@ import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
mode: ['client'],
html: `<p>test costs $1</p><p>test 2 costs $2</p><p>test costs $1</p><p>test 2 costs $2</p><button>add</button><button>change</button><button>reload</button>`,
skip_if_ssr: 'permanent',
skip_if_hydrate: 'permanent',
async test({ assert, target }) {
const [btn1, btn2, btn3] = target.querySelectorAll('button');

@ -1,8 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_hydrate: 'permanent', // unnecessary to test
skip_if_ssr: 'permanent', // unnecessary to test
mode: ['client'],
async test({ assert, target }) {
const [b1, b2] = target.querySelectorAll('button');

@ -1,8 +1,7 @@
import { test } from '../../test';
export default test({
skip_if_hydrate: 'permanent', // unnecessary to test
skip_if_ssr: 'permanent', // unnecessary to test
mode: ['client'],
async test({ assert, target }) {
const [b1, b2] = target.querySelectorAll('button');

@ -10,8 +10,8 @@ let log;
let original_log;
export default test({
skip_if_ssr: 'permanent',
skip_if_hydrate: 'permanent', // log patching will be too late
mode: ['client'],
before_test() {
log = [];
original_log = console.log;

@ -4,17 +4,20 @@ let math_random = Math.random;
let calls = 0;
export default test({
skip_if_hydrate: 'permanent',
mode: ['client', 'server'],
before_test() {
Math.random = function () {
calls++;
return math_random.call(this);
};
},
after_test() {
Math.random = math_random;
calls = 0;
},
test({ assert }) {
assert.equal(calls, 1);
}

@ -2,7 +2,7 @@ import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
skip_if_ssr: 'permanent',
mode: ['client', 'hydrate'],
html: `
<input><input><input><div>3</div>
`

Loading…
Cancel
Save