1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 var sendRequestNatives = requireNative('sendRequest');
7 function registerHooks(api) {
8 var chromeTest = api.compiledApi;
9 var apiFunctions = api.apiFunctions;
11 apiFunctions.setHandleRequest('notifyPass', function() {
12 requireAsync('testNatives').then(function(natives) {
17 apiFunctions.setHandleRequest('notifyFail', function(message) {
18 requireAsync('testNatives').then(function(natives) {
19 natives.NotifyFail(message);
23 apiFunctions.setHandleRequest('log', function() {
24 requireAsync('testNatives').then(function(natives) {
25 natives.Log($Array.join(arguments, ' '));
31 function testDone(runNextTest) {
32 // Use a promise here to allow previous test contexts to be eligible for
33 // garbage collection.
34 Promise.resolve().then(function() {
39 function exportTests(tests, runTests, exports) {
40 $Array.forEach(tests, function(test) {
41 exports[test.name] = function() {
49 * A fake implementation of setTimeout and clearTimeout.
52 function TimeoutManager() {
54 this.nextTimeoutId_ = 0;
56 this.autorunEnabled_ = false;
60 * Installs setTimeout and clearTimeout into the global object.
62 TimeoutManager.prototype.installGlobals = function() {
63 var global = sendRequestNatives.GetGlobal({});
64 global.setTimeout = this.setTimeout_.bind(this);
65 global.clearTimeout = this.clearTimeout_.bind(this);
69 * Starts auto-running of timeout callbacks. Until |numCallbacksToRun| callbacks
70 * have run, any timeout callbacks set by calls to setTimeout (including before
71 * the call to run) will cause the currentTime to be advanced to the time of
74 TimeoutManager.prototype.run = function(numCallbacksToRun) {
75 this.numCallbacksToRun_ = numCallbacksToRun;
76 Promise.resolve().then(this.autoRun_.bind(this));
80 * Runs timeout callbacks with earliest timeout.
83 TimeoutManager.prototype.autoRun_ = function() {
84 if (this.numCallbacksToRun_ <= 0 || $Object.keys(this.timeouts_).length == 0)
87 // Bucket the timeouts by their timeout time.
88 var timeoutsByTimeout = {};
89 var timeoutIds = $Object.keys(this.timeouts_);
90 for (var i = 0; i < timeoutIds.length; i++) {
91 var timeout = this.timeouts_[timeoutIds[i]];
92 var timeMs = timeout.timeMs;
93 if (!timeoutsByTimeout[timeMs])
94 timeoutsByTimeout[timeMs] = [];
95 timeoutsByTimeout[timeMs].push(timeout);
98 $Function.apply(Math.min, null, $Object.keys((timeoutsByTimeout)));
99 // Run all timeouts in the earliest timeout bucket.
100 var timeouts = timeoutsByTimeout[this.currentTime];
101 for (var i = 0; i < timeouts.length; i++) {
102 var currentTimeout = timeouts[i];
103 if (!this.timeouts_[currentTimeout.id])
105 this.numCallbacksToRun_--;
106 delete this.timeouts_[currentTimeout.id];
108 currentTimeout.target();
110 console.log('error calling timeout target ' + e.stack);
113 // Continue running any later callbacks.
114 Promise.resolve().then(this.autoRun_.bind(this));
118 * A fake implementation of setTimeout. This does not support passing callback
122 TimeoutManager.prototype.setTimeout_ = function(target, timeoutMs) {
123 var timeoutId = this.nextTimeoutId_++;
124 this.timeouts_[timeoutId] = {
127 timeMs: timeoutMs + this.currentTime,
129 if (this.autorunEnabled_)
130 Promise.resolve().then(this.autoRun_.bind(this));
135 * A fake implementation of clearTimeout.
138 TimeoutManager.prototype.clearTimeout_ = function(timeoutId) {
139 if (this.timeouts_[timeoutId])
140 delete this.timeouts_[timeoutId];
143 exports.registerHooks = registerHooks;
144 exports.testDone = testDone;
145 exports.exportTests = exportTests;
146 exports.TimeoutManager = TimeoutManager;