chore: test for batches flush fix (#16915)

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
pull/16458/merge
Simon H 2 days ago committed by GitHub
parent 844fab7798
commit 9c350cfdab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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,
`
<p>true</p>
<button>toggle</button>
<button>shift</button>
`
);
const toggle = target.querySelector('button');
toggle?.click();
await tick();
assert.htmlEqual(
target.innerHTML,
`
<p>true</p>
<button>toggle</button>
<button>shift</button>
`
);
shift?.click();
await tick();
assert.htmlEqual(
target.innerHTML,
`
<p>true</p>
<button>toggle</button>
<button>shift</button>
`
);
shift?.click();
await tick();
assert.htmlEqual(
target.innerHTML,
`
<button>toggle</button>
<button>shift</button>
`
);
}
});

@ -0,0 +1,41 @@
<script>
let show = $state(true);
let count = $state(0);
let queue = [];
function foo() {
const {promise, resolve} = Promise.withResolvers();
const s = show;
queue.push(() => resolve(s));
return promise;
}
function bar() {
const {promise, resolve} = Promise.withResolvers();
const s = show;
queue.push(() => {
// This will create a new batch while the other batch is still in flight
count++
resolve(s);
});
return promise;
}
$effect(() => { count; });
</script>
<svelte:boundary>
{#if await foo()}
<p>{await bar()}</p>
{/if}
<button onclick={() => {
show = !show
}}>toggle</button>
{#snippet pending()}
<p>loading...</p>
{/snippet}
</svelte:boundary>
<button onclick={() => queue.shift()()}>shift</button>
Loading…
Cancel
Save