Bug 1259788 - Create haveEvents() and friends in head.js. r=jib

When we expect multiple events of the same type (in this case "addtrack" on
MediaStream) we can use this convenience function to attach a listener and
wait for the expected number of events before removing the listener and resolving.

This also adds a function to check that there were no extra events of the same
kind after the expected N events, and a function that checks that we don't see
a certain event within a given timeout period.

MozReview-Commit-ID: 1P8MkEI0Yzm

--HG--
extra : rebase_source : a815d5834c71785359613c2fb5af3cdb14ba1a54
This commit is contained in:
Andreas Pehrson 2016-08-22 12:01:39 +02:00
parent 68018df353
commit 515d54094e
2 changed files with 71 additions and 12 deletions

View File

@ -591,6 +591,33 @@ function createOneShotEventWrapper(wrapper, obj, event) {
};
}
/**
* Returns a promise that resolves when `target` has raised an event with the
* given name the given number of times. Cancel the returned promise by passing
* in a `cancelPromise` and resolve it.
*
* @param {object} target
* The target on which the event should occur.
* @param {string} name
* The name of the event that should occur.
* @param {integer} count
* Optional number of times the event should be raised before resolving.
* @param {promise} cancelPromise
* Optional promise that on resolving rejects the returned promise,
* so we can avoid logging results after a test has finished.
* @returns {promise} A promise that resolves to the last of the seen events.
*/
function haveEvents(target, name, count, cancelPromise) {
var listener;
var counter = count || 1;
return Promise.race([
(cancelPromise || new Promise(() => {})).then(e => Promise.reject(e)),
new Promise(resolve =>
target.addEventListener(name, listener = e => (--counter < 1 && resolve(e))))
])
.then(e => (target.removeEventListener(name, listener), e));
};
/**
* Returns a promise that resolves when `target` has raised an event with the
* given name. Cancel the returned promise by passing in a `cancelPromise` and
@ -601,16 +628,52 @@ function createOneShotEventWrapper(wrapper, obj, event) {
* @param {string} name
* The name of the event that should occur.
* @param {promise} cancelPromise
* A promise that on resolving rejects the returned promise,
* Optional promise that on resolving rejects the returned promise,
* so we can avoid logging results after a test has finished.
* @returns {promise} A promise that resolves to the seen event.
*/
function haveEvent(target, name, cancelPromise) {
var listener;
var p = Promise.race([
(cancelPromise || new Promise()).then(e => Promise.reject(e)),
new Promise(resolve => target.addEventListener(name, listener = resolve))
]);
return p.then(event => (target.removeEventListener(name, listener), event));
return haveEvents(target, name, 1, cancelPromise);
};
/**
* Returns a promise that resolves if the target has not seen the given event
* after one crank (or until the given timeoutPromise resolves) of the event
* loop.
*
* @param {object} target
* The target on which the event should not occur.
* @param {string} name
* The name of the event that should not occur.
* @param {promise} timeoutPromise
* Optional promise defining how long we should wait before resolving.
* @returns {promise} A promise that is rejected if we see the given event, or
* resolves after a timeout otherwise.
*/
function haveNoEvent(target, name, timeoutPromise) {
return haveEvent(target, name, timeoutPromise || wait(0))
.then(() => Promise.reject(new Error("Too many " + name + " events")),
() => {});
};
/**
* Returns a promise that resolves after the target has seen the given number
* of events but no such event in a following crank of the event loop.
*
* @param {object} target
* The target on which the events should occur.
* @param {string} name
* The name of the event that should occur.
* @param {integer} count
* Optional number of times the event should be raised before resolving.
* @param {promise} cancelPromise
* Optional promise that on resolving rejects the returned promise,
* so we can avoid logging results after a test has finished.
* @returns {promise} A promise that resolves to the last of the seen events.
*/
function haveEventsButNoMore(target, name, count, cancelPromise) {
return haveEvents(target, name, count, cancelPromise)
.then(e => haveNoEvent(target, name).then(() => e));
};
/**

View File

@ -32,7 +32,6 @@ runNetworkTest(function (options) {
test.pcLocal.removeSender(videoSenderIndex);
test.pcLocal.attachLocalTrack(stream.getTracks()[0], localStream);
let onNextLoop = wait(0);
eventsPromise = haveEvent(remoteStream, "addtrack", wait(50000, "No addtrack event"))
.then(trackEvent => {
ok(trackEvent instanceof MediaStreamTrackEvent,
@ -43,10 +42,7 @@ runNetworkTest(function (options) {
is(trackEvent.track.readyState, "live",
"added track should be live");
})
.then(() => haveEvent(remoteStream, "addtrack", onNextLoop)
.then(() => Promise.reject("Unexpected addtrack event for remote stream " + remoteStream.id),
() => Promise.resolve())
);
.then(() => haveNoEvent(remoteStream, "addtrack"));
remoteStream.addEventListener("removetrack",
function onRemovetrack(trackEvent) {
ok(false, "UA shouldn't raise 'removetrack' when receiving peer connection");