|
1 | 1 | 'use strict'; |
2 | 2 |
|
3 | 3 | var Plotly = require('@lib/index'); |
4 | | -var Plots = require('@src/plots/plots'); |
5 | 4 |
|
6 | | -var createGraphDiv = require('../assets/create_graph_div'); |
7 | | -var destroyGraphDiv = require('../assets/destroy_graph_div'); |
| 5 | +var withSetupTeardown = require('../assets/with_setup_teardown'); |
8 | 6 | var mouseEvent = require('../assets/mouse_event'); |
9 | 7 |
|
10 | | -function teardown(gd, done) { |
| 8 | +// Expected shape of projection-related data |
| 9 | +var cameraStructure = { |
| 10 | + up: {x: jasmine.any(Number), y: jasmine.any(Number), z: jasmine.any(Number)}, |
| 11 | + center: {x: jasmine.any(Number), y: jasmine.any(Number), z: jasmine.any(Number)}, |
| 12 | + eye: {x: jasmine.any(Number), y: jasmine.any(Number), z: jasmine.any(Number)} |
| 13 | +}; |
11 | 14 |
|
12 | | - // The teardown function needs information of what to tear down so afterEach can not be used without global vars. |
13 | | - // In addition to removing the plot from the DOM it also destroy possibly present 2D or 3D scenes |
14 | | - |
15 | | - // TODO we should figure out something to only rely on public API calls |
16 | | - // In other words, how can users themselves properly destroy the plot through the API? |
17 | | - // This function is left in this file until the above todo is looked into. |
18 | | - var fullLayout = gd._fullLayout; |
19 | | - |
20 | | - Plots.getSubplotIds(fullLayout, 'gl3d').forEach(function(sceneId) { |
21 | | - var scene = fullLayout[sceneId]._scene; |
22 | | - if(scene.glplot) scene.destroy(); |
23 | | - }); |
24 | | - |
25 | | - Plots.getSubplotIds(fullLayout, 'gl2d').forEach(function(sceneId) { |
26 | | - var scene2d = fullLayout._plots[sceneId]._scene2d; |
27 | | - if(scene2d.glplot) { |
28 | | - scene2d.stopped = true; |
29 | | - scene2d.destroy(); |
30 | | - } |
31 | | - }); |
32 | | - |
33 | | - destroyGraphDiv(); |
34 | | - |
35 | | - // A test case can only be called 'done' when the above destroy methods had been performed. |
36 | | - // One way of helping ensure that the destroys are not forgotten is that done() is part of |
37 | | - // the teardown, consequently if a test case omits the teardown by accident, the test will |
38 | | - // visibly hang. If the teardown receives no proper arguments, it'll also visibly fail. |
39 | | - done(); |
| 15 | +function makePlot(gd, mock) { |
| 16 | + return Plotly.plot(gd, mock.data, mock.layout); |
40 | 17 | } |
41 | 18 |
|
42 | | -describe('Test gl plot interactions', function() { |
43 | | - |
44 | | - describe('gl3d plots', function() { |
45 | | - |
46 | | - // Expected shape of projection-related data |
47 | | - var cameraStructure = { |
48 | | - up: {x: jasmine.any(Number), y: jasmine.any(Number), z: jasmine.any(Number)}, |
49 | | - center: {x: jasmine.any(Number), y: jasmine.any(Number), z: jasmine.any(Number)}, |
50 | | - eye: {x: jasmine.any(Number), y: jasmine.any(Number), z: jasmine.any(Number)} |
51 | | - }; |
52 | | - |
53 | | - function makePlot(mock) { |
54 | | - return Plotly.plot(createGraphDiv(), mock.data, mock.layout); |
55 | | - } |
| 19 | +function addEventCallback(graphDiv) { |
| 20 | + var relayoutCallback = jasmine.createSpy('relayoutCallback'); |
| 21 | + graphDiv.on('plotly_relayout', relayoutCallback); |
| 22 | + return {graphDiv: graphDiv, relayoutCallback: relayoutCallback}; |
| 23 | +} |
56 | 24 |
|
57 | | - function addEventCallback(graphDiv) { |
58 | | - var relayoutCallback = jasmine.createSpy('relayoutCallback'); |
59 | | - graphDiv.on('plotly_relayout', relayoutCallback); |
60 | | - return {graphDiv: graphDiv, relayoutCallback: relayoutCallback}; |
61 | | - } |
| 25 | +function verifyInteractionEffects(tuple) { |
62 | 26 |
|
63 | | - function verifyInteractionEffects(tuple) { |
| 27 | + // One 'drag': simulating fairly thoroughly as the mouseup event is also needed here |
| 28 | + mouseEvent('mousemove', 400, 200); |
| 29 | + mouseEvent('mousedown', 400, 200); |
| 30 | + mouseEvent('mousemove', 320, 320, {buttons: 1}); |
| 31 | + mouseEvent('mouseup', 320, 320); |
64 | 32 |
|
65 | | - // One 'drag': simulating fairly thoroughly as the mouseup event is also needed here |
66 | | - mouseEvent('mousemove', 400, 200); |
67 | | - mouseEvent('mousedown', 400, 200); |
68 | | - mouseEvent('mousemove', 320, 320, {buttons: 1}); |
69 | | - mouseEvent('mouseup', 320, 320); |
| 33 | + // Check event emission count |
| 34 | + expect(tuple.relayoutCallback).toHaveBeenCalledTimes(1); |
70 | 35 |
|
71 | | - // Check event emission count |
72 | | - expect(tuple.relayoutCallback).toHaveBeenCalledTimes(1); |
| 36 | + // Check structure of event callback value contents |
| 37 | + expect(tuple.relayoutCallback).toHaveBeenCalledWith(jasmine.objectContaining({scene: cameraStructure})); |
73 | 38 |
|
74 | | - // Check structure of event callback value contents |
75 | | - expect(tuple.relayoutCallback).toHaveBeenCalledWith(jasmine.objectContaining({scene: cameraStructure})); |
| 39 | + // Check camera contents on the DIV layout |
| 40 | + var divCamera = tuple.graphDiv.layout.scene.camera; |
76 | 41 |
|
77 | | - // Check camera contents on the DIV layout |
78 | | - var divCamera = tuple.graphDiv.layout.scene.camera; |
| 42 | + expect(divCamera).toEqual(cameraStructure); |
79 | 43 |
|
80 | | - expect(divCamera).toEqual(cameraStructure); |
| 44 | + return tuple.graphDiv; |
| 45 | +} |
81 | 46 |
|
82 | | - return tuple.graphDiv; |
83 | | - } |
| 47 | +function testEvents(plot) { |
| 48 | + return plot |
| 49 | + .then(function(graphDiv) { |
| 50 | + var tuple = addEventCallback(graphDiv); // TODO disuse tuple with ES6 |
| 51 | + verifyInteractionEffects(tuple); |
| 52 | + }); |
| 53 | +} |
84 | 54 |
|
85 | | - function testEvents(plot, done) { |
86 | | - plot.then(function(graphDiv) { |
87 | | - var tuple = addEventCallback(graphDiv); // TODO disuse tuple with ES6 |
88 | | - verifyInteractionEffects(tuple); |
89 | | - teardown(graphDiv, done); |
90 | | - }); |
91 | | - } |
| 55 | +describe('gl3d plots', function() { |
92 | 56 |
|
93 | | - it('should respond to drag interactions with mock of unset camera', function(done) { |
94 | | - testEvents(makePlot(require('@mocks/gl3d_scatter3d-connectgaps.json')), done); |
| 57 | + it('should respond to drag interactions with mock of unset camera', function(done) { |
| 58 | + withSetupTeardown(done, function(gd) { |
| 59 | + return testEvents(makePlot(gd, require('@mocks/gl3d_scatter3d-connectgaps.json'))); |
95 | 60 | }); |
| 61 | + }); |
96 | 62 |
|
97 | | - it('should respond to drag interactions with mock of partially set camera', function(done) { |
98 | | - testEvents(makePlot(require('@mocks/gl3d_errorbars_zx.json')), done); |
| 63 | + it('should respond to drag interactions with mock of partially set camera', function(done) { |
| 64 | + withSetupTeardown(done, function(gd) { |
| 65 | + return testEvents(makePlot(gd, require('@mocks/gl3d_errorbars_zx.json'))); |
99 | 66 | }); |
100 | 67 | }); |
101 | 68 | }); |
0 commit comments