diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-1/_config.js b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-1/_config.js
new file mode 100644
index 0000000000..03d8e49b6f
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-1/_config.js
@@ -0,0 +1,107 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ async test({ assert, target }) {
+ await tick();
+ const [a_b, a_c, b_d, shift, pop] = target.querySelectorAll('button');
+
+ a_b.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ a_c.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ b_d.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 1 | b 1 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 2 | b 1 | c 1 | d 0
+
+
+
+
+
+ `
+ );
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 2 | b 2 | c 1 | d 1
+
+
+
+
+
+ `
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-1/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-1/main.svelte
new file mode 100644
index 0000000000..25dbe586ca
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-1/main.svelte
@@ -0,0 +1,26 @@
+
+
+a {await delay(a)} | b {await delay(b)} | c {c} | d {d}
+
+
+
+
+
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-2/_config.js b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-2/_config.js
new file mode 100644
index 0000000000..f4aff83aad
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-2/_config.js
@@ -0,0 +1,82 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ skip: true, // TODO works on https://github.com/sveltejs/svelte/pull/17971
+ async test({ assert, target }) {
+ await tick();
+ const [a_b, a_c, b_d, shift, pop] = target.querySelectorAll('button');
+
+ a_b.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ a_c.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ b_d.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ pop.click(); // second b resolved, blocked on first batch because a still pending
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ for (let i = 0; i < 3; i++) {
+ pop.click(); // second a resolved, first a/b now obsolete; empty queue
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 2 | b 2 | c 1 | d 1
+
+
+
+
+
+ `
+ );
+ }
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-2/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-2/main.svelte
new file mode 100644
index 0000000000..25dbe586ca
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-2/main.svelte
@@ -0,0 +1,26 @@
+
+
+a {await delay(a)} | b {await delay(b)} | c {c} | d {d}
+
+
+
+
+
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-3/_config.js b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-3/_config.js
new file mode 100644
index 0000000000..c9e7513b22
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-3/_config.js
@@ -0,0 +1,108 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ skip: true, // TODO works on https://github.com/sveltejs/svelte/pull/17971
+ async test({ assert, target }) {
+ await tick();
+ const [a_b, a_c, b_d, shift, pop] = target.querySelectorAll('button');
+
+ a_b.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ a_c.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ b_d.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ shift.click(); // first a resolved, still pending: [b, a, b]
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ pop.click(); // second b resolved, still pending: [b, a]
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ shift.click(); // first b resolved, first + last batch settled, still pending: [a]
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 1 | b 2 | c 0 | d 1
+
+
+
+
+
+ `
+ );
+
+ shift.click(); // all resolved
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 2 | b 2 | c 1 | d 1
+
+
+
+
+
+ `
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-3/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-3/main.svelte
new file mode 100644
index 0000000000..25dbe586ca
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-3/main.svelte
@@ -0,0 +1,26 @@
+
+
+a {await delay(a)} | b {await delay(b)} | c {c} | d {d}
+
+
+
+
+
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-4/_config.js b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-4/_config.js
new file mode 100644
index 0000000000..472a3ebcaf
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-4/_config.js
@@ -0,0 +1,110 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ skip: true, // TODO works on https://github.com/sveltejs/svelte/pull/17971
+ async test({ assert, target }) {
+ await tick();
+ const [a_b, a_c, b_d, shift, pop] = target.querySelectorAll('button');
+
+ a_b.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ a_c.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ b_d.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ shift.click(); // first a resolved, still pending: [b, a, b]
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ pop.click(); // second b resolved, still pending: [b, a]
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ pop.click(); // second a resolved, first a/b now obsolete
+ // TODO would be nice to show final result here already, right now it doesn't because
+ // we have no handle on the already resolved first a anymore
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+
+ `
+ );
+
+ shift.click(); // queue empty
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 2 | b 2 | c 1 | d 1
+
+
+
+
+
+ `
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-4/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-4/main.svelte
new file mode 100644
index 0000000000..25dbe586ca
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-4/main.svelte
@@ -0,0 +1,26 @@
+
+
+a {await delay(a)} | b {await delay(b)} | c {c} | d {d}
+
+
+
+
+
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-5/_config.js b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-5/_config.js
new file mode 100644
index 0000000000..d03f3cfbb8
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-5/_config.js
@@ -0,0 +1,118 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ async test({ assert, target }) {
+ await tick();
+ const [a, c, shift, pop] = target.querySelectorAll('button');
+
+ a.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+ `
+ );
+
+ c.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+ `
+ );
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+ `
+ );
+
+ // how it's on main
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 1 | d 1
+
+
+
+
+ `
+ );
+
+ shift.click();
+ await tick();
+ shift.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 1 | b 2 | c 1 | d 3
+
+
+
+
+ `
+ );
+
+ // how it's on https://github.com/sveltejs/svelte/pull/17971
+ // shift.click();
+ // await tick();
+ // assert.htmlEqual(
+ // target.innerHTML,
+ // `
+ // a 0 | b 0 | c 0 | d 0
+ //
+ //
+ //
+ //
+ // `
+ // );
+
+ // shift.click();
+ // await tick();
+ // assert.htmlEqual(
+ // target.innerHTML,
+ // `
+ // a 1 | b 2 | c 0 | d 2
+ //
+ //
+ //
+ //
+ // `
+ // );
+
+ // shift.click();
+ // await tick();
+ // assert.htmlEqual(
+ // target.innerHTML,
+ // `
+ // a 1 | b 2 | c 1 | d 3
+ //
+ //
+ //
+ //
+ // `
+ // );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-5/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-5/main.svelte
new file mode 100644
index 0000000000..cf028718c2
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-5/main.svelte
@@ -0,0 +1,23 @@
+
+
+a {a} | b {b} | c {c} | d {d}
+
+
+
+
\ No newline at end of file
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-6/_config.js b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-6/_config.js
new file mode 100644
index 0000000000..27152889a2
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-6/_config.js
@@ -0,0 +1,76 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ async test({ assert, target }) {
+ await tick();
+ const [a, c, shift, pop] = target.querySelectorAll('button');
+
+ a.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+ `
+ );
+
+ c.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+ `
+ );
+
+ // Although the second batch is eventually connected to the first one, we can't see that
+ // at this point yet and so the second one flushes right away.
+ pop.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 1 | d 1
+
+
+
+
+ `
+ );
+
+ pop.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 1 | d 1
+
+
+
+
+ `
+ );
+
+ pop.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 1 | b 2 | c 1 | d 3
+
+
+
+
+ `
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-6/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-6/main.svelte
new file mode 100644
index 0000000000..cf028718c2
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-6/main.svelte
@@ -0,0 +1,23 @@
+
+
+a {a} | b {b} | c {c} | d {d}
+
+
+
+
\ No newline at end of file
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-7/_config.js b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-7/_config.js
new file mode 100644
index 0000000000..b1bf53a2fc
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-7/_config.js
@@ -0,0 +1,129 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ async test({ assert, target }) {
+ await tick();
+ const [a, c, shift, pop] = target.querySelectorAll('button');
+
+ a.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+ `
+ );
+
+ c.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+ `
+ );
+
+ shift.click(); // schedules second step of first batch and schedules rerun of second batch
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 0 | b 0 | c 0 | d 0
+
+
+
+
+ `
+ );
+
+ // how it's on main
+
+ pop.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 1 | b 2 | c 0 | d 2
+
+
+
+
+ `
+ );
+
+ shift.click(); // obsolete second batch promise (already rejected)
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 1 | b 2 | c 0 | d 2
+
+
+
+
+ `
+ );
+
+ shift.click(); // first batch resolves
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+ a 1 | b 2 | c 1 | d 3
+
+
+
+
+ `
+ );
+
+ // how it's on https://github.com/sveltejs/svelte/pull/17971
+ // pop.click(); // second batch resolves but knows it needs to wait on first batch
+ // await tick();
+ // assert.htmlEqual(
+ // target.innerHTML,
+ // `
+ // a 0 | b 0 | c 0 | d 0
+ //
+ //
+ //
+ //
+ // `
+ // );
+
+ // shift.click(); // obsolete second batch promise (already rejected)
+ // await tick();
+ // assert.htmlEqual(
+ // target.innerHTML,
+ // `
+ // a 0 | b 0 | c 0 | d 0
+ //
+ //
+ //
+ //
+ // `
+ // );
+
+ // shift.click(); // first batch resolves, with it second can now resolve as well
+ // await tick();
+ // assert.htmlEqual(
+ // target.innerHTML,
+ // `
+ // a 1 | b 2 | c 1 | d 3
+ //
+ //
+ //
+ //
+ // `
+ // );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-7/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-7/main.svelte
new file mode 100644
index 0000000000..cf028718c2
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-7/main.svelte
@@ -0,0 +1,23 @@
+
+
+a {a} | b {b} | c {c} | d {d}
+
+
+
+
\ No newline at end of file
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-1/_config.js b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-1/_config.js
new file mode 100644
index 0000000000..07ce7e340f
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-1/_config.js
@@ -0,0 +1,34 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ async test({ assert, target }) {
+ await tick();
+ const [a_b_fork, a_c, shift, pop, commit] = target.querySelectorAll('button');
+ const [p] = target.querySelectorAll('p');
+
+ a_b_fork.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 0 | b 0 | c 0');
+
+ a_c.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 0 | b 0 | c 0');
+
+ pop.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 1 | b 0 | c 1');
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 1 | b 0 | c 1');
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 1 | b 0 | c 1');
+
+ commit.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 1 | b 1 | c 1');
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-1/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-1/main.svelte
new file mode 100644
index 0000000000..60ba74fb8e
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-1/main.svelte
@@ -0,0 +1,27 @@
+
+
+
a {await delay(a)} | b {await delay(b)} | c {c}
+
+
+
+
+
+
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-2/_config.js b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-2/_config.js
new file mode 100644
index 0000000000..180a190dae
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-2/_config.js
@@ -0,0 +1,42 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ async test({ assert, target }) {
+ await tick();
+ const [a_b_fork, a_c, b_d, shift, pop, commit] = target.querySelectorAll('button');
+ const [p] = target.querySelectorAll('p');
+
+ a_b_fork.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 0 | b 0 | c 0 | d 0');
+
+ a_c.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 0 | b 0 | c 0 | d 0');
+
+ b_d.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 0 | b 0 | c 0 | d 0');
+
+ pop.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 0 | b 1 | c 0 | d 1');
+
+ pop.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 1 | b 1 | c 1 | d 1');
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 1 | b 1 | c 1 | d 1');
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 1 | b 1 | c 1 | d 1');
+
+ commit.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 1 | b 1 | c 1 | d 1');
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-2/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-2/main.svelte
new file mode 100644
index 0000000000..6d1c4ab418
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-2/main.svelte
@@ -0,0 +1,31 @@
+
+
+a {await delay(a)} | b {await delay(b)} | c {c} | d {d}
+
+
+
+
+
+
+
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-3/_config.js b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-3/_config.js
new file mode 100644
index 0000000000..61360d8dc9
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-3/_config.js
@@ -0,0 +1,43 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ skip: true,
+ async test({ assert, target }) {
+ await tick();
+ const [a_b_fork, a_c, b_d, shift, pop, commit] = target.querySelectorAll('button');
+ const [p] = target.querySelectorAll('p');
+
+ a_b_fork.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 0 | b 0 | c 0 | d 0');
+
+ a_c.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 0 | b 0 | c 0 | d 0');
+
+ b_d.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 0 | b 0 | c 0 | d 0');
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 0 | b 0 | c 0 | d 0');
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 0 | b 0 | c 0 | d 0');
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 1 | b 0 | c 1 | d 0');
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 1 | b 1 | c 1 | d 1');
+
+ commit.click();
+ await tick();
+ assert.htmlEqual(p.innerHTML, 'a 1 | b 1 | c 1 | d 1');
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-3/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-3/main.svelte
new file mode 100644
index 0000000000..6d1c4ab418
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-overlap-multiple-fork-3/main.svelte
@@ -0,0 +1,31 @@
+
+
+a {await delay(a)} | b {await delay(b)} | c {c} | d {d}
+
+
+
+
+
+
+
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-1/Child.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-1/Child.svelte
new file mode 100644
index 0000000000..6b765526c8
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-1/Child.svelte
@@ -0,0 +1,7 @@
+
+
+{x}
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-1/_config.js b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-1/_config.js
new file mode 100644
index 0000000000..0af275009c
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-1/_config.js
@@ -0,0 +1,38 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ skip: true, // TODO works on https://github.com/sveltejs/svelte/pull/17971
+ async test({ assert, target, logs }) {
+ const [x, y, resolve] = target.querySelectorAll('button');
+
+ x.click();
+ await tick();
+
+ y.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+ ` // if this shows world world - that would also be ok
+ );
+
+ resolve.click();
+ await tick();
+ assert.deepEqual(logs, ['universe', 'universe', '$effect: universe', '$effect: universe']);
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+ universe
+ universe
+ universe
+ `
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-1/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-1/main.svelte
new file mode 100644
index 0000000000..8edc718de2
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-1/main.svelte
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+{#if x === 'universe'}
+ {await delay(x)}
+
+{/if}
+
+{#if y > 0}
+
+{/if}
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-2/Child.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-2/Child.svelte
new file mode 100644
index 0000000000..f8c01e9efd
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-2/Child.svelte
@@ -0,0 +1,11 @@
+
+
+
+{x}
+{JSON.stringify(x)}
+{#if x === 'universe'}universe{:else}world{/if}
+{#if JSON.stringify(x) === '"universe"'}universe{:else}world{/if}
+{await Promise.resolve(x)}
+{await Promise.resolve(JSON.stringify(x))}
\ No newline at end of file
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-2/_config.js b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-2/_config.js
new file mode 100644
index 0000000000..035616dfb6
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-2/_config.js
@@ -0,0 +1,49 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ skip: true, // TODO works on https://github.com/sveltejs/svelte/pull/17971
+ async test({ assert, target }) {
+ const [x, y, resolve] = target.querySelectorAll('button');
+
+ x.click();
+ await tick();
+
+ y.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+ ` // if this shows world world "world" world world world "world" - then this would also be ok
+ );
+
+ resolve.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+ universe
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+ `
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-2/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-2/main.svelte
new file mode 100644
index 0000000000..11c4bdf5d1
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-2/main.svelte
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+{#if x === 'universe'}
+ {await delay(x)}
+
+{/if}
+
+
+
+{#if y > 0}
+
+{/if}
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-3/Child.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-3/Child.svelte
new file mode 100644
index 0000000000..f8c01e9efd
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-3/Child.svelte
@@ -0,0 +1,11 @@
+
+
+
+{x}
+{JSON.stringify(x)}
+{#if x === 'universe'}universe{:else}world{/if}
+{#if JSON.stringify(x) === '"universe"'}universe{:else}world{/if}
+{await Promise.resolve(x)}
+{await Promise.resolve(JSON.stringify(x))}
\ No newline at end of file
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-3/_config.js b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-3/_config.js
new file mode 100644
index 0000000000..a2d615b6e5
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-3/_config.js
@@ -0,0 +1,61 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ skip: true, // TODO works on https://github.com/sveltejs/svelte/pull/17971
+ async test({ assert, target }) {
+ const [x, y, resolve] = target.querySelectorAll('button');
+
+ x.click();
+ await tick();
+
+ y.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+ `
+ );
+
+ resolve.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+ ` // if this shows world world "world" world world world "world" - then this would also be ok
+ );
+
+ resolve.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+ universe
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+ `
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-3/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-3/main.svelte
new file mode 100644
index 0000000000..b02ab20995
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-3/main.svelte
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+{#if x === 'universe'}
+ {await delay(x)}
+
+{/if}
+
+
+
+{#if y > 0}
+
+{/if}
+
\ No newline at end of file
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-all-combinations/Child.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-all-combinations/Child.svelte
new file mode 100644
index 0000000000..f8c01e9efd
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-all-combinations/Child.svelte
@@ -0,0 +1,11 @@
+
+
+
+{x}
+{JSON.stringify(x)}
+{#if x === 'universe'}universe{:else}world{/if}
+{#if JSON.stringify(x) === '"universe"'}universe{:else}world{/if}
+{await Promise.resolve(x)}
+{await Promise.resolve(JSON.stringify(x))}
\ No newline at end of file
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-all-combinations/_config.js b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-all-combinations/_config.js
new file mode 100644
index 0000000000..8b7e7784de
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-all-combinations/_config.js
@@ -0,0 +1,171 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ skip: true, // TODO more combinations pass on https://github.com/sveltejs/svelte/pull/17971
+ timeout: 20_000,
+ async test({ assert, target }) {
+ const [x, fork_x, y, fork_y, shift, pop, commit_x, commit_y, reset] =
+ target.querySelectorAll('button');
+
+ const initial = `
+
+
+
+
+
+
+
+
+
+
+ `;
+
+ const final = `
+
+
+
+
+
+
+
+
+
+ universe
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+ `;
+
+ /** @param {HTMLElement} button */
+ async function click(button) {
+ button.click();
+ await tick();
+ }
+
+ /**
+ * Generate all permutations of an array.
+ * @param {HTMLElement[]} actions
+ * @returns {HTMLElement[][]}
+ */
+ function permutations(actions) {
+ if (actions.length <= 1) return [actions];
+
+ /** @type {HTMLElement[][]} */
+ const result = [];
+
+ for (let i = 0; i < actions.length; i++) {
+ const head = actions[i];
+ const rest = actions.slice(0, i).concat(actions.slice(i + 1));
+ for (const tail of permutations(rest)) {
+ result.push([head, ...tail]);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Keep only valid orders where fork commits happen after their fork action.
+ * @param {HTMLElement[]} order
+ */
+ function is_valid_order(order) {
+ const x_fork_index = order.indexOf(fork_x);
+ const commit_x_index = order.indexOf(commit_x);
+ if (commit_x_index !== -1 && (x_fork_index === -1 || commit_x_index < x_fork_index)) {
+ return false;
+ }
+
+ const y_fork_index = order.indexOf(fork_y);
+ const commit_y_index = order.indexOf(commit_y);
+ if (commit_y_index !== -1 && (y_fork_index === -1 || commit_y_index < y_fork_index)) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Four control scenarios:
+ * - x direct, y direct
+ * - x direct, y via fork+commit
+ * - x via fork+commit, y direct
+ * - x via fork+commit, y via fork+commit
+ */
+ const control_scenarios = [
+ [x, y],
+ [x, fork_y, commit_y],
+ [fork_x, commit_x, y],
+ [fork_x, commit_x, fork_y, commit_y]
+ ];
+
+ const control_orders = control_scenarios.flatMap((scenario) =>
+ permutations(scenario).filter(is_valid_order)
+ );
+
+ /**
+ * All shift/pop combinations for draining async work.
+ * We click three times because this scenario can queue up to 3 deferred resolutions.
+ */
+ const resolve_orders = [
+ [shift, shift, shift],
+ [shift, pop, pop],
+ [pop, shift, shift],
+ [pop, pop, pop]
+ ];
+
+ for (const controls of control_orders) {
+ for (const resolves of resolve_orders) {
+ for (const action of controls) {
+ await click(action);
+ }
+
+ for (const action of resolves) {
+ await click(action);
+ }
+
+ const failure_msg = `Failed for: ${controls
+ .map((btn) => btn.textContent)
+ .concat(...resolves.map((btn) => btn.textContent))
+ .join(', ')}`;
+ assert.htmlEqual(target.innerHTML, final, failure_msg);
+
+ await click(reset);
+ assert.htmlEqual(target.innerHTML, initial, failure_msg);
+ }
+ }
+
+ const other_scenarios = [
+ [x, shift, y, shift, shift],
+ [x, shift, y, pop, pop],
+ [fork_x, shift, y, shift, commit_x, shift],
+ [fork_x, shift, y, pop, commit_x, pop],
+ [y, shift, x, shift, shift],
+ [y, shift, x, pop, pop],
+ [fork_y, shift, x, shift, commit_y, shift],
+ [fork_y, shift, x, pop, commit_y, pop]
+ ];
+
+ for (const scenario of other_scenarios) {
+ for (const action of scenario) {
+ await click(action);
+ }
+
+ const failure_msg = `Failed for: ${scenario.map((btn) => btn.textContent).join(', ')}`;
+ assert.htmlEqual(target.innerHTML, final, failure_msg);
+
+ await click(reset);
+ assert.htmlEqual(target.innerHTML, initial, failure_msg);
+ }
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-all-combinations/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-all-combinations/main.svelte
new file mode 100644
index 0000000000..bb821d9b0f
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-all-combinations/main.svelte
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+{#if x === 'universe'}
+ {await delay(x)}
+
+{/if}
+
+
+
+{#if y > 0}
+
+{/if}
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-1/Child.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-1/Child.svelte
new file mode 100644
index 0000000000..f8c01e9efd
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-1/Child.svelte
@@ -0,0 +1,11 @@
+
+
+
+{x}
+{JSON.stringify(x)}
+{#if x === 'universe'}universe{:else}world{/if}
+{#if JSON.stringify(x) === '"universe"'}universe{:else}world{/if}
+{await Promise.resolve(x)}
+{await Promise.resolve(JSON.stringify(x))}
\ No newline at end of file
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-1/_config.js b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-1/_config.js
new file mode 100644
index 0000000000..737169cb91
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-1/_config.js
@@ -0,0 +1,90 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ skip: true, // TODO works on https://github.com/sveltejs/svelte/pull/17971
+ async test({ assert, target }) {
+ const [x, y, shift, pop, commit] = target.querySelectorAll('button');
+
+ x.click();
+ await tick();
+
+ y.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+
+ `
+ );
+
+ commit.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+
+ `
+ );
+
+ shift.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+ universe
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+
+ `
+ );
+
+ shift.click();
+ await tick();
+ shift.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+ universe
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+ `
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-1/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-1/main.svelte
new file mode 100644
index 0000000000..5f8d5efa13
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-1/main.svelte
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+{#if x === 'universe'}
+ {await delay(x)}
+
+{/if}
+
+
+
+{#if y > 0}
+
+{/if}
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-2/Child.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-2/Child.svelte
new file mode 100644
index 0000000000..f8c01e9efd
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-2/Child.svelte
@@ -0,0 +1,11 @@
+
+
+
+{x}
+{JSON.stringify(x)}
+{#if x === 'universe'}universe{:else}world{/if}
+{#if JSON.stringify(x) === '"universe"'}universe{:else}world{/if}
+{await Promise.resolve(x)}
+{await Promise.resolve(JSON.stringify(x))}
\ No newline at end of file
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-2/_config.js b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-2/_config.js
new file mode 100644
index 0000000000..a712e70630
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-2/_config.js
@@ -0,0 +1,71 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ skip: true, // TODO works on https://github.com/sveltejs/svelte/pull/17971
+ async test({ assert, target }) {
+ const [x, y, shift, pop, commit] = target.querySelectorAll('button');
+
+ y.click();
+ await tick();
+
+ x.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+
+ `
+ );
+
+ commit.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+
+ `
+ );
+
+ shift.click();
+ await tick();
+ shift.click();
+ await tick();
+ shift.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+ universe
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+ `
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-2/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-2/main.svelte
new file mode 100644
index 0000000000..5f8d5efa13
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-2/main.svelte
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+{#if x === 'universe'}
+ {await delay(x)}
+
+{/if}
+
+
+
+{#if y > 0}
+
+{/if}
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-3/Child.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-3/Child.svelte
new file mode 100644
index 0000000000..f8c01e9efd
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-3/Child.svelte
@@ -0,0 +1,11 @@
+
+
+
+{x}
+{JSON.stringify(x)}
+{#if x === 'universe'}universe{:else}world{/if}
+{#if JSON.stringify(x) === '"universe"'}universe{:else}world{/if}
+{await Promise.resolve(x)}
+{await Promise.resolve(JSON.stringify(x))}
\ No newline at end of file
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-3/_config.js b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-3/_config.js
new file mode 100644
index 0000000000..905e76511b
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-3/_config.js
@@ -0,0 +1,70 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ async test({ assert, target }) {
+ const [x, y, shift, pop, commit] = target.querySelectorAll('button');
+
+ y.click();
+ await tick();
+
+ x.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+
+ `
+ );
+
+ commit.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+
+ `
+ );
+
+ pop.click();
+ await tick();
+ pop.click();
+ await tick();
+ pop.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+ universe
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+ `
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-3/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-3/main.svelte
new file mode 100644
index 0000000000..5f8d5efa13
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-3/main.svelte
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+{#if x === 'universe'}
+ {await delay(x)}
+
+{/if}
+
+
+
+{#if y > 0}
+
+{/if}
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-4/Child.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-4/Child.svelte
new file mode 100644
index 0000000000..f8c01e9efd
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-4/Child.svelte
@@ -0,0 +1,11 @@
+
+
+
+{x}
+{JSON.stringify(x)}
+{#if x === 'universe'}universe{:else}world{/if}
+{#if JSON.stringify(x) === '"universe"'}universe{:else}world{/if}
+{await Promise.resolve(x)}
+{await Promise.resolve(JSON.stringify(x))}
\ No newline at end of file
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-4/_config.js b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-4/_config.js
new file mode 100644
index 0000000000..6a6399a19e
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-4/_config.js
@@ -0,0 +1,76 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ skip: true, // TODO works on https://github.com/sveltejs/svelte/pull/17971
+ async test({ assert, target }) {
+ const [x, y, resolve, commit] = target.querySelectorAll('button');
+
+ x.click();
+ await tick();
+
+ y.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+ world
+ "world"
+ world
+ world
+ world
+ "world"
+ `
+ );
+
+ commit.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+ world
+ "world"
+ world
+ world
+ world
+ "world"
+ `
+ );
+
+ resolve.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+ universe
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+ `
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-4/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-4/main.svelte
new file mode 100644
index 0000000000..5f00fc4dec
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-4/main.svelte
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+{#if x === 'universe'}
+ {await delay(x)}
+
+{/if}
+
+
+
+{#if y > 0}
+
+{/if}
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-5/Child.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-5/Child.svelte
new file mode 100644
index 0000000000..f8c01e9efd
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-5/Child.svelte
@@ -0,0 +1,11 @@
+
+
+
+{x}
+{JSON.stringify(x)}
+{#if x === 'universe'}universe{:else}world{/if}
+{#if JSON.stringify(x) === '"universe"'}universe{:else}world{/if}
+{await Promise.resolve(x)}
+{await Promise.resolve(JSON.stringify(x))}
\ No newline at end of file
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-5/_config.js b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-5/_config.js
new file mode 100644
index 0000000000..9221a96c2e
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-5/_config.js
@@ -0,0 +1,85 @@
+import { tick } from 'svelte';
+import { test } from '../../test';
+
+export default test({
+ skip: true, // TODO works on https://github.com/sveltejs/svelte/pull/17971
+ async test({ assert, target }) {
+ const [x, y, resolve, commit] = target.querySelectorAll('button');
+
+ x.click();
+ await tick();
+
+ y.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+ `
+ );
+
+ commit.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+ `
+ );
+
+ resolve.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+
+ world
+ "world"
+ world
+ world
+ world
+ "world"
+ `
+ );
+
+ resolve.click();
+ await tick();
+ resolve.click();
+ await tick();
+ assert.htmlEqual(
+ target.innerHTML,
+ `
+
+
+
+
+ universe
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+
+ universe
+ "universe"
+ universe
+ universe
+ universe
+ "universe"
+ `
+ );
+ }
+});
diff --git a/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-5/main.svelte b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-5/main.svelte
new file mode 100644
index 0000000000..5575e3cbd4
--- /dev/null
+++ b/packages/svelte/tests/runtime-runes/samples/async-state-new-branch-fork-5/main.svelte
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+{#if x === 'universe'}
+ {await delay(x)}
+
+{/if}
+
+
+
+{#if y > 0}
+
+{/if}
diff --git a/packages/svelte/tests/suite.ts b/packages/svelte/tests/suite.ts
index bbd252b8e1..af36f16e29 100644
--- a/packages/svelte/tests/suite.ts
+++ b/packages/svelte/tests/suite.ts
@@ -4,6 +4,7 @@ import { it } from 'vitest';
export interface BaseTest {
skip?: boolean;
solo?: boolean;
+ timeout?: number;
}
/**
@@ -30,7 +31,7 @@ export function suite(fn: (config: Test, test_dir: string
await for_each_dir(cwd, samples_dir, (config, dir) => {
let it_fn = config.skip ? it.skip : config.solo ? it.only : it;
- it_fn(dir, () => fn(config, `${cwd}/${samples_dir}/${dir}`));
+ it_fn(dir, { timeout: config.timeout }, () => fn(config, `${cwd}/${samples_dir}/${dir}`));
});
}
};
@@ -57,7 +58,7 @@ export function suite_with_variants {
+ it_fn(`${dir} (${variant})`, { timeout: config.timeout }, async () => {
if (!called_common) {
called_common = true;
common = await common_setup(config, `${cwd}/${samples_dir}/${dir}`);