-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PR-URL: nodejs/node#43151 Refs: nodejs/node#40678 Reviewed-By: Masashi Hirano <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: James M Snell <[email protected]>
- Loading branch information
Showing
106 changed files
with
6,906 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
96 changes: 96 additions & 0 deletions
96
test/fixtures/wpt/dom/events/AddEventListenerOptions-once.any.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// META: title=AddEventListenerOptions.once | ||
|
||
"use strict"; | ||
|
||
test(function() { | ||
var invoked_once = false; | ||
var invoked_normal = false; | ||
function handler_once() { | ||
invoked_once = true; | ||
} | ||
function handler_normal() { | ||
invoked_normal = true; | ||
} | ||
|
||
const et = new EventTarget(); | ||
et.addEventListener('test', handler_once, {once: true}); | ||
et.addEventListener('test', handler_normal); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(invoked_once, true, "Once handler should be invoked"); | ||
assert_equals(invoked_normal, true, "Normal handler should be invoked"); | ||
|
||
invoked_once = false; | ||
invoked_normal = false; | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(invoked_once, false, "Once handler shouldn't be invoked again"); | ||
assert_equals(invoked_normal, true, "Normal handler should be invoked again"); | ||
et.removeEventListener('test', handler_normal); | ||
}, "Once listener should be invoked only once"); | ||
|
||
test(function() { | ||
const et = new EventTarget(); | ||
var invoked_count = 0; | ||
function handler() { | ||
invoked_count++; | ||
if (invoked_count == 1) | ||
et.dispatchEvent(new Event('test')); | ||
} | ||
et.addEventListener('test', handler, {once: true}); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(invoked_count, 1, "Once handler should only be invoked once"); | ||
|
||
invoked_count = 0; | ||
function handler2() { | ||
invoked_count++; | ||
if (invoked_count == 1) | ||
et.addEventListener('test', handler2, {once: true}); | ||
if (invoked_count <= 2) | ||
et.dispatchEvent(new Event('test')); | ||
} | ||
et.addEventListener('test', handler2, {once: true}); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(invoked_count, 2, "Once handler should only be invoked once after each adding"); | ||
}, "Once listener should be invoked only once even if the event is nested"); | ||
|
||
test(function() { | ||
var invoked_count = 0; | ||
function handler() { | ||
invoked_count++; | ||
} | ||
|
||
const et = new EventTarget(); | ||
|
||
et.addEventListener('test', handler, {once: true}); | ||
et.addEventListener('test', handler); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(invoked_count, 1, "The handler should only be added once"); | ||
|
||
invoked_count = 0; | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(invoked_count, 0, "The handler was added as a once listener"); | ||
|
||
invoked_count = 0; | ||
et.addEventListener('test', handler, {once: true}); | ||
et.removeEventListener('test', handler); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(invoked_count, 0, "The handler should have been removed"); | ||
}, "Once listener should be added / removed like normal listeners"); | ||
|
||
test(function() { | ||
const et = new EventTarget(); | ||
|
||
var invoked_count = 0; | ||
|
||
for (let n = 4; n > 0; n--) { | ||
et.addEventListener('test', (e) => { | ||
invoked_count++; | ||
e.stopImmediatePropagation(); | ||
}, {once: true}); | ||
} | ||
|
||
for (let n = 4; n > 0; n--) { | ||
et.dispatchEvent(new Event('test')); | ||
} | ||
|
||
assert_equals(invoked_count, 4, "The listeners should be invoked"); | ||
}, "Multiple once listeners should be invoked even if the stopImmediatePropagation is set"); |
134 changes: 134 additions & 0 deletions
134
test/fixtures/wpt/dom/events/AddEventListenerOptions-passive.any.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// META: title=AddEventListenerOptions.passive | ||
|
||
test(function() { | ||
var supportsPassive = false; | ||
var query_options = { | ||
get passive() { | ||
supportsPassive = true; | ||
return false; | ||
}, | ||
get dummy() { | ||
assert_unreached("dummy value getter invoked"); | ||
return false; | ||
} | ||
}; | ||
|
||
const et = new EventTarget(); | ||
et.addEventListener('test_event', null, query_options); | ||
assert_true(supportsPassive, "addEventListener doesn't support the passive option"); | ||
|
||
supportsPassive = false; | ||
et.removeEventListener('test_event', null, query_options); | ||
assert_false(supportsPassive, "removeEventListener supports the passive option when it should not"); | ||
}, "Supports passive option on addEventListener only"); | ||
|
||
function testPassiveValue(optionsValue, expectedDefaultPrevented, existingEventTarget) { | ||
var defaultPrevented = undefined; | ||
var handler = function handler(e) { | ||
assert_false(e.defaultPrevented, "Event prematurely marked defaultPrevented"); | ||
e.preventDefault(); | ||
defaultPrevented = e.defaultPrevented; | ||
} | ||
const et = existingEventTarget || new EventTarget(); | ||
et.addEventListener('test', handler, optionsValue); | ||
var uncanceled = et.dispatchEvent(new Event('test', {bubbles: true, cancelable: true})); | ||
|
||
assert_equals(defaultPrevented, expectedDefaultPrevented, "Incorrect defaultPrevented for options: " + JSON.stringify(optionsValue)); | ||
assert_equals(uncanceled, !expectedDefaultPrevented, "Incorrect return value from dispatchEvent"); | ||
|
||
et.removeEventListener('test', handler, optionsValue); | ||
} | ||
|
||
test(function() { | ||
testPassiveValue(undefined, true); | ||
testPassiveValue({}, true); | ||
testPassiveValue({passive: false}, true); | ||
testPassiveValue({passive: true}, false); | ||
testPassiveValue({passive: 0}, true); | ||
testPassiveValue({passive: 1}, false); | ||
}, "preventDefault should be ignored if-and-only-if the passive option is true"); | ||
|
||
function testPassiveValueOnReturnValue(test, optionsValue, expectedDefaultPrevented) { | ||
var defaultPrevented = undefined; | ||
var handler = test.step_func(e => { | ||
assert_false(e.defaultPrevented, "Event prematurely marked defaultPrevented"); | ||
e.returnValue = false; | ||
defaultPrevented = e.defaultPrevented; | ||
}); | ||
const et = new EventTarget(); | ||
et.addEventListener('test', handler, optionsValue); | ||
var uncanceled = et.dispatchEvent(new Event('test', {bubbles: true, cancelable: true})); | ||
|
||
assert_equals(defaultPrevented, expectedDefaultPrevented, "Incorrect defaultPrevented for options: " + JSON.stringify(optionsValue)); | ||
assert_equals(uncanceled, !expectedDefaultPrevented, "Incorrect return value from dispatchEvent"); | ||
|
||
et.removeEventListener('test', handler, optionsValue); | ||
} | ||
|
||
async_test(t => { | ||
testPassiveValueOnReturnValue(t, undefined, true); | ||
testPassiveValueOnReturnValue(t, {}, true); | ||
testPassiveValueOnReturnValue(t, {passive: false}, true); | ||
testPassiveValueOnReturnValue(t, {passive: true}, false); | ||
testPassiveValueOnReturnValue(t, {passive: 0}, true); | ||
testPassiveValueOnReturnValue(t, {passive: 1}, false); | ||
t.done(); | ||
}, "returnValue should be ignored if-and-only-if the passive option is true"); | ||
|
||
function testPassiveWithOtherHandlers(optionsValue, expectedDefaultPrevented) { | ||
var handlerInvoked1 = false; | ||
var dummyHandler1 = function() { | ||
handlerInvoked1 = true; | ||
}; | ||
var handlerInvoked2 = false; | ||
var dummyHandler2 = function() { | ||
handlerInvoked2 = true; | ||
}; | ||
|
||
const et = new EventTarget(); | ||
et.addEventListener('test', dummyHandler1, {passive:true}); | ||
et.addEventListener('test', dummyHandler2); | ||
|
||
testPassiveValue(optionsValue, expectedDefaultPrevented, et); | ||
|
||
assert_true(handlerInvoked1, "Extra passive handler not invoked"); | ||
assert_true(handlerInvoked2, "Extra non-passive handler not invoked"); | ||
|
||
et.removeEventListener('test', dummyHandler1); | ||
et.removeEventListener('test', dummyHandler2); | ||
} | ||
|
||
test(function() { | ||
testPassiveWithOtherHandlers({}, true); | ||
testPassiveWithOtherHandlers({passive: false}, true); | ||
testPassiveWithOtherHandlers({passive: true}, false); | ||
}, "passive behavior of one listener should be unaffected by the presence of other listeners"); | ||
|
||
function testOptionEquivalence(optionValue1, optionValue2, expectedEquality) { | ||
var invocationCount = 0; | ||
var handler = function handler(e) { | ||
invocationCount++; | ||
} | ||
const et = new EventTarget(); | ||
et.addEventListener('test', handler, optionValue1); | ||
et.addEventListener('test', handler, optionValue2); | ||
et.dispatchEvent(new Event('test', {bubbles: true})); | ||
assert_equals(invocationCount, expectedEquality ? 1 : 2, "equivalence of options " + | ||
JSON.stringify(optionValue1) + " and " + JSON.stringify(optionValue2)); | ||
et.removeEventListener('test', handler, optionValue1); | ||
et.removeEventListener('test', handler, optionValue2); | ||
} | ||
|
||
test(function() { | ||
// Sanity check options that should be treated as distinct handlers | ||
testOptionEquivalence({capture:true}, {capture:false, passive:false}, false); | ||
testOptionEquivalence({capture:true}, {passive:true}, false); | ||
|
||
// Option values that should be treated as equivalent | ||
testOptionEquivalence({}, {passive:false}, true); | ||
testOptionEquivalence({passive:true}, {passive:false}, true); | ||
testOptionEquivalence(undefined, {passive:true}, true); | ||
testOptionEquivalence({capture: true, passive: false}, {capture: true, passive: true}, true); | ||
|
||
}, "Equivalence of option values"); | ||
|
143 changes: 143 additions & 0 deletions
143
test/fixtures/wpt/dom/events/AddEventListenerOptions-signal.any.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
'use strict'; | ||
|
||
test(function() { | ||
let count = 0; | ||
function handler() { | ||
count++; | ||
} | ||
const et = new EventTarget(); | ||
const controller = new AbortController(); | ||
et.addEventListener('test', handler, { signal: controller.signal }); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(count, 1, "Adding a signal still adds a listener"); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(count, 2, "The listener was not added with the once flag"); | ||
controller.abort(); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(count, 2, "Aborting on the controller removes the listener"); | ||
et.addEventListener('test', handler, { signal: controller.signal }); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(count, 2, "Passing an aborted signal never adds the handler"); | ||
}, "Passing an AbortSignal to addEventListener options should allow removing a listener"); | ||
|
||
test(function() { | ||
let count = 0; | ||
function handler() { | ||
count++; | ||
} | ||
const et = new EventTarget(); | ||
const controller = new AbortController(); | ||
et.addEventListener('test', handler, { signal: controller.signal }); | ||
et.removeEventListener('test', handler); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(count, 0, "The listener was still removed"); | ||
}, "Passing an AbortSignal to addEventListener does not prevent removeEventListener"); | ||
|
||
test(function() { | ||
let count = 0; | ||
function handler() { | ||
count++; | ||
} | ||
const et = new EventTarget(); | ||
const controller = new AbortController(); | ||
et.addEventListener('test', handler, { signal: controller.signal, once: true }); | ||
controller.abort(); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(count, 0, "The listener was still removed"); | ||
}, "Passing an AbortSignal to addEventListener works with the once flag"); | ||
|
||
test(function() { | ||
let count = 0; | ||
function handler() { | ||
count++; | ||
} | ||
const et = new EventTarget(); | ||
const controller = new AbortController(); | ||
et.addEventListener('test', handler, { signal: controller.signal, once: true }); | ||
et.removeEventListener('test', handler); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(count, 0, "The listener was still removed"); | ||
}, "Removing a once listener works with a passed signal"); | ||
|
||
test(function() { | ||
let count = 0; | ||
function handler() { | ||
count++; | ||
} | ||
const et = new EventTarget(); | ||
const controller = new AbortController(); | ||
et.addEventListener('first', handler, { signal: controller.signal, once: true }); | ||
et.addEventListener('second', handler, { signal: controller.signal, once: true }); | ||
controller.abort(); | ||
et.dispatchEvent(new Event('first')); | ||
et.dispatchEvent(new Event('second')); | ||
assert_equals(count, 0, "The listener was still removed"); | ||
}, "Passing an AbortSignal to multiple listeners"); | ||
|
||
test(function() { | ||
let count = 0; | ||
function handler() { | ||
count++; | ||
} | ||
const et = new EventTarget(); | ||
const controller = new AbortController(); | ||
et.addEventListener('test', handler, { signal: controller.signal, capture: true }); | ||
controller.abort(); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(count, 0, "The listener was still removed"); | ||
}, "Passing an AbortSignal to addEventListener works with the capture flag"); | ||
|
||
test(function() { | ||
let count = 0; | ||
function handler() { | ||
count++; | ||
} | ||
const et = new EventTarget(); | ||
const controller = new AbortController(); | ||
et.addEventListener('test', () => { | ||
controller.abort(); | ||
}, { signal: controller.signal }); | ||
et.addEventListener('test', handler, { signal: controller.signal }); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(count, 0, "The listener was still removed"); | ||
}, "Aborting from a listener does not call future listeners"); | ||
|
||
test(function() { | ||
let count = 0; | ||
function handler() { | ||
count++; | ||
} | ||
const et = new EventTarget(); | ||
const controller = new AbortController(); | ||
et.addEventListener('test', () => { | ||
et.addEventListener('test', handler, { signal: controller.signal }); | ||
controller.abort(); | ||
}, { signal: controller.signal }); | ||
et.dispatchEvent(new Event('test')); | ||
assert_equals(count, 0, "The listener was still removed"); | ||
}, "Adding then aborting a listener in another listener does not call it"); | ||
|
||
test(function() { | ||
const et = new EventTarget(); | ||
const ac = new AbortController(); | ||
let count = 0; | ||
et.addEventListener('foo', () => { | ||
et.addEventListener('foo', () => { | ||
count++; | ||
if (count > 5) ac.abort(); | ||
et.dispatchEvent(new Event('foo')); | ||
}, { signal: ac.signal }); | ||
et.dispatchEvent(new Event('foo')); | ||
}, { once: true }); | ||
et.dispatchEvent(new Event('foo')); | ||
}, "Aborting from a nested listener should remove it"); | ||
|
||
test(function() { | ||
const et = new EventTarget(); | ||
assert_throws_js(TypeError, () => { et.addEventListener("foo", () => {}, { signal: null }); }); | ||
}, "Passing null as the signal should throw"); | ||
|
||
test(function() { | ||
const et = new EventTarget(); | ||
assert_throws_js(TypeError, () => { et.addEventListener("foo", null, { signal: null }); }); | ||
}, "Passing null as the signal should throw (listener is also null)"); |
Oops, something went wrong.