Make unit tests return a promise instead of manually calling done
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Mar 2017 18:15:33 +0000 (18:15 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Mar 2017 18:15:33 +0000 (18:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=169663

Reviewed by Antti Koivisto.

Make the existing unit tests always reutrn a promise instead of manually calling "done" callback as done
in r213969. The promise tests are a lot more stable and less error prone.

Also use MockRemoteAPI.waitForRequest() instead of chaining two resolved promises where appropriate.

* unit-tests/analysis-task-tests.js:
* unit-tests/buildbot-syncer-tests.js:
* unit-tests/checkconfig.js:
* unit-tests/privileged-api-tests.js:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@213993 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Websites/perf.webkit.org/ChangeLog
Websites/perf.webkit.org/unit-tests/analysis-task-tests.js
Websites/perf.webkit.org/unit-tests/buildbot-syncer-tests.js
Websites/perf.webkit.org/unit-tests/checkconfig.js
Websites/perf.webkit.org/unit-tests/privileged-api-tests.js

index c823c35..ea68368 100644 (file)
@@ -1,3 +1,20 @@
+2017-03-15  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Make unit tests return a promise instead of manually calling done
+        https://bugs.webkit.org/show_bug.cgi?id=169663
+
+        Reviewed by Antti Koivisto.
+
+        Make the existing unit tests always reutrn a promise instead of manually calling "done" callback as done
+        in r213969. The promise tests are a lot more stable and less error prone.
+
+        Also use MockRemoteAPI.waitForRequest() instead of chaining two resolved promises where appropriate.
+
+        * unit-tests/analysis-task-tests.js:
+        * unit-tests/buildbot-syncer-tests.js:
+        * unit-tests/checkconfig.js:
+        * unit-tests/privileged-api-tests.js:
+
 2017-03-15  Dewei Zhu  <dewei_zhu@apple.com>
 
         Rewrite 'pull-os-versions' script in Javascript to add support for reporting os revisions with sub commits.
index 5735762..d6b0800 100644 (file)
@@ -1,6 +1,6 @@
 'use strict';
 
-var assert = require('assert');
+const assert = require('assert');
 
 require('../tools/js/v3-models.js');
 let MockModels = require('./resources/mock-v3-models.js').MockModels;
@@ -116,57 +116,56 @@ function measurementCluster()
     };
 }
 
-describe('AnalysisTask', function () {
+describe('AnalysisTask', () => {
     MockModels.inject();
     let requests = MockRemoteAPI.inject();
 
-    describe('fetchAll', function () {
-        it('should request all analysis tasks', function () {
-            var callCount = 0;
-            AnalysisTask.fetchAll().then(function () { callCount++; });
+    describe('fetchAll', () => {
+        it('should request all analysis tasks', () => {
+            let callCount = 0;
+            AnalysisTask.fetchAll().then(() => { callCount++; });
             assert.equal(callCount, 0);
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '../api/analysis-tasks');
         });
 
-        it('should not request all analysis tasks multiple times', function () {
-            var callCount = 0;
-            AnalysisTask.fetchAll().then(function () { callCount++; });
+        it('should not request all analysis tasks multiple times', () => {
+            let callCount = 0;
+            AnalysisTask.fetchAll().then(() => { callCount++; });
             assert.equal(callCount, 0);
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '../api/analysis-tasks');
 
-            AnalysisTask.fetchAll().then(function () { callCount++; });
+            AnalysisTask.fetchAll().then(() => { callCount++; });
             assert.equal(callCount, 0);
             assert.equal(requests.length, 1);
         });
 
-        it('should resolve the promise when the request is fullfilled', function (done) {
-            var callCount = 0;
-            var promise = AnalysisTask.fetchAll().then(function () { callCount++; });
+        it('should resolve the promise when the request is fullfilled', () => {
+            let callCount = 0;
+            const promise = AnalysisTask.fetchAll().then(() => { callCount++; });
             assert.equal(callCount, 0);
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '../api/analysis-tasks');
 
             requests[0].resolve(sampleAnalysisTask());
 
-            var anotherCallCount = 0;
-            promise.then(function () {
+            let anotherCallCount = 0;
+            return promise.then(() => {
                 assert.equal(callCount, 1);
-                AnalysisTask.fetchAll().then(function () { anotherCallCount++; });
-            }).then(function () {
+                AnalysisTask.fetchAll().then(() => { anotherCallCount++; });
+            }).then(() => {
                 assert.equal(callCount, 1);
                 assert.equal(anotherCallCount, 1);
                 assert.equal(requests.length, 1);
-                done();
-            }).catch(function (error) { done(error); });
+            });
         });
 
-        it('should create AnalysisTask objects', function (done) {
-            var promise = AnalysisTask.fetchAll();
+        it('should create AnalysisTask objects', () => {
+            const promise = AnalysisTask.fetchAll();
             requests[0].resolve(sampleAnalysisTask());
 
-            promise.then(function () {
+            return promise.then(() => {
                 assert.equal(AnalysisTask.all().length, 1);
                 var task = AnalysisTask.all()[0];
                 assert.equal(task.id(), 1082);
@@ -181,15 +180,14 @@ describe('AnalysisTask', function () {
                 assert.equal(task.startTime(), 1454444458791);
                 assert.equal(task.endMeasurementId(), 37253448);
                 assert.equal(task.endTime(), 1454515020303);
-                done();
-            }).catch(function (error) { done(error); });
+            });
         });
 
-        it('should create CommitLog objects for `causes`', function (done) {
-            var promise = AnalysisTask.fetchAll();
+        it('should create CommitLog objects for `causes`', () => {
+            const promise = AnalysisTask.fetchAll();
             requests[0].resolve(sampleAnalysisTask());
 
-            promise.then(function () {
+            return promise.then(() => {
                 assert.equal(AnalysisTask.all().length, 1);
                 var task = AnalysisTask.all()[0];
 
@@ -199,20 +197,19 @@ describe('AnalysisTask', function () {
                 assert.equal(commit.revision(), '196051');
                 assert.equal(commit.repository(), MockModels.webkit);
                 assert.equal(+commit.time(), 1454481246108);
-                done();
-            }).catch(function (error) { done(error); });
+            });
         });
 
-        it('should find CommitLog objects for `causes` when MeasurementAdaptor created matching objects', function (done) {
-            var adaptor = new MeasurementAdaptor(measurementCluster().formatMap);
-            var adaptedMeasurement = adaptor.applyTo(measurementCluster().configurations.current[0]);
+        it('should find CommitLog objects for `causes` when MeasurementAdaptor created matching objects', () => {
+            const adaptor = new MeasurementAdaptor(measurementCluster().formatMap);
+            const adaptedMeasurement = adaptor.applyTo(measurementCluster().configurations.current[0]);
             assert.equal(adaptedMeasurement.id, 37188161);
             assert.equal(adaptedMeasurement.commitSet().commitForRepository(MockModels.webkit).revision(), '196051');
 
-            var promise = AnalysisTask.fetchAll();
+            const promise = AnalysisTask.fetchAll();
             requests[0].resolve(sampleAnalysisTask());
 
-            promise.then(function () {
+            return promise.then(() => {
                 assert.equal(AnalysisTask.all().length, 1);
                 var task = AnalysisTask.all()[0];
 
@@ -221,8 +218,7 @@ describe('AnalysisTask', function () {
                 assert.equal(commit.revision(), '196051');
                 assert.equal(commit.repository(), MockModels.webkit);
                 assert.equal(+commit.time(), 1454481246108);
-                done();
-            }).catch(function (error) { done(error); });
+            });
         });
     });
 });
index b709b4d..cb6c45a 100644 (file)
@@ -416,113 +416,113 @@ function sampleFinishedBuild(buildRequestId, slaveName)
     };
 }
 
-describe('BuildbotSyncer', function () {
+describe('BuildbotSyncer', () => {
     MockModels.inject();
     let requests = MockRemoteAPI.inject('http://build.webkit.org');
 
-    describe('_loadConfig', function () {
+    describe('_loadConfig', () => {
 
-        it('should create BuildbotSyncer objects for a configuration that specify all required options', function () {
+        it('should create BuildbotSyncer objects for a configuration that specify all required options', () => {
             let syncers = BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [smallConfiguration()]});
             assert.equal(syncers.length, 1);
         });
 
-        it('should throw when some required options are missing', function () {
-            assert.throws(function () {
+        it('should throw when some required options are missing', () => {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 delete config['builder'];
                 BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [config]});
             }, 'builder should be a required option');
-            assert.throws(function () {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 delete config['platform'];
                 BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [config]});
             }, 'platform should be a required option');
-            assert.throws(function () {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 delete config['test'];
                 BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [config]});
             }, 'test should be a required option');
-            assert.throws(function () {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 delete config['arguments'];
                 BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [config]});
             });
-            assert.throws(function () {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 delete config['buildRequestArgument'];
                 BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [config]});
             });
         });
 
-        it('should throw when a test name is not an array of strings', function () {
-            assert.throws(function () {
+        it('should throw when a test name is not an array of strings', () => {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 config.test = 'some test';
                 BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [config]});
             });
-            assert.throws(function () {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 config.test = [1];
                 BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [config]});
             });
         });
 
-        it('should throw when arguments is not an object', function () {
-            assert.throws(function () {
+        it('should throw when arguments is not an object', () => {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 config.arguments = 'hello';
                 BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [config]});
             });
         });
 
-        it('should throw when arguments\'s values are malformed', function () {
-            assert.throws(function () {
+        it('should throw when arguments\'s values are malformed', () => {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 config.arguments = {'some': {'root': 'some root', 'rootsExcluding': ['other root']}};
                 BuildbotSyncer._loadConfig(RemoteAPI, {'configurations': [config]});
             });
-            assert.throws(function () {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 config.arguments = {'some': {'otherKey': 'some root'}};
                 BuildbotSyncer._loadConfig(RemoteAPI, {'configurations': [config]});
             });
-            assert.throws(function () {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 config.arguments = {'some': {'root': ['a', 'b']}};
                 BuildbotSyncer._loadConfig(RemoteAPI, {'configurations': [config]});
             });
-            assert.throws(function () {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 config.arguments = {'some': {'root': 1}};
                 BuildbotSyncer._loadConfig(RemoteAPI, {'configurations': [config]});
             });
-            assert.throws(function () {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 config.arguments = {'some': {'rootsExcluding': 'a'}};
                 BuildbotSyncer._loadConfig(RemoteAPI, {'configurations': [config]});
             });
-            assert.throws(function () {
+            assert.throws(() => {
                 let config = smallConfiguration();
                 config.arguments = {'some': {'rootsExcluding': [1]}};
                 BuildbotSyncer._loadConfig(RemoteAPI, {'configurations': [config]});
             });
         });
 
-        it('should create BuildbotSyncer objects for valid configurations', function () {
+        it('should create BuildbotSyncer objects for valid configurations', () => {
             let syncers = BuildbotSyncer._loadConfig(RemoteAPI, sampleiOSConfig());
             assert.equal(syncers.length, 2);
             assert.ok(syncers[0] instanceof BuildbotSyncer);
             assert.ok(syncers[1] instanceof BuildbotSyncer);
         });
 
-        it('should parse builder names correctly', function () {
+        it('should parse builder names correctly', () => {
             let syncers = BuildbotSyncer._loadConfig(RemoteAPI, sampleiOSConfig());
             assert.equal(syncers[0].builderName(), 'ABTest-iPhone-RunBenchmark-Tests');
             assert.equal(syncers[1].builderName(), 'ABTest-iPad-RunBenchmark-Tests');
         });
 
-        it('should parse test configurations correctly', function () {
+        it('should parse test configurations correctly', () => {
             let syncers = BuildbotSyncer._loadConfig(RemoteAPI, sampleiOSConfig());
 
             let configurations = syncers[0].testConfigurations();
@@ -542,7 +542,7 @@ describe('BuildbotSyncer', function () {
             assert.equal(configurations[1].test, MockModels.jetstream);
         });
 
-        it('should parse test configurations with types and platforms expansions correctly', function () {
+        it('should parse test configurations with types and platforms expansions correctly', () => {
             let syncers = BuildbotSyncer._loadConfig(RemoteAPI, sampleiOSConfigWithExpansions());
 
             assert.equal(syncers.length, 2);
@@ -567,14 +567,14 @@ describe('BuildbotSyncer', function () {
         });
     });
 
-    describe('_propertiesForBuildRequest', function () {
-        it('should include all properties specified in a given configuration', function () {
+    describe('_propertiesForBuildRequest', () => {
+        it('should include all properties specified in a given configuration', () => {
             let syncers = BuildbotSyncer._loadConfig(RemoteAPI, sampleiOSConfig());
             let properties = syncers[0]._propertiesForBuildRequest(createSampleBuildRequest(MockModels.iphone, MockModels.speedometer));
             assert.deepEqual(Object.keys(properties), ['desired_image', 'opensource', 'roots_dict', 'test_name', 'forcescheduler', 'build_request_id']);
         });
 
-        it('should preserve non-parametric property values', function () {
+        it('should preserve non-parametric property values', () => {
             let syncers = BuildbotSyncer._loadConfig(RemoteAPI, sampleiOSConfig());
             let properties = syncers[0]._propertiesForBuildRequest(createSampleBuildRequest(MockModels.iphone, MockModels.speedometer));
             assert.equal(properties['test_name'], 'speedometer');
@@ -585,25 +585,25 @@ describe('BuildbotSyncer', function () {
             assert.equal(properties['forcescheduler'], 'ABTest-iPad-RunBenchmark-Tests-ForceScheduler');
         });
 
-        it('should resolve "root"', function () {
+        it('should resolve "root"', () => {
             let syncers = BuildbotSyncer._loadConfig(RemoteAPI, sampleiOSConfig());
             let properties = syncers[0]._propertiesForBuildRequest(createSampleBuildRequest(MockModels.iphone, MockModels.speedometer));
             assert.equal(properties['desired_image'], '13A452');
         });
 
-        it('should resolve "rootOptions"', function () {
+        it('should resolve "rootOptions"', () => {
             let syncers = BuildbotSyncer._loadConfig(RemoteAPI, sampleiOSConfig());
             let properties = syncers[0]._propertiesForBuildRequest(createSampleBuildRequest(MockModels.iphone, MockModels.speedometer));
             assert.equal(properties['roots_dict'], JSON.stringify(sampleCommitSetData));
         });
 
-        it('should resolve "rootsExcluding"', function () {
+        it('should resolve "rootsExcluding"', () => {
             let syncers = BuildbotSyncer._loadConfig(RemoteAPI, sampleiOSConfig());
             let properties = syncers[0]._propertiesForBuildRequest(createSampleBuildRequest(MockModels.iphone, MockModels.speedometer));
             assert.equal(properties['roots_dict'], JSON.stringify(sampleCommitSetData));
         });
 
-        it('should set the property for the build request id', function () {
+        it('should set the property for the build request id', () => {
             let syncers = BuildbotSyncer._loadConfig(RemoteAPI, sampleiOSConfig());
             let request = createSampleBuildRequest(MockModels.iphone, MockModels.speedometer);
             let properties = syncers[0]._propertiesForBuildRequest(request);
@@ -611,8 +611,8 @@ describe('BuildbotSyncer', function () {
         });
     });
 
-    describe('pullBuildbot', function () {
-        it('should fetch pending builds from the right URL', function () {
+    describe('pullBuildbot', () => {
+        it('should fetch pending builds from the right URL', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
             assert.equal(syncer.builderName(), 'ABTest-iPad-RunBenchmark-Tests');
             let expectedURL = '/json/builders/ABTest-iPad-RunBenchmark-Tests/pendingBuilds';
@@ -622,7 +622,7 @@ describe('BuildbotSyncer', function () {
             assert.equal(requests[0].url, expectedURL);
         });
 
-        it('should fetch recent builds once pending builds have been fetched', function (done) {
+        it('should fetch recent builds once pending builds have been fetched', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
             assert.equal(syncer.builderName(), 'ABTest-iPad-RunBenchmark-Tests');
 
@@ -630,32 +630,30 @@ describe('BuildbotSyncer', function () {
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '/json/builders/ABTest-iPad-RunBenchmark-Tests/pendingBuilds');
             requests[0].resolve([]);
-            Promise.resolve().then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 assert.equal(requests[1].url, '/json/builders/ABTest-iPad-RunBenchmark-Tests/builds/?select=-1');
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should fetch the right number of recent builds', function (done) {
+        it('should fetch the right number of recent builds', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
             syncer.pullBuildbot(3);
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '/json/builders/ABTest-iPad-RunBenchmark-Tests/pendingBuilds');
             requests[0].resolve([]);
-            Promise.resolve().then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 assert.equal(requests[1].url, '/json/builders/ABTest-iPad-RunBenchmark-Tests/builds/?select=-1&select=-2&select=-3');
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should create BuildbotBuildEntry for pending builds', function (done) {
+        it('should create BuildbotBuildEntry for pending builds', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
             let promise = syncer.pullBuildbot();
             requests[0].resolve([samplePendingBuild()]);
-            promise.then(function (entries) {
+            return promise.then((entries) => {
                 assert.equal(entries.length, 1);
                 let entry = entries[0];
                 assert.ok(entry instanceof BuildbotBuildEntry);
@@ -666,22 +664,20 @@ describe('BuildbotSyncer', function () {
                 assert.ok(!entry.isInProgress());
                 assert.ok(!entry.hasFinished());
                 assert.equal(entry.url(), 'http://build.webkit.org/builders/ABTest-iPad-RunBenchmark-Tests/');
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should create BuildbotBuildEntry for in-progress builds', function (done) {
+        it('should create BuildbotBuildEntry for in-progress builds', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
             let promise = syncer.pullBuildbot(1);
             assert.equal(requests.length, 1);
             requests[0].resolve([]);
-            Promise.resolve().then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 requests[1].resolve({[-1]: sampleInProgressBuild()});
-            }).catch(done);
-
-            promise.then(function (entries) {
+                return promise;
+            }).then((entries) => {
                 assert.equal(entries.length, 1);
                 let entry = entries[0];
                 assert.ok(entry instanceof BuildbotBuildEntry);
@@ -692,22 +688,20 @@ describe('BuildbotSyncer', function () {
                 assert.ok(entry.isInProgress());
                 assert.ok(!entry.hasFinished());
                 assert.equal(entry.url(), 'http://build.webkit.org/builders/ABTest-iPad-RunBenchmark-Tests/builds/614');
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should create BuildbotBuildEntry for finished builds', function (done) {
+        it('should create BuildbotBuildEntry for finished builds', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
             let promise = syncer.pullBuildbot(1);
             assert.equal(requests.length, 1);
             requests[0].resolve([]);
-            Promise.resolve().then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 requests[1].resolve({[-1]: sampleFinishedBuild()});
-            }).catch(done);
-
-            promise.then(function (entries) {
+                return promise;
+            }).then((entries) => {
                 assert.deepEqual(entries.length, 1);
                 let entry = entries[0];
                 assert.ok(entry instanceof BuildbotBuildEntry);
@@ -718,11 +712,10 @@ describe('BuildbotSyncer', function () {
                 assert.ok(!entry.isInProgress());
                 assert.ok(entry.hasFinished());
                 assert.equal(entry.url(), 'http://build.webkit.org/builders/ABTest-iPad-RunBenchmark-Tests/builds/1755');
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should create BuildbotBuildEntry for mixed pending, in-progress, finished, and missing builds', function (done) {
+        it('should create BuildbotBuildEntry for mixed pending, in-progress, finished, and missing builds', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
             let promise = syncer.pullBuildbot(5);
@@ -730,12 +723,11 @@ describe('BuildbotSyncer', function () {
 
             requests[0].resolve([samplePendingBuild(123)]);
 
-            Promise.resolve().then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 requests[1].resolve({[-1]: sampleFinishedBuild(), [-2]: {'error': 'Not available'}, [-4]: sampleInProgressBuild()});
-            }).catch(done);
-
-            promise.then(function (entries) {
+                return promise;
+            }).then((entries) => {
                 assert.deepEqual(entries.length, 3);
 
                 let entry = entries[0];
@@ -767,12 +759,10 @@ describe('BuildbotSyncer', function () {
                 assert.ok(!entry.isInProgress());
                 assert.ok(entry.hasFinished());
                 assert.equal(entry.url(), 'http://build.webkit.org/builders/ABTest-iPad-RunBenchmark-Tests/builds/1755');
-
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should sort BuildbotBuildEntry by order', function (done) {
+        it('should sort BuildbotBuildEntry by order', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
             let promise = syncer.pullBuildbot(5);
@@ -780,12 +770,11 @@ describe('BuildbotSyncer', function () {
 
             requests[0].resolve([samplePendingBuild(456, 2), samplePendingBuild(123, 1)]);
 
-            Promise.resolve().then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 requests[1].resolve({[-3]: sampleFinishedBuild(), [-1]: {'error': 'Not available'}, [-2]: sampleInProgressBuild()});
-            }).catch(done);
-
-            promise.then(function (entries) {
+                return promise;
+            }).then((entries) => {
                 assert.deepEqual(entries.length, 4);
 
                 let entry = entries[0];
@@ -827,12 +816,10 @@ describe('BuildbotSyncer', function () {
                 assert.ok(!entry.isInProgress());
                 assert.ok(entry.hasFinished());
                 assert.equal(entry.url(), 'http://build.webkit.org/builders/ABTest-iPad-RunBenchmark-Tests/builds/1755');
-
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should override BuildbotBuildEntry for pending builds by in-progress builds', function (done) {
+        it('should override BuildbotBuildEntry for pending builds by in-progress builds', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
             let promise = syncer.pullBuildbot(5);
@@ -840,12 +827,11 @@ describe('BuildbotSyncer', function () {
 
             requests[0].resolve([samplePendingBuild()]);
 
-            Promise.resolve().then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 requests[1].resolve({[-1]: sampleInProgressBuild()});
-            }).catch(done);
-
-            promise.then(function (entries) {
+                return promise;
+            }).then((entries) => {
                 assert.equal(entries.length, 1);
 
                 let entry = entries[0];
@@ -857,12 +843,10 @@ describe('BuildbotSyncer', function () {
                 assert.ok(entry.isInProgress());
                 assert.ok(!entry.hasFinished());
                 assert.equal(entry.url(), 'http://build.webkit.org/builders/ABTest-iPad-RunBenchmark-Tests/builds/614');
-
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should override BuildbotBuildEntry for pending builds by finished builds', function (done) {
+        it('should override BuildbotBuildEntry for pending builds by finished builds', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
             let promise = syncer.pullBuildbot(5);
@@ -870,12 +854,11 @@ describe('BuildbotSyncer', function () {
 
             requests[0].resolve([samplePendingBuild()]);
 
-            Promise.resolve().then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 requests[1].resolve({[-1]: sampleFinishedBuild(16733)});
-            }).catch(done);
-
-            promise.then(function (entries) {
+                return promise;
+            }).then((entries) => {
                 assert.equal(entries.length, 1);
 
                 let entry = entries[0];
@@ -887,18 +870,17 @@ describe('BuildbotSyncer', function () {
                 assert.ok(!entry.isInProgress());
                 assert.ok(entry.hasFinished());
                 assert.equal(entry.url(), 'http://build.webkit.org/builders/ABTest-iPad-RunBenchmark-Tests/builds/1755');
-
-                done();
-            }).catch(done);
+            });
         });
     });
 
-    describe('scheduleRequest', function () {
-        it('should schedule a build request on a specified slave', function (done) {
+    describe('scheduleRequest', () => {
+        it('should schedule a build request on a specified slave', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[0];
 
+            const waitForRequest = MockRemoteAPI.waitForRequest();
             syncer.scheduleRequest(createSampleBuildRequest(MockModels.iphone, MockModels.speedometer), 'some-slave');
-            Promise.resolve().then(function () {
+            return waitForRequest.then(() => {
                 assert.equal(requests.length, 1);
                 assert.equal(requests[0].url, '/builders/ABTest-iPhone-RunBenchmark-Tests/force');
                 assert.equal(requests[0].method, 'POST');
@@ -913,188 +895,160 @@ describe('BuildbotSyncer', function () {
                     'slavename': 'some-slave',
                     'test_name': 'speedometer'
                 });
-                done();
-            }).catch(done);
+            });
         });
     });
 
-    describe('scheduleRequestInGroupIfAvailable', function () {
+    describe('scheduleRequestInGroupIfAvailable', () => {
 
         function pullBuildbotWithAssertion(syncer, pendingBuilds, inProgressAndFinishedBuilds)
         {
-            let promise = syncer.pullBuildbot(5);
+            const promise = syncer.pullBuildbot(5);
             assert.equal(requests.length, 1);
             requests[0].resolve(pendingBuilds);
-            return Promise.resolve().then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 requests[1].resolve(inProgressAndFinishedBuilds);
                 requests.length = 0;
-            }).then(function () {
                 return promise;
             });
         }
 
-        it('should schedule a build if builder has no builds if slaveList is not specified', function (done) {
+        it('should schedule a build if builder has no builds if slaveList is not specified', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [smallConfiguration()]})[0];
 
-            pullBuildbotWithAssertion(syncer, [], {}).then(function () {
+            return pullBuildbotWithAssertion(syncer, [], {}).then(() => {
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.somePlatform, MockModels.someTest));
-            }).then(function () {
                 assert.equal(requests.length, 1);
                 assert.equal(requests[0].url, '/builders/some%20builder/force');
                 assert.equal(requests[0].method, 'POST');
                 assert.deepEqual(requests[0].data, {id: '16733-' + MockModels.somePlatform.id()});
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should schedule a build if builder only has finished builds if slaveList is not specified', function (done) {
+        it('should schedule a build if builder only has finished builds if slaveList is not specified', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [smallConfiguration()]})[0];
 
-            pullBuildbotWithAssertion(syncer, [], {[-1]: smallFinishedBuild()}).then(function () {
+            return pullBuildbotWithAssertion(syncer, [], {[-1]: smallFinishedBuild()}).then(() => {
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.somePlatform, MockModels.someTest));
-            }).then(function () {
                 assert.equal(requests.length, 1);
                 assert.equal(requests[0].url, '/builders/some%20builder/force');
                 assert.equal(requests[0].method, 'POST');
                 assert.deepEqual(requests[0].data, {id: '16733-' + MockModels.somePlatform.id()});
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should not schedule a build if builder has a pending build if slaveList is not specified', function (done) {
+        it('should not schedule a build if builder has a pending build if slaveList is not specified', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [smallConfiguration()]})[0];
 
-            pullBuildbotWithAssertion(syncer, [smallPendingBuild()], {}).then(function () {
+            return pullBuildbotWithAssertion(syncer, [smallPendingBuild()], {}).then(() => {
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.somePlatform, MockModels.someTest));
-            }).then(function () {
                 assert.equal(requests.length, 0);
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should schedule a build if builder does not have pending or completed builds on the matching slave', function (done) {
+        it('should schedule a build if builder does not have pending or completed builds on the matching slave', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[0];
 
-            pullBuildbotWithAssertion(syncer, [], {}).then(function () {
+            return pullBuildbotWithAssertion(syncer, [], {}).then(() => {
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.iphone, MockModels.speedometer));
-            }).then(function () {
                 assert.equal(requests.length, 1);
                 assert.equal(requests[0].url, '/builders/ABTest-iPhone-RunBenchmark-Tests/force');
                 assert.equal(requests[0].method, 'POST');
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should schedule a build if builder only has finished builds on the matching slave', function (done) {
+        it('should schedule a build if builder only has finished builds on the matching slave', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
-            pullBuildbotWithAssertion(syncer, [], {[-1]: sampleFinishedBuild()}).then(function () {
+            pullBuildbotWithAssertion(syncer, [], {[-1]: sampleFinishedBuild()}).then(() => {
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.ipad, MockModels.speedometer));
-            }).then(function () {
                 assert.equal(requests.length, 1);
                 assert.equal(requests[0].url, '/builders/ABTest-iPad-RunBenchmark-Tests/force');
                 assert.equal(requests[0].method, 'POST');
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should not schedule a build if builder has a pending build on the maching slave', function (done) {
+        it('should not schedule a build if builder has a pending build on the maching slave', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
-            pullBuildbotWithAssertion(syncer, [samplePendingBuild()], {}).then(function () {
+            pullBuildbotWithAssertion(syncer, [samplePendingBuild()], {}).then(() => {
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.ipad, MockModels.speedometer));
-            }).then(function () {
                 assert.equal(requests.length, 0);
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should schedule a build if builder only has a pending build on a non-maching slave', function (done) {
+        it('should schedule a build if builder only has a pending build on a non-maching slave', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
-            pullBuildbotWithAssertion(syncer, [samplePendingBuild(1, 1, 'another-slave')], {}).then(function () {
+            return pullBuildbotWithAssertion(syncer, [samplePendingBuild(1, 1, 'another-slave')], {}).then(() => {
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.ipad, MockModels.speedometer));
-            }).then(function () {
                 assert.equal(requests.length, 1);
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should schedule a build if builder only has an in-progress build on the matching slave', function (done) {
+        it('should schedule a build if builder only has an in-progress build on the matching slave', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
-            pullBuildbotWithAssertion(syncer, [], {[-1]: sampleInProgressBuild()}).then(function () {
+            return pullBuildbotWithAssertion(syncer, [], {[-1]: sampleInProgressBuild()}).then(() => {
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.ipad, MockModels.speedometer));
-            }).then(function () {
                 assert.equal(requests.length, 1);
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should schedule a build if builder has an in-progress build on another slave', function (done) {
+        it('should schedule a build if builder has an in-progress build on another slave', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
-            pullBuildbotWithAssertion(syncer, [], {[-1]: sampleInProgressBuild('other-slave')}).then(function () {
+            return pullBuildbotWithAssertion(syncer, [], {[-1]: sampleInProgressBuild('other-slave')}).then(() => {
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.ipad, MockModels.speedometer));
-            }).then(function () {
                 assert.equal(requests.length, 1);
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should not schedule a build if the request does not match any configuration', function (done) {
+        it('should not schedule a build if the request does not match any configuration', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[0];
 
-            pullBuildbotWithAssertion(syncer, [], {}).then(function () {
+            return pullBuildbotWithAssertion(syncer, [], {}).then(() => {
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.ipad, MockModels.speedometer));
-            }).then(function () {
                 assert.equal(requests.length, 0);
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should not schedule a build if a new request had been submitted to the same slave', function (done) {
+        it('should not schedule a build if a new request had been submitted to the same slave', (done) => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
-            pullBuildbotWithAssertion(syncer, [], {}).then(function () {
+            pullBuildbotWithAssertion(syncer, [], {}).then(() => {
                 syncer.scheduleRequest(createSampleBuildRequest(MockModels.ipad, MockModels.speedometer), 'ABTest-iPad-0');
                 syncer.scheduleRequest(createSampleBuildRequest(MockModels.ipad, MockModels.speedometer), 'ABTest-iPad-1');
-            }).then(function () {
+            }).then(() => {
                 assert.equal(requests.length, 2);
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.ipad, MockModels.speedometer));
-            }).then(function () {
+            }).then(() => {
                 assert.equal(requests.length, 2);
                 done();
             }).catch(done);
         });
 
-        it('should schedule a build if a new request had been submitted to another slave', function (done) {
+        it('should schedule a build if a new request had been submitted to another slave', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, sampleiOSConfig())[1];
 
-            pullBuildbotWithAssertion(syncer, [], {}).then(function () {
+            return pullBuildbotWithAssertion(syncer, [], {}).then(() => {
                 syncer.scheduleRequest(createSampleBuildRequest(MockModels.ipad, MockModels.speedometer), 'ABTest-iPad-0');
-            }).then(function () {
                 assert.equal(requests.length, 1);
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.ipad, MockModels.speedometer), 'ABTest-iPad-1');
-            }).then(function () {
                 assert.equal(requests.length, 2);
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should not schedule a build if a new request had been submitted to the same builder without slaveList', function (done) {
+        it('should not schedule a build if a new request had been submitted to the same builder without slaveList', () => {
             let syncer = BuildbotSyncer._loadConfig(MockRemoteAPI, {'configurations': [smallConfiguration()]})[0];
 
-            pullBuildbotWithAssertion(syncer, [], {}).then(function () {
+            return pullBuildbotWithAssertion(syncer, [], {}).then(() => {
                 syncer.scheduleRequest(createSampleBuildRequest(MockModels.somePlatform, MockModels.someTest), null);
-            }).then(function () {
                 assert.equal(requests.length, 1);
                 syncer.scheduleRequestInGroupIfAvailable(createSampleBuildRequest(MockModels.somePlatform, MockModels.someTest));
-            }).then(function () {
                 assert.equal(requests.length, 1);
-                done();
-            }).catch(done);
+            });
         });
     });
 });
index d6c6f2a..53c2aa2 100644 (file)
@@ -1,48 +1,48 @@
 'use strict';
 
-var assert = require('assert');
-var fs = require('fs');
+const assert = require('assert');
+const fs = require('fs');
 
-var Config = require('../tools/js/config.js');
-var Database = require('../tools/js/database.js');
+const Config = require('../tools/js/config.js');
+const Database = require('../tools/js/database.js');
 
-describe('config.json', function () {
-    it('should be a valid file', function () {
-        assert.doesNotThrow(function () {
+describe('config.json', () => {
+    it('should be a valid file', () => {
+        assert.doesNotThrow(() => {
             fs.readFileSync(Config.configFilePath())
         });
     });
 
-    it('should be a valid JSON', function () {
-        assert.doesNotThrow(function () {
+    it('should be a valid JSON', () => {
+        assert.doesNotThrow(() => {
             JSON.parse(fs.readFileSync(Config.configFilePath()));
         });
     });
 
-    it('should define `siteTitle`', function () {
+    it('should define `siteTitle`', () => {
         assert.equal(typeof Config.value('siteTitle'), 'string');
     });
 
-    it('should define `dataDirectory`', function () {
+    it('should define `dataDirectory`', () => {
         assert.ok(Config.value('dataDirectory'));
         assert.ok(fs.existsSync(Config.path('dataDirectory')), 'dataDirectory should exist');
         assert.ok(fs.statSync(Config.path('dataDirectory')).isDirectory(), 'dataDirectory should be a dictionary');
     });
 
-    it('should define `jsonCacheMaxAge`', function () {
+    it('should define `jsonCacheMaxAge`', () => {
         assert.equal(typeof Config.value('jsonCacheMaxAge'), 'number');
     });
 
-    it('should define `jsonCacheMaxAge`', function () {
+    it('should define `jsonCacheMaxAge`', () => {
         assert.equal(typeof Config.value('jsonCacheMaxAge'), 'number');
     });
 
-    it('should define `clusterStart`', function () {
-        var clusterStart = Config.value('clusterStart');
+    it('should define `clusterStart`', () => {
+        const clusterStart = Config.value('clusterStart');
         assert.ok(clusterStart instanceof Array);
         assert.equal(clusterStart.length, [2000, 1, 1, 0, 0].length,
             'Must specify year, month, date, hour, and minute');
-        var maxYear = (new Date).getFullYear() + 1;
+        const maxYear = (new Date).getFullYear() + 1;
         assert.ok(clusterStart[0] >= 1970 && clusterStart[0] <= maxYear, `year must be between 1970 and ${maxYear}`);
         assert.ok(clusterStart[1] >= 1 && clusterStart[1] <= 12, 'month must be between 1 and 12');
         assert.ok(clusterStart[2] >= 1 && clusterStart[2] <= 31, 'date must be between 1 and 31');
@@ -50,8 +50,8 @@ describe('config.json', function () {
         assert.ok(clusterStart[4] >= 0 && clusterStart[4] <= 60, 'minute must be between 0 and 60');
     });
 
-    it('should define `clusterSize`', function () {
-        var clusterSize = Config.value('clusterSize');
+    it('should define `clusterSize`', () => {
+        const clusterSize = Config.value('clusterSize');
         assert.ok(clusterSize instanceof Array);
         assert.equal(clusterSize.length, [0, 2, 0].length,
             'Must specify the number of years, months, and days');
@@ -60,35 +60,34 @@ describe('config.json', function () {
         assert.equal(typeof clusterSize[2], 'number', 'the number of days must be a number');
     });
 
-    describe('`dashboards`', function () {
-        var dashboards = Config.value('dashboards');
+    describe('`dashboards`', () => {
+        const dashboards = Config.value('dashboards');
 
-        it('should exist for v2 and v3 UI', function () {
+        it('should exist for v2 and v3 UI', () => {
             assert.equal(typeof dashboards, 'object');
         });
 
-        it('dashboard names that do not contain /', function () {
-            for (var name in dashboards)
+        it('dashboard names that do not contain /', () => {
+            for (let name in dashboards)
                 assert.ok(name.indexOf('/') < 0, 'Dashboard name "${name}" should not contain "/"');
         });
 
-        it('each dashboard must be an array', function () {
-            for (var name in dashboards)
+        it('each dashboard must be an array', () => {
+            for (let name in dashboards)
                 assert.ok(dashboards[name] instanceof Array);
         });
 
-        it('each row in a dashboard must be an array', function () {
-            for (var name in dashboards) {
-                for (var row of dashboards[name]) {
+        it('each row in a dashboard must be an array', () => {
+            for (let name in dashboards) {
+                for (let row of dashboards[name])
                     console.assert(row instanceof Array);
-                }
             }
         });
 
-        it('each cell in a dashboard must be an array or a string', function () {
-            for (var name in dashboards) {
-                for (var row of dashboards[name]) {
-                    for (var cell of row) {
+        it('each cell in a dashboard must be an array or a string', () => {
+            for (let name in dashboards) {
+                for (let row of dashboards[name]) {
+                    for (let cell of row) {
                         if (cell instanceof Array)
                             assert.ok(cell.length == 0 || cell.length == 2,
                                 'Each cell must be empty or specify [platform, metric] pair');
@@ -101,67 +100,66 @@ describe('config.json', function () {
 
     });
 
-    describe('`database`', function () {
-        it('should exist', function () {
+    describe('`database`', () => {
+        it('should exist', () => {
             assert.ok(Config.value('database'));
         });
 
-        it('should define `database.host`', function () {
+        it('should define `database.host`', () => {
             assert.equal(typeof Config.value('database.host'), 'string');
         });
 
-        it('should define `database.port`', function () {
+        it('should define `database.port`', () => {
             assert.equal(typeof Config.value('database.port'), 'string');
         });
 
-        it('should define `database.username`', function () {
+        it('should define `database.username`', () => {
             assert.equal(typeof Config.value('database.username'), 'string');
         });
 
-        it('should define `database.password`', function () {
+        it('should define `database.password`', () => {
             assert.equal(typeof Config.value('database.password'), 'string');
         });
 
-        it('should define `database.name`', function () {
+        it('should define `database.name`', () => {
             assert.equal(typeof Config.value('database.name'), 'string');
         });
 
-        it('should be able to connect to the database', function (done) {
+        it('should be able to connect to the database', () => {
             let database = new Database;
-            database.connect().then(function () {
+            database.connect().then(() => {
                 database.disconnect();
-                done();
-            }, function (error) {
+            }, (error) => {
                 database.disconnect();
-                done(error);
+                throw error;
             });
         });
     });
 
-    describe('optional configurations', function () {
+    describe('optional configurations', () => {
         function assertNullOrType(value, type) {
             if (value !== null)
                 assert.equal(typeof value, type);
         }
 
-        it('`debug` should be `null` or a boolean', function () {
+        it('`debug` should be `null` or a boolean', () => {
             assertNullOrType(Config.value('debug'), 'boolean');
         });
 
-        it('`maintenanceMode` should be `null` or a boolean', function () {
+        it('`maintenanceMode` should be `null` or a boolean', () => {
             assertNullOrType(Config.value('maintenanceMode'), 'boolean');
         });
 
-        it('`maintenanceDirectory` should be `null` or a string', function () {
+        it('`maintenanceDirectory` should be `null` or a string', () => {
             assertNullOrType(Config.value('maintenanceDirectory'), 'string');
         });
 
-        it('`maintenanceDirectory` should be a string if `maintenanceMode` is true', function () {
+        it('`maintenanceDirectory` should be a string if `maintenanceMode` is true', () => {
             if (Config.value('maintenanceMode'))
                 assert.equal(Config.value('maintenanceDirectory'), 'string');
         });
 
-        it('`universalSlavePassword` should be `null` or a string', function () {
+        it('`universalSlavePassword` should be `null` or a string', () => {
             assertNullOrType(Config.value('universalSlavePassword'), 'string');
         });
     });
index 83985b7..5095e59 100644 (file)
@@ -2,24 +2,24 @@
 
 const assert = require('assert');
 
-let MockRemoteAPI = require('./resources/mock-remote-api.js').MockRemoteAPI;
+const MockRemoteAPI = require('./resources/mock-remote-api.js').MockRemoteAPI;
 require('../tools/js/v3-models.js');
 
-describe('PrivilegedAPI', function () {
+describe('PrivilegedAPI', () => {
     let requests = MockRemoteAPI.inject();
 
-    beforeEach(function () {
+    beforeEach(() => {
         PrivilegedAPI._token = null;
-    })
+    });
 
-    describe('requestCSRFToken', function () {
-        it('should generate a new token', function () {
+    describe('requestCSRFToken', () => {
+        it('should generate a new token', () => {
             PrivilegedAPI.requestCSRFToken();
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
         });
 
-        it('should not generate a new token if the existing token had not expired', function (done) {
+        it('should not generate a new token if the existing token had not expired', () => {
             const tokenRequest = PrivilegedAPI.requestCSRFToken();
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
@@ -27,15 +27,14 @@ describe('PrivilegedAPI', function () {
                 token: 'abc',
                 expiration: Date.now() + 3600 * 1000,
             });
-            tokenRequest.then(function (token) {
+            return tokenRequest.then((token) => {
                 assert.equal(token, 'abc');
                 PrivilegedAPI.requestCSRFToken();
                 assert.equal(requests.length, 1);
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should generate a new token if the existing token had already expired', function (done) {
+        it('should generate a new token if the existing token had already expired', () => {
             const tokenRequest = PrivilegedAPI.requestCSRFToken();
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
@@ -43,36 +42,32 @@ describe('PrivilegedAPI', function () {
                 token: 'abc',
                 expiration: Date.now() - 1,
             });
-            tokenRequest.then(function (token) {
+            return tokenRequest.then((token) => {
                 assert.equal(token, 'abc');
                 PrivilegedAPI.requestCSRFToken();
                 assert.equal(requests.length, 2);
                 assert.equal(requests[1].url, '/privileged-api/generate-csrf-token');
-                done();
-            }).catch(done);
+            });
         });
     });
     
-    describe('sendRequest', function () {
+    describe('sendRequest', () => {
 
-        it('should generate a new token if no token had been fetched', function (done) {
-            PrivilegedAPI.sendRequest('test', {});
+        it('should generate a new token if no token had been fetched', () => {
+            const promise = PrivilegedAPI.sendRequest('test', {});
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
             requests[0].resolve({
                 token: 'abc',
                 expiration: Date.now() + 100 * 1000,
             });
-            Promise.resolve().then(function () {
-                return Promise.resolve();
-            }).then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 assert.equal(requests[1].url, '/privileged-api/test');
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should not generate a new token if the existing token had not been expired', function (done) {
+        it('should not generate a new token if the existing token had not been expired', () => {
             PrivilegedAPI.sendRequest('test', {});
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
@@ -80,37 +75,31 @@ describe('PrivilegedAPI', function () {
                 token: 'abc',
                 expiration: Date.now() + 3600 * 1000,
             });
-            Promise.resolve().then(function () {
-                return Promise.resolve();
-            }).then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 assert.equal(requests[1].url, '/privileged-api/test');
                 PrivilegedAPI.sendRequest('test2', {});
-                return Promise.resolve();
-            }).then(function () {
+                return MockRemoteAPI.waitForRequest();
+            }).then(() => {
                 assert.equal(requests.length, 3);
                 assert.equal(requests[2].url, '/privileged-api/test2');
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should reject immediately when a token generation had failed', function (done) {
+        it('should reject immediately when a token generation had failed', () => {
             const request = PrivilegedAPI.sendRequest('test', {});
             let caught = false;
-            request.catch(function () { caught = true; });
+            request.catch(() => { caught = true; });
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
             requests[0].reject({status: 'FailedToGenerateToken'});
-            Promise.resolve().then(function () {
-                return Promise.resolve();
-            }).then(function () {
+            return new Promise((resolve) => setTimeout(resolve, 0)).then(() => {
                 assert.equal(requests.length, 1);
                 assert(caught);
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should re-generate token when it had become invalid', function (done) {
+        it('should re-generate token when it had become invalid', () => {
             PrivilegedAPI.sendRequest('test', {});
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
@@ -118,63 +107,61 @@ describe('PrivilegedAPI', function () {
                 token: 'abc',
                 expiration: Date.now() + 3600 * 1000,
             });
-            Promise.resolve().then(function () {
-                return Promise.resolve();
-            }).then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 assert.equal(requests[1].data.token, 'abc');
                 assert.equal(requests[1].url, '/privileged-api/test');
                 requests[1].reject('InvalidToken');
-                return Promise.resolve();
-            }).then(function () {
+                return MockRemoteAPI.waitForRequest();
+            }).then(() => {
                 assert.equal(requests.length, 3);
                 assert.equal(requests[2].url, '/privileged-api/generate-csrf-token');
                 requests[2].resolve({
                     token: 'def',
                     expiration: Date.now() + 3600 * 1000,
                 });
-                return Promise.resolve();
-            }).then(function () {
+                return MockRemoteAPI.waitForRequest();
+            }).then(() => {
                 assert.equal(requests.length, 4);
                 assert.equal(requests[3].data.token, 'def');
                 assert.equal(requests[3].url, '/privileged-api/test');
-                done();
-            }).catch(done);
+            });
         });
 
-        it('should not re-generate token when the re-fetched token was invalid', function (done) {
-            PrivilegedAPI.sendRequest('test', {});
+        it('should not re-generate token when the re-fetched token was invalid', () => {
+            const request = PrivilegedAPI.sendRequest('test', {});
+            let caught = false;
+            request.catch(() => caught = true);
             assert.equal(requests.length, 1);
             assert.equal(requests[0].url, '/privileged-api/generate-csrf-token');
             requests[0].resolve({
                 token: 'abc',
                 expiration: Date.now() + 3600 * 1000,
             });
-            Promise.resolve().then(function () {
-                return Promise.resolve();
-            }).then(function () {
+            return MockRemoteAPI.waitForRequest().then(() => {
                 assert.equal(requests.length, 2);
                 assert.equal(requests[1].data.token, 'abc');
                 assert.equal(requests[1].url, '/privileged-api/test');
                 requests[1].reject('InvalidToken');
-                return Promise.resolve();
-            }).then(function () {
+                return MockRemoteAPI.waitForRequest();
+            }).then(() => {
                 assert.equal(requests.length, 3);
                 assert.equal(requests[2].url, '/privileged-api/generate-csrf-token');
                 requests[2].resolve({
                     token: 'def',
                     expiration: Date.now() + 3600 * 1000,
                 });
-                return Promise.resolve();
-            }).then(function () {
+                return MockRemoteAPI.waitForRequest();
+            }).then(() => {
                 assert.equal(requests.length, 4);
                 assert.equal(requests[3].data.token, 'def');
                 assert.equal(requests[3].url, '/privileged-api/test');
                 requests[3].reject('InvalidToken');
-            }).then(function () {
+                return new Promise((resolve) => setTimeout(resolve, 0));
+            }).then(() => {
+                assert(caught);
                 assert.equal(requests.length, 4);
-                done();
-            }).catch(done);
+            });
         });
 
     });