mirror of https://github.com/sveltejs/svelte
parent
c411d0c4f5
commit
27b37bb143
@ -0,0 +1,46 @@
|
|||||||
|
import { test } from '../../test';
|
||||||
|
import { tick } from 'svelte';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
html: `
|
||||||
|
<select>
|
||||||
|
<option value="1">1</option>
|
||||||
|
<option value="US">US</option>
|
||||||
|
<option value="FR">FR</option>
|
||||||
|
</select>
|
||||||
|
<button id="btn-us">US</button>
|
||||||
|
<button id="btn-reset">Reset</button>
|
||||||
|
<button id="btn-fr">FR</button>
|
||||||
|
`,
|
||||||
|
|
||||||
|
async test({ assert, component, window, logs }) {
|
||||||
|
// Primary assertion: No infinite loop error
|
||||||
|
assert.notInclude(logs, 'Infinite loop detected');
|
||||||
|
|
||||||
|
// Verify component state
|
||||||
|
const select = window.document.querySelector('select');
|
||||||
|
if (!select) {
|
||||||
|
assert.fail('Select element not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// With default_details fallback nothing is selected
|
||||||
|
assert.equal(select.value, '');
|
||||||
|
assert.equal(select.disabled, false);
|
||||||
|
|
||||||
|
window.document.getElementById('btn-us')?.click();
|
||||||
|
await tick();
|
||||||
|
assert.equal(select.disabled, true);
|
||||||
|
assert.equal(select.value, 'US');
|
||||||
|
|
||||||
|
window.document.getElementById('btn-reset')?.click();
|
||||||
|
await tick();
|
||||||
|
assert.equal(select.value, '');
|
||||||
|
assert.equal(select.disabled, false);
|
||||||
|
|
||||||
|
window.document.getElementById('btn-fr')?.click();
|
||||||
|
await tick();
|
||||||
|
assert.equal(select.value, 'FR');
|
||||||
|
assert.equal(select.disabled, true);
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,41 @@
|
|||||||
|
<script>
|
||||||
|
const default_details = { country: '' };
|
||||||
|
|
||||||
|
$: data = { locked: false, details: null };
|
||||||
|
|
||||||
|
let details;
|
||||||
|
$: {
|
||||||
|
details = guard_infinite_loop() ?? data.details ?? default_details;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Guard: if this reactive block runs too often we assume an infinite loop
|
||||||
|
let guard_infinite_loop_counter = 0;
|
||||||
|
function guard_infinite_loop() {
|
||||||
|
guard_infinite_loop_counter++;
|
||||||
|
if (guard_infinite_loop_counter > 20) {
|
||||||
|
throw new Error('Infinite loop detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUS() {
|
||||||
|
data = { locked: true, details: { country: 'US' } };
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetData() {
|
||||||
|
data = { locked: false, details: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFR() {
|
||||||
|
data = { locked: true, details: { country: 'FR' } };
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<select bind:value={details.country} disabled={data.locked}>
|
||||||
|
<option value="1">1</option>
|
||||||
|
<option value="US">US</option>
|
||||||
|
<option value="FR">FR</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button id="btn-us" on:click={setUS}>US</button>
|
||||||
|
<button id="btn-reset" on:click={resetData}>Reset</button>
|
||||||
|
<button id="btn-fr" on:click={setFR}>FR</button>
|
@ -0,0 +1,46 @@
|
|||||||
|
import { tick } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
html: `
|
||||||
|
<select>
|
||||||
|
<option value="1">1</option>
|
||||||
|
<option value="US">US</option>
|
||||||
|
<option value="FR">FR</option>
|
||||||
|
</select>
|
||||||
|
<button id="btn-us">US</button>
|
||||||
|
<button id="btn-reset">Reset</button>
|
||||||
|
<button id="btn-fr">FR</button>
|
||||||
|
`,
|
||||||
|
|
||||||
|
async test({ assert, component, window, logs }) {
|
||||||
|
// Primary assertion: No infinite loop error
|
||||||
|
assert.notInclude(logs, 'Infinite loop detected');
|
||||||
|
|
||||||
|
// Verify component state
|
||||||
|
const select = window.document.querySelector('select');
|
||||||
|
if (!select) {
|
||||||
|
assert.fail('Select element not found');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// With default_details fallback nothing is selected
|
||||||
|
assert.equal(select.value, '');
|
||||||
|
assert.equal(select.disabled, false);
|
||||||
|
|
||||||
|
window.document.getElementById('btn-us')?.click();
|
||||||
|
await tick();
|
||||||
|
assert.equal(select.disabled, true);
|
||||||
|
assert.equal(select.value, 'US');
|
||||||
|
|
||||||
|
window.document.getElementById('btn-reset')?.click();
|
||||||
|
await tick();
|
||||||
|
assert.equal(select.value, '');
|
||||||
|
assert.equal(select.disabled, false);
|
||||||
|
|
||||||
|
window.document.getElementById('btn-fr')?.click();
|
||||||
|
await tick();
|
||||||
|
assert.equal(select.value, 'FR');
|
||||||
|
assert.equal(select.disabled, true);
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,38 @@
|
|||||||
|
<script>
|
||||||
|
const default_details = { country: '' };
|
||||||
|
|
||||||
|
$: data = { locked: false, details: null };
|
||||||
|
|
||||||
|
$: details = guard_infinite_loop() ?? data.details ?? default_details;
|
||||||
|
|
||||||
|
// Guard: if this reactive block runs too often we assume an infinite loop
|
||||||
|
let guard_infinite_loop_counter = 0;
|
||||||
|
function guard_infinite_loop() {
|
||||||
|
guard_infinite_loop_counter++;
|
||||||
|
if (guard_infinite_loop_counter > 20) {
|
||||||
|
throw new Error('Infinite loop detected');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setUS() {
|
||||||
|
data = { locked: true, details: { country: 'US' } };
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetData() {
|
||||||
|
data = { locked: false, details: null };
|
||||||
|
}
|
||||||
|
|
||||||
|
function setFR() {
|
||||||
|
data = { locked: true, details: { country: 'FR' } };
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<select bind:value={details.country} disabled={data.locked}>
|
||||||
|
<option value="1">1</option>
|
||||||
|
<option value="US">US</option>
|
||||||
|
<option value="FR">FR</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<button id="btn-us" on:click={setUS}>US</button>
|
||||||
|
<button id="btn-reset" on:click={resetData}>Reset</button>
|
||||||
|
<button id="btn-fr" on:click={setFR}>FR</button>
|
Loading…
Reference in new issue