Skip to content

Commit 7eef2e1

Browse files
committed
#30a removing new test case from the test file that's currently ignored by CI. The plan is to move more and more tests here, i.e. continuously improve on testing coverage. This test file purposefully avoids beforeEach and afterEach to favor a simpler to follow data flow (no globals).
1 parent 7c23e2e commit 7eef2e1

File tree

2 files changed

+101
-64
lines changed

2 files changed

+101
-64
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
'use strict';
2+
3+
var Plotly = require('@lib/index');
4+
var Plots = require('@src/plots/plots');
5+
6+
var createGraphDiv = require('../assets/create_graph_div');
7+
var destroyGraphDiv = require('../assets/destroy_graph_div');
8+
var mouseEvent = require('../assets/mouse_event');
9+
10+
function teardown(gd, done) {
11+
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();
40+
}
41+
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+
}
56+
57+
function addEventCallback(graphDiv) {
58+
var relayoutCallback = jasmine.createSpy('relayoutCallback');
59+
graphDiv.on('plotly_relayout', relayoutCallback);
60+
return {graphDiv: graphDiv, relayoutCallback: relayoutCallback};
61+
}
62+
63+
function verifyInteractionEffects(tuple) {
64+
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);
70+
71+
// Check event emission count
72+
expect(tuple.relayoutCallback).toHaveBeenCalledTimes(1);
73+
74+
// Check structure of event callback value contents
75+
expect(tuple.relayoutCallback).toHaveBeenCalledWith(jasmine.objectContaining({scene: cameraStructure}));
76+
77+
// Check camera contents on the DIV layout
78+
var divCamera = tuple.graphDiv.layout.scene.camera;
79+
80+
expect(divCamera).toEqual(cameraStructure);
81+
82+
return tuple.graphDiv;
83+
}
84+
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+
}
92+
93+
it('should respond to drag interactions with mock of unset camera', function(done) {
94+
testEvents(makePlot(require('@mocks/gl3d_scatter3d-connectgaps.json')), done);
95+
});
96+
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);
99+
});
100+
});
101+
});

test/jasmine/tests/gl_plot_interact_test.js

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -211,70 +211,6 @@ describe('Test gl plot interactions', function() {
211211

212212
});
213213

214-
describe('gl3d plots', function() {
215-
216-
// Expected shape of projection-related data
217-
var cameraStructure = {
218-
up: {x: jasmine.any(Number), y: jasmine.any(Number), z: jasmine.any(Number)},
219-
center: {x: jasmine.any(Number), y: jasmine.any(Number), z: jasmine.any(Number)},
220-
eye: {x: jasmine.any(Number), y: jasmine.any(Number), z: jasmine.any(Number)}
221-
};
222-
223-
function makePlot(mock) {
224-
return Plotly.plot(createGraphDiv(), mock.data, mock.layout);
225-
}
226-
227-
function addEventCallback(graphDiv) {
228-
var relayoutCallback = jasmine.createSpy('relayoutCallback');
229-
graphDiv.on('plotly_relayout', relayoutCallback);
230-
return {graphDiv: graphDiv, relayoutCallback: relayoutCallback};
231-
}
232-
233-
function verifyInteractionEffects(tuple) {
234-
235-
// One 'drag': simulating fairly thoroughly as the mouseup event is also needed here
236-
mouseEvent('mousemove', 400, 200);
237-
mouseEvent('mousedown', 400, 200);
238-
mouseEvent('mousemove', 320, 320, {buttons: 1});
239-
mouseEvent('mouseup', 320, 320);
240-
241-
// Check event emission count
242-
expect(tuple.relayoutCallback).toHaveBeenCalledTimes(1);
243-
244-
// Check structure of event callback value contents
245-
expect(tuple.relayoutCallback).toHaveBeenCalledWith(jasmine.objectContaining({scene: cameraStructure}));
246-
247-
// Check camera contents on the DIV layout
248-
var divCamera = tuple.graphDiv.layout.scene.camera;
249-
250-
expect(divCamera).toEqual(cameraStructure);
251-
252-
return tuple.graphDiv;
253-
}
254-
255-
function markForTeardown(graphDiv) {
256-
// TODO consider changing this test file such that the teardown needs no communication via a global variable
257-
gd = graphDiv;
258-
}
259-
260-
function testEvents(plot, done) {
261-
plot.then(function(graphDiv) {
262-
var tuple = addEventCallback(graphDiv);
263-
verifyInteractionEffects(tuple);
264-
markForTeardown(graphDiv);
265-
done();
266-
});
267-
}
268-
269-
it('should respond to drag interactions with mock of unset camera', function(done) {
270-
testEvents(makePlot(require('@mocks/gl3d_scatter3d-connectgaps.json')), done);
271-
});
272-
273-
it('should respond to drag interactions with mock of partially set camera', function(done) {
274-
testEvents(makePlot(require('@mocks/gl3d_errorbars_zx.json')), done);
275-
});
276-
});
277-
278214
describe('gl2d plots', function() {
279215
var mock = require('@mocks/gl2d_10.json'),
280216
modeBar, relayoutCallback;

0 commit comments

Comments
 (0)