]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Throttle all events (to 1 / frame each) (#6953)
authorJukka Kurkela <jukka.kurkela@gmail.com>
Tue, 14 Jan 2020 12:34:08 +0000 (14:34 +0200)
committerEvert Timberg <evert.timberg+github@gmail.com>
Tue, 14 Jan 2020 12:34:08 +0000 (07:34 -0500)
* Throttle all events
* Asynchronize event tests

14 files changed:
src/platforms/platform.dom.js
test/.eslintrc.yml
test/index.js
test/specs/controller.bubble.tests.js
test/specs/controller.doughnut.tests.js
test/specs/controller.line.tests.js
test/specs/controller.polarArea.tests.js
test/specs/controller.radar.tests.js
test/specs/controller.scatter.tests.js
test/specs/core.controller.tests.js
test/specs/core.tooltip.tests.js
test/specs/platform.dom.tests.js
test/specs/plugin.legend.tests.js
test/utils.js

index c8c9661a557382593e364234e8e6c646708bd1a1..1579e0e15dc916c335cd929de67c0e6833466312 100644 (file)
@@ -422,9 +422,9 @@ export default {
 
                var expando = listener[EXPANDO_KEY] || (listener[EXPANDO_KEY] = {});
                var proxies = expando.proxies || (expando.proxies = {});
-               var proxy = proxies[chart.id + '_' + type] = function(event) {
+               var proxy = proxies[chart.id + '_' + type] = throttled(function(event) {
                        listener(fromNativeEvent(event, chart));
-               };
+               }, chart);
 
                addListener(canvas, type, proxy);
        },
index 4ddd37820f926fb0fdfc6dc32dd30ea9dfff3ab0..9e769972d5ae0ddcc6a3d739b1f0e03820f3911a 100644 (file)
@@ -7,6 +7,7 @@ env:
 
 globals:
   acquireChart: true
+  afterEvent: true
   Chart: true
   moment: true
   waitForResize: true
index c0ed152680175b89e85a8f2078708262650cad50..a7ac0459e868246dfe4e14e67b89910ac29f4373 100644 (file)
@@ -30,6 +30,7 @@ var utils = require('./utils');
        window.devicePixelRatio = 1;
 
        window.acquireChart = acquireChart;
+       window.afterEvent = utils.afterEvent;
        window.releaseChart = releaseChart;
        window.waitForResize = utils.waitForResize;
        window.createMockContext = createMockContext;
index be098a599fcc4af502992304c5e2ce24010209de..3c690997f004235521e45b46ce7f2e4a0a290eb9 100644 (file)
@@ -288,24 +288,30 @@ describe('Chart.controllers.bubble', function() {
                        });
                });
 
-               it ('should handle default hover styles', function() {
+               it ('should handle default hover styles', function(done) {
                        var chart = this.chart;
                        var point = chart.getDatasetMeta(0).data[0];
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(point.options.backgroundColor).toBe('rgb(49, 135, 221)');
+                               expect(point.options.borderColor).toBe('rgb(22, 89, 156)');
+                               expect(point.options.borderWidth).toBe(1);
+                               expect(point.options.radius).toBe(20 + 4);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(point.options.borderWidth).toBe(2);
+                                       expect(point.options.radius).toBe(20);
+
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', point);
+                       });
                        jasmine.triggerMouseEvent(chart, 'mousemove', point);
-                       expect(point.options.backgroundColor).toBe('rgb(49, 135, 221)');
-                       expect(point.options.borderColor).toBe('rgb(22, 89, 156)');
-                       expect(point.options.borderWidth).toBe(1);
-                       expect(point.options.radius).toBe(20 + 4);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', point);
-                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(point.options.borderWidth).toBe(2);
-                       expect(point.options.radius).toBe(20);
                });
 
-               it ('should handle hover styles defined via dataset properties', function() {
+               it ('should handle hover styles defined via dataset properties', function(done) {
                        var chart = this.chart;
                        var point = chart.getDatasetMeta(0).data[0];
 
@@ -318,20 +324,27 @@ describe('Chart.controllers.bubble', function() {
 
                        chart.update();
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(point.options.backgroundColor).toBe('rgb(200, 100, 150)');
+                               expect(point.options.borderColor).toBe('rgb(150, 50, 100)');
+                               expect(point.options.borderWidth).toBe(8.4);
+                               expect(point.options.radius).toBe(20 + 4.2);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(point.options.borderWidth).toBe(2);
+                                       expect(point.options.radius).toBe(20);
+
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', point);
+
+                       });
                        jasmine.triggerMouseEvent(chart, 'mousemove', point);
-                       expect(point.options.backgroundColor).toBe('rgb(200, 100, 150)');
-                       expect(point.options.borderColor).toBe('rgb(150, 50, 100)');
-                       expect(point.options.borderWidth).toBe(8.4);
-                       expect(point.options.radius).toBe(20 + 4.2);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', point);
-                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(point.options.borderWidth).toBe(2);
-                       expect(point.options.radius).toBe(20);
                });
 
-               it ('should handle hover styles defined via element options', function() {
+               it ('should handle hover styles defined via element options', function(done) {
                        var chart = this.chart;
                        var point = chart.getDatasetMeta(0).data[0];
 
@@ -344,17 +357,23 @@ describe('Chart.controllers.bubble', function() {
 
                        chart.update();
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(point.options.backgroundColor).toBe('rgb(200, 100, 150)');
+                               expect(point.options.borderColor).toBe('rgb(150, 50, 100)');
+                               expect(point.options.borderWidth).toBe(8.4);
+                               expect(point.options.radius).toBe(20 + 4.2);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(point.options.borderWidth).toBe(2);
+                                       expect(point.options.radius).toBe(20);
+
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', point);
+                       });
                        jasmine.triggerMouseEvent(chart, 'mousemove', point);
-                       expect(point.options.backgroundColor).toBe('rgb(200, 100, 150)');
-                       expect(point.options.borderColor).toBe('rgb(150, 50, 100)');
-                       expect(point.options.borderWidth).toBe(8.4);
-                       expect(point.options.radius).toBe(20 + 4.2);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', point);
-                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(point.options.borderWidth).toBe(2);
-                       expect(point.options.radius).toBe(20);
                });
        });
 });
index a1eaf71c8596ef50b9aa7ba66e9d981c5ca404a9..19643977b625c311f3ae8a035858abf82b143cf3 100644 (file)
@@ -347,22 +347,28 @@ describe('Chart.controllers.doughnut', function() {
                        });
                });
 
-               it ('should handle default hover styles', function() {
+               it ('should handle default hover styles', function(done) {
                        var chart = this.chart;
                        var arc = chart.getDatasetMeta(0).data[0];
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(arc.options.backgroundColor).toBe('rgb(49, 135, 221)');
+                               expect(arc.options.borderColor).toBe('rgb(22, 89, 156)');
+                               expect(arc.options.borderWidth).toBe(2);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(arc.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(arc.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(arc.options.borderWidth).toBe(2);
+
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', arc);
+                       });
                        jasmine.triggerMouseEvent(chart, 'mousemove', arc);
-                       expect(arc.options.backgroundColor).toBe('rgb(49, 135, 221)');
-                       expect(arc.options.borderColor).toBe('rgb(22, 89, 156)');
-                       expect(arc.options.borderWidth).toBe(2);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', arc);
-                       expect(arc.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(arc.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(arc.options.borderWidth).toBe(2);
                });
 
-               it ('should handle hover styles defined via dataset properties', function() {
+               it ('should handle hover styles defined via dataset properties', function(done) {
                        var chart = this.chart;
                        var arc = chart.getDatasetMeta(0).data[0];
 
@@ -374,18 +380,24 @@ describe('Chart.controllers.doughnut', function() {
 
                        chart.update();
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(arc.options.backgroundColor).toBe('rgb(200, 100, 150)');
+                               expect(arc.options.borderColor).toBe('rgb(150, 50, 100)');
+                               expect(arc.options.borderWidth).toBe(8.4);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(arc.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(arc.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(arc.options.borderWidth).toBe(2);
+
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', arc);
+                       });
                        jasmine.triggerMouseEvent(chart, 'mousemove', arc);
-                       expect(arc.options.backgroundColor).toBe('rgb(200, 100, 150)');
-                       expect(arc.options.borderColor).toBe('rgb(150, 50, 100)');
-                       expect(arc.options.borderWidth).toBe(8.4);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', arc);
-                       expect(arc.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(arc.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(arc.options.borderWidth).toBe(2);
                });
 
-               it ('should handle hover styles defined via element options', function() {
+               it ('should handle hover styles defined via element options', function(done) {
                        var chart = this.chart;
                        var arc = chart.getDatasetMeta(0).data[0];
 
@@ -397,15 +409,21 @@ describe('Chart.controllers.doughnut', function() {
 
                        chart.update();
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(arc.options.backgroundColor).toBe('rgb(200, 100, 150)');
+                               expect(arc.options.borderColor).toBe('rgb(150, 50, 100)');
+                               expect(arc.options.borderWidth).toBe(8.4);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(arc.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(arc.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(arc.options.borderWidth).toBe(2);
+
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', arc);
+                       });
                        jasmine.triggerMouseEvent(chart, 'mousemove', arc);
-                       expect(arc.options.backgroundColor).toBe('rgb(200, 100, 150)');
-                       expect(arc.options.borderColor).toBe('rgb(150, 50, 100)');
-                       expect(arc.options.borderWidth).toBe(8.4);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', arc);
-                       expect(arc.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(arc.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(arc.options.borderWidth).toBe(2);
                });
        });
 });
index ea332008ba9bc36913278c8bb403c85dae2db29d..f2fdc10007673d27d6582e5be6acfcdf4dfa968a 100644 (file)
@@ -790,24 +790,31 @@ describe('Chart.controllers.line', function() {
                        });
                });
 
-               it ('should handle default hover styles', function() {
+               it ('should handle default hover styles', function(done) {
                        var chart = this.chart;
                        var point = chart.getDatasetMeta(0).data[0];
 
-                       jasmine.triggerMouseEvent(chart, 'mousemove', point);
-                       expect(point.options.backgroundColor).toBe('rgb(49, 135, 221)');
-                       expect(point.options.borderColor).toBe('rgb(22, 89, 156)');
-                       expect(point.options.borderWidth).toBe(1);
-                       expect(point.options.radius).toBe(4);
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(point.options.backgroundColor).toBe('rgb(49, 135, 221)');
+                               expect(point.options.borderColor).toBe('rgb(22, 89, 156)');
+                               expect(point.options.borderWidth).toBe(1);
+                               expect(point.options.radius).toBe(4);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(point.options.borderWidth).toBe(2);
+                                       expect(point.options.radius).toBe(3);
+                                       done();
+                               });
+
+                               jasmine.triggerMouseEvent(chart, 'mouseout', point);
+                       });
 
-                       jasmine.triggerMouseEvent(chart, 'mouseout', point);
-                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(point.options.borderWidth).toBe(2);
-                       expect(point.options.radius).toBe(3);
+                       jasmine.triggerMouseEvent(chart, 'mousemove', point);
                });
 
-               it ('should handle hover styles defined via dataset properties', function() {
+               it ('should handle hover styles defined via dataset properties', function(done) {
                        var chart = this.chart;
                        var point = chart.getDatasetMeta(0).data[0];
 
@@ -820,20 +827,26 @@ describe('Chart.controllers.line', function() {
 
                        chart.update();
 
-                       jasmine.triggerMouseEvent(chart, 'mousemove', point);
-                       expect(point.options.backgroundColor).toBe('rgb(200, 100, 150)');
-                       expect(point.options.borderColor).toBe('rgb(150, 50, 100)');
-                       expect(point.options.borderWidth).toBe(8.4);
-                       expect(point.options.radius).toBe(4.2);
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(point.options.backgroundColor).toBe('rgb(200, 100, 150)');
+                               expect(point.options.borderColor).toBe('rgb(150, 50, 100)');
+                               expect(point.options.borderWidth).toBe(8.4);
+                               expect(point.options.radius).toBe(4.2);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(point.options.borderWidth).toBe(2);
+                                       expect(point.options.radius).toBe(3);
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', point);
+                       });
 
-                       jasmine.triggerMouseEvent(chart, 'mouseout', point);
-                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(point.options.borderWidth).toBe(2);
-                       expect(point.options.radius).toBe(3);
+                       jasmine.triggerMouseEvent(chart, 'mousemove', point);
                });
 
-               it ('should handle hover styles defined via element options', function() {
+               it ('should handle hover styles defined via element options', function(done) {
                        var chart = this.chart;
                        var point = chart.getDatasetMeta(0).data[0];
 
@@ -846,20 +859,28 @@ describe('Chart.controllers.line', function() {
 
                        chart.update();
 
-                       jasmine.triggerMouseEvent(chart, 'mousemove', point);
-                       expect(point.options.backgroundColor).toBe('rgb(200, 100, 150)');
-                       expect(point.options.borderColor).toBe('rgb(150, 50, 100)');
-                       expect(point.options.borderWidth).toBe(8.4);
-                       expect(point.options.radius).toBe(4.2);
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(point.options.backgroundColor).toBe('rgb(200, 100, 150)');
+                               expect(point.options.borderColor).toBe('rgb(150, 50, 100)');
+                               expect(point.options.borderWidth).toBe(8.4);
+                               expect(point.options.radius).toBe(4.2);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(point.options.borderWidth).toBe(2);
+                                       expect(point.options.radius).toBe(3);
+
+                                       done();
+                               });
 
-                       jasmine.triggerMouseEvent(chart, 'mouseout', point);
-                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(point.options.borderWidth).toBe(2);
-                       expect(point.options.radius).toBe(3);
+                               jasmine.triggerMouseEvent(chart, 'mouseout', point);
+                       });
+
+                       jasmine.triggerMouseEvent(chart, 'mousemove', point);
                });
 
-               it ('should handle dataset hover styles defined via dataset properties', function() {
+               it ('should handle dataset hover styles defined via dataset properties', function(done) {
                        var chart = this.chart;
                        var point = chart.getDatasetMeta(0).data[0];
                        var dataset = chart.getDatasetMeta(0).dataset;
@@ -876,15 +897,23 @@ describe('Chart.controllers.line', function() {
                        chart.options.hover = {mode: 'dataset'};
                        chart.update();
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(dataset.options.backgroundColor).toBe('#000');
+                               expect(dataset.options.borderColor).toBe('#111');
+                               expect(dataset.options.borderWidth).toBe(12);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(dataset.options.backgroundColor).toBe('#AAA');
+                                       expect(dataset.options.borderColor).toBe('#BBB');
+                                       expect(dataset.options.borderWidth).toBe(6);
+
+                                       done();
+                               });
+
+                               jasmine.triggerMouseEvent(chart, 'mouseout', point);
+                       });
+
                        jasmine.triggerMouseEvent(chart, 'mousemove', point);
-                       expect(dataset.options.backgroundColor).toBe('#000');
-                       expect(dataset.options.borderColor).toBe('#111');
-                       expect(dataset.options.borderWidth).toBe(12);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', point);
-                       expect(dataset.options.backgroundColor).toBe('#AAA');
-                       expect(dataset.options.borderColor).toBe('#BBB');
-                       expect(dataset.options.borderWidth).toBe(6);
                });
        });
 
index 7780f9fde3bc0040fca5993f1c08eb6aa90e4c12..f23bb439e817b0bbb18b5e071d64df7fa5d1218b 100644 (file)
@@ -260,22 +260,28 @@ describe('Chart.controllers.polarArea', function() {
                        });
                });
 
-               it ('should handle default hover styles', function() {
+               it ('should handle default hover styles', function(done) {
                        var chart = this.chart;
                        var arc = chart.getDatasetMeta(0).data[0];
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(arc.options.backgroundColor).toBe('rgb(49, 135, 221)');
+                               expect(arc.options.borderColor).toBe('rgb(22, 89, 156)');
+                               expect(arc.options.borderWidth).toBe(2);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(arc.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(arc.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(arc.options.borderWidth).toBe(2);
+
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', arc);
+                       });
                        jasmine.triggerMouseEvent(chart, 'mousemove', arc);
-                       expect(arc.options.backgroundColor).toBe('rgb(49, 135, 221)');
-                       expect(arc.options.borderColor).toBe('rgb(22, 89, 156)');
-                       expect(arc.options.borderWidth).toBe(2);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', arc);
-                       expect(arc.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(arc.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(arc.options.borderWidth).toBe(2);
                });
 
-               it ('should handle hover styles defined via dataset properties', function() {
+               it ('should handle hover styles defined via dataset properties', function(done) {
                        var chart = this.chart;
                        var arc = chart.getDatasetMeta(0).data[0];
 
@@ -287,18 +293,24 @@ describe('Chart.controllers.polarArea', function() {
 
                        chart.update();
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(arc.options.backgroundColor).toBe('rgb(200, 100, 150)');
+                               expect(arc.options.borderColor).toBe('rgb(150, 50, 100)');
+                               expect(arc.options.borderWidth).toBe(8.4);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(arc.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(arc.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(arc.options.borderWidth).toBe(2);
+
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', arc);
+                       });
                        jasmine.triggerMouseEvent(chart, 'mousemove', arc);
-                       expect(arc.options.backgroundColor).toBe('rgb(200, 100, 150)');
-                       expect(arc.options.borderColor).toBe('rgb(150, 50, 100)');
-                       expect(arc.options.borderWidth).toBe(8.4);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', arc);
-                       expect(arc.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(arc.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(arc.options.borderWidth).toBe(2);
                });
 
-               it ('should handle hover styles defined via element options', function() {
+               it ('should handle hover styles defined via element options', function(done) {
                        var chart = this.chart;
                        var arc = chart.getDatasetMeta(0).data[0];
 
@@ -310,15 +322,21 @@ describe('Chart.controllers.polarArea', function() {
 
                        chart.update();
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(arc.options.backgroundColor).toBe('rgb(200, 100, 150)');
+                               expect(arc.options.borderColor).toBe('rgb(150, 50, 100)');
+                               expect(arc.options.borderWidth).toBe(8.4);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(arc.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(arc.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(arc.options.borderWidth).toBe(2);
+
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', arc);
+                       });
                        jasmine.triggerMouseEvent(chart, 'mousemove', arc);
-                       expect(arc.options.backgroundColor).toBe('rgb(200, 100, 150)');
-                       expect(arc.options.borderColor).toBe('rgb(150, 50, 100)');
-                       expect(arc.options.borderWidth).toBe(8.4);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', arc);
-                       expect(arc.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(arc.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(arc.options.borderWidth).toBe(2);
                });
        });
 });
index d26c003f9a2c8ebfb1fb087e5d558b515dc30854..bdc7769c65bdc172012e4be60cbc23cc0f67fd65 100644 (file)
@@ -252,24 +252,30 @@ describe('Chart.controllers.radar', function() {
                        });
                });
 
-               it ('should handle default hover styles', function() {
+               it ('should handle default hover styles', function(done) {
                        var chart = this.chart;
                        var point = chart.getDatasetMeta(0).data[0];
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(point.options.backgroundColor).toBe('rgb(49, 135, 221)');
+                               expect(point.options.borderColor).toBe('rgb(22, 89, 156)');
+                               expect(point.options.borderWidth).toBe(1);
+                               expect(point.options.radius).toBe(4);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(point.options.borderWidth).toBe(2);
+                                       expect(point.options.radius).toBe(3);
+
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', point);
+                       });
                        jasmine.triggerMouseEvent(chart, 'mousemove', point);
-                       expect(point.options.backgroundColor).toBe('rgb(49, 135, 221)');
-                       expect(point.options.borderColor).toBe('rgb(22, 89, 156)');
-                       expect(point.options.borderWidth).toBe(1);
-                       expect(point.options.radius).toBe(4);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', point);
-                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(point.options.borderWidth).toBe(2);
-                       expect(point.options.radius).toBe(3);
                });
 
-               it ('should handle hover styles defined via dataset properties', function() {
+               it ('should handle hover styles defined via dataset properties', function(done) {
                        var chart = this.chart;
                        var point = chart.getDatasetMeta(0).data[0];
 
@@ -282,20 +288,26 @@ describe('Chart.controllers.radar', function() {
 
                        chart.update();
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(point.options.backgroundColor).toBe('rgb(200, 100, 150)');
+                               expect(point.options.borderColor).toBe('rgb(150, 50, 100)');
+                               expect(point.options.borderWidth).toBe(8.4);
+                               expect(point.options.radius).toBe(4.2);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(point.options.borderWidth).toBe(2);
+                                       expect(point.options.radius).toBe(3);
+
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', point);
+                       });
                        jasmine.triggerMouseEvent(chart, 'mousemove', point);
-                       expect(point.options.backgroundColor).toBe('rgb(200, 100, 150)');
-                       expect(point.options.borderColor).toBe('rgb(150, 50, 100)');
-                       expect(point.options.borderWidth).toBe(8.4);
-                       expect(point.options.radius).toBe(4.2);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', point);
-                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(point.options.borderWidth).toBe(2);
-                       expect(point.options.radius).toBe(3);
                });
 
-               it ('should handle hover styles defined via element options', function() {
+               it ('should handle hover styles defined via element options', function(done) {
                        var chart = this.chart;
                        var point = chart.getDatasetMeta(0).data[0];
 
@@ -308,17 +320,24 @@ describe('Chart.controllers.radar', function() {
 
                        chart.update();
 
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(point.options.backgroundColor).toBe('rgb(200, 100, 150)');
+                               expect(point.options.borderColor).toBe('rgb(150, 50, 100)');
+                               expect(point.options.borderWidth).toBe(8.4);
+                               expect(point.options.radius).toBe(4.2);
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
+                                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
+                                       expect(point.options.borderWidth).toBe(2);
+                                       expect(point.options.radius).toBe(3);
+
+                                       done();
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mouseout', point);
+
+                       });
                        jasmine.triggerMouseEvent(chart, 'mousemove', point);
-                       expect(point.options.backgroundColor).toBe('rgb(200, 100, 150)');
-                       expect(point.options.borderColor).toBe('rgb(150, 50, 100)');
-                       expect(point.options.borderWidth).toBe(8.4);
-                       expect(point.options.radius).toBe(4.2);
-
-                       jasmine.triggerMouseEvent(chart, 'mouseout', point);
-                       expect(point.options.backgroundColor).toBe('rgb(100, 150, 200)');
-                       expect(point.options.borderColor).toBe('rgb(50, 100, 150)');
-                       expect(point.options.borderWidth).toBe(2);
-                       expect(point.options.radius).toBe(3);
                });
        });
 
index 45f4bf08c2f6639b5ffa6fce7de1665fdf759916..ace955b6c2df47dc6eaaa3e390011ccba5d8dbcc 100644 (file)
@@ -3,7 +3,7 @@ describe('Chart.controllers.scatter', function() {
                expect(typeof Chart.controllers.scatter).toBe('function');
        });
 
-       it('should test default tooltip callbacks', function() {
+       it('should test default tooltip callbacks', function(done) {
                var chart = window.acquireChart({
                        type: 'scatter',
                        data: {
@@ -18,11 +18,16 @@ describe('Chart.controllers.scatter', function() {
                        options: {}
                });
                var point = chart.getDatasetMeta(0).data[0];
-               jasmine.triggerMouseEvent(chart, 'mousemove', point);
 
-               // Title should be empty
-               expect(chart.tooltip.title.length).toBe(0);
-               expect(chart.tooltip.body[0].lines).toEqual(['(10, 15)']);
+               afterEvent(chart, 'mousemove', function() {
+                       // Title should be empty
+                       expect(chart.tooltip.title.length).toBe(0);
+                       expect(chart.tooltip.body[0].lines).toEqual(['(10, 15)']);
+
+                       done();
+               });
+
+               jasmine.triggerMouseEvent(chart, 'mousemove', point);
        });
 
        describe('showLines option', function() {
index 743ab43bfd0c9fff634dc5fa1297de718e7b59e6..1ba338c7158a186940db948aa56b06399d3abb3a 100644 (file)
@@ -1104,7 +1104,7 @@ describe('Chart', function() {
                        expect(chart.tooltip.options).toEqual(jasmine.objectContaining(newTooltipConfig));
                });
 
-               it ('should update the tooltip on update', function() {
+               it ('should update the tooltip on update', function(done) {
                        var chart = acquireChart({
                                type: 'line',
                                data: {
@@ -1126,18 +1126,21 @@ describe('Chart', function() {
                        var meta = chart.getDatasetMeta(0);
                        var point = meta.data[1];
 
-                       jasmine.triggerMouseEvent(chart, 'mousemove', point);
+                       afterEvent(chart, 'mousemove', function() {
+                               // Check and see if tooltip was displayed
+                               var tooltip = chart.tooltip;
 
-                       // Check and see if tooltip was displayed
-                       var tooltip = chart.tooltip;
+                               expect(chart.lastActive[0].element).toEqual(point);
+                               expect(tooltip._active[0].element).toEqual(point);
 
-                       expect(chart.lastActive[0].element).toEqual(point);
-                       expect(tooltip._active[0].element).toEqual(point);
+                               // Update and confirm tooltip is updated
+                               chart.update();
+                               expect(chart.lastActive[0].element).toEqual(point);
+                               expect(tooltip._active[0].element).toEqual(point);
 
-                       // Update and confirm tooltip is updated
-                       chart.update();
-                       expect(chart.lastActive[0].element).toEqual(point);
-                       expect(tooltip._active[0].element).toEqual(point);
+                               done();
+                       });
+                       jasmine.triggerMouseEvent(chart, 'mousemove', point);
                });
 
                it ('should update the metadata', function() {
index 27145e543fe304642f7cc2e37ca716333b41ac25..b1f9cc2b403683943b19a41ce0a719929ad36a2f 100644 (file)
@@ -29,7 +29,7 @@ describe('Core.Tooltip', function() {
        });
 
        describe('index mode', function() {
-               it('Should only use x distance when intersect is false', function() {
+               it('Should only use x distance when intersect is false', function(done) {
                        var chart = window.acquireChart({
                                type: 'line',
                                data: {
@@ -62,20 +62,165 @@ describe('Core.Tooltip', function() {
                        var meta = chart.getDatasetMeta(0);
                        var point = meta.data[1];
 
-                       var node = chart.canvas;
-                       var rect = node.getBoundingClientRect();
+                       afterEvent(chart, 'mousemove', function() {
+                               // Check and see if tooltip was displayed
+                               var tooltip = chart.tooltip;
+                               var defaults = Chart.defaults;
+
+                               expect(tooltip.options.xPadding).toEqual(6);
+                               expect(tooltip.options.yPadding).toEqual(6);
+                               expect(tooltip.xAlign).toEqual('left');
+                               expect(tooltip.yAlign).toEqual('center');
+
+                               expect(tooltip.options).toEqual(jasmine.objectContaining({
+                                       // Body
+                                       bodyFontColor: '#fff',
+                                       bodyFontFamily: defaults.fontFamily,
+                                       bodyFontStyle: defaults.fontStyle,
+                                       bodyAlign: 'left',
+                                       bodyFontSize: defaults.fontSize,
+                                       bodySpacing: 2,
+                               }));
+
+                               expect(tooltip.options).toEqual(jasmine.objectContaining({
+                                       // Title
+                                       titleFontColor: '#fff',
+                                       titleFontFamily: defaults.fontFamily,
+                                       titleFontStyle: 'bold',
+                                       titleFontSize: defaults.fontSize,
+                                       titleAlign: 'left',
+                                       titleSpacing: 2,
+                                       titleMarginBottom: 6,
+                               }));
+
+                               expect(tooltip.options).toEqual(jasmine.objectContaining({
+                                       // Footer
+                                       footerFontColor: '#fff',
+                                       footerFontFamily: defaults.fontFamily,
+                                       footerFontStyle: 'bold',
+                                       footerFontSize: defaults.fontSize,
+                                       footerAlign: 'left',
+                                       footerSpacing: 2,
+                                       footerMarginTop: 6,
+                               }));
+
+                               expect(tooltip.options).toEqual(jasmine.objectContaining({
+                                       // Appearance
+                                       caretSize: 5,
+                                       caretPadding: 2,
+                                       cornerRadius: 6,
+                                       backgroundColor: 'rgba(0,0,0,0.8)',
+                                       multiKeyBackground: '#fff',
+                                       displayColors: true
+                               }));
+
+                               expect(tooltip).toEqual(jasmine.objectContaining({
+                                       opacity: 1,
+
+                                       // Text
+                                       title: ['Point 2'],
+                                       beforeBody: [],
+                                       body: [{
+                                               before: [],
+                                               lines: ['Dataset 1: 20'],
+                                               after: []
+                                       }, {
+                                               before: [],
+                                               lines: ['Dataset 2: 40'],
+                                               after: []
+                                       }],
+                                       afterBody: [],
+                                       footer: [],
+                                       labelColors: [{
+                                               borderColor: defaults.color,
+                                               backgroundColor: defaults.color
+                                       }, {
+                                               borderColor: defaults.color,
+                                               backgroundColor: defaults.color
+                                       }]
+                               }));
+
+                               expect(tooltip.x).toBeCloseToPixel(267);
+                               expect(tooltip.y).toBeCloseToPixel(155);
+
+                               done();
+                       });
+                       jasmine.triggerMouseEvent(chart, 'mousemove', {x: point.x, y: chart.chartArea.top});
+               });
+
+               it('Should only display if intersecting if intersect is set', function(done) {
+                       var chart = window.acquireChart({
+                               type: 'line',
+                               data: {
+                                       datasets: [{
+                                               label: 'Dataset 1',
+                                               data: [10, 20, 30],
+                                               pointHoverBorderColor: 'rgb(255, 0, 0)',
+                                               pointHoverBackgroundColor: 'rgb(0, 255, 0)'
+                                       }, {
+                                               label: 'Dataset 2',
+                                               data: [40, 40, 40],
+                                               pointHoverBorderColor: 'rgb(0, 0, 255)',
+                                               pointHoverBackgroundColor: 'rgb(0, 255, 255)'
+                                       }],
+                                       labels: ['Point 1', 'Point 2', 'Point 3']
+                               },
+                               options: {
+                                       tooltips: {
+                                               mode: 'index',
+                                               intersect: true
+                                       }
+                               }
+                       });
+
+                       // Trigger an event over top of the
+                       var meta = chart.getDatasetMeta(0);
+                       var point = meta.data[1];
+
+                       afterEvent(chart, 'mousemove', function() {
+                               // Check and see if tooltip was displayed
+                               var tooltip = chart.tooltip;
+
+                               expect(tooltip).toEqual(jasmine.objectContaining({
+                                       opacity: 0,
+                               }));
 
-                       var evt = new MouseEvent('mousemove', {
-                               view: window,
-                               bubbles: true,
-                               cancelable: true,
-                               clientX: rect.left + point.x,
-                               clientY: rect.top + chart.chartArea.top + 5 // +5 to make tests work consistently
+                               done();
                        });
+                       jasmine.triggerMouseEvent(chart, 'mousemove', {x: point.x, y: 0});
+               });
+       });
+
+       it('Should display in single mode', function(done) {
+               var chart = window.acquireChart({
+                       type: 'line',
+                       data: {
+                               datasets: [{
+                                       label: 'Dataset 1',
+                                       data: [10, 20, 30],
+                                       pointHoverBorderColor: 'rgb(255, 0, 0)',
+                                       pointHoverBackgroundColor: 'rgb(0, 255, 0)'
+                               }, {
+                                       label: 'Dataset 2',
+                                       data: [40, 40, 40],
+                                       pointHoverBorderColor: 'rgb(0, 0, 255)',
+                                       pointHoverBackgroundColor: 'rgb(0, 255, 255)'
+                               }],
+                               labels: ['Point 1', 'Point 2', 'Point 3']
+                       },
+                       options: {
+                               tooltips: {
+                                       mode: 'nearest',
+                                       intersect: true
+                               }
+                       }
+               });
 
-                       // Manually trigger rather than having an async test
-                       node.dispatchEvent(evt);
+               // Trigger an event over top of the
+               var meta = chart.getDatasetMeta(0);
+               var point = meta.data[1];
 
+               afterEvent(chart, 'mousemove', function() {
                        // Check and see if tooltip was displayed
                        var tooltip = chart.tooltip;
                        var defaults = Chart.defaults;
@@ -137,197 +282,25 @@ describe('Core.Tooltip', function() {
                                        before: [],
                                        lines: ['Dataset 1: 20'],
                                        after: []
-                               }, {
-                                       before: [],
-                                       lines: ['Dataset 2: 40'],
-                                       after: []
                                }],
                                afterBody: [],
                                footer: [],
+                               labelTextColors: ['#fff'],
                                labelColors: [{
                                        borderColor: defaults.color,
                                        backgroundColor: defaults.color
-                               }, {
-                                       borderColor: defaults.color,
-                                       backgroundColor: defaults.color
                                }]
                        }));
 
                        expect(tooltip.x).toBeCloseToPixel(267);
-                       expect(tooltip.y).toBeCloseToPixel(155);
-               });
-
-               it('Should only display if intersecting if intersect is set', function() {
-                       var chart = window.acquireChart({
-                               type: 'line',
-                               data: {
-                                       datasets: [{
-                                               label: 'Dataset 1',
-                                               data: [10, 20, 30],
-                                               pointHoverBorderColor: 'rgb(255, 0, 0)',
-                                               pointHoverBackgroundColor: 'rgb(0, 255, 0)'
-                                       }, {
-                                               label: 'Dataset 2',
-                                               data: [40, 40, 40],
-                                               pointHoverBorderColor: 'rgb(0, 0, 255)',
-                                               pointHoverBackgroundColor: 'rgb(0, 255, 255)'
-                                       }],
-                                       labels: ['Point 1', 'Point 2', 'Point 3']
-                               },
-                               options: {
-                                       tooltips: {
-                                               mode: 'index',
-                                               intersect: true
-                                       }
-                               }
-                       });
-
-                       // Trigger an event over top of the
-                       var meta = chart.getDatasetMeta(0);
-                       var point = meta.data[1];
-
-                       var node = chart.canvas;
-                       var rect = node.getBoundingClientRect();
-
-                       var evt = new MouseEvent('mousemove', {
-                               view: window,
-                               bubbles: true,
-                               cancelable: true,
-                               clientX: rect.left + point.x,
-                               clientY: 0
-                       });
-
-                       // Manually trigger rather than having an async test
-                       node.dispatchEvent(evt);
-
-                       // Check and see if tooltip was displayed
-                       var tooltip = chart.tooltip;
-
-                       expect(tooltip).toEqual(jasmine.objectContaining({
-                               opacity: 0,
-                       }));
-               });
-       });
-
-       it('Should display in single mode', function() {
-               var chart = window.acquireChart({
-                       type: 'line',
-                       data: {
-                               datasets: [{
-                                       label: 'Dataset 1',
-                                       data: [10, 20, 30],
-                                       pointHoverBorderColor: 'rgb(255, 0, 0)',
-                                       pointHoverBackgroundColor: 'rgb(0, 255, 0)'
-                               }, {
-                                       label: 'Dataset 2',
-                                       data: [40, 40, 40],
-                                       pointHoverBorderColor: 'rgb(0, 0, 255)',
-                                       pointHoverBackgroundColor: 'rgb(0, 255, 255)'
-                               }],
-                               labels: ['Point 1', 'Point 2', 'Point 3']
-                       },
-                       options: {
-                               tooltips: {
-                                       mode: 'nearest',
-                                       intersect: true
-                               }
-                       }
-               });
-
-               // Trigger an event over top of the
-               var meta = chart.getDatasetMeta(0);
-               var point = meta.data[1];
+                       expect(tooltip.y).toBeCloseToPixel(312);
 
-               var node = chart.canvas;
-               var rect = node.getBoundingClientRect();
-
-               var evt = new MouseEvent('mousemove', {
-                       view: window,
-                       bubbles: true,
-                       cancelable: true,
-                       clientX: rect.left + point.x,
-                       clientY: rect.top + point.y
+                       done();
                });
-
-               // Manually trigger rather than having an async test
-               node.dispatchEvent(evt);
-
-               // Check and see if tooltip was displayed
-               var tooltip = chart.tooltip;
-               var defaults = Chart.defaults;
-
-               expect(tooltip.options.xPadding).toEqual(6);
-               expect(tooltip.options.yPadding).toEqual(6);
-               expect(tooltip.xAlign).toEqual('left');
-               expect(tooltip.yAlign).toEqual('center');
-
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Body
-                       bodyFontColor: '#fff',
-                       bodyFontFamily: defaults.fontFamily,
-                       bodyFontStyle: defaults.fontStyle,
-                       bodyAlign: 'left',
-                       bodyFontSize: defaults.fontSize,
-                       bodySpacing: 2,
-               }));
-
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Title
-                       titleFontColor: '#fff',
-                       titleFontFamily: defaults.fontFamily,
-                       titleFontStyle: 'bold',
-                       titleFontSize: defaults.fontSize,
-                       titleAlign: 'left',
-                       titleSpacing: 2,
-                       titleMarginBottom: 6,
-               }));
-
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Footer
-                       footerFontColor: '#fff',
-                       footerFontFamily: defaults.fontFamily,
-                       footerFontStyle: 'bold',
-                       footerFontSize: defaults.fontSize,
-                       footerAlign: 'left',
-                       footerSpacing: 2,
-                       footerMarginTop: 6,
-               }));
-
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Appearance
-                       caretSize: 5,
-                       caretPadding: 2,
-                       cornerRadius: 6,
-                       backgroundColor: 'rgba(0,0,0,0.8)',
-                       multiKeyBackground: '#fff',
-                       displayColors: true
-               }));
-
-               expect(tooltip).toEqual(jasmine.objectContaining({
-                       opacity: 1,
-
-                       // Text
-                       title: ['Point 2'],
-                       beforeBody: [],
-                       body: [{
-                               before: [],
-                               lines: ['Dataset 1: 20'],
-                               after: []
-                       }],
-                       afterBody: [],
-                       footer: [],
-                       labelTextColors: ['#fff'],
-                       labelColors: [{
-                               borderColor: defaults.color,
-                               backgroundColor: defaults.color
-                       }]
-               }));
-
-               expect(tooltip.x).toBeCloseToPixel(267);
-               expect(tooltip.y).toBeCloseToPixel(312);
+               jasmine.triggerMouseEvent(chart, 'mousemove', point);
        });
 
-       it('Should display information from user callbacks', function() {
+       it('Should display information from user callbacks', function(done) {
                var chart = window.acquireChart({
                        type: 'line',
                        data: {
@@ -393,102 +366,93 @@ describe('Core.Tooltip', function() {
                var meta = chart.getDatasetMeta(0);
                var point = meta.data[1];
 
-               var node = chart.canvas;
-               var rect = node.getBoundingClientRect();
+               afterEvent(chart, 'mousemove', function() {
+                       // Check and see if tooltip was displayed
+                       var tooltip = chart.tooltip;
+                       var defaults = Chart.defaults;
+
+                       expect(tooltip.options.xPadding).toEqual(6);
+                       expect(tooltip.options.yPadding).toEqual(6);
+                       expect(tooltip.xAlign).toEqual('center');
+                       expect(tooltip.yAlign).toEqual('top');
 
-               var evt = new MouseEvent('mousemove', {
-                       view: window,
-                       bubbles: true,
-                       cancelable: true,
-                       clientX: rect.left + point.x,
-                       clientY: rect.top + point.y
-               });
+                       expect(tooltip.options).toEqual(jasmine.objectContaining({
+                               // Body
+                               bodyFontColor: '#fff',
+                               bodyFontFamily: defaults.fontFamily,
+                               bodyFontStyle: defaults.fontStyle,
+                               bodyAlign: 'left',
+                               bodyFontSize: defaults.fontSize,
+                               bodySpacing: 2,
+                       }));
 
-               // Manually trigger rather than having an async test
-               node.dispatchEvent(evt);
+                       expect(tooltip.options).toEqual(jasmine.objectContaining({
+                               // Title
+                               titleFontColor: '#fff',
+                               titleFontFamily: defaults.fontFamily,
+                               titleFontStyle: 'bold',
+                               titleFontSize: defaults.fontSize,
+                               titleAlign: 'left',
+                               titleSpacing: 2,
+                               titleMarginBottom: 6,
+                       }));
 
-               // Check and see if tooltip was displayed
-               var tooltip = chart.tooltip;
-               var defaults = Chart.defaults;
+                       expect(tooltip.options).toEqual(jasmine.objectContaining({
+                               // Footer
+                               footerFontColor: '#fff',
+                               footerFontFamily: defaults.fontFamily,
+                               footerFontStyle: 'bold',
+                               footerFontSize: defaults.fontSize,
+                               footerAlign: 'left',
+                               footerSpacing: 2,
+                               footerMarginTop: 6,
+                       }));
+
+                       expect(tooltip.options).toEqual(jasmine.objectContaining({
+                               // Appearance
+                               caretSize: 5,
+                               caretPadding: 2,
+                               cornerRadius: 6,
+                               backgroundColor: 'rgba(0,0,0,0.8)',
+                               multiKeyBackground: '#fff',
+                       }));
+
+                       expect(tooltip).toEqual(jasmine.objectContaining({
+                               opacity: 1,
+
+                               // Text
+                               title: ['beforeTitle', 'title', 'afterTitle'],
+                               beforeBody: ['beforeBody'],
+                               body: [{
+                                       before: ['beforeLabel'],
+                                       lines: ['label'],
+                                       after: ['afterLabel']
+                               }, {
+                                       before: ['beforeLabel'],
+                                       lines: ['label'],
+                                       after: ['afterLabel']
+                               }],
+                               afterBody: ['afterBody'],
+                               footer: ['beforeFooter', 'footer', 'afterFooter'],
+                               labelTextColors: ['labelTextColor', 'labelTextColor'],
+                               labelColors: [{
+                                       borderColor: defaults.color,
+                                       backgroundColor: defaults.color
+                               }, {
+                                       borderColor: defaults.color,
+                                       backgroundColor: defaults.color
+                               }]
+                       }));
 
-               expect(tooltip.options.xPadding).toEqual(6);
-               expect(tooltip.options.yPadding).toEqual(6);
-               expect(tooltip.xAlign).toEqual('center');
-               expect(tooltip.yAlign).toEqual('top');
-
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Body
-                       bodyFontColor: '#fff',
-                       bodyFontFamily: defaults.fontFamily,
-                       bodyFontStyle: defaults.fontStyle,
-                       bodyAlign: 'left',
-                       bodyFontSize: defaults.fontSize,
-                       bodySpacing: 2,
-               }));
-
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Title
-                       titleFontColor: '#fff',
-                       titleFontFamily: defaults.fontFamily,
-                       titleFontStyle: 'bold',
-                       titleFontSize: defaults.fontSize,
-                       titleAlign: 'left',
-                       titleSpacing: 2,
-                       titleMarginBottom: 6,
-               }));
-
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Footer
-                       footerFontColor: '#fff',
-                       footerFontFamily: defaults.fontFamily,
-                       footerFontStyle: 'bold',
-                       footerFontSize: defaults.fontSize,
-                       footerAlign: 'left',
-                       footerSpacing: 2,
-                       footerMarginTop: 6,
-               }));
-
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Appearance
-                       caretSize: 5,
-                       caretPadding: 2,
-                       cornerRadius: 6,
-                       backgroundColor: 'rgba(0,0,0,0.8)',
-                       multiKeyBackground: '#fff',
-               }));
-
-               expect(tooltip).toEqual(jasmine.objectContaining({
-                       opacity: 1,
-
-                       // Text
-                       title: ['beforeTitle', 'title', 'afterTitle'],
-                       beforeBody: ['beforeBody'],
-                       body: [{
-                               before: ['beforeLabel'],
-                               lines: ['label'],
-                               after: ['afterLabel']
-                       }, {
-                               before: ['beforeLabel'],
-                               lines: ['label'],
-                               after: ['afterLabel']
-                       }],
-                       afterBody: ['afterBody'],
-                       footer: ['beforeFooter', 'footer', 'afterFooter'],
-                       labelTextColors: ['labelTextColor', 'labelTextColor'],
-                       labelColors: [{
-                               borderColor: defaults.color,
-                               backgroundColor: defaults.color
-                       }, {
-                               borderColor: defaults.color,
-                               backgroundColor: defaults.color
-                       }]
-               }));
-
-               expect(tooltip.x).toBeCloseToPixel(214);
-               expect(tooltip.y).toBeCloseToPixel(190);
+                       expect(tooltip.x).toBeCloseToPixel(214);
+                       expect(tooltip.y).toBeCloseToPixel(190);
+
+                       done();
+               });
+               jasmine.triggerMouseEvent(chart, 'mousemove', point);
        });
 
-       it('Should allow sorting items', function() {
+       it('Should allow sorting items', function(done) {
                var chart = window.acquireChart({
                        type: 'line',
                        data: {
@@ -519,57 +483,49 @@ describe('Core.Tooltip', function() {
                var meta0 = chart.getDatasetMeta(0);
                var point0 = meta0.data[1];
 
-               var node = chart.canvas;
-               var rect = node.getBoundingClientRect();
+               afterEvent(chart, 'mousemove', function() {
+                       // Check and see if tooltip was displayed
+                       var tooltip = chart.tooltip;
+                       var defaults = Chart.defaults;
 
-               var evt = new MouseEvent('mousemove', {
-                       view: window,
-                       bubbles: true,
-                       cancelable: true,
-                       clientX: rect.left + point0.x,
-                       clientY: rect.top + point0.y
-               });
+                       expect(tooltip).toEqual(jasmine.objectContaining({
+                               // Positioning
+                               xAlign: 'left',
+                               yAlign: 'center',
+
+                               // Text
+                               title: ['Point 2'],
+                               beforeBody: [],
+                               body: [{
+                                       before: [],
+                                       lines: ['Dataset 2: 40'],
+                                       after: []
+                               }, {
+                                       before: [],
+                                       lines: ['Dataset 1: 20'],
+                                       after: []
+                               }],
+                               afterBody: [],
+                               footer: [],
+                               labelColors: [{
+                                       borderColor: defaults.color,
+                                       backgroundColor: defaults.color
+                               }, {
+                                       borderColor: defaults.color,
+                                       backgroundColor: defaults.color
+                               }]
+                       }));
 
-               // Manually trigger rather than having an async test
-               node.dispatchEvent(evt);
+                       expect(tooltip.x).toBeCloseToPixel(267);
+                       expect(tooltip.y).toBeCloseToPixel(155);
 
-               // Check and see if tooltip was displayed
-               var tooltip = chart.tooltip;
-               var defaults = Chart.defaults;
+                       done();
+               });
+               jasmine.triggerMouseEvent(chart, 'mousemove', point0);
 
-               expect(tooltip).toEqual(jasmine.objectContaining({
-                       // Positioning
-                       xAlign: 'left',
-                       yAlign: 'center',
-
-                       // Text
-                       title: ['Point 2'],
-                       beforeBody: [],
-                       body: [{
-                               before: [],
-                               lines: ['Dataset 2: 40'],
-                               after: []
-                       }, {
-                               before: [],
-                               lines: ['Dataset 1: 20'],
-                               after: []
-                       }],
-                       afterBody: [],
-                       footer: [],
-                       labelColors: [{
-                               borderColor: defaults.color,
-                               backgroundColor: defaults.color
-                       }, {
-                               borderColor: defaults.color,
-                               backgroundColor: defaults.color
-                       }]
-               }));
-
-               expect(tooltip.x).toBeCloseToPixel(267);
-               expect(tooltip.y).toBeCloseToPixel(155);
        });
 
-       it('Should allow reversing items', function() {
+       it('Should allow reversing items', function(done) {
                var chart = window.acquireChart({
                        type: 'line',
                        data: {
@@ -598,57 +554,49 @@ describe('Core.Tooltip', function() {
                var meta0 = chart.getDatasetMeta(0);
                var point0 = meta0.data[1];
 
-               var node = chart.canvas;
-               var rect = node.getBoundingClientRect();
+               afterEvent(chart, 'mousemove', function() {
+                       // Check and see if tooltip was displayed
+                       var tooltip = chart.tooltip;
+                       var defaults = Chart.defaults;
+
+                       expect(tooltip).toEqual(jasmine.objectContaining({
+                               // Positioning
+                               xAlign: 'left',
+                               yAlign: 'center',
 
-               var evt = new MouseEvent('mousemove', {
-                       view: window,
-                       bubbles: true,
-                       cancelable: true,
-                       clientX: rect.left + point0.x,
-                       clientY: rect.top + point0.y
-               });
+                               // Text
+                               title: ['Point 2'],
+                               beforeBody: [],
+                               body: [{
+                                       before: [],
+                                       lines: ['Dataset 2: 40'],
+                                       after: []
+                               }, {
+                                       before: [],
+                                       lines: ['Dataset 1: 20'],
+                                       after: []
+                               }],
+                               afterBody: [],
+                               footer: [],
+                               labelColors: [{
+                                       borderColor: defaults.color,
+                                       backgroundColor: defaults.color
+                               }, {
+                                       borderColor: defaults.color,
+                                       backgroundColor: defaults.color
+                               }]
+                       }));
 
-               // Manually trigger rather than having an async test
-               node.dispatchEvent(evt);
+                       expect(tooltip.x).toBeCloseToPixel(267);
+                       expect(tooltip.y).toBeCloseToPixel(155);
 
-               // Check and see if tooltip was displayed
-               var tooltip = chart.tooltip;
-               var defaults = Chart.defaults;
+                       done();
+               });
 
-               expect(tooltip).toEqual(jasmine.objectContaining({
-                       // Positioning
-                       xAlign: 'left',
-                       yAlign: 'center',
-
-                       // Text
-                       title: ['Point 2'],
-                       beforeBody: [],
-                       body: [{
-                               before: [],
-                               lines: ['Dataset 2: 40'],
-                               after: []
-                       }, {
-                               before: [],
-                               lines: ['Dataset 1: 20'],
-                               after: []
-                       }],
-                       afterBody: [],
-                       footer: [],
-                       labelColors: [{
-                               borderColor: defaults.color,
-                               backgroundColor: defaults.color
-                       }, {
-                               borderColor: defaults.color,
-                               backgroundColor: defaults.color
-                       }]
-               }));
-
-               expect(tooltip.x).toBeCloseToPixel(267);
-               expect(tooltip.y).toBeCloseToPixel(155);
+               jasmine.triggerMouseEvent(chart, 'mousemove', point0);
        });
 
-       it('Should follow dataset order', function() {
+       it('Should follow dataset order', function(done) {
                var chart = window.acquireChart({
                        type: 'line',
                        data: {
@@ -678,57 +626,49 @@ describe('Core.Tooltip', function() {
                var meta0 = chart.getDatasetMeta(0);
                var point0 = meta0.data[1];
 
-               var node = chart.canvas;
-               var rect = node.getBoundingClientRect();
+               afterEvent(chart, 'mousemove', function() {
+                       // Check and see if tooltip was displayed
+                       var tooltip = chart.tooltip;
+                       var defaults = Chart.defaults;
 
-               var evt = new MouseEvent('mousemove', {
-                       view: window,
-                       bubbles: true,
-                       cancelable: true,
-                       clientX: rect.left + point0.x,
-                       clientY: rect.top + point0.y
-               });
+                       expect(tooltip).toEqual(jasmine.objectContaining({
+                               // Positioning
+                               xAlign: 'left',
+                               yAlign: 'center',
+
+                               // Text
+                               title: ['Point 2'],
+                               beforeBody: [],
+                               body: [{
+                                       before: [],
+                                       lines: ['Dataset 2: 40'],
+                                       after: []
+                               }, {
+                                       before: [],
+                                       lines: ['Dataset 1: 20'],
+                                       after: []
+                               }],
+                               afterBody: [],
+                               footer: [],
+                               labelColors: [{
+                                       borderColor: defaults.color,
+                                       backgroundColor: defaults.color
+                               }, {
+                                       borderColor: defaults.color,
+                                       backgroundColor: defaults.color
+                               }]
+                       }));
 
-               // Manually trigger rather than having an async test
-               node.dispatchEvent(evt);
+                       expect(tooltip.x).toBeCloseToPixel(267);
+                       expect(tooltip.y).toBeCloseToPixel(155);
 
-               // Check and see if tooltip was displayed
-               var tooltip = chart.tooltip;
-               var defaults = Chart.defaults;
+                       done();
+               });
 
-               expect(tooltip).toEqual(jasmine.objectContaining({
-                       // Positioning
-                       xAlign: 'left',
-                       yAlign: 'center',
-
-                       // Text
-                       title: ['Point 2'],
-                       beforeBody: [],
-                       body: [{
-                               before: [],
-                               lines: ['Dataset 2: 40'],
-                               after: []
-                       }, {
-                               before: [],
-                               lines: ['Dataset 1: 20'],
-                               after: []
-                       }],
-                       afterBody: [],
-                       footer: [],
-                       labelColors: [{
-                               borderColor: defaults.color,
-                               backgroundColor: defaults.color
-                       }, {
-                               borderColor: defaults.color,
-                               backgroundColor: defaults.color
-                       }]
-               }));
-
-               expect(tooltip.x).toBeCloseToPixel(267);
-               expect(tooltip.y).toBeCloseToPixel(155);
+               jasmine.triggerMouseEvent(chart, 'mousemove', point0);
        });
 
-       it('should filter items from the tooltip using the callback', function() {
+       it('should filter items from the tooltip using the callback', function(done) {
                var chart = window.acquireChart({
                        type: 'line',
                        data: {
@@ -761,47 +701,39 @@ describe('Core.Tooltip', function() {
                var meta0 = chart.getDatasetMeta(0);
                var point0 = meta0.data[1];
 
-               var node = chart.canvas;
-               var rect = node.getBoundingClientRect();
+               afterEvent(chart, 'mousemove', function() {
+                       // Check and see if tooltip was displayed
+                       var tooltip = chart.tooltip;
+                       var defaults = Chart.defaults;
 
-               var evt = new MouseEvent('mousemove', {
-                       view: window,
-                       bubbles: true,
-                       cancelable: true,
-                       clientX: rect.left + point0.x,
-                       clientY: rect.top + point0.y
-               });
+                       expect(tooltip).toEqual(jasmine.objectContaining({
+                               // Positioning
+                               xAlign: 'left',
+                               yAlign: 'center',
 
-               // Manually trigger rather than having an async test
-               node.dispatchEvent(evt);
+                               // Text
+                               title: ['Point 2'],
+                               beforeBody: [],
+                               body: [{
+                                       before: [],
+                                       lines: ['Dataset 2: 40'],
+                                       after: []
+                               }],
+                               afterBody: [],
+                               footer: [],
+                               labelColors: [{
+                                       borderColor: defaults.color,
+                                       backgroundColor: defaults.color
+                               }]
+                       }));
 
-               // Check and see if tooltip was displayed
-               var tooltip = chart.tooltip;
-               var defaults = Chart.defaults;
+                       done();
+               });
 
-               expect(tooltip).toEqual(jasmine.objectContaining({
-                       // Positioning
-                       xAlign: 'left',
-                       yAlign: 'center',
-
-                       // Text
-                       title: ['Point 2'],
-                       beforeBody: [],
-                       body: [{
-                               before: [],
-                               lines: ['Dataset 2: 40'],
-                               after: []
-                       }],
-                       afterBody: [],
-                       footer: [],
-                       labelColors: [{
-                               borderColor: defaults.color,
-                               backgroundColor: defaults.color
-                       }]
-               }));
+               jasmine.triggerMouseEvent(chart, 'mousemove', point0);
        });
 
-       it('should set the caretPadding based on a config setting', function() {
+       it('should set the caretPadding based on a config setting', function(done) {
                var chart = window.acquireChart({
                        type: 'line',
                        data: {
@@ -830,31 +762,23 @@ describe('Core.Tooltip', function() {
                var meta0 = chart.getDatasetMeta(0);
                var point0 = meta0.data[1];
 
-               var node = chart.canvas;
-               var rect = node.getBoundingClientRect();
-
-               var evt = new MouseEvent('mousemove', {
-                       view: window,
-                       bubbles: true,
-                       cancelable: true,
-                       clientX: rect.left + point0.x,
-                       clientY: rect.top + point0.y
-               });
+               afterEvent(chart, 'mousemove', function() {
+                       // Check and see if tooltip was displayed
+                       var tooltip = chart.tooltip;
 
-               // Manually trigger rather than having an async test
-               node.dispatchEvent(evt);
+                       expect(tooltip.options).toEqual(jasmine.objectContaining({
+                               // Positioning
+                               caretPadding: 10,
+                       }));
 
-               // Check and see if tooltip was displayed
-               var tooltip = chart.tooltip;
+                       done();
+               });
 
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Positioning
-                       caretPadding: 10,
-               }));
+               jasmine.triggerMouseEvent(chart, 'mousemove', point0);
        });
 
        ['line', 'bar', 'horizontalBar'].forEach(function(type) {
-               it('Should have dataPoints in a ' + type + ' chart', function() {
+               it('Should have dataPoints in a ' + type + ' chart', function(done) {
                        var chart = window.acquireChart({
                                type: type,
                                data: {
@@ -883,27 +807,32 @@ describe('Core.Tooltip', function() {
                        var pointIndex = 1;
                        var datasetIndex = 0;
                        var point = chart.getDatasetMeta(datasetIndex).data[pointIndex];
-                       jasmine.triggerMouseEvent(chart, 'mousemove', point);
 
-                       // Check and see if tooltip was displayed
-                       var tooltip = chart.tooltip;
+                       afterEvent(chart, 'mousemove', function() {
+                               // Check and see if tooltip was displayed
+                               var tooltip = chart.tooltip;
+
+                               expect(tooltip instanceof Object).toBe(true);
+                               expect(tooltip.dataPoints instanceof Array).toBe(true);
+                               expect(tooltip.dataPoints.length).toBe(1);
 
-                       expect(tooltip instanceof Object).toBe(true);
-                       expect(tooltip.dataPoints instanceof Array).toBe(true);
-                       expect(tooltip.dataPoints.length).toBe(1);
+                               var tooltipItem = tooltip.dataPoints[0];
 
-                       var tooltipItem = tooltip.dataPoints[0];
+                               expect(tooltipItem.index).toBe(pointIndex);
+                               expect(tooltipItem.datasetIndex).toBe(datasetIndex);
+                               expect(typeof tooltipItem.label).toBe('string');
+                               expect(tooltipItem.label).toBe(chart.data.labels[pointIndex]);
+                               expect(typeof tooltipItem.value).toBe('string');
+                               expect(tooltipItem.value).toBe('' + chart.data.datasets[datasetIndex].data[pointIndex]);
 
-                       expect(tooltipItem.index).toBe(pointIndex);
-                       expect(tooltipItem.datasetIndex).toBe(datasetIndex);
-                       expect(typeof tooltipItem.label).toBe('string');
-                       expect(tooltipItem.label).toBe(chart.data.labels[pointIndex]);
-                       expect(typeof tooltipItem.value).toBe('string');
-                       expect(tooltipItem.value).toBe('' + chart.data.datasets[datasetIndex].data[pointIndex]);
+                               done();
+                       });
+
+                       jasmine.triggerMouseEvent(chart, 'mousemove', point);
                });
        });
 
-       it('Should not update if active element has not changed', function() {
+       it('Should not update if active element has not changed', function(done) {
                var chart = window.acquireChart({
                        type: 'line',
                        data: {
@@ -937,36 +866,29 @@ describe('Core.Tooltip', function() {
                var meta = chart.getDatasetMeta(0);
                var firstPoint = meta.data[1];
 
-               var node = chart.canvas;
-               var rect = node.getBoundingClientRect();
-
-               var firstEvent = new MouseEvent('mousemove', {
-                       view: window,
-                       bubbles: false,
-                       cancelable: true,
-                       clientX: rect.left + firstPoint.x,
-                       clientY: rect.top + firstPoint.y
-               });
-
                var tooltip = chart.tooltip;
                spyOn(tooltip, 'update');
 
-               /* Manually trigger rather than having an async test */
+               afterEvent(chart, 'mousemove', function() {
+                       expect(tooltip.update).toHaveBeenCalledWith(true);
 
-               // First dispatch change event, should update tooltip
-               node.dispatchEvent(firstEvent);
-               expect(tooltip.update).toHaveBeenCalledWith(true);
+                       // Reset calls
+                       tooltip.update.calls.reset();
 
-               // Reset calls
-               tooltip.update.calls.reset();
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(tooltip.update).not.toHaveBeenCalled();
 
-               // Second dispatch change event (same event), should not update tooltip
-               node.dispatchEvent(firstEvent);
-               expect(tooltip.update).not.toHaveBeenCalled();
+                               done();
+                       });
+                       // Second dispatch change event (same event), should not update tooltip
+                       jasmine.triggerMouseEvent(chart, 'mousemove', firstPoint);
+               });
+               // First dispatch change event, should update tooltip
+               jasmine.triggerMouseEvent(chart, 'mousemove', firstPoint);
        });
 
        describe('positioners', function() {
-               it('Should call custom positioner with correct parameters and scope', function() {
+               it('Should call custom positioner with correct parameters and scope', function(done) {
 
                        Chart.Tooltip.positioners.test = function() {
                                return {x: 0, y: 0};
@@ -1003,29 +925,22 @@ describe('Core.Tooltip', function() {
                        var datasetIndex = 0;
                        var meta = chart.getDatasetMeta(datasetIndex);
                        var point = meta.data[pointIndex];
-                       var node = chart.canvas;
-                       var rect = node.getBoundingClientRect();
-                       var evt = new MouseEvent('mousemove', {
-                               view: window,
-                               bubbles: true,
-                               cancelable: true,
-                               clientX: rect.left + point.x,
-                               clientY: rect.top + point.y
-                       });
+                       var fn = Chart.Tooltip.positioners.test;
 
-                       // Manually trigger rather than having an async test
-                       node.dispatchEvent(evt);
+                       afterEvent(chart, 'mousemove', function() {
+                               expect(fn.calls.count()).toBe(1);
+                               expect(fn.calls.first().args[0] instanceof Array).toBe(true);
+                               expect(Object.prototype.hasOwnProperty.call(fn.calls.first().args[1], 'x')).toBe(true);
+                               expect(Object.prototype.hasOwnProperty.call(fn.calls.first().args[1], 'y')).toBe(true);
+                               expect(fn.calls.first().object instanceof Chart.Tooltip).toBe(true);
 
-                       var fn = Chart.Tooltip.positioners.test;
-                       expect(fn.calls.count()).toBe(1);
-                       expect(fn.calls.first().args[0] instanceof Array).toBe(true);
-                       expect(Object.prototype.hasOwnProperty.call(fn.calls.first().args[1], 'x')).toBe(true);
-                       expect(Object.prototype.hasOwnProperty.call(fn.calls.first().args[1], 'y')).toBe(true);
-                       expect(fn.calls.first().object instanceof Chart.Tooltip).toBe(true);
+                               done();
+                       });
+                       jasmine.triggerMouseEvent(chart, 'mousemove', point);
                });
        });
 
-       it('Should avoid tooltip truncation in x axis if there is enough space to show tooltip without truncation', function() {
+       it('Should avoid tooltip truncation in x axis if there is enough space to show tooltip without truncation', function(done) {
                var chart = window.acquireChart({
                        type: 'pie',
                        data: {
@@ -1057,46 +972,47 @@ describe('Core.Tooltip', function() {
                        }
                });
 
-               // Trigger an event over top of the slice
-               for (var slice = 0; slice < 2; slice++) {
+               function testSlice(slice, count) {
                        var meta = chart.getDatasetMeta(0);
                        var point = meta.data[slice].getCenterPoint();
                        var tooltipPosition = meta.data[slice].tooltipPosition();
-                       var node = chart.canvas;
-                       var rect = node.getBoundingClientRect();
-
-                       var mouseMoveEvent = new MouseEvent('mousemove', {
-                               view: window,
-                               bubbles: true,
-                               cancelable: true,
-                               clientX: rect.left + point.x,
-                               clientY: rect.top + point.y
-                       });
-                       var mouseOutEvent = new MouseEvent('mouseout');
 
-                       // Lets cycle while tooltip is narrower than chart area
-                       var infiniteCycleDefense = 70;
-                       for (var i = 0; i < infiniteCycleDefense; i++) {
+                       function recursive(left) {
                                chart.config.data.labels[slice] = chart.config.data.labels[slice] + 'l';
                                chart.update();
-                               node.dispatchEvent(mouseOutEvent);
-                               node.dispatchEvent(mouseMoveEvent);
-                               var tooltip = chart.tooltip;
-                               expect(tooltip.dataPoints.length).toBe(1);
-                               expect(tooltip.x).toBeGreaterThanOrEqual(0);
-                               if (tooltip.width <= chart.width) {
-                                       expect(tooltip.x + tooltip.width).toBeLessThanOrEqual(chart.width);
-                               }
-                               expect(tooltip.caretX).toBeCloseToPixel(tooltipPosition.x);
-                               // if tooltip is longer than chart area then all tests done
-                               if (tooltip.width > chart.width) {
-                                       break;
-                               }
+
+                               afterEvent(chart, 'mouseout', function() {
+                                       afterEvent(chart, 'mousemove', function() {
+                                               var tooltip = chart.tooltip;
+                                               expect(tooltip.dataPoints.length).toBe(1);
+                                               expect(tooltip.x).toBeGreaterThanOrEqual(0);
+                                               if (tooltip.width <= chart.width) {
+                                                       expect(tooltip.x + tooltip.width).toBeLessThanOrEqual(chart.width);
+                                               }
+                                               expect(tooltip.caretX).toBeCloseToPixel(tooltipPosition.x);
+                                               // if tooltip is longer than chart area then all tests done
+                                               if (tooltip.width > chart.width || left === 0) {
+                                                       done(left === 0 && new Error('max iterations reached'));
+                                               } else {
+                                                       recursive(left - 1);
+                                               }
+                                       });
+                                       jasmine.triggerMouseEvent(chart, 'mousemove', point);
+                               });
+
+                               jasmine.triggerMouseEvent(chart, 'mouseout', point);
                        }
+
+                       recursive(count);
+               }
+
+               // Trigger an event over top of the slice
+               for (var slice = 0; slice < 2; slice++) {
+                       testSlice(slice, 70);
                }
        });
 
-       it('Should split newlines into separate lines in user callbacks', function() {
+       it('Should split newlines into separate lines in user callbacks', function(done) {
                var chart = window.acquireChart({
                        type: 'line',
                        data: {
@@ -1161,95 +1077,89 @@ describe('Core.Tooltip', function() {
                // Trigger an event over top of the
                var meta = chart.getDatasetMeta(0);
                var point = meta.data[1];
-               var node = chart.canvas;
-               var rect = node.getBoundingClientRect();
-               var evt = new MouseEvent('mousemove', {
-                       view: window,
-                       bubbles: true,
-                       cancelable: true,
-                       clientX: rect.left + point.x,
-                       clientY: rect.top + point.y
-               });
 
-               // Manually trigger rather than having an async test
-               node.dispatchEvent(evt);
+               afterEvent(chart, 'mousemove', function() {
+                       // Check and see if tooltip was displayed
+                       var tooltip = chart.tooltip;
+                       var defaults = Chart.defaults;
 
-               // Check and see if tooltip was displayed
-               var tooltip = chart.tooltip;
-               var defaults = Chart.defaults;
+                       expect(tooltip.options.xPadding).toEqual(6);
+                       expect(tooltip.options.yPadding).toEqual(6);
+                       expect(tooltip.xAlign).toEqual('center');
+                       expect(tooltip.yAlign).toEqual('top');
+
+                       expect(tooltip.options).toEqual(jasmine.objectContaining({
+                               // Body
+                               bodyFontColor: '#fff',
+                               bodyFontFamily: defaults.fontFamily,
+                               bodyFontStyle: defaults.fontStyle,
+                               bodyAlign: 'left',
+                               bodyFontSize: defaults.fontSize,
+                               bodySpacing: 2,
+                       }));
+
+                       expect(tooltip.options).toEqual(jasmine.objectContaining({
+                               // Title
+                               titleFontColor: '#fff',
+                               titleFontFamily: defaults.fontFamily,
+                               titleFontStyle: 'bold',
+                               titleFontSize: defaults.fontSize,
+                               titleAlign: 'left',
+                               titleSpacing: 2,
+                               titleMarginBottom: 6,
+                       }));
+
+                       expect(tooltip.options).toEqual(jasmine.objectContaining({
+                               // Footer
+                               footerFontColor: '#fff',
+                               footerFontFamily: defaults.fontFamily,
+                               footerFontStyle: 'bold',
+                               footerFontSize: defaults.fontSize,
+                               footerAlign: 'left',
+                               footerSpacing: 2,
+                               footerMarginTop: 6,
+                       }));
+
+                       expect(tooltip.options).toEqual(jasmine.objectContaining({
+                               // Appearance
+                               caretSize: 5,
+                               caretPadding: 2,
+                               cornerRadius: 6,
+                               backgroundColor: 'rgba(0,0,0,0.8)',
+                               multiKeyBackground: '#fff',
+                       }));
+
+                       expect(tooltip).toEqual(jasmine.objectContaining({
+                               opacity: 1,
+
+                               // Text
+                               title: ['beforeTitle', 'newline', 'title', 'newline', 'afterTitle', 'newline'],
+                               beforeBody: ['beforeBody', 'newline'],
+                               body: [{
+                                       before: ['beforeLabel', 'newline'],
+                                       lines: ['label'],
+                                       after: ['afterLabel', 'newline']
+                               }, {
+                                       before: ['beforeLabel', 'newline'],
+                                       lines: ['label'],
+                                       after: ['afterLabel', 'newline']
+                               }],
+                               afterBody: ['afterBody', 'newline'],
+                               footer: ['beforeFooter', 'newline', 'footer', 'newline', 'afterFooter', 'newline'],
+                               labelTextColors: ['labelTextColor', 'labelTextColor'],
+                               labelColors: [{
+                                       borderColor: defaults.color,
+                                       backgroundColor: defaults.color
+                               }, {
+                                       borderColor: defaults.color,
+                                       backgroundColor: defaults.color
+                               }]
+                       }));
+
+                       done();
+               });
 
-               expect(tooltip.options.xPadding).toEqual(6);
-               expect(tooltip.options.yPadding).toEqual(6);
-               expect(tooltip.xAlign).toEqual('center');
-               expect(tooltip.yAlign).toEqual('top');
-
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Body
-                       bodyFontColor: '#fff',
-                       bodyFontFamily: defaults.fontFamily,
-                       bodyFontStyle: defaults.fontStyle,
-                       bodyAlign: 'left',
-                       bodyFontSize: defaults.fontSize,
-                       bodySpacing: 2,
-               }));
-
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Title
-                       titleFontColor: '#fff',
-                       titleFontFamily: defaults.fontFamily,
-                       titleFontStyle: 'bold',
-                       titleFontSize: defaults.fontSize,
-                       titleAlign: 'left',
-                       titleSpacing: 2,
-                       titleMarginBottom: 6,
-               }));
-
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Footer
-                       footerFontColor: '#fff',
-                       footerFontFamily: defaults.fontFamily,
-                       footerFontStyle: 'bold',
-                       footerFontSize: defaults.fontSize,
-                       footerAlign: 'left',
-                       footerSpacing: 2,
-                       footerMarginTop: 6,
-               }));
-
-               expect(tooltip.options).toEqual(jasmine.objectContaining({
-                       // Appearance
-                       caretSize: 5,
-                       caretPadding: 2,
-                       cornerRadius: 6,
-                       backgroundColor: 'rgba(0,0,0,0.8)',
-                       multiKeyBackground: '#fff',
-               }));
-
-               expect(tooltip).toEqual(jasmine.objectContaining({
-                       opacity: 1,
-
-                       // Text
-                       title: ['beforeTitle', 'newline', 'title', 'newline', 'afterTitle', 'newline'],
-                       beforeBody: ['beforeBody', 'newline'],
-                       body: [{
-                               before: ['beforeLabel', 'newline'],
-                               lines: ['label'],
-                               after: ['afterLabel', 'newline']
-                       }, {
-                               before: ['beforeLabel', 'newline'],
-                               lines: ['label'],
-                               after: ['afterLabel', 'newline']
-                       }],
-                       afterBody: ['afterBody', 'newline'],
-                       footer: ['beforeFooter', 'newline', 'footer', 'newline', 'afterFooter', 'newline'],
-                       labelTextColors: ['labelTextColor', 'labelTextColor'],
-                       labelColors: [{
-                               borderColor: defaults.color,
-                               backgroundColor: defaults.color
-                       }, {
-                               borderColor: defaults.color,
-                               backgroundColor: defaults.color
-                       }]
-               }));
+               jasmine.triggerMouseEvent(chart, 'mousemove', point);
        });
 
        describe('text align', function() {
index c5c145b08fcf0a0473bb92608249da12592f31ed..987be1b24ce634a3304ef8485c0dbdc5c6ea56bb 100644 (file)
@@ -356,7 +356,7 @@ describe('Platform.dom', function() {
        });
 
        describe('event handling', function() {
-               it('should notify plugins about events', function() {
+               it('should notify plugins about events', function(done) {
                        var notifiedEvent;
                        var plugin = {
                                afterEvent: function(chart, e) {
@@ -377,32 +377,24 @@ describe('Platform.dom', function() {
                                plugins: [plugin]
                        });
 
-                       var node = chart.canvas;
-                       var rect = node.getBoundingClientRect();
-                       var clientX = (rect.left + rect.right) / 2;
-                       var clientY = (rect.top + rect.bottom) / 2;
-
-                       var evt = new MouseEvent('click', {
-                               view: window,
-                               bubbles: true,
-                               cancelable: true,
-                               clientX: clientX,
-                               clientY: clientY
-                       });
+                       afterEvent(chart, 'click', function() {
+                               // Check that notifiedEvent is correct
+                               expect(notifiedEvent).not.toBe(undefined);
 
-                       // Manually trigger rather than having an async test
-                       node.dispatchEvent(evt);
+                               // Is type correctly translated
+                               expect(notifiedEvent.type).toBe('click');
 
-                       // Check that notifiedEvent is correct
-                       expect(notifiedEvent).not.toBe(undefined);
-                       expect(notifiedEvent.native).toBe(evt);
+                               // Relative Position
+                               expect(notifiedEvent.x).toBeCloseToPixel(chart.width / 2);
+                               expect(notifiedEvent.y).toBeCloseToPixel(chart.height / 2);
 
-                       // Is type correctly translated
-                       expect(notifiedEvent.type).toBe(evt.type);
+                               done();
+                       });
 
-                       // Relative Position
-                       expect(notifiedEvent.x).toBeCloseToPixel(chart.width / 2);
-                       expect(notifiedEvent.y).toBeCloseToPixel(chart.height / 2);
+                       jasmine.triggerMouseEvent(chart, 'click', {
+                               x: chart.width / 2,
+                               y: chart.height / 2
+                       });
                });
        });
 });
index 6fe15c161ec275187ccbaf59f881cb85555da0e5..991c81f927e13b5042da61dc9e35d8cc7dcaeb99 100644 (file)
@@ -602,7 +602,7 @@ describe('Legend block tests', function() {
        });
 
        describe('callbacks', function() {
-               it('should call onClick, onHover and onLeave at the correct times', function() {
+               it('should call onClick, onHover and onLeave at the correct times', function(done) {
                        var clickItem = null;
                        var hoverItem = null;
                        var leaveItem = null;
@@ -636,17 +636,22 @@ describe('Legend block tests', function() {
                                y: hb.top + (hb.height / 2)
                        };
 
-                       jasmine.triggerMouseEvent(chart, 'click', el);
-
-                       expect(clickItem).toBe(chart.legend.legendItems[0]);
-
-                       jasmine.triggerMouseEvent(chart, 'mousemove', el);
+                       afterEvent(chart, 'click', function() {
+                               expect(clickItem).toBe(chart.legend.legendItems[0]);
 
-                       expect(hoverItem).toBe(chart.legend.legendItems[0]);
+                               afterEvent(chart, 'mousemove', function() {
+                                       expect(hoverItem).toBe(chart.legend.legendItems[0]);
 
-                       jasmine.triggerMouseEvent(chart, 'mousemove', chart.getDatasetMeta(0).data[0]);
+                                       afterEvent(chart, 'mousemove', function() {
+                                               expect(leaveItem).toBe(chart.legend.legendItems[0]);
 
-                       expect(leaveItem).toBe(chart.legend.legendItems[0]);
+                                               done();
+                                       });
+                                       jasmine.triggerMouseEvent(chart, 'mousemove', chart.getDatasetMeta(0).data[0]);
+                               });
+                               jasmine.triggerMouseEvent(chart, 'mousemove', el);
+                       });
+                       jasmine.triggerMouseEvent(chart, 'click', el);
                });
        });
 });
index 7a8e31c1a905d6fb98ca5c189812b7179b87573a..daae1626c119dc7b5be6a638cba17ae36b25c7e5 100644 (file)
@@ -106,6 +106,18 @@ function waitForResize(chart, callback) {
        };
 }
 
+function afterEvent(chart, type, callback) {
+       var override = chart.eventHandler;
+       chart.eventHandler = function(event) {
+               override.call(this, event);
+               if (event.type === type) {
+                       chart.eventHandler = override;
+                       // eslint-disable-next-line callback-return
+                       callback();
+               }
+       };
+}
+
 function _resolveElementPoint(el) {
        var point = {x: 0, y: 0};
        if (el) {
@@ -140,5 +152,6 @@ module.exports = {
        releaseChart: releaseChart,
        readImageData: readImageData,
        triggerMouseEvent: triggerMouseEvent,
-       waitForResize: waitForResize
+       waitForResize: waitForResize,
+       afterEvent: afterEvent
 };