bug 1316154 - allow testing that an async event comes before or after other events r=yzen
authorTrevor Saunders <tbsaunde@tbsaunde.org>
Tue, 08 Nov 2016 17:02:35 -0500
changeset 322763 cb47917f245791b147cc830fbdc016aac7aea19c
parent 322762 dd21f10a7d6eb49adf92e452cd43e023ff5127fa
child 322764 419e1a311337ecdf208f5474f182d1f88102cc9f
push id30961
push userkwierso@gmail.com
push dateThu, 17 Nov 2016 01:08:03 +0000
treeherdermozilla-central@c27117f67fa3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyzen
bugs1316154
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1316154 - allow testing that an async event comes before or after other events r=yzen There are cases where we want to test for several events, and while several may have a correct ordering some of the events can be fired in different orders WRT some but not all other events. The only purpose of the orderChecker is to force that all preceeding checkers succeed before allowing any following checkers to match.
accessible/tests/mochitest/events.js
--- a/accessible/tests/mochitest/events.js
+++ b/accessible/tests/mochitest/events.js
@@ -531,33 +531,52 @@ function eventQueue(aEventType)
         if (eventQueue.compareEvents(nextChecker, aEvent)) {
           this.processMatchedChecker(aEvent, nextChecker, scnIdx, eventSeq.idx);
           hasMatchedCheckers = true;
           continue;
         }
       }
 
       // Check if handled event matches any expected async events.
+      var haveUnmatchedAsync = false;
       for (idx = 0; idx < eventSeq.length; idx++) {
+        if (eventSeq[idx] instanceof orderChecker && haveUnmatchedAsync) {
+            break;
+        }
+
+        if (!eventSeq[idx].wasCaught) {
+          haveUnmatchedAsync = true;
+        }
+
         if (!eventSeq[idx].unexpected && eventSeq[idx].async) {
           if (eventQueue.compareEvents(eventSeq[idx], aEvent)) {
             this.processMatchedChecker(aEvent, eventSeq[idx], scnIdx, idx);
             hasMatchedCheckers = true;
             break;
           }
         }
       }
     }
 
     if (hasMatchedCheckers) {
       var invoker = this.getInvoker();
       if ("check" in invoker)
         invoker.check(aEvent);
     }
 
+    for (idx = 0; idx < eventSeq.length; idx++) {
+      if (!eventSeq[idx].wasCaught) {
+        if (eventSeq[idx] instanceof orderChecker) {
+          eventSeq[idx].wasCaught++;
+        } else {
+          break;
+        }
+      }
+    }
+
     // If we don't have more events to wait then schedule next invoker.
     if (this.hasMatchedScenario()) {
       if (this.mNextInvokerStatus == kInvokerNotScheduled) {
         this.processNextInvokerInTimeout();
 
       } else if (this.mNextInvokerStatus == kInvokerCanceled) {
         this.setInvokerStatus(kInvokerPending,
                               "Full match. Void the cancelation of next invoker processing");
@@ -591,33 +610,34 @@ function eventQueue(aEventType)
   {
     if (!("idx" in aEventSeq))
       aEventSeq.idx = 0;
 
     while (aEventSeq.idx < aEventSeq.length &&
            (aEventSeq[aEventSeq.idx].unexpected ||
             aEventSeq[aEventSeq.idx].todo ||
             aEventSeq[aEventSeq.idx].async ||
+            aEventSeq[aEventSeq.idx] instanceof orderChecker ||
             aEventSeq[aEventSeq.idx].wasCaught > 0)) {
       aEventSeq.idx++;
     }
 
     return aEventSeq.idx != aEventSeq.length ? aEventSeq[aEventSeq.idx] : null;
   }
 
   this.areExpectedEventsLeft =
     function eventQueue_areExpectedEventsLeft(aScenario)
   {
     function scenarioHasUnhandledExpectedEvent(aEventSeq)
     {
       // Check if we have unhandled async (can be anywhere in the sequance) or
       // sync expcected events yet.
       for (var idx = 0; idx < aEventSeq.length; idx++) {
         if (!aEventSeq[idx].unexpected && !aEventSeq[idx].todo &&
-            !aEventSeq[idx].wasCaught)
+            !aEventSeq[idx].wasCaught && !(aEventSeq[idx] instanceof orderChecker))
           return true;
       }
 
       return false;
     }
 
     if (aScenario)
       return scenarioHasUnhandledExpectedEvent(aScenario);
@@ -1675,16 +1695,25 @@ function invokerChecker(aEventType, aTar
     return prettyName(this.mTarget);
   }
 
   this.mTarget = aTargetOrFunc;
   this.mTargetFuncArg = aTargetFuncArg;
 }
 
 /**
+ * event checker that forces preceeding async events to happen before this
+ * checker.
+ */
+function orderChecker()
+{
+  this.__proto__ = new invokerChecker(null, null, null, false);
+}
+
+/**
  * Generic invoker checker for todo events.
  */
 function todo_invokerChecker(aEventType, aTargetOrFunc, aTargetFuncArg)
 {
   this.__proto__ = new invokerChecker(aEventType, aTargetOrFunc,
                                       aTargetFuncArg, true);
   this.todo = true;
 }