Home | History | Annotate | Download | only in base
      1 <!DOCTYPE html>
      2 <!--
      3 Copyright (c) 2014 The Chromium Authors. All rights reserved.
      4 Use of this source code is governed by a BSD-style license that can be
      5 found in the LICENSE file.
      6 -->
      7 <link rel="import" href="/tracing/base/raf.html">
      8 <script>
      9 'use strict';
     10 
     11 tr.b.unittest.testSuite(function() {
     12   if (tr.isHeadless)
     13     return;
     14 
     15   test('idleCallbackWorks', function() {
     16     return new Promise(function(resolve, reject) {
     17       tr.b.requestIdleCallback(resolve);
     18     });
     19   });
     20 
     21   test('forceAllPendingTasksToRunForTest', function() {
     22     var rafRan = false;
     23     tr.b.requestAnimationFrame(function() {
     24       rafRan = true;
     25     });
     26     var idleRan = false;
     27     tr.b.requestIdleCallback(function() {
     28       idleRan = true;
     29     });
     30     assert.isFalse(rafRan);
     31     assert.isFalse(idleRan);
     32     tr.b.forceAllPendingTasksToRunForTest();
     33     assert.isTrue(rafRan);
     34     assert.isTrue(idleRan);
     35   });
     36 
     37   test('forcePendingRAFTasksToRun', function() {
     38     var rafRan = false;
     39     tr.b.requestAnimationFrame(function() {
     40       rafRan = true;
     41     });
     42     var idleRan = false;
     43     tr.b.requestIdleCallback(function() {
     44       idleRan = true;
     45     });
     46     tr.b.forcePendingRAFTasksToRun();
     47     assert.isTrue(rafRan);
     48     assert.isFalse(idleRan);
     49   });
     50 
     51   var fakeNow = undefined;
     52   function withFakeWindowPerformanceNow(func) {
     53     var oldNow = window.performance.now;
     54     try {
     55       window.performance.now = function() { return fakeNow; };
     56       func();
     57     } finally {
     58       window.performance.now = oldNow;
     59     }
     60   }
     61 
     62   // None of the following tests are relevant if the browser supports idle
     63   // callbacks natively. Nevertheless, run them without native idle support to
     64   // make sure the fallback keeps working.
     65   function withoutNativeIdleCallbacks(func) {
     66     var oldRIC = window.requestIdleCallback;
     67     try {
     68       window.requestIdleCallback = undefined;
     69       func();
     70     } finally {
     71       window.requestIdleCallback = oldRIC;
     72     }
     73   }
     74 
     75   function withMockedScheduling(func) {
     76     withFakeWindowPerformanceNow(function() {
     77       withoutNativeIdleCallbacks(func);
     78     });
     79   }
     80 
     81   test('runIdleTaskWhileIdle', function() {
     82     withMockedScheduling(function() {
     83       tr.b.forceAllPendingTasksToRunForTest();
     84 
     85       var rafRan = false;
     86       tr.b.requestAnimationFrame(function() {
     87         rafRan = true;
     88       });
     89       var idleRan = false;
     90       tr.b.requestIdleCallback(function() {
     91         idleRan = true;
     92       });
     93       fakeNow = 0;
     94       tr.b.forcePendingRAFTasksToRun(fakeNow);
     95       assert.isFalse(idleRan);
     96       assert.isTrue(rafRan);
     97       tr.b.forcePendingRAFTasksToRun(fakeNow);
     98       assert.isTrue(idleRan);
     99     });
    100   });
    101 
    102   test('twoShortIdleCallbacks', function() {
    103     withMockedScheduling(function() {
    104       tr.b.forceAllPendingTasksToRunForTest();
    105 
    106       var idle1Ran = false;
    107       var idle2Ran = false;
    108       tr.b.requestIdleCallback(function() {
    109         fakeNow += 1;
    110         idle1Ran = true;
    111       });
    112       tr.b.requestIdleCallback(function() {
    113         fakeNow += 1;
    114         idle2Ran = true;
    115       });
    116       fakeNow = 0;
    117       tr.b.forcePendingRAFTasksToRun(fakeNow);
    118       assert.isTrue(idle1Ran);
    119       assert.isTrue(idle2Ran);
    120     });
    121   });
    122 
    123 
    124   test('oneLongOneShortIdleCallback', function() {
    125     withMockedScheduling(function() {
    126       tr.b.forceAllPendingTasksToRunForTest();
    127 
    128       var idle1Ran = false;
    129       var idle2Ran = false;
    130       tr.b.requestIdleCallback(function() {
    131         fakeNow += 100;
    132         idle1Ran = true;
    133       });
    134       tr.b.requestIdleCallback(function() {
    135         fakeNow += 1;
    136         idle2Ran = true;
    137       });
    138       fakeNow = 0;
    139       tr.b.forcePendingRAFTasksToRun(fakeNow);
    140       assert.isTrue(idle1Ran);
    141       assert.isFalse(idle2Ran);
    142 
    143       // Reset idle1Ran to verify that it dosn't run again.
    144       idle1Ran = false;
    145 
    146       // Now run. idle2 should now run.
    147       tr.b.forcePendingRAFTasksToRun(fakeNow);
    148       assert.isFalse(idle1Ran);
    149       assert.isTrue(idle2Ran);
    150     });
    151   });
    152 
    153   test('buggyPerformanceNowDoesNotBlockIdleTasks', function() {
    154     withMockedScheduling(function() {
    155       tr.b.forcePendingRAFTasksToRun();  // Clear current RAF task queue.
    156 
    157       var idle1Ran = false;
    158       var idle2Ran = false;
    159       tr.b.requestIdleCallback(function() {
    160         fakeNow += 100;
    161         idle1Ran = true;
    162       });
    163       tr.b.requestIdleCallback(function() {
    164         fakeNow += 1;
    165         idle2Ran = true;
    166       });
    167       fakeNow = 10000;
    168       tr.b.forcePendingRAFTasksToRun(0);
    169       assert.isTrue(idle1Ran);
    170       assert.isFalse(idle2Ran);
    171 
    172       // Reset idle1Ran to verify that it dosn't run again.
    173       idle1Ran = false;
    174 
    175       // Now run. idle2 should now run.
    176       tr.b.forcePendingRAFTasksToRun(0);
    177       assert.isFalse(idle1Ran);
    178       assert.isTrue(idle2Ran);
    179     });
    180   });
    181 
    182   function withFixedIdleTimeRemaining(idleTime, func) {
    183     var oldRIC = window.requestIdleCallback;
    184     try {
    185       var pendingIdleCallbacks = [];
    186       window.requestIdleCallback = function(callback) {
    187         var deadline = {
    188           timeRemaining: function() {
    189             return idleTime;
    190           }
    191         };
    192         pendingIdleCallbacks.push(function() {
    193           callback(deadline, false /* didTimeout */);
    194         });
    195       };
    196       func(pendingIdleCallbacks);
    197     } finally {
    198       window.requestIdleCallback = oldRIC;
    199     }
    200   }
    201 
    202   test('idleCallbackWithIdletime', function() {
    203     withFixedIdleTimeRemaining(1000, function(pendingIdleCallbacks) {
    204       var idle1Ran = false;
    205       var idle2Ran = false;
    206       tr.b.requestIdleCallback(function() {
    207         idle1Ran = true;
    208       });
    209       tr.b.requestIdleCallback(function() {
    210         idle2Ran = true;
    211       });
    212       assert.lengthOf(pendingIdleCallbacks, 1);
    213       pendingIdleCallbacks.shift()();
    214 
    215       // Both callbacks should have run since there was idle time.
    216       assert.isTrue(idle1Ran);
    217       assert.isTrue(idle2Ran);
    218     });
    219   });
    220 
    221   test('idleCallbackWithoutIdletime', function() {
    222     withFixedIdleTimeRemaining(0, function(pendingIdleCallbacks) {
    223       var idle1Ran = false;
    224       var idle2Ran = false;
    225       tr.b.requestIdleCallback(function() {
    226         idle1Ran = true;
    227       });
    228       tr.b.requestIdleCallback(function() {
    229         idle2Ran = true;
    230       });
    231       assert.lengthOf(pendingIdleCallbacks, 1);
    232       pendingIdleCallbacks.shift()();
    233 
    234       // Only the first idle callback should have run since there was no idle
    235       // time left.
    236       assert.isTrue(idle1Ran);
    237       assert.isFalse(idle2Ran);
    238 
    239       // Run the remaining idle task.
    240       assert.lengthOf(pendingIdleCallbacks, 1);
    241       pendingIdleCallbacks.shift()();
    242       assert.isTrue(idle2Ran);
    243     });
    244   });
    245 
    246 });
    247 </script>
    248