mirror of https://github.com/sveltejs/svelte
commit
d4d82532ce
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: replace `undefined` with `void(0)` in CallExpressions
|
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: place store setup inside async body
|
@ -0,0 +1,41 @@
|
|||||||
|
import { tick } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const [increment, pop] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
increment.click();
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
pop.click();
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
pop.click();
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>increment</button>
|
||||||
|
<button>pop</button>
|
||||||
|
<p>1</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
increment.click();
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
pop.click();
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>increment</button>
|
||||||
|
<button>pop</button>
|
||||||
|
<p>2</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
<script>
|
||||||
|
let count = $state(0);
|
||||||
|
|
||||||
|
let deferreds = [];
|
||||||
|
|
||||||
|
class X {
|
||||||
|
constructor(promise) {
|
||||||
|
this.promise = promise;
|
||||||
|
}
|
||||||
|
|
||||||
|
get then() {
|
||||||
|
count;
|
||||||
|
|
||||||
|
return (resolve) => this.promise.then(() => count).then(resolve)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function push() {
|
||||||
|
const deferred = Promise.withResolvers();
|
||||||
|
deferreds.push(deferred);
|
||||||
|
return new X(deferred.promise);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={() => count += 1}>increment</button>
|
||||||
|
<button onclick={() => deferreds.pop()?.resolve(count)}>pop</button>
|
||||||
|
|
||||||
|
<svelte:boundary>
|
||||||
|
<p>{await push()}</p>
|
||||||
|
|
||||||
|
{#snippet pending()}
|
||||||
|
<p>loading...</p>
|
||||||
|
{/snippet}
|
||||||
|
</svelte:boundary>
|
@ -0,0 +1,7 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { resolve } from './main.svelte';
|
||||||
|
|
||||||
|
const bar = await new Promise((r) => resolve.push(() => r('bar')));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>bar: {bar}</p>
|
@ -0,0 +1,10 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { resolve } from './main.svelte';
|
||||||
|
import Bar from './Bar.svelte';
|
||||||
|
|
||||||
|
const foo = await new Promise((r) => resolve.push(() => r('foo')));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>foo: {foo}</p>
|
||||||
|
|
||||||
|
<Bar/>
|
@ -0,0 +1,42 @@
|
|||||||
|
import { tick } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const [show, resolve] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
show.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>show</button>
|
||||||
|
<button>resolve</button>
|
||||||
|
<p>pending...</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
resolve.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>show</button>
|
||||||
|
<button>resolve</button>
|
||||||
|
<p>pending...</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
resolve.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>show</button>
|
||||||
|
<button>resolve</button>
|
||||||
|
<p>foo: foo</p>
|
||||||
|
<p>bar: bar</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,31 @@
|
|||||||
|
<script module>
|
||||||
|
export let resolve = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Foo from './Foo.svelte';
|
||||||
|
|
||||||
|
let show = $state(false);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={() => show = true}>
|
||||||
|
show
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button onclick={() => resolve.shift()()}>
|
||||||
|
resolve
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<svelte:boundary>
|
||||||
|
{#if show}
|
||||||
|
<Foo/>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if $effect.pending()}
|
||||||
|
<p>pending...</p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#snippet pending()}
|
||||||
|
<p>initializing...</p>
|
||||||
|
{/snippet}
|
||||||
|
</svelte:boundary>
|
@ -0,0 +1,9 @@
|
|||||||
|
import { tick } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target }) {
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(target.innerHTML, 'value');
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,9 @@
|
|||||||
|
<script>
|
||||||
|
const value = await 'value';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#snippet valueSnippet()}
|
||||||
|
{value}
|
||||||
|
{/snippet}
|
||||||
|
|
||||||
|
{@render valueSnippet()}
|
@ -0,0 +1,8 @@
|
|||||||
|
<script>
|
||||||
|
import App from './app.svelte';
|
||||||
|
</script>
|
||||||
|
<svelte:boundary>
|
||||||
|
{#snippet pending()}
|
||||||
|
{/snippet}
|
||||||
|
<App />
|
||||||
|
</svelte:boundary>
|
@ -0,0 +1,8 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { resolve } from './main.svelte';
|
||||||
|
|
||||||
|
const foo = $derived(await new Promise((r) => resolve.push(() => r('foo'))));
|
||||||
|
const bar = $derived(await new Promise((r) => resolve.push(() => r('bar'))));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<p>{foo} {bar}</p>
|
@ -0,0 +1,41 @@
|
|||||||
|
import { tick } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const [show, resolve] = target.querySelectorAll('button');
|
||||||
|
|
||||||
|
show.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>show</button>
|
||||||
|
<button>resolve</button>
|
||||||
|
<p>pending...</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
resolve.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>show</button>
|
||||||
|
<button>resolve</button>
|
||||||
|
<p>pending...</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
resolve.click();
|
||||||
|
await tick();
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<button>show</button>
|
||||||
|
<button>resolve</button>
|
||||||
|
<p>foo bar</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,31 @@
|
|||||||
|
<script module>
|
||||||
|
export let resolve = [];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Foo from './Foo.svelte';
|
||||||
|
|
||||||
|
let show = $state(false);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={() => show = true}>
|
||||||
|
show
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button onclick={() => resolve.shift()()}>
|
||||||
|
resolve
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<svelte:boundary>
|
||||||
|
{#if show}
|
||||||
|
<Foo/>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if $effect.pending()}
|
||||||
|
<p>pending...</p>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#snippet pending()}
|
||||||
|
<p>initializing...</p>
|
||||||
|
{/snippet}
|
||||||
|
</svelte:boundary>
|
@ -0,0 +1,28 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
mode: ['client', 'hydrate'],
|
||||||
|
|
||||||
|
html: `<input><p>a</a>`,
|
||||||
|
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const [input] = target.querySelectorAll('input');
|
||||||
|
|
||||||
|
input.focus();
|
||||||
|
input.value = 'ab';
|
||||||
|
input.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
||||||
|
flushSync();
|
||||||
|
|
||||||
|
assert.htmlEqual(target.innerHTML, `<input><p>ab</a>`);
|
||||||
|
assert.equal(input.value, 'ab');
|
||||||
|
|
||||||
|
input.focus();
|
||||||
|
input.value = 'abc';
|
||||||
|
input.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
||||||
|
flushSync();
|
||||||
|
|
||||||
|
assert.htmlEqual(target.innerHTML, `<input><p>abc</a>`);
|
||||||
|
assert.equal(input.value, 'abc');
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,8 @@
|
|||||||
|
<script>
|
||||||
|
let array = $state([{ value: 'a' }]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#each array as obj}
|
||||||
|
<input bind:value={() => obj.value, (value) => array = [{ value }]} />
|
||||||
|
<p>{obj.value}</p>
|
||||||
|
{/each}
|
@ -0,0 +1,30 @@
|
|||||||
|
import { tick } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
mode: ['client', 'hydrate'],
|
||||||
|
|
||||||
|
async test({ assert, target }) {
|
||||||
|
const [input] = target.querySelectorAll('input');
|
||||||
|
|
||||||
|
input.focus();
|
||||||
|
input.value = 'Ab';
|
||||||
|
input.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
||||||
|
|
||||||
|
await tick();
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
assert.equal(input.value, 'AB');
|
||||||
|
assert.htmlEqual(target.innerHTML, `<input /><p>AB</p>`);
|
||||||
|
|
||||||
|
input.focus();
|
||||||
|
input.value = 'ABc';
|
||||||
|
input.dispatchEvent(new InputEvent('input', { bubbles: true }));
|
||||||
|
|
||||||
|
await tick();
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
assert.equal(input.value, 'ABC');
|
||||||
|
assert.htmlEqual(target.innerHTML, `<input /><p>ABC</p>`);
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,6 @@
|
|||||||
|
<script>
|
||||||
|
let text = $state('A');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<input bind:value={() => text, (v) => text = v.toUpperCase()} />
|
||||||
|
<p>{text}</p>
|
@ -0,0 +1,7 @@
|
|||||||
|
<script>
|
||||||
|
let { text } = $props();
|
||||||
|
|
||||||
|
$effect(() => console.log(text));
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{text}
|
@ -0,0 +1,12 @@
|
|||||||
|
import { async_mode } from '../../../helpers';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
// In legacy mode this succeeds and logs 'hello'
|
||||||
|
// In async mode this throws an error because flushSync is called inside an effect
|
||||||
|
async test({ assert, target, logs }) {
|
||||||
|
assert.htmlEqual(target.innerHTML, `<button>show</button> <div>hello</div>`);
|
||||||
|
assert.deepEqual(logs, ['hello']);
|
||||||
|
},
|
||||||
|
runtime_error: async_mode ? 'flush_sync_in_effect' : undefined
|
||||||
|
});
|
@ -0,0 +1,13 @@
|
|||||||
|
<script>
|
||||||
|
import { flushSync, mount } from 'svelte'
|
||||||
|
import Child from './Child.svelte';
|
||||||
|
|
||||||
|
let show = $state(false);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<button onclick={() => show = true}>show</button>
|
||||||
|
|
||||||
|
<div {@attach (target) => {
|
||||||
|
mount(Child, { target, props: { text: 'hello' } });
|
||||||
|
flushSync();
|
||||||
|
}}></div>
|
Loading…
Reference in new issue