failing test (that uncovered other unrelated bug) + fix

pull/17116/head
Simon Holthausen 6 days ago
parent 1032b313ab
commit 22435b2447

@ -664,15 +664,18 @@ function reconnect(derived) {
/**
* Removes the WAS_MARKED flag from the derived and its dependencies
* @param {Derived} derived
* @param {Value} derived
*/
function remove_marked_flag(derived) {
if ((derived.f & WAS_MARKED) === 0) return;
derived.f ^= WAS_MARKED;
// We cannot stop at the first non-marked derived because batch_values can
// cause "holes" of unmarked deriveds in an otherwise marked graph
if ((derived.f & DERIVED) === 0) return;
derived.f &= ~WAS_MARKED;
// Only deriveds with dependencies can be marked
for (const dep of /** @type {Value[]} */ (derived.deps)) {
remove_marked_flag(/** @type {Derived} */ (dep));
for (const dep of /** @type {Value[]} */ (/** @type {Derived} */ (derived).deps)) {
remove_marked_flag(dep);
}
}

@ -0,0 +1,27 @@
<script>
import { untrack } from "svelte";
let { double } = $props();
// Test setup:
// - component initialized while pending work
// - derived that depends on mulitple sources
// - indirect updates to subsequent deriveds
// - two sibling effects where the former influences the latter
// - first effect reads derived of second inside untrack
let x = $state(0);
const other = $derived(double + x);
const another = $derived(other + 1);
const another2 = $derived(another + 1);
$effect(() => {
untrack(() => {
another2;
x++
});
});
$effect(() => {
console.log(another2);
})
</script>

@ -0,0 +1,18 @@
import { tick } from 'svelte';
import { test } from '../../test';
export default test({
async test({ assert, target, logs }) {
const button = target.querySelector('button');
button?.click();
await tick();
// TODO this is wrong: it should be [5]
assert.deepEqual(logs, [4]);
button?.click();
await tick();
// TODO this is wrong: it should be [5, 7]
assert.deepEqual(logs, [4, 7]);
}
});

@ -0,0 +1,19 @@
<script>
import Component from './Component.svelte';
let count = $state(0);
const double = $derived(count * 2);
</script>
<svelte:boundary>
{await new Promise((r) => {
// long enough for the test to do all its other stuff while this is pending
setTimeout(r, 10);
})}
{#snippet pending()}{/snippet}
</svelte:boundary>
<button onclick={() => count += 1}>{count}</button>
{#if count > 0}
<Component {double} />
{/if}
Loading…
Cancel
Save