node/test/parallel/test-eventtarget-whatwg-once.js
Ethan Arrowood 7cba786531 events: port some wpt tests
Add WPT AddEventListenerOptions-once test.

PR-URL: https://github.com/nodejs/node/pull/34169
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Denys Otrishko <shishugi@gmail.com>
2020-11-11 00:47:31 +01:00

133 lines
4.2 KiB
JavaScript

'use strict';
const common = require('../common');
const {
strictEqual,
} = require('assert');
// Manually ported from: wpt@dom/events/AddEventListenerOptions-once.html
{
const document = new EventTarget();
let invoked_once = false;
let invoked_normal = false;
function handler_once() {
invoked_once = true;
}
function handler_normal() {
invoked_normal = true;
}
document.addEventListener('test', handler_once, { once: true });
document.addEventListener('test', handler_normal);
document.dispatchEvent(new Event('test'));
strictEqual(invoked_once, true, 'Once handler should be invoked');
strictEqual(invoked_normal, true, 'Normal handler should be invoked');
invoked_once = false;
invoked_normal = false;
document.dispatchEvent(new Event('test'));
strictEqual(invoked_once, false, 'Once handler shouldn\'t be invoked again');
strictEqual(invoked_normal, true, 'Normal handler should be invoked again');
document.removeEventListener('test', handler_normal);
}
{
// Manually ported from AddEventListenerOptions-once.html
const document = new EventTarget();
let invoked_count = 0;
function handler() {
invoked_count++;
}
document.addEventListener('test', handler, { once: true });
document.addEventListener('test', handler);
document.dispatchEvent(new Event('test'));
strictEqual(invoked_count, 1, 'The handler should only be added once');
invoked_count = 0;
document.dispatchEvent(new Event('test'));
strictEqual(invoked_count, 0, 'The handler was added as a once listener');
invoked_count = 0;
document.addEventListener('test', handler, { once: true });
document.removeEventListener('test', handler);
document.dispatchEvent(new Event('test'));
strictEqual(invoked_count, 0, 'The handler should have been removed');
}
{
// TODO(benjamingr) fix EventTarget recursion
common.skip('EventTarget recursion is currently broken');
const document = new EventTarget();
let invoked_count = 0;
function handler() {
invoked_count++;
if (invoked_count === 1)
document.dispatchEvent(new Event('test'));
}
document.addEventListener('test', handler, { once: true });
document.dispatchEvent(new Event('test'));
strictEqual(invoked_count, 1, 'Once handler should only be invoked once');
invoked_count = 0;
function handler2() {
invoked_count++;
if (invoked_count === 1)
document.addEventListener('test', handler2, { once: true });
if (invoked_count <= 2)
document.dispatchEvent(new Event('test'));
}
document.addEventListener('test', handler2, { once: true });
document.dispatchEvent(new Event('test'));
strictEqual(invoked_count, 2, 'Once handler should only be invoked once');
}
// Manually converted from https://github.com/web-platform-tests/wpt/blob/master/dom/events/AddEventListenerOptions-once.html
// in order to define the `document` ourselves
{
const document = new EventTarget();
// Should only fire for first event
document.addEventListener('test', common.mustCall(1), { once: true });
// Should fire for both events
document.addEventListener('test', common.mustCall(2));
// Fire events
document.dispatchEvent(new Event('test'));
document.dispatchEvent(new Event('test'));
}
{
const document = new EventTarget();
const handler = common.mustCall(2);
// Both should only fire on first event
document.addEventListener('test', handler.bind(), { once: true });
document.addEventListener('test', handler.bind(), { once: true });
// Fire events
document.dispatchEvent(new Event('test'));
document.dispatchEvent(new Event('test'));
}
{
const document = new EventTarget();
const handler = common.mustCall(2);
// Should only fire once on first event
document.addEventListener('test', common.mustCall(1), { once: true });
// Should fire twice until removed
document.addEventListener('test', handler);
// Fire two events
document.dispatchEvent(new Event('test'));
document.dispatchEvent(new Event('test'));
// Should only fire once on the next event
document.addEventListener('test', common.mustCall(1), { once: true });
// The previous handler should no longer fire
document.removeEventListener('test', handler);
// Fire final event triggering
document.dispatchEvent(new Event('test'));
}