From b3d175d1794705291a779dd51d66fcd843a964af Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Wed, 8 Oct 2025 14:55:24 +0200 Subject: [PATCH] chore: test for batches flush fix Test for #16912 Also some explanation what the bug was: 1. async batch kicks off 2. outer async work succeeds, still something pending, so doesn't do anything for now 3. something unrelated writes to a signal (in the remote functions case it's the query writing to loading, raw etc), which creates a new batch 4. new batch executes. since there are multiple batches it takes the previous value which means if block is still alive. commits that, since no async work from the perspective of this branch 5. inner async work succeeds. now the batch has zero pending async work so it can flush. But the if block is no longer dirty since it was done by the other batch already -> never undos the other work #16912 fixes it by still traversing the tree which means the if block deletion is scheduled to commit later, which it then does --- .../async-inner-after-outer/_config.js | 57 +++++++++++++++++++ .../async-inner-after-outer/main.svelte | 41 +++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 packages/svelte/tests/runtime-runes/samples/async-inner-after-outer/_config.js create mode 100644 packages/svelte/tests/runtime-runes/samples/async-inner-after-outer/main.svelte diff --git a/packages/svelte/tests/runtime-runes/samples/async-inner-after-outer/_config.js b/packages/svelte/tests/runtime-runes/samples/async-inner-after-outer/_config.js new file mode 100644 index 000000000000..8905ee4bf556 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-inner-after-outer/_config.js @@ -0,0 +1,57 @@ +import { tick } from 'svelte'; +import { test } from '../../test'; + +export default test({ + async test({ assert, target }) { + const shift = document.querySelector('button'); + shift?.click(); + await tick(); + shift?.click(); + await tick(); + + assert.htmlEqual( + target.innerHTML, + ` +

true

+ + + ` + ); + + const toggle = target.querySelector('button'); + toggle?.click(); + await tick(); + + assert.htmlEqual( + target.innerHTML, + ` +

true

+ + + ` + ); + + shift?.click(); + await tick(); + + assert.htmlEqual( + target.innerHTML, + ` +

true

+ + + ` + ); + + shift?.click(); + await tick(); + + assert.htmlEqual( + target.innerHTML, + ` + + + ` + ); + } +}); diff --git a/packages/svelte/tests/runtime-runes/samples/async-inner-after-outer/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-inner-after-outer/main.svelte new file mode 100644 index 000000000000..0b3b21f28cb8 --- /dev/null +++ b/packages/svelte/tests/runtime-runes/samples/async-inner-after-outer/main.svelte @@ -0,0 +1,41 @@ + + + + {#if await foo()} +

{await bar()}

+ {/if} + + + + {#snippet pending()} +

loading...

+ {/snippet} +
+ + \ No newline at end of file