-
Notifications
You must be signed in to change notification settings - Fork 31
/
test-barplots.js
370 lines (349 loc) · 15.5 KB
/
test-barplots.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
require([
"jquery",
"underscore",
"spectrum",
"Empress",
"BarplotLayer",
"UtilitiesForTesting",
"Colorer",
], function (
$,
_,
spectrum,
Empress,
BarplotLayer,
UtilitiesForTesting,
Colorer
) {
module("Barplots", {
setup: function () {
// Clear any prior layer HTML stuff so as to not mess up other
// barplot tests. This is a gross solution; we need to do this
// because the barplot panel doesn't have any logic to clear any
// existing HTML when it's created, since only one barplot panel
// should be created during the normal usage of Empress.
$("#barplot-layer-container").empty();
this.testData = UtilitiesForTesting.getTestData();
this.initTestEmpress = function () {
return new Empress(
this.testData.tree,
this.testData.biom,
this.testData.fmCols,
this.testData.splitTaxCols,
this.testData.tm,
this.testData.im,
this.testData.canvas
);
};
},
});
test("Barplot panel is initialized with one layer", function () {
var empress = this.initTestEmpress();
equal(empress._barplotPanel.layers.length, 1);
});
test("Layout availability toggling: initialization (default unrooted layout)", function () {
// The default layout should influence whether the barplot panel's
// "available" or "unavailable" content is shown. As of writing, the
// default layout will always be Unrooted.
var empress = this.initTestEmpress("Unrooted");
ok(empress._barplotPanel.availContent.classList.contains("hidden"));
notOk(
empress._barplotPanel.unavailContent.classList.contains("hidden")
);
});
test("Layout availability toggling post-initialization", function () {
var empress = this.initTestEmpress("Unrooted");
// We need to call this in order to make updateLayout() work.
// Otherwise, things start breaking -- see
// https://github.com/biocore/empress/pull/320 for context.
empress.initialize();
// After updating the layout to something that supports barplots, the
// barplot "available content" should now be shown.
empress.updateLayout("Rectangular");
notOk(empress._barplotPanel.availContent.classList.contains("hidden"));
ok(empress._barplotPanel.unavailContent.classList.contains("hidden"));
// ... And going back to a not-compatible-with-barplots layout should
// switch back to the unavailable content.
empress.updateLayout("Unrooted");
ok(empress._barplotPanel.availContent.classList.contains("hidden"));
notOk(
empress._barplotPanel.unavailContent.classList.contains("hidden")
);
});
test("Barplot panel border option initialization (incl. initBorderOptions)", function () {
var empress = this.initTestEmpress();
deepEqual(empress._barplotPanel.borderColor, 16777215);
// Color picker should correctly default to white
var obsColor = $(empress._barplotPanel.borderColorPicker)
.spectrum("get")
.toHexString();
deepEqual(obsColor, "#ffffff");
// Test that the border length defaults to 1/10 the default barplot
// layer length (previously it was 1/2 of this, but we made the default
// barplot layer length a lot thicker so I'm changing this accordingly)
var expBorderLen = BarplotLayer.DEFAULT_LENGTH / 10;
deepEqual(empress._barplotPanel.borderLength, expBorderLen);
// Test that the border length input's default value and minimum value
// are set properly
// (The +s convert things to numbers, since value / getAttribute()
// seem to just provide Strings [e.g. "10"].)
deepEqual(
+empress._barplotPanel.borderLengthInput.value,
+expBorderLen
);
deepEqual(
+empress._barplotPanel.borderLengthInput.getAttribute("min"),
+BarplotLayer.MIN_LENGTH
);
});
test("Barplot layers default to feature metadata layers, but only if feature metadata is available", function () {
// (Sample metadata should always be available. (... That is, until we
// support visualizing a tree without table / sample metadata info.)
var empressWithFM = this.initTestEmpress();
equal(empressWithFM._barplotPanel.layers[0].barplotType, "fm");
var empressWithNoFM = new Empress(
this.testData.tree,
this.testData.biom,
[],
[],
{},
{},
this.testData.canvas
);
equal(empressWithNoFM._barplotPanel.layers[0].barplotType, "sm");
});
test("No barplot panel created if Empress has no feature or sample metadata", function () {
var empWithNoMetadata = new Empress(
this.testData.tree,
null,
[],
[],
{},
{},
this.testData.canvas
);
equal(empWithNoMetadata._barplotPanel, null);
var empWithFM = new Empress(
this.testData.tree,
null,
this.testData.fmCols,
[],
this.testData.tm,
this.testData.im,
this.testData.canvas
);
notEqual(empWithFM._barplotPanel, null);
var empWithSM = new Empress(
this.testData.tree,
this.testData.biom,
[],
[],
{},
{},
this.testData.canvas
);
notEqual(empWithSM._barplotPanel, null);
});
test("Barplot layers only have metadata toggling buttons if Empress has both feature and sample metadata", function () {
var empress = this.initTestEmpress();
// In the one layer in the barplot panel, there should be a row of
// feature / sample metadata toggling buttons (one of which should be
// selected). We use the presence of this selected button's class to
// check that these toggling buttons exist; this is kind of hacky, but
// it's a quick way to do this.
equal(
$(empress._barplotPanel.layerContainer).find(
".selected-metadata-choice"
).length,
1
);
$("#barplot-layer-container").empty();
// If only one type of metadata was provided to Empress, then don't
// bother showing the metadata toggling buttons.
var empWithJustFM = new Empress(
this.testData.tree,
null,
this.testData.fmCols,
[],
this.testData.tm,
this.testData.im,
this.testData.canvas
);
equal(
$(empWithJustFM._barplotPanel.layerContainer).find(
".selected-metadata-choice"
).length,
0
);
$("#barplot-layer-container").empty();
var empWithJustSM = new Empress(
this.testData.tree,
this.testData.biom,
[],
[],
{},
{},
this.testData.canvas
);
equal(
$(empWithJustSM._barplotPanel.layerContainer).find(
".selected-metadata-choice"
).length,
0
);
});
test("BarplotPanelHandler.addLayer", function () {
var scope = this;
var empress = this.initTestEmpress();
// Add on two layers
empress._barplotPanel.addLayer();
equal(empress._barplotPanel.layers.length, 2);
empress._barplotPanel.addLayer();
equal(empress._barplotPanel.layers.length, 3);
// Check that each layer was provided correct information
_.each(empress._barplotPanel.layers, function (layer, i) {
// Basic information about the visualization -- should be the same
// across every layer
equal(layer.fmCols, scope.testData.fmCols);
equal(layer.smCols, empress._barplotPanel.smCols);
equal(layer.barplotPanel, empress._barplotPanel);
equal(layer.layerContainer, empress._barplotPanel.layerContainer);
// Check that the "num" and "unique num" of each barplot layer were
// assigned correctly. Since no layers have been removed, these
// numbers should be identical.
equal(layer.num, i + 1);
equal(layer.uniqueNum, i + 1);
// Check that each layer's header says "Layer N" (N = layer.num)
equal(layer.headerElement.innerText, "Layer " + (i + 1));
});
});
test("BarplotPanelHandler.removeLayer", function () {
var empress = this.initTestEmpress();
empress._barplotPanel.addLayer();
equal(empress._barplotPanel.layers.length, 2);
empress._barplotPanel.addLayer();
equal(empress._barplotPanel.layers.length, 3);
// Remove the second of the three layers
empress._barplotPanel.removeLayer(2);
// Check that now there are only two layers
equal(empress._barplotPanel.layers.length, 2);
// Check that layer 1's number stayed the same, while layer 3's number
// was decremented
equal(empress._barplotPanel.layers[0].num, 1);
equal(empress._barplotPanel.layers[1].num, 2);
// Check that layer 1's header stayed the same, while layer 3's header
// was decremented along with its number
equal(
empress._barplotPanel.layers[0].headerElement.innerText,
"Layer 1"
);
equal(
empress._barplotPanel.layers[1].headerElement.innerText,
"Layer 2"
);
// Check that the *unique numbers* of each layer remained the same
// (so that the HTML elements created for each layer will have distinct
// IDs)
equal(empress._barplotPanel.layers[0].uniqueNum, 1);
equal(empress._barplotPanel.layers[1].uniqueNum, 3);
// Try adding on a new layer. It should be named "Layer 3" (and have a
// number of 3), but its unique number should be 4 -- since it's the
// fourth layer created thus far, ignoring all removal operations.
empress._barplotPanel.addLayer();
equal(empress._barplotPanel.layers.length, 3);
// Verify all the layers' numbers / headers / unique numbers correct
// (Layer 1 and 2 (previously Layer 3) shouldn't have changed, but we
// might as well verify they don't break when we add a new layer after
// them.)
equal(empress._barplotPanel.layers[0].num, 1);
equal(empress._barplotPanel.layers[1].num, 2);
equal(empress._barplotPanel.layers[2].num, 3);
equal(
empress._barplotPanel.layers[0].headerElement.innerText,
"Layer 1"
);
equal(
empress._barplotPanel.layers[1].headerElement.innerText,
"Layer 2"
);
equal(
empress._barplotPanel.layers[2].headerElement.innerText,
"Layer 3"
);
equal(empress._barplotPanel.layers[0].uniqueNum, 1);
equal(empress._barplotPanel.layers[1].uniqueNum, 3);
// This is the most important check -- the newest layer should have a
// distinct unique number.
equal(empress._barplotPanel.layers[2].uniqueNum, 4);
});
test("BarplotLayer initialization: state matches UI", function () {
var empress = this.initTestEmpress();
var layer1 = empress._barplotPanel.layers[0];
// initTestEmpress() passes in feature metadata, so barplots should
// default to feature metadata
equal(layer1.barplotType, "fm");
// Default color (for feature metadata barplots) defaults to red,
// a.k.a. the first "Classic QIIME Colors" color
equal(layer1.initialDefaultColorHex, "#ff0000");
equal(layer1.defaultColor, 255);
// Default length defaults to, well, DEFAULT_LENGTH
equal(layer1.defaultLength, BarplotLayer.DEFAULT_LENGTH);
// Check feature metadata coloring defaults. By default, feature
// metadata coloring isn't used -- a just-created feature metadata
// barplot doesn't have any color or length encodings.
notOk(layer1.colorByFM);
equal(layer1.colorByFMField, empress._barplotPanel.fmCols[0]);
equal(layer1.colorByFMColorMap, "discrete-coloring-qiime");
notOk(layer1.colorByFMColorReverse);
notOk(layer1.colorByFMContinuous);
ok(layer1.colorByFMColorMapDiscrete);
// Check feature metadata length-scaling defaults
notOk(layer1.scaleLengthByFM);
equal(layer1.scaleLengthByFMField, empress._barplotPanel.fmCols[0]);
equal(layer1.scaleLengthByFMMin, BarplotLayer.DEFAULT_MIN_LENGTH);
equal(layer1.scaleLengthByFMMax, BarplotLayer.DEFAULT_MAX_LENGTH);
// Check sample metadata barplot defaults
equal(layer1.colorBySMField, empress._barplotPanel.smCols[0]);
equal(layer1.colorBySMColorMap, "discrete-coloring-qiime");
notOk(layer1.colorBySMColorReverse);
equal(layer1.lengthSM, BarplotLayer.DEFAULT_LENGTH);
});
test("Empress.getBarplotData() throws error if layout doesn't support barplots", function () {
var empress = this.initTestEmpress();
empress._barplotPanel.addLayer();
throws(function () {
empress.getBarplotData();
}, /Non-barplot-supporting layout 'Unrooted' in use./);
});
test('"Freebies": barplot borders aren\'t drawn when the border color matches the background color', function () {
var empress = this.initTestEmpress();
empress.initialize();
empress.updateLayout("Rectangular");
// By default, the border color should default to the background color
// -- so we get freebies by default.
empress._barplotPanel.borderCheckbox.click();
var data = empress.getBarplotData(empress.getBarplotLayers());
// For each bar in the rectangular layout, six (x, y, rgb) groups are
// added to the coords array for each tip's bar: this is due to how
// Empress._addRectangularBarCoords() / _addTriangleCoords() works.
// Since there are four tips in the test tree, we then expect to see
// exactly 72 values in the coords array: 4 * 6 * 3.
// (tips) (xyr groups) (x,y,rgb)
deepEqual(data.coords.length, 72);
// When we change the barplot border color, we should no longer get
// freebies -- now we add on two full extra bars for each tip.
empress._barplotPanel.borderColor = Colorer.rgbToFloat([0, 0, 0]);
var data2 = empress.getBarplotData(empress.getBarplotLayers());
// Each barplot border layer takes up the same amount of elements in
// coords as a "normal" layer. So we should see 72 * 3 = 216 elements.
deepEqual(data2.coords.length, 216);
// Check that resetting the border color to white re-enables "freebies"
// (...less stuff to draw.)
empress._barplotPanel.borderColor = Colorer.rgbToFloat([255, 255, 255]);
var data3 = empress.getBarplotData(empress.getBarplotLayers());
deepEqual(data3.coords.length, 72);
});
// TODO: Test that interacting with various elements of the BarplotLayer UI
// also changes the BarplotLayer state. Testing this shouldn't really be
// that difficult, it'll just be kind of tedious.
});