bug 1316154 - allow testing that an async event comes before or after other events r=yzen a=lizzard
authorTrevor Saunders <tbsaunde@tbsaunde.org>
Tue, 08 Nov 2016 17:02:35 -0500
changeset 352925 3873f6f9aacf915d5da9ff96ef0cdf6971fe52b2
parent 352924 00ced46aa9d09f6db2f9d9aa2483aaf9cf66e460
child 352926 a9fdf64f8f34654aa7d2685c96d53f680ac6aa1d
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyzen, lizzard
bugs1316154
milestone52.0a2
bug 1316154 - allow testing that an async event comes before or after other events r=yzen a=lizzard 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;
 }