test: cover branch commit order and merged blocking pending

async-another-try-pt-1-prune
Nic 8 hours ago
parent 8ab778b621
commit 28fb668d48

@ -0,0 +1,31 @@
import { tick } from 'svelte';
import { test } from '../../test';
const buttons =
'<button>a</button><button>b</button><button>resolve a1</button><button>resolve b1</button>';
export default test({
async test({ assert, target }) {
await tick();
const [a, b, resolve_a1, resolve_b1] = target.querySelectorAll('button');
assert.htmlEqual(target.innerHTML, `<p>0</p><p>0</p>${buttons}`);
// batch A waits on its key; batch B registers its key right away
a.click();
await tick();
b.click();
await tick();
assert.htmlEqual(target.innerHTML, `<p>0</p><p>0</p>${buttons}`);
// the older batch commits first
resolve_a1.click();
await tick();
assert.htmlEqual(target.innerHTML, `<p>0</p><p>1</p>${buttons}`);
// the newer batch commits with its own branch
resolve_b1.click();
await tick();
assert.htmlEqual(target.innerHTML, `<p>1</p><p>B</p>${buttons}`);
}
});

@ -0,0 +1,30 @@
<script>
let a = $state(0);
let b = $state(0);
let pend = false;
const pending = new Map();
function delay(key, value) {
if (!pend) return value;
return new Promise((resolve) => pending.set(key, () => resolve(value)));
}
function resolve(key) {
pending.get(key)();
pending.delete(key);
}
const k = $derived(b === 0 ? await delay(`a${a}`, a) : 'B');
</script>
<p>{await delay(`b${b}`, b)}</p>
{#key k}
<p>{k}</p>
{/key}
<button onclick={() => { pend = true; a = 1; }}>a</button>
<button onclick={() => { pend = true; b = 1; }}>b</button>
<button onclick={() => resolve('a1')}>resolve a1</button>
<button onclick={() => resolve('b1')}>resolve b1</button>

@ -0,0 +1,38 @@
import { tick } from 'svelte';
import { test } from '../../test';
const buttons =
'<button>X</button><button>Y</button><button>Z</button><button>W</button><button>resolve e</button><button>resolve x1</button>';
export default test({
async test({ assert, target, logs }) {
await tick();
const [X, Y, Z, W, resolve_e, resolve_x1] = target.querySelectorAll('button');
assert.htmlEqual(target.innerHTML, `<p>n = 0</p><p>x = 0</p>${buttons}`);
// X is deferred on its own await
X.click();
await tick();
// Y is deferred on the await inside the new branch
Y.click();
await tick();
// Z hides that branch again, merges into Y, which merges into X
Z.click();
await tick();
assert.htmlEqual(target.innerHTML, `<p>n = 0</p><p>x = 0</p>${buttons}`);
assert.deepEqual(logs, ['delay x0', 'delay x1', 'delay e']);
// the branch's await resolves while it is hidden
resolve_e.click();
await tick();
// W shows the branch again and merges into X
W.click();
await tick();
// nothing is pending any more, so X commits
resolve_x1.click();
await tick();
assert.htmlEqual(target.innerHTML, `<p>n = 4</p><p>x = 1</p><p>cond: e</p>${buttons}`);
}
});

@ -0,0 +1,38 @@
<script>
let n = $state(0);
let x = $state(0);
let cond = $state(false);
let pend = false;
const pending = new Map();
function delay(key, value) {
console.log(`delay ${key}`);
if (!pend) return value;
return new Promise((resolve) => pending.set(key, () => resolve(value)));
}
function resolve(key) {
pending.get(key)();
pending.delete(key);
}
</script>
<svelte:boundary>
<p>n = {n}</p>
<p>x = {await delay(`x${x}`, x)}</p>
{#if cond}
<p>cond: {await delay('e', 'e')}</p>
{/if}
{#snippet pending()}
<p>loading</p>
{/snippet}
</svelte:boundary>
<button onclick={() => { pend = true; n++; x = 1; }}>X</button>
<button onclick={() => { n++; cond = true; }}>Y</button>
<button onclick={() => { n++; cond = false; }}>Z</button>
<button onclick={() => { n++; cond = true; }}>W</button>
<button onclick={() => resolve('e')}>resolve e</button>
<button onclick={() => resolve('x1')}>resolve x1</button>
Loading…
Cancel
Save