mirror of https://github.com/sveltejs/svelte
dynamic events: validate handler before executing (#4105)
parent
b59673155c
commit
8a596936d2
@ -0,0 +1,56 @@
|
||||
export default {
|
||||
html: `
|
||||
<p>
|
||||
<button>set handler 1</button>
|
||||
<button>set handler 2</button>
|
||||
</p>
|
||||
<p>0</p>
|
||||
<button>click</button>
|
||||
`,
|
||||
|
||||
async test({ assert, component, target, window }) {
|
||||
const [updateButton1, updateButton2, button] = target.querySelectorAll(
|
||||
'button'
|
||||
);
|
||||
|
||||
const event = new window.MouseEvent('click');
|
||||
let err = "";
|
||||
window.addEventListener('error', (e) => {
|
||||
e.preventDefault();
|
||||
err = e.message;
|
||||
});
|
||||
|
||||
await button.dispatchEvent(event);
|
||||
assert.equal(err, "", err);
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<p>
|
||||
<button>set handler 1</button>
|
||||
<button>set handler 2</button>
|
||||
</p>
|
||||
<p>0</p>
|
||||
<button>click</button>
|
||||
`);
|
||||
|
||||
await updateButton1.dispatchEvent(event);
|
||||
await button.dispatchEvent(event);
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<p>
|
||||
<button>set handler 1</button>
|
||||
<button>set handler 2</button>
|
||||
</p>
|
||||
<p>1</p>
|
||||
<button>click</button>
|
||||
`);
|
||||
|
||||
await updateButton2.dispatchEvent(event);
|
||||
await button.dispatchEvent(event);
|
||||
assert.htmlEqual(target.innerHTML, `
|
||||
<p>
|
||||
<button>set handler 1</button>
|
||||
<button>set handler 2</button>
|
||||
</p>
|
||||
<p>2</p>
|
||||
<button>click</button>
|
||||
`);
|
||||
},
|
||||
};
|
@ -0,0 +1,23 @@
|
||||
<script>
|
||||
let clickHandler = {};
|
||||
let number = 0;
|
||||
|
||||
function updateHandler1(){
|
||||
clickHandler.f = () => number = 1;
|
||||
}
|
||||
|
||||
function updateHandler2(){
|
||||
clickHandler.f = () => number = 2;
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<p>
|
||||
<button on:click={updateHandler1}>set handler 1</button>
|
||||
<button on:click={updateHandler2}>set handler 2</button>
|
||||
</p>
|
||||
|
||||
<p>{ number }</p>
|
||||
|
||||
<button on:click={clickHandler.f}>click</button>
|
@ -0,0 +1,28 @@
|
||||
export default {
|
||||
html: `<button>undef</button>
|
||||
<button>null</button>
|
||||
<button>invalid</button>`,
|
||||
|
||||
async test({ assert, component, target, window }) {
|
||||
const [buttonUndef, buttonNull, buttonInvalid] = target.querySelectorAll(
|
||||
'button'
|
||||
);
|
||||
|
||||
const event = new window.MouseEvent('click');
|
||||
let err = "";
|
||||
window.addEventListener('error', (e) => {
|
||||
e.preventDefault();
|
||||
err = e.message;
|
||||
});
|
||||
|
||||
// All three should not throw if proper checking is done in runtime code
|
||||
await buttonUndef.dispatchEvent(event);
|
||||
assert.equal(err, "", err);
|
||||
|
||||
await buttonNull.dispatchEvent(event);
|
||||
assert.equal(err, "", err);
|
||||
|
||||
await buttonInvalid.dispatchEvent(event);
|
||||
assert.equal(err, "", err);
|
||||
},
|
||||
};
|
@ -0,0 +1,13 @@
|
||||
<script>
|
||||
let handlerUndef;
|
||||
let handlerNull;
|
||||
let handlerInvalid;
|
||||
|
||||
handlerUndef = undefined;
|
||||
handlerNull = null;
|
||||
handlerInvalid = 42;
|
||||
</script>
|
||||
|
||||
<button on:click={handlerUndef}>undef</button>
|
||||
<button on:click={handlerNull}>null</button>
|
||||
<button on:click={handlerInvalid}>invalid</button>
|
@ -0,0 +1,16 @@
|
||||
export default {
|
||||
html: `
|
||||
<button>0</button>
|
||||
`,
|
||||
|
||||
async test({ assert, component, target, window }) {
|
||||
const button = target.querySelector('button');
|
||||
const event = new window.MouseEvent('click');
|
||||
|
||||
await button.dispatchEvent(event);
|
||||
assert.equal(component.count, 1);
|
||||
|
||||
await button.dispatchEvent(event);
|
||||
assert.equal(component.count, 1);
|
||||
}
|
||||
};
|
@ -0,0 +1,7 @@
|
||||
<script>
|
||||
let f;
|
||||
export let count = 0;
|
||||
f = () => count += 1;
|
||||
</script>
|
||||
|
||||
<button on:click|once="{f}">{count}</button>
|
@ -0,0 +1,16 @@
|
||||
export default {
|
||||
html: `
|
||||
<button>click me</button>
|
||||
`,
|
||||
|
||||
async test({ assert, component, target, window }) {
|
||||
const button = target.querySelector('button');
|
||||
const event = new window.MouseEvent('click', {
|
||||
cancelable: true
|
||||
});
|
||||
|
||||
await button.dispatchEvent(event);
|
||||
|
||||
assert.ok(component.default_was_prevented);
|
||||
}
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
<script>
|
||||
export let default_was_prevented;
|
||||
let f;
|
||||
|
||||
function handle_click(event) {
|
||||
default_was_prevented = event.defaultPrevented;
|
||||
}
|
||||
f = handle_click;
|
||||
</script>
|
||||
|
||||
<button on:click|preventDefault={f}>click me</button>
|
@ -0,0 +1,16 @@
|
||||
export default {
|
||||
html: `
|
||||
<div>
|
||||
<button>click me</button>
|
||||
</div>
|
||||
`,
|
||||
|
||||
async test({ assert, component, target, window }) {
|
||||
const button = target.querySelector('button');
|
||||
const event = new window.MouseEvent('click');
|
||||
|
||||
await button.dispatchEvent(event);
|
||||
|
||||
assert.ok(!component.inner_clicked);
|
||||
},
|
||||
};
|
@ -0,0 +1,13 @@
|
||||
<script>
|
||||
export let inner_clicked;
|
||||
let f;
|
||||
|
||||
function handle_click(event) {
|
||||
inner_clicked = true;
|
||||
}
|
||||
f = handle_click;
|
||||
</script>
|
||||
|
||||
<div on:click|self={f}>
|
||||
<button>click me</button>
|
||||
</div>
|
@ -0,0 +1,19 @@
|
||||
export default {
|
||||
html: `
|
||||
<div>
|
||||
<button>click me</button>
|
||||
</div>
|
||||
`,
|
||||
|
||||
async test({ assert, component, target, window }) {
|
||||
const button = target.querySelector('button');
|
||||
const event = new window.MouseEvent('click', {
|
||||
bubbles: true
|
||||
});
|
||||
|
||||
await button.dispatchEvent(event);
|
||||
|
||||
assert.ok(component.inner_clicked);
|
||||
assert.ok(!component.outer_clicked);
|
||||
}
|
||||
};
|
@ -0,0 +1,20 @@
|
||||
<script>
|
||||
export let inner_clicked;
|
||||
export let outer_clicked;
|
||||
let f1;
|
||||
let f2;
|
||||
|
||||
function handle_inner_click(event) {
|
||||
inner_clicked = true;
|
||||
}
|
||||
|
||||
function handle_outer_click(event) {
|
||||
outer_clicked = true;
|
||||
}
|
||||
f1 = handle_inner_click;
|
||||
f2 = handle_outer_click;
|
||||
</script>
|
||||
|
||||
<div on:click={f2}>
|
||||
<button on:click|stopPropagation={f1}>click me</button>
|
||||
</div>
|
@ -0,0 +1,14 @@
|
||||
export default {
|
||||
html: `
|
||||
<button>click me</button>
|
||||
`,
|
||||
|
||||
async test({ assert, component, target, window }) {
|
||||
const button = target.querySelector('button');
|
||||
const event = new window.MouseEvent('click');
|
||||
|
||||
await button.dispatchEvent(event);
|
||||
assert.equal(component.clickHandlerOne, 1);
|
||||
assert.equal(component.clickHandlerTwo, 1);
|
||||
}
|
||||
};
|
@ -0,0 +1,11 @@
|
||||
<script>
|
||||
export let clickHandlerOne = 0;
|
||||
export let clickHandlerTwo = 0;
|
||||
let f1;
|
||||
let f2;
|
||||
|
||||
f1 = () => clickHandlerOne++;
|
||||
f2 = () => clickHandlerTwo++;
|
||||
</script>
|
||||
|
||||
<button on:click='{f1}' on:click='{f2}'>click me</button>
|
Loading…
Reference in new issue