monkey-patch console.log and console.warn for all tests (#11265)

* monkey-patch console.log and console.warn for all tests

* update legacy tests

* various

* tests passing

* tidy up

* tidy up

* tidier output
pull/11260/head
Rich Harris 4 months ago committed by GitHub
parent 47ba488cf2
commit fd5f5bb85d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -11,5 +11,9 @@ export default test({
test(assert, target) { test(assert, target) {
assert.equal(target.querySelector('a')?.getAttribute('href'), '/bar'); assert.equal(target.querySelector('a')?.getAttribute('href'), '/bar');
} },
errors: [
'Detected a href attribute value change during hydration. This will not be repaired during hydration, the href value that came from the server will be used. Related element:'
]
}); });

@ -32,6 +32,7 @@ interface HydrationTest extends BaseTest {
) => void | Promise<void>; ) => void | Promise<void>;
before_test?: () => void; before_test?: () => void;
after_test?: () => void; after_test?: () => void;
errors?: any[];
} }
function read(path: string): string | void { function read(path: string): string | void {
@ -65,6 +66,7 @@ const { test, run } = suite<HydrationTest>(async (config, cwd) => {
const snapshot = config.snapshot ? config.snapshot(target) : {}; const snapshot = config.snapshot ? config.snapshot(target) : {};
const error = console.error; const error = console.error;
const errors: any[] = [];
let got_hydration_error = false; let got_hydration_error = false;
console.error = (message: any) => { console.error = (message: any) => {
if (typeof message === 'string' && message.startsWith('ERR_SVELTE_HYDRATION_MISMATCH')) { if (typeof message === 'string' && message.startsWith('ERR_SVELTE_HYDRATION_MISMATCH')) {
@ -73,7 +75,7 @@ const { test, run } = suite<HydrationTest>(async (config, cwd) => {
error(message); error(message);
} }
} else { } else {
error(message); errors.push(message);
} }
}; };
@ -85,12 +87,19 @@ const { test, run } = suite<HydrationTest>(async (config, cwd) => {
}); });
console.error = error; console.error = error;
if (config.expect_hydration_error) { if (config.expect_hydration_error) {
assert.ok(got_hydration_error, 'Expected hydration error'); assert.ok(got_hydration_error, 'Expected hydration error');
} else { } else {
assert.ok(!got_hydration_error, 'Unexpected hydration error'); assert.ok(!got_hydration_error, 'Unexpected hydration error');
} }
if (config.errors) {
assert.deepEqual(errors, config.errors);
} else if (errors.length) {
throw new Error(`Unexpected errors: ${errors.join('\n')}`);
}
const expected = read(`${cwd}/_expected.html`) ?? rendered.html; const expected = read(`${cwd}/_expected.html`) ?? rendered.html;
assert_html_equal(target.innerHTML, expected); assert_html_equal(target.innerHTML, expected);

@ -14,7 +14,6 @@ let browser: import('@playwright/test').Browser;
beforeAll(async () => { beforeAll(async () => {
browser = await chromium.launch(); browser = await chromium.launch();
console.log('[runtime-browser] Launched browser');
}, 20000); }, 20000);
afterAll(async () => { afterAll(async () => {

@ -2,11 +2,11 @@ import { flushSync } from 'svelte';
import { test } from '../../test'; import { test } from '../../test';
export default test({ export default test({
test({ assert, component, target }) { test({ assert, target, logs }) {
const [b1, b2, b3] = target.querySelectorAll('button'); const [b1, b2, b3] = target.querySelectorAll('button');
const first_h1 = target.querySelector('h1'); const first_h1 = target.querySelector('h1');
assert.deepEqual(component.log, [undefined, first_h1]); assert.deepEqual(logs, [undefined, first_h1]);
flushSync(() => { flushSync(() => {
b3.click(); b3.click();
@ -14,12 +14,12 @@ export default test({
const third_h1 = target.querySelector('h1'); const third_h1 = target.querySelector('h1');
assert.deepEqual(component.log, [undefined, first_h1, third_h1]); assert.deepEqual(logs, [undefined, first_h1, third_h1]);
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
}); });
assert.deepEqual(component.log, [undefined, first_h1, third_h1, target.querySelector('h1')]); assert.deepEqual(logs, [undefined, first_h1, third_h1, target.querySelector('h1')]);
} }
}); });

@ -1,9 +1,8 @@
<script> <script>
let activeTab = 0; let activeTab = 0;
let activeHeading; let activeHeading;
export let log = [];
$: log.push(activeHeading); $: console.log(activeHeading);
</script> </script>
<div class="tabs"> <div class="tabs">

@ -4,5 +4,7 @@ import { unmount } from 'svelte';
export default test({ export default test({
test({ component }) { test({ component }) {
unmount(component.l1); unmount(component.l1);
} },
warnings: ['Tried to unmount a component that was not mounted.']
}); });

@ -1,14 +1,14 @@
<script> <script>
let keys = ['a', 'b']; let keys = ['a', 'b'];
let items = ['c', 'd']; let items = ['c', 'd'];
export let log;
function setKey(key, value, item) { function setKey(key, value, item) {
log.push(`setKey(${key}, ${value}, ${item})`); console.log(`setKey(${key}, ${value}, ${item})`);
} }
</script> </script>
{#each items as item (item)} {#each items as item (item)}
{#each keys as key (key)} {#each keys as key (key)}
<slot {key} {item} set={(value) => setKey(key, value, item)} /> <slot {key} {item} set={(value) => setKey(key, value, item)} />
{/each} {/each}
{/each} {/each}

@ -7,25 +7,26 @@ export default test({
<button type="button">Set a-d</button> <button type="button">Set a-d</button>
<button type="button">Set b-d</button> <button type="button">Set b-d</button>
`, `,
async test({ assert, target, window, component }) {
async test({ assert, target, window, logs }) {
const [btn1, btn2, btn3, btn4] = target.querySelectorAll('button'); const [btn1, btn2, btn3, btn4] = target.querySelectorAll('button');
const click = new window.MouseEvent('click', { bubbles: true }); const click = new window.MouseEvent('click', { bubbles: true });
await btn1.dispatchEvent(click); await btn1.dispatchEvent(click);
assert.deepEqual(component.log, ['setKey(a, value-a-c, c)']); assert.deepEqual(logs, ['setKey(a, value-a-c, c)']);
await btn2.dispatchEvent(click); await btn2.dispatchEvent(click);
assert.deepEqual(component.log, ['setKey(a, value-a-c, c)', 'setKey(b, value-b-c, c)']); assert.deepEqual(logs, ['setKey(a, value-a-c, c)', 'setKey(b, value-b-c, c)']);
await btn3.dispatchEvent(click); await btn3.dispatchEvent(click);
assert.deepEqual(component.log, [ assert.deepEqual(logs, [
'setKey(a, value-a-c, c)', 'setKey(a, value-a-c, c)',
'setKey(b, value-b-c, c)', 'setKey(b, value-b-c, c)',
'setKey(a, value-a-d, d)' 'setKey(a, value-a-d, d)'
]); ]);
await btn4.dispatchEvent(click); await btn4.dispatchEvent(click);
assert.deepEqual(component.log, [ assert.deepEqual(logs, [
'setKey(a, value-a-c, c)', 'setKey(a, value-a-c, c)',
'setKey(b, value-b-c, c)', 'setKey(b, value-b-c, c)',
'setKey(a, value-a-d, d)', 'setKey(a, value-a-d, d)',

@ -1,8 +1,7 @@
<script> <script>
import Nested from './Nested.svelte'; import Nested from './Nested.svelte';
export let log = [];
</script> </script>
<Nested {log} let:set let:key let:item> <Nested let:set let:key let:item>
<button type="button" on:click={() => set(`value-${key}-${item}`)}>Set {key}-{item}</button> <button type="button" on:click={() => set(`value-${key}-${item}`)}>Set {key}-{item}</button>
</Nested> </Nested>

@ -1,11 +1,11 @@
<script> <script>
let keys = ['a', 'b']; let keys = ['a', 'b'];
export let log;
function setKey(key, value) { function setKey(key, value) {
log.push(`setKey(${key}, ${value})`); console.log(`setKey(${key}, ${value})`);
} }
</script> </script>
{#each keys as key (key)} {#each keys as key (key)}
<slot {key} set={(value) => setKey(key, value)} /> <slot {key} set={(value) => setKey(key, value)} />
{/each} {/each}

@ -5,14 +5,15 @@ export default test({
<button type="button">Set a</button> <button type="button">Set a</button>
<button type="button">Set b</button> <button type="button">Set b</button>
`, `,
async test({ assert, target, window, component }) {
async test({ assert, target, window, logs }) {
const [btn1, btn2] = target.querySelectorAll('button'); const [btn1, btn2] = target.querySelectorAll('button');
const click = new window.MouseEvent('click', { bubbles: true }); const click = new window.MouseEvent('click', { bubbles: true });
await btn1.dispatchEvent(click); await btn1.dispatchEvent(click);
assert.deepEqual(component.log, ['setKey(a, value-a)']); assert.deepEqual(logs, ['setKey(a, value-a)']);
await btn2.dispatchEvent(click); await btn2.dispatchEvent(click);
assert.deepEqual(component.log, ['setKey(a, value-a)', 'setKey(b, value-b)']); assert.deepEqual(logs, ['setKey(a, value-a)', 'setKey(b, value-b)']);
} }
}); });

@ -1,8 +1,7 @@
<script> <script>
import Nested from './Nested.svelte'; import Nested from './Nested.svelte';
export let log = [];
</script> </script>
<Nested {log} let:set let:key> <Nested let:set let:key>
<button type="button" on:click={() => set(`value-${key}`)}>Set {key}</button> <button type="button" on:click={() => set(`value-${key}`)}>Set {key}</button>
</Nested> </Nested>

@ -1,9 +1,8 @@
<script> <script>
export let log;
function setKey(key, value) { function setKey(key, value) {
log.push(`setKey(${key}, ${value})`); console.log(`setKey(${key}, ${value})`);
} }
</script> </script>
<slot key="a" set={setKey} /> <slot key="a" set={setKey} />
<slot key="b" set={setKey} /> <slot key="b" set={setKey} />

@ -1,8 +1,7 @@
<script> <script>
import Inner from './Inner.svelte'; import Inner from './Inner.svelte';
export let log;
</script> </script>
<Inner {log} let:key let:set> <Inner let:key let:set>
<slot {key} set={(value) => set(key, value)} /> <slot {key} set={(value) => set(key, value)} />
</Inner> </Inner>

@ -5,14 +5,15 @@ export default test({
<button type="button">Set a</button> <button type="button">Set a</button>
<button type="button">Set b</button> <button type="button">Set b</button>
`, `,
async test({ assert, target, window, component }) {
async test({ assert, target, window, logs }) {
const [btn1, btn2] = target.querySelectorAll('button'); const [btn1, btn2] = target.querySelectorAll('button');
const click = new window.MouseEvent('click', { bubbles: true }); const click = new window.MouseEvent('click', { bubbles: true });
await btn1.dispatchEvent(click); await btn1.dispatchEvent(click);
assert.deepEqual(component.log, ['setKey(a, value-a)']); assert.deepEqual(logs, ['setKey(a, value-a)']);
await btn2.dispatchEvent(click); await btn2.dispatchEvent(click);
assert.deepEqual(component.log, ['setKey(a, value-a)', 'setKey(b, value-b)']); assert.deepEqual(logs, ['setKey(a, value-a)', 'setKey(b, value-b)']);
} }
}); });

@ -1,8 +1,7 @@
<script> <script>
import Nested from './Nested.svelte'; import Nested from './Nested.svelte';
export let log = [];
</script> </script>
<Nested {log} let:set let:key> <Nested let:set let:key>
<button type="button" on:click={() => set(`value-${key}`)}>Set {key}</button> <button type="button" on:click={() => set(`value-${key}`)}>Set {key}</button>
</Nested> </Nested>

@ -5,5 +5,10 @@ export default test({
test({ component }) { test({ component }) {
unmount(component); unmount(component);
unmount(component); unmount(component);
} },
warnings: [
'Tried to unmount a component that was not mounted.',
'Tried to unmount a component that was not mounted.'
]
}); });

@ -1,6 +1,6 @@
<script> <script>
import { onDestroy } from 'svelte'; import { onDestroy } from 'svelte';
onDestroy(() => { onDestroy(() => {
console.log('destroy'); console.log('destroy');

@ -1,30 +1,14 @@
import { test } from '../../test'; import { test } from '../../test';
/**
* @type {{ (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; (...data: any[]): void; (message?: any, ...optionalParams: any[]): void; }}
*/
let log;
export default test({ export default test({
html: ` html: `
<button>destroy component</button> <button>destroy component</button>
`, `,
before_test() { async test({ assert, target, window, logs }) {
log = console.log;
},
after_test() {
console.log = log;
},
async test({ assert, target, window }) {
const button = target.querySelector('button'); const button = target.querySelector('button');
const event = new window.MouseEvent('click'); const event = new window.MouseEvent('click');
/**
* @type {any[]}
*/
const messages = [];
console.log = (msg) => messages.push(msg);
// @ts-ignore // @ts-ignore
await button.dispatchEvent(event); await button.dispatchEvent(event);
assert.htmlEqual( assert.htmlEqual(
@ -33,6 +17,6 @@ export default test({
<button>destroy component</button> <button>destroy component</button>
` `
); );
assert.deepEqual(messages, ['destroy']); assert.deepEqual(logs, ['destroy']);
} }
}); });

@ -3,6 +3,6 @@
let active = true; let active = true;
</script> </script>
<button on:click='{() => active = false }'>destroy component</button> <button on:click={() => active = false }>destroy component</button>
<svelte:component this={active ? Empty : null} /> <svelte:component this={active ? Empty : null} />

@ -2,7 +2,7 @@ import { flushSync } from 'svelte';
import { ok, test } from '../../test'; import { ok, test } from '../../test';
export default test({ export default test({
test({ assert, component, target, window }) { test({ assert, logs, target }) {
const button = target.querySelector('button'); const button = target.querySelector('button');
ok(button); ok(button);
@ -10,12 +10,12 @@ export default test({
button.click(); button.click();
}); });
assert.deepEqual(component.log, ['1 - 1']); assert.deepEqual(logs, ['1 - 1']);
flushSync(() => { flushSync(() => {
button.click(); button.click();
}); });
assert.deepEqual(component.log, ['1 - 1', '2 - 2']); assert.deepEqual(logs, ['1 - 1', '2 - 2']);
} }
}); });

@ -1,5 +1,4 @@
<script> <script>
export let log = [];
let referenced_directly = 0; let referenced_directly = 0;
let not_referenced_directly = 0; let not_referenced_directly = 0;
let css_based_on_not_referenced = ''; let css_based_on_not_referenced = '';
@ -8,7 +7,7 @@
referenced_directly += 1; referenced_directly += 1;
not_referenced_directly += 1; not_referenced_directly += 1;
css_based_on_not_referenced = not_referenced_directly % 2 == 1 ? 'background-color: red' : ''; css_based_on_not_referenced = not_referenced_directly % 2 == 1 ? 'background-color: red' : '';
log.push(referenced_directly + ' - ' + not_referenced_directly); //only referenced_directly is increasing console.log(referenced_directly + ' - ' + not_referenced_directly); //only referenced_directly is increasing
} }
</script> </script>

@ -1,24 +1,23 @@
<script> <script>
import { beforeUpdate, afterUpdate } from "svelte"; import { beforeUpdate, afterUpdate } from "svelte";
import { log } from './log.js';
export let a; export let a;
export let b; export let b;
beforeUpdate(() => { beforeUpdate(() => {
log.push('before'); console.log('before');
}); });
beforeUpdate(()=>{ beforeUpdate(()=>{
log.push(`before ${a}, ${b}`); console.log(`before ${a}, ${b}`);
}); });
afterUpdate(() => { afterUpdate(() => {
log.push('after'); console.log('after');
}); });
afterUpdate(()=>{ afterUpdate(()=>{
log.push(`after ${a}, ${b}`); console.log(`after ${a}, ${b}`);
}); });
</script> </script>

@ -1,13 +1,8 @@
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { log } from './log.js';
import { test, ok } from '../../test'; import { test, ok } from '../../test';
export default test({ export default test({
before_test: () => { test({ assert, target, logs }) {
log.length = 0;
},
test({ assert, target }) {
const [button1, button2] = target.querySelectorAll('button'); const [button1, button2] = target.querySelectorAll('button');
ok(button1); ok(button1);
ok(button2); ok(button2);
@ -18,7 +13,7 @@ export default test({
button2.click(); button2.click();
flushSync(); flushSync();
assert.deepEqual(log, [ assert.deepEqual(logs, [
'before', 'before',
'before 0, 0', 'before 0, 0',
'after', 'after',

@ -1,7 +1,6 @@
<script> <script>
export let name; export let name;
export let log; $: console.log('name in child: ' + name);
$: log.push('name in child: ' + name);
</script> </script>
<p>welcome, dan</p> <p>welcome, dan</p>

@ -2,11 +2,11 @@ import { test } from '../../test';
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
export default test({ export default test({
async test({ assert, target, component }) { async test({ assert, target, logs }) {
const input = /** @type {HTMLInputElement} */ (target.querySelector('input')); const input = /** @type {HTMLInputElement} */ (target.querySelector('input'));
assert.equal(input?.value, 'rich'); assert.equal(input?.value, 'rich');
assert.deepEqual(component.log, []); assert.deepEqual(logs, []);
const inputEvent = new window.InputEvent('input'); const inputEvent = new window.InputEvent('input');
input.value = 'dan'; input.value = 'dan';
@ -14,15 +14,15 @@ export default test({
flushSync(); flushSync();
assert.deepEqual(component.log, ['name in child: dan']); assert.deepEqual(logs, ['name in child: dan']);
component.log.length = 0; logs.length = 0;
input.value = 'da'; input.value = 'da';
await input.dispatchEvent(inputEvent); await input.dispatchEvent(inputEvent);
flushSync(); flushSync();
assert.deepEqual(component.log, []); assert.deepEqual(logs, []);
} }
}); });

@ -2,8 +2,6 @@
import { beforeUpdate } from 'svelte'; import { beforeUpdate } from 'svelte';
import Child from './Child.svelte'; import Child from './Child.svelte';
export let log = [];
let name = 'rich'; let name = 'rich';
let allowed = false; let allowed = false;
@ -16,5 +14,5 @@
<input bind:value={name} /> <input bind:value={name} />
{#if allowed} {#if allowed}
<Child name={name} log={log} /> <Child name={name} />
{/if} {/if}

@ -1,21 +1,16 @@
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
html: '<button>1 / 1</button>', html: '<button>1 / 1</button>',
before_test() { test({ assert, target, logs }) {
log.length = 0; assert.deepEqual(logs, [2, 1]);
},
test({ assert, target }) {
assert.deepEqual(log, [2, 1]);
const button = target.querySelector('button'); const button = target.querySelector('button');
flushSync(() => button?.click()); flushSync(() => button?.click());
assert.deepEqual(log, [2, 1, 2, 1]); assert.deepEqual(logs, [2, 1, 2, 1]);
assert.htmlEqual(target.innerHTML, '<button>3 / 2</button>'); assert.htmlEqual(target.innerHTML, '<button>3 / 2</button>');
} }

@ -1,6 +1,4 @@
<script> <script>
import { log } from './log.js';
let count1 = 0; let count1 = 0;
let count2 = 0; let count2 = 0;
@ -9,12 +7,12 @@
} }
$: if (count2 < 10) { $: if (count2 < 10) {
log.push(1); console.log(1);
increaseCount1(); increaseCount1();
} }
$: if (count1 < 10) { $: if (count1 < 10) {
log.push(2); console.log(2);
count2++; count2++;
} }
</script> </script>

@ -1,7 +1,6 @@
import * as fs from 'node:fs'; import * as fs from 'node:fs';
import { setImmediate } from 'node:timers/promises'; import { setImmediate } from 'node:timers/promises';
import glob from 'tiny-glob/sync.js'; import glob from 'tiny-glob/sync.js';
import * as $ from 'svelte/internal/client';
import { createClassComponent } from 'svelte/legacy'; import { createClassComponent } from 'svelte/legacy';
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { render } from 'svelte/server'; import { render } from 'svelte/server';
@ -56,6 +55,8 @@ export interface RuntimeTest<Props extends Record<string, any> = Record<string,
KeyboardEvent: typeof KeyboardEvent; KeyboardEvent: typeof KeyboardEvent;
MouseEvent: typeof MouseEvent; MouseEvent: typeof MouseEvent;
}; };
logs: any[];
warnings: any[];
}) => void | Promise<void>; }) => void | Promise<void>;
test_ssr?: (args: { assert: Assert }) => void | Promise<void>; test_ssr?: (args: { assert: Assert }) => void | Promise<void>;
accessors?: boolean; accessors?: boolean;
@ -151,6 +152,36 @@ async function run_test_variant(
) { ) {
let unintended_error = false; let unintended_error = false;
// eslint-disable-next-line no-console
const { log, warn } = console;
let logs: string[] = [];
let warnings: string[] = [];
{
// use some crude static analysis to determine if logs/warnings are intercepted.
// we do this instead of using getters on the `test` parameters so that we can
// squelch logs in SSR tests while printing temporary logs in other cases
let str = config.test?.toString() ?? '';
let n = 0;
let i = 0;
while (i < str.length) {
if (str[i] === '(') n++;
if (str[i] === ')' && --n === 0) break;
i++;
}
if (str.slice(0, i).includes('logs')) {
// eslint-disable-next-line no-console
console.log = (...args) => logs.push(...args);
}
if (str.slice(0, i).includes('warnings') || config.warnings) {
// eslint-disable-next-line no-console
console.warn = (...args) => warnings.push(...args);
}
}
try { try {
unhandled_rejection = null; unhandled_rejection = null;
@ -237,15 +268,9 @@ async function run_test_variant(
}); });
} }
} else { } else {
config.before_test?.(); logs.length = warnings.length = 0;
const warnings: string[] = []; config.before_test?.();
// eslint-disable-next-line no-console
const warn = console.warn;
// eslint-disable-next-line no-console
console.warn = (warning) => {
warnings.push(warning);
};
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
const error = console.error; const error = console.error;
@ -266,8 +291,6 @@ async function run_test_variant(
hydrate: variant === 'hydrate' hydrate: variant === 'hydrate'
}); });
// eslint-disable-next-line no-console
console.warn = warn;
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.error = error; console.error = error;
@ -276,13 +299,6 @@ async function run_test_variant(
assert.fail('Expected a runtime error'); assert.fail('Expected a runtime error');
} }
if (config.warnings) {
assert.deepEqual(warnings, config.warnings);
} else if (warnings.length) {
unintended_error = true;
assert.fail('Received unexpected warnings');
}
if (config.html) { if (config.html) {
flushSync(); flushSync();
assert_html_equal_with_options(target.innerHTML, config.html, { assert_html_equal_with_options(target.innerHTML, config.html, {
@ -309,7 +325,9 @@ async function run_test_variant(
snapshot, snapshot,
window, window,
raf, raf,
compileOptions compileOptions,
logs,
warnings
}); });
} }
@ -319,6 +337,15 @@ async function run_test_variant(
} }
} finally { } finally {
instance.$destroy(); instance.$destroy();
if (config.warnings) {
assert.deepEqual(warnings, config.warnings);
} else if (warnings.length && console.warn === warn) {
unintended_error = true;
warn.apply(console, warnings);
assert.fail('Received unexpected warnings');
}
assert_html_equal( assert_html_equal(
target.innerHTML, target.innerHTML,
'', '',
@ -341,6 +368,9 @@ async function run_test_variant(
throw err; throw err;
} }
} finally { } finally {
console.log = log;
console.warn = warn;
config.after_test?.(); config.after_test?.();
// Free up the microtask queue // Free up the microtask queue

@ -1,22 +1,17 @@
import { ok, test } from '../../test'; import { ok, test } from '../../test';
import { flushSync, tick } from 'svelte'; import { flushSync } from 'svelte';
import { log } from './log.js';
export default test({ export default test({
html: `<button>0</button>`, html: `<button>0</button>`,
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const btn = target.querySelector('button'); const btn = target.querySelector('button');
ok(btn); ok(btn);
flushSync(() => btn.click()); flushSync(() => btn.click());
assert.deepEqual(log, ['update', 0, 1]); assert.deepEqual(logs, ['update', 0, 1]);
flushSync(() => btn.click()); flushSync(() => btn.click());
assert.deepEqual(log, ['update', 0, 1, 'destroy', 1]); assert.deepEqual(logs, ['update', 0, 1, 'destroy', 1]);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,6 +1,4 @@
<script> <script>
import { log } from './log.js';
let count = $state(0); let count = $state(0);
/** /**
@ -12,10 +10,10 @@
count, count,
/** @param {number} count */ /** @param {number} count */
update(count) { update(count) {
log.push('update', this.count, (this.count = count)); console.log('update', this.count, (this.count = count));
}, },
destroy() { destroy() {
log.push('destroy', this.count); console.log('destroy', this.count);
}, },
} }
}; };

@ -1,6 +1,4 @@
<script> <script>
import { log } from './log.js';
const { prop } = $props() const { prop } = $props()
let trackedState = $state(0) let trackedState = $state(0)
@ -8,7 +6,7 @@
function dummyAction(el, { getTrackedState, propFromComponent }) { function dummyAction(el, { getTrackedState, propFromComponent }) {
$effect(() => { $effect(() => {
log.push("action $effect: ", { buttonClicked: getTrackedState() }) console.log("action $effect: ", { buttonClicked: getTrackedState() })
}) })
} }
</script> </script>

@ -1,15 +1,10 @@
import { test } from '../../test'; import { test } from '../../test';
import { flushSync, tick } from 'svelte'; import { flushSync } from 'svelte';
import { log } from './log.js';
export default test({ export default test({
before_test() {
log.length = 0;
},
html: `<div class="container">{"text":"initial"}</div><button>update tracked state</button><button>Update prop</button>`, html: `<div class="container">{"text":"initial"}</div><button>update tracked state</button><button>Update prop</button>`,
async test({ assert, target }) { async test({ assert, target, logs }) {
const [btn1, btn2] = target.querySelectorAll('button'); const [btn1, btn2] = target.querySelectorAll('button');
flushSync(() => { flushSync(() => {
@ -30,7 +25,7 @@ export default test({
`<div class="container">{"text":"updated"}</div><button>update tracked state</button><button>Update prop</button>` `<div class="container">{"text":"updated"}</div><button>update tracked state</button><button>Update prop</button>`
); );
assert.deepEqual(log, [ assert.deepEqual(logs, [
'action $effect: ', 'action $effect: ',
{ buttonClicked: 0 }, { buttonClicked: 0 },
'action $effect: ', 'action $effect: ',

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -2,11 +2,10 @@
<script> <script>
import { beforeUpdate } from 'svelte'; import { beforeUpdate } from 'svelte';
import { logs } from './logs.js'
export let object; export let object;
beforeUpdate(() => { beforeUpdate(() => {
logs.push('changed'); console.log('changed');
}); });
</script> </script>

@ -1,20 +1,15 @@
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { test } from '../../test'; import { test } from '../../test';
import { logs } from './logs.js';
export default test({ export default test({
html: `<button>clicks: 0</button>`, html: `<button>clicks: 0</button>`,
test({ assert, target }) { test({ assert, target, logs }) {
const btn = target.querySelector('button'); const btn = target.querySelector('button');
flushSync(() => btn?.click()); flushSync(() => btn?.click());
assert.htmlEqual(target.innerHTML, `<button>clicks: 1</button>`); assert.htmlEqual(target.innerHTML, `<button>clicks: 1</button>`);
assert.deepEqual(logs, ['changed', 'changed']); assert.deepEqual(logs, ['changed', 'changed']);
},
after_test() {
logs.length = 0;
} }
}); });

@ -1,15 +1,10 @@
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
before_test: () => {
log.length = 0;
},
html: `<button>Toggle</button><div>Hello\nworld</div>`, html: `<button>Toggle</button><div>Hello\nworld</div>`,
async test({ assert, target }) { async test({ assert, target, logs }) {
const [btn1] = target.querySelectorAll('button'); const [btn1] = target.querySelectorAll('button');
flushSync(() => { flushSync(() => {
@ -24,6 +19,6 @@ export default test({
assert.htmlEqual(target.innerHTML, `<button>Toggle</button><div>Hello\nworld</div>`); assert.htmlEqual(target.innerHTML, `<button>Toggle</button><div>Hello\nworld</div>`);
assert.deepEqual(log, [{ a: {} }, null, { a: {} }]); assert.deepEqual(logs, [{ a: {} }, null, { a: {} }]);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,12 +1,11 @@
<script> <script>
import { log } from './log.js';
import Component from './Component.svelte'; import Component from './Component.svelte';
let type = $state(Component) let type = $state(Component)
let elem = $state() let elem = $state()
$effect(() => { $effect(() => {
log.push(elem); console.log(elem);
}); });
</script> </script>

@ -1,14 +1,9 @@
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
html: `<button>0</button>`, html: `<button>0</button>`,
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const btn = target.querySelector('button'); const btn = target.querySelector('button');
await btn?.click(); await btn?.click();
@ -17,6 +12,6 @@ export default test({
await btn?.click(); await btn?.click();
assert.htmlEqual(target.innerHTML, `<button>0</button>`); assert.htmlEqual(target.innerHTML, `<button>0</button>`);
assert.deepEqual(log, ['read only', 'read only']); assert.deepEqual(logs, ['read only', 'read only']);
} }
}); });

@ -1,6 +1,4 @@
<script> <script>
import { log } from './log.js';
class Counter { class Counter {
count = $state.frozen({ a: 0 }); count = $state.frozen({ a: 0 });
} }
@ -11,6 +9,6 @@
try { try {
counter.count.a++ counter.count.a++
} catch (e) { } catch (e) {
log.push('read only') console.log('read only')
} }
}}>{counter.count.a}</button> }}>{counter.count.a}</button>

@ -1,14 +1,9 @@
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
html: `<button>0</button>`, html: `<button>0</button>`,
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const btn = target.querySelector('button'); const btn = target.querySelector('button');
await btn?.click(); await btn?.click();
@ -17,6 +12,6 @@ export default test({
await btn?.click(); await btn?.click();
assert.htmlEqual(target.innerHTML, `<button>0</button>`); assert.htmlEqual(target.innerHTML, `<button>0</button>`);
assert.deepEqual(log, ['read only', 'read only']); assert.deepEqual(logs, ['read only', 'read only']);
} }
}); });

@ -1,6 +1,4 @@
<script> <script>
import { log } from './log.js';
class Counter { class Counter {
#count = $state.frozen(); #count = $state.frozen();
@ -22,6 +20,6 @@
try { try {
counter.count.a++ counter.count.a++
} catch (e) { } catch (e) {
log.push('read only') console.log('read only')
} }
}}>{counter.count.a}</button> }}>{counter.count.a}</button>

@ -1,41 +1,36 @@
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
// The component context class instance gets shared between tests, strangely, causing hydration to fail? // The component context class instance gets shared between tests, strangely, causing hydration to fail?
mode: ['client', 'server'], mode: ['client', 'server'],
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const btn = target.querySelector('button'); const btn = target.querySelector('button');
flushSync(() => { flushSync(() => {
btn?.click(); btn?.click();
}); });
assert.deepEqual(log, [0, 'class trigger false', 'local trigger false', 1]); assert.deepEqual(logs, [0, 'class trigger false', 'local trigger false', 1]);
flushSync(() => { flushSync(() => {
btn?.click(); btn?.click();
}); });
assert.deepEqual(log, [0, 'class trigger false', 'local trigger false', 1, 2]); assert.deepEqual(logs, [0, 'class trigger false', 'local trigger false', 1, 2]);
flushSync(() => { flushSync(() => {
btn?.click(); btn?.click();
}); });
assert.deepEqual(log, [0, 'class trigger false', 'local trigger false', 1, 2, 3]); assert.deepEqual(logs, [0, 'class trigger false', 'local trigger false', 1, 2, 3]);
flushSync(() => { flushSync(() => {
btn?.click(); btn?.click();
}); });
assert.deepEqual(log, [ assert.deepEqual(logs, [
0, 0,
'class trigger false', 'class trigger false',
'local trigger false', 'local trigger false',

@ -11,8 +11,6 @@
</script> </script>
<script> <script>
import { log } from './log.js';
function increment() { function increment() {
someLogic.trigger(); someLogic.trigger();
} }
@ -20,13 +18,13 @@
let localDerived = $derived(someLogic.someValue > 3); let localDerived = $derived(someLogic.someValue > 3);
$effect(() => { $effect(() => {
log.push(someLogic.someValue); console.log(someLogic.someValue);
}); });
$effect(() => { $effect(() => {
log.push('class trigger ' + someLogic.isAboveThree) console.log('class trigger ' + someLogic.isAboveThree)
}); });
$effect(() => { $effect(() => {
log.push('local trigger ' + localDerived) console.log('local trigger ' + localDerived)
}); });
</script> </script>

@ -1,14 +1,9 @@
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
html: `<button>0</button>`, html: `<button>0</button>`,
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const btn = target.querySelector('button'); const btn = target.querySelector('button');
await btn?.click(); await btn?.click();
@ -17,6 +12,6 @@ export default test({
await btn?.click(); await btn?.click();
assert.htmlEqual(target.innerHTML, `<button>2</button>`); assert.htmlEqual(target.innerHTML, `<button>2</button>`);
assert.deepEqual(log, [undefined]); assert.deepEqual(logs, [undefined]);
} }
}); });

@ -1,8 +1,6 @@
<script> <script>
import { log } from './log.js';
const logger = (obj) => { const logger = (obj) => {
log.push(obj.count) console.log(obj.count)
} }
class Counter { class Counter {

@ -1,14 +1,9 @@
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
html: `<button>0</button>`, html: `<button>0</button>`,
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const btn = target.querySelector('button'); const btn = target.querySelector('button');
await btn?.click(); await btn?.click();
@ -17,6 +12,6 @@ export default test({
await btn?.click(); await btn?.click();
assert.htmlEqual(target.innerHTML, `<button>2</button>`); assert.htmlEqual(target.innerHTML, `<button>2</button>`);
assert.deepEqual(log, [undefined]); assert.deepEqual(logs, [undefined]);
} }
}); });

@ -1,12 +1,10 @@
<script> <script>
import { log } from './log.js';
class Counter { class Counter {
count = $state(); count = $state();
#count; #count;
constructor(initial_count) { constructor(initial_count) {
log.push(this.count) console.log(this.count)
this.count = initial_count; this.count = initial_count;
} }
} }

@ -1,14 +1,9 @@
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
html: `<button>0</button>`, html: `<button>0</button>`,
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const btn = target.querySelector('button'); const btn = target.querySelector('button');
await btn?.click(); await btn?.click();
@ -17,6 +12,6 @@ export default test({
await btn?.click(); await btn?.click();
assert.htmlEqual(target.innerHTML, `<button>2</button>`); assert.htmlEqual(target.innerHTML, `<button>2</button>`);
assert.deepEqual(log, [100]); assert.deepEqual(logs, [100]);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,12 +1,10 @@
<script> <script>
import { log } from './log.js';
class Counter { class Counter {
count = $state(100); count = $state(100);
#count; #count;
constructor(initial_count) { constructor(initial_count) {
log.push(this.count) console.log(this.count)
this.count = initial_count; this.count = initial_count;
} }
} }

@ -1,28 +1,23 @@
import { test } from '../../test'; import { test } from '../../test';
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { log } from './log.js';
export default test({ export default test({
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const [b1, b2, b3] = target.querySelectorAll('button'); const [b1, b2, b3] = target.querySelectorAll('button');
log.length = 0; logs.length = 0;
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
}); });
assert.deepEqual(log, ['a', 1]); assert.deepEqual(logs, ['a', 1]);
log.length = 0; logs.length = 0;
flushSync(() => { flushSync(() => {
b2.click(); b2.click();
}); });
assert.deepEqual(log, ['b', 1]); assert.deepEqual(logs, ['b', 1]);
log.length = 0; logs.length = 0;
flushSync(() => { flushSync(() => {
b3.click(); b3.click();
}); });
assert.deepEqual(log, ['c', 1]); assert.deepEqual(logs, ['c', 1]);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,21 +1,19 @@
<script> <script>
import { log } from './log.js';
let a = $state(0); let a = $state(0);
let b = $state(0); let b = $state(0);
let c = $state(0); let c = $state(0);
const {a: a1, b: b1, c: c1} = $derived({a, b, c}); const {a: a1, b: b1, c: c1} = $derived({a, b, c});
$effect(() => { $effect(() => {
log.push('a', a1) console.log('a', a1)
}); });
$effect(() => { $effect(() => {
log.push('b', b1) console.log('b', b1)
}); });
$effect(() => { $effect(() => {
log.push('c', c1) console.log('c', c1)
}); });
</script> </script>

@ -1,19 +1,15 @@
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
before_test() { mode: ['server'],
log.length = 0;
},
html: `<button>0</button>`, html: `<button>0</button>`,
async test({ assert, target, window }) { async test({ assert, target, window, logs }) {
const btn = target.querySelector('button'); const btn = target.querySelector('button');
const clickEvent = new window.Event('click', { bubbles: true }); const clickEvent = new window.Event('click', { bubbles: true });
await btn?.dispatchEvent(clickEvent); await btn?.dispatchEvent(clickEvent);
assert.htmlEqual(target.innerHTML, `<button>2</button>`); assert.htmlEqual(target.innerHTML, `<button>2</button>`);
assert.deepEqual(log, ['create_derived']); assert.deepEqual(logs, ['create_derived']);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,9 +1,7 @@
<script> <script>
import {log} from './log.js'
let count = $state(0); let count = $state(0);
function create_derived() { function create_derived() {
log.push('create_derived'); console.log('create_derived');
return () => { return () => {
return { return {
get double() { get double() {

@ -1,13 +1,8 @@
import { test } from '../../test'; import { test } from '../../test';
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { log } from './log.js';
export default test({ export default test({
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const [b1] = target.querySelectorAll('button'); const [b1] = target.querySelectorAll('button');
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
@ -21,6 +16,6 @@ export default test({
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
}); });
assert.deepEqual(log, [0, 2, 4]); assert.deepEqual(logs, [0, 2, 4]);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,12 +1,10 @@
<script> <script>
import { log } from './log.js';
let count = $state(0); let count = $state(0);
const derived = $derived(Math.floor(count / 2)); const derived = $derived(Math.floor(count / 2));
const derived2 = $derived(derived * 2); const derived2 = $derived(derived * 2);
$effect(() => { $effect(() => {
log.push(derived2); console.log(derived2);
}); });
</script> </script>

@ -1,15 +1,10 @@
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target, window }) {
const btn = target.querySelector('button'); const btn = target.querySelector('button');
await btn?.click(); await btn?.click();
assert.deepEqual(log, ['works!']); assert.deepEqual(logs, ['works!']);
} }
}); });

@ -1,9 +1,7 @@
<script> <script>
import { log } from './log.js';
let structured = $state({ let structured = $state({
handler() { handler() {
log.push('works!') console.log('works!')
} }
}); });
</script> </script>

@ -1,31 +1,26 @@
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const [b1, b2] = target.querySelectorAll('button'); const [b1, b2] = target.querySelectorAll('button');
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
}); });
assert.deepEqual(log, ['transition 2']); assert.deepEqual(logs, ['transition 2']);
flushSync(() => { flushSync(() => {
b2.click(); b2.click();
}); });
assert.deepEqual(log, ['transition 2']); assert.deepEqual(logs, ['transition 2']);
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
}); });
assert.deepEqual(log, ['transition 2', 'transition 1']); assert.deepEqual(logs, ['transition 2', 'transition 1']);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,8 +1,6 @@
<script> <script>
import { log } from './log.js';
function transition1() { function transition1() {
log.push('transition 1') console.log('transition 1')
return { return {
tick() { tick() {
@ -11,7 +9,7 @@
} }
function transition2() { function transition2() {
log.push('transition 2') console.log('transition 2')
return { return {
tick() { tick() {

@ -1,13 +1,8 @@
import { test } from '../../test'; import { test } from '../../test';
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { log } from './log.js';
export default test({ export default test({
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const [b1] = target.querySelectorAll('button'); const [b1] = target.querySelectorAll('button');
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
@ -15,6 +10,6 @@ export default test({
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
}); });
assert.deepEqual(log, ['init 0', 'cleanup 2', null, 'init 2', 'cleanup 4', null, 'init 4']); assert.deepEqual(logs, ['init 0', 'cleanup 2', null, 'init 2', 'cleanup 4', null, 'init 4']);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,17 +1,15 @@
<script> <script>
import { log } from './log.js';
let count = $state(0); let count = $state(0);
$effect(() => { $effect(() => {
let double = $derived(count * 2) let double = $derived(count * 2)
log.push('init ' + double); console.log('init ' + double);
return function() { return function() {
log.push('cleanup ' + double); console.log('cleanup ' + double);
// @ts-expect-error // @ts-expect-error
log.push(this); console.log(this);
}; };
}) })
</script> </script>

@ -1,13 +1,8 @@
import { test } from '../../test'; import { test } from '../../test';
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { log } from './log.js';
export default test({ export default test({
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const [b1] = target.querySelectorAll('button'); const [b1] = target.querySelectorAll('button');
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
@ -15,7 +10,7 @@ export default test({
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
}); });
assert.deepEqual(log, [ assert.deepEqual(logs, [
{ a: 1 }, { a: 1 },
{ b: 1 }, { b: 1 },
{ c: 1 }, { c: 1 },

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,19 +1,18 @@
<script> <script>
import { log } from './log.js';
let a = $state(1); let a = $state(1);
let b = $state(1); let b = $state(1);
let c = $state(1); let c = $state(1);
$effect(() => { $effect(() => {
log.push({ a }); console.log({ a });
}); });
$effect(() => { $effect(() => {
log.push({ b }); console.log({ b });
}); });
$effect(() => { $effect(() => {
log.push({ c }); console.log({ c });
}); });
function increment() { function increment() {

@ -1,13 +1,8 @@
import { test } from '../../test'; import { test } from '../../test';
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { log } from './log.js';
export default test({ export default test({
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const [b1] = target.querySelectorAll('button'); const [b1] = target.querySelectorAll('button');
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
@ -15,6 +10,6 @@ export default test({
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
}); });
assert.deepEqual(log, ['A', 'B', 'A', 'B', 'A', 'B']); assert.deepEqual(logs, ['A', 'B', 'A', 'B', 'A', 'B']);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,17 +1,15 @@
<script> <script>
import { log } from './log.js';
let s = $state(0); let s = $state(0);
let d = $derived(s) let d = $derived(s)
$effect(() => { $effect(() => {
s; s;
log.push('A') console.log('A')
}) })
$effect(() => { $effect(() => {
d; d;
log.push('B') console.log('B')
}) })
</script> </script>

@ -1,31 +1,26 @@
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const [b1, b2] = target.querySelectorAll('button'); const [b1, b2] = target.querySelectorAll('button');
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
}); });
assert.deepEqual(log, [0]); assert.deepEqual(logs, [0]);
flushSync(() => { flushSync(() => {
b2.click(); b2.click();
}); });
assert.deepEqual(log, [0, 'cleanup']); assert.deepEqual(logs, [0, 'cleanup']);
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
}); });
assert.deepEqual(log, [0, 'cleanup']); assert.deepEqual(logs, [0, 'cleanup']);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,11 +1,9 @@
<script> <script>
import { log } from './log.js';
let x = $state(0); let x = $state(0);
const cleanup = $effect.root(() => { const cleanup = $effect.root(() => {
log.push(x); console.log(x);
return () => log.push('cleanup'); return () => console.log('cleanup');
}); });
</script> </script>

@ -1,13 +1,8 @@
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const [b1, b2, b3] = target.querySelectorAll('button'); const [b1, b2, b3] = target.querySelectorAll('button');
flushSync(() => { flushSync(() => {
@ -15,19 +10,19 @@ export default test({
b2.click(); b2.click();
}); });
assert.deepEqual(log, [0, 1]); assert.deepEqual(logs, [0, 1]);
flushSync(() => { flushSync(() => {
b3.click(); b3.click();
}); });
assert.deepEqual(log, [0, 1, 'cleanup 1', 'cleanup 2']); assert.deepEqual(logs, [0, 1, 'cleanup 1', 'cleanup 2']);
flushSync(() => { flushSync(() => {
b1.click(); b1.click();
b2.click(); b2.click();
}); });
assert.deepEqual(log, [0, 1, 'cleanup 1', 'cleanup 2']); assert.deepEqual(logs, [0, 1, 'cleanup 1', 'cleanup 2']);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,22 +1,20 @@
<script> <script>
import { log } from './log.js';
let x = $state(0); let x = $state(0);
let y = $state(0); let y = $state(0);
const cleanup = $effect.root(() => { const cleanup = $effect.root(() => {
$effect(() => { $effect(() => {
log.push(x); console.log(x);
}); });
const nested_cleanup = $effect.root(() => { const nested_cleanup = $effect.root(() => {
return () => { return () => {
log.push('cleanup 2'); console.log('cleanup 2');
} }
}); });
return () => { return () => {
log.push('cleanup 1'); console.log('cleanup 1');
nested_cleanup(); nested_cleanup();
} }
}); });

@ -1,17 +1,12 @@
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const [b1, b2] = target.querySelectorAll('button'); const [b1, b2] = target.querySelectorAll('button');
b1.click(); b1.click();
b2.click(); b2.click();
await Promise.resolve(); await Promise.resolve();
assert.deepEqual(log, [0, 1]); assert.deepEqual(logs, [0, 1]);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,11 +1,9 @@
<script> <script>
import { log } from './log.js';
let x = $state(0); let x = $state(0);
let y = $state(0); let y = $state(0);
$effect(() => { $effect(() => {
log.push(x); console.log(x);
}); });
</script> </script>

@ -1,17 +1,12 @@
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const [b1, b2] = target.querySelectorAll('button'); const [b1, b2] = target.querySelectorAll('button');
b1.click(); b1.click();
b2.click(); b2.click();
await Promise.resolve(); await Promise.resolve();
assert.deepEqual(log, ['first0', 'second0', 'first1', 'second1']); assert.deepEqual(logs, ['first0', 'second0', 'first1', 'second1']);
} }
}); });

@ -1,2 +0,0 @@
/** @type {any[]} */
export const log = [];

@ -1,15 +1,13 @@
<script> <script>
import { log } from './log.js';
let x = $state(0); let x = $state(0);
let y = $state(0); let y = $state(0);
$effect.pre(() => { $effect.pre(() => {
log.push('first'+x); console.log('first'+x);
}); });
$effect(() => { $effect(() => {
log.push('second'+x); console.log('second'+x);
}); });
</script> </script>

@ -1,13 +1,8 @@
import { flushSync } from 'svelte'; import { flushSync } from 'svelte';
import { test } from '../../test'; import { test } from '../../test';
import { log } from './log.js';
export default test({ export default test({
before_test() { async test({ assert, target, logs }) {
log.length = 0;
},
async test({ assert, target }) {
const [b1] = target.querySelectorAll('button'); const [b1] = target.querySelectorAll('button');
flushSync(() => { flushSync(() => {
@ -15,6 +10,6 @@ export default test({
}); });
await Promise.resolve(); await Promise.resolve();
assert.deepEqual(log, ['clicked button']); assert.deepEqual(logs, ['clicked button']);
} }
}); });

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save