Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package jalview.schemes

File FeatureColourTest.java

 

Code metrics

0
366
13
1
807
505
15
0.04
28.15
13
1.15

Classes

Class Line # Actions
FeatureColourTest 41 366 15
0.9947229699.5%
 

Contributing tests

This file is covered by 12 tests. .

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package jalview.schemes;
22   
23    import static org.testng.AssertJUnit.assertEquals;
24    import static org.testng.AssertJUnit.assertFalse;
25    import static org.testng.AssertJUnit.assertNull;
26    import static org.testng.AssertJUnit.assertTrue;
27    import static org.testng.AssertJUnit.fail;
28    import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
29   
30    import jalview.api.FeatureColourI;
31    import jalview.datamodel.SequenceFeature;
32    import jalview.gui.JvOptionPane;
33    import jalview.util.ColorUtils;
34    import jalview.util.Format;
35   
36    import java.awt.Color;
37   
38    import org.testng.annotations.BeforeClass;
39    import org.testng.annotations.Test;
40   
 
41    public class FeatureColourTest
42    {
43   
 
44  1 toggle @BeforeClass(alwaysRun = true)
45    public void setUpJvOptionPane()
46    {
47  1 JvOptionPane.setInteractiveMode(false);
48  1 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
49    }
50   
 
51  1 toggle @Test(groups = { "Functional" })
52    public void testConstructors()
53    {
54  1 FeatureColourI fc = new FeatureColour();
55  1 assertNull(fc.getColour());
56  1 assertTrue(fc.isSimpleColour());
57  1 assertFalse(fc.isColourByLabel());
58  1 assertFalse(fc.isGraduatedColour());
59  1 assertFalse(fc.isColourByAttribute());
60  1 assertEquals(Color.white, fc.getMinColour());
61  1 assertEquals(Color.black, fc.getMaxColour());
62   
63  1 fc = new FeatureColour(Color.RED);
64  1 assertEquals(Color.red, fc.getColour());
65  1 assertTrue(fc.isSimpleColour());
66  1 assertFalse(fc.isColourByLabel());
67  1 assertFalse(fc.isGraduatedColour());
68  1 assertFalse(fc.isColourByAttribute());
69  1 assertEquals(ColorUtils.bleachColour(Color.RED, 0.9f),
70    fc.getMinColour());
71  1 assertEquals(Color.RED, fc.getMaxColour());
72   
73    }
74   
 
75  1 toggle @Test(groups = { "Functional" })
76    public void testCopyConstructor()
77    {
78    /*
79    * plain colour
80    */
81  1 FeatureColour fc = new FeatureColour(Color.RED);
82  1 FeatureColour fc1 = new FeatureColour(fc);
83  1 assertTrue(fc1.getColour().equals(Color.RED));
84  1 assertFalse(fc1.isGraduatedColour());
85  1 assertFalse(fc1.isColourByLabel());
86  1 assertFalse(fc1.isColourByAttribute());
87  1 assertNull(fc1.getAttributeName());
88   
89    /*
90    * min-max colour
91    */
92  1 fc = new FeatureColour(null, Color.gray, Color.black, Color.gray, 10f,
93    20f);
94  1 fc.setAboveThreshold(true);
95  1 fc.setThreshold(12f);
96  1 fc1 = new FeatureColour(fc);
97  1 assertTrue(fc1.isGraduatedColour());
98  1 assertFalse(fc1.isColourByLabel());
99  1 assertTrue(fc1.isAboveThreshold());
100  1 assertFalse(fc1.isColourByAttribute());
101  1 assertNull(fc1.getAttributeName());
102  1 assertEquals(12f, fc1.getThreshold());
103  1 assertEquals(Color.gray, fc1.getMinColour());
104  1 assertEquals(Color.black, fc1.getMaxColour());
105  1 assertEquals(Color.gray, fc1.getNoColour());
106  1 assertEquals(10f, fc1.getMin());
107  1 assertEquals(20f, fc1.getMax());
108   
109    /*
110    * min-max-noValue colour
111    */
112  1 fc = new FeatureColour(Color.red, Color.gray, Color.black, Color.green,
113    10f, 20f);
114  1 fc.setAboveThreshold(true);
115  1 fc.setThreshold(12f);
116  1 fc1 = new FeatureColour(fc);
117  1 assertTrue(fc1.isGraduatedColour());
118  1 assertFalse(fc1.isColourByLabel());
119  1 assertFalse(fc1.isSimpleColour());
120  1 assertFalse(fc1.isColourByAttribute());
121  1 assertNull(fc1.getAttributeName());
122  1 assertTrue(fc1.isAboveThreshold());
123  1 assertEquals(12f, fc1.getThreshold());
124  1 assertEquals(Color.gray, fc1.getMinColour());
125  1 assertEquals(Color.black, fc1.getMaxColour());
126  1 assertEquals(Color.green, fc1.getNoColour());
127  1 assertEquals(Color.red, fc1.getColour());
128  1 assertEquals(10f, fc1.getMin());
129  1 assertEquals(20f, fc1.getMax());
130   
131    /*
132    * colour by label
133    */
134  1 fc = new FeatureColour();
135  1 fc.setColourByLabel(true);
136  1 fc1 = new FeatureColour(fc);
137  1 assertTrue(fc1.isColourByLabel());
138  1 assertFalse(fc1.isGraduatedColour());
139  1 assertFalse(fc1.isColourByAttribute());
140  1 assertNull(fc1.getAttributeName());
141   
142    /*
143    * colour by attribute (label)
144    */
145  1 fc = new FeatureColour();
146  1 fc.setColourByLabel(true);
147  1 fc.setAttributeName("AF");
148  1 fc1 = new FeatureColour(fc);
149  1 assertTrue(fc1.isColourByLabel());
150  1 assertFalse(fc1.isGraduatedColour());
151  1 assertTrue(fc1.isColourByAttribute());
152  1 assertArrayEquals(new String[] { "AF" }, fc1.getAttributeName());
153   
154    /*
155    * colour by attribute (value)
156    */
157  1 fc = new FeatureColour(Color.yellow, Color.gray, Color.black,
158    Color.green, 10f, 20f);
159  1 fc.setAboveThreshold(true);
160  1 fc.setThreshold(12f);
161  1 fc.setAttributeName("AF");
162  1 fc1 = new FeatureColour(fc);
163  1 assertTrue(fc1.isGraduatedColour());
164  1 assertFalse(fc1.isColourByLabel());
165  1 assertTrue(fc1.isColourByAttribute());
166  1 assertFalse(fc1.isSimpleColour());
167  1 assertArrayEquals(new String[] { "AF" }, fc1.getAttributeName());
168  1 assertTrue(fc1.isAboveThreshold());
169  1 assertEquals(12f, fc1.getThreshold());
170  1 assertEquals(Color.gray, fc1.getMinColour());
171  1 assertEquals(Color.black, fc1.getMaxColour());
172  1 assertEquals(Color.green, fc1.getNoColour());
173  1 assertEquals(Color.yellow, fc1.getColour());
174  1 assertEquals(10f, fc1.getMin());
175  1 assertEquals(20f, fc1.getMax());
176   
177    /*
178    * modify original attribute label and check that copy doesn't change
179    */
180  1 fc.setAttributeName("MAF", "AF");
181  1 assertArrayEquals(new String[] { "AF" }, fc1.getAttributeName());
182   
183    }
184   
 
185  1 toggle @Test(groups = { "Functional" })
186    public void testGetColor_simpleColour()
187    {
188  1 FeatureColour fc = new FeatureColour(Color.RED);
189  1 assertEquals(Color.RED,
190    fc.getColor(new SequenceFeature("Cath", "", 1, 2, 0f, null)));
191    }
192   
 
193  1 toggle @Test(groups = { "Functional" })
194    public void testGetColor_colourByLabel()
195    {
196  1 FeatureColour fc = new FeatureColour();
197  1 fc.setColourByLabel(true);
198  1 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 1f,
199    null);
200  1 Color expected = ColorUtils.createColourFromName("desc");
201  1 assertEquals(expected, fc.getColor(sf));
202    }
203   
 
204  1 toggle @Test(groups = { "Functional" })
205    public void testGetColor_Graduated()
206    {
207    /*
208    * graduated colour from
209    * score 0 to 100
210    * gray(128, 128, 128) to red(255, 0, 0)
211    */
212  1 FeatureColour fc = new FeatureColour(null, Color.GRAY, Color.RED, null,
213    0f, 100f);
214    // feature score is 75 which is 3/4 of the way from GRAY to RED
215  1 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
216    null);
217    // the colour gradient is computed in float values from 0-1 (where 1 == 255)
218  1 float red = 128 / 255f + 3 / 4f * (255 - 128) / 255f;
219  1 float green = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
220  1 float blue = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
221  1 Color expected = new Color(red, green, blue);
222  1 assertEquals(expected, fc.getColor(sf));
223    }
224   
 
225  1 toggle @Test(groups = { "Functional" })
226    public void testGetColor_aboveBelowThreshold()
227    {
228    // gradient from [50, 150] from WHITE(255, 255, 255) to BLACK(0, 0, 0)
229  1 FeatureColour fc = new FeatureColour(null, Color.WHITE, Color.BLACK,
230    Color.white, 50f, 150f);
231  1 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 70f,
232    null);
233   
234    /*
235    * feature with score of Float.NaN is always assigned minimum colour
236    */
237  1 SequenceFeature sf2 = new SequenceFeature("type", "desc", 0, 20,
238    Float.NaN, null);
239   
240  1 fc.setThreshold(100f); // ignore for now
241  1 assertEquals(new Color(204, 204, 204), fc.getColor(sf));
242  1 assertEquals(Color.white, fc.getColor(sf2));
243   
244  1 fc.setAboveThreshold(true); // feature lies below threshold
245  1 assertNull(fc.getColor(sf));
246  1 assertEquals(Color.white, fc.getColor(sf2));
247   
248  1 fc.setBelowThreshold(true);
249  1 fc.setThreshold(70f);
250  1 assertNull(fc.getColor(sf)); // feature score == threshold - hidden
251  1 assertEquals(Color.white, fc.getColor(sf2));
252  1 fc.setThreshold(69f);
253  1 assertNull(fc.getColor(sf)); // feature score > threshold - hidden
254  1 assertEquals(Color.white, fc.getColor(sf2));
255    }
256   
257    /**
258    * Test output of feature colours to Jalview features file format
259    */
 
260  1 toggle @Test(groups = { "Functional" })
261    public void testToJalviewFormat()
262    {
263    /*
264    * plain colour - to RGB hex code
265    */
266  1 FeatureColour fc = new FeatureColour(Color.RED);
267  1 String redHex = Format.getHexString(Color.RED);
268  1 String hexColour = redHex;
269  1 assertEquals("domain\t" + hexColour, fc.toJalviewFormat("domain"));
270   
271    /*
272    * colour by label (no threshold)
273    */
274  1 fc = new FeatureColour();
275  1 fc.setColourByLabel(true);
276  1 assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
277   
278    /*
279    * colour by attribute text (no threshold)
280    */
281  1 fc = new FeatureColour();
282  1 fc.setColourByLabel(true);
283  1 fc.setAttributeName("CLIN_SIG");
284  1 assertEquals("domain\tattribute|CLIN_SIG", fc.toJalviewFormat("domain"));
285   
286    /*
287    * colour by label (autoscaled) (an odd state you can reach by selecting
288    * 'above threshold', then deselecting 'threshold is min/max' then 'colour
289    * by label')
290    */
291  1 fc.setAttributeName((String[]) null);
292  1 fc.setAutoScaled(true);
293  1 assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
294   
295    /*
296    * colour by label (above threshold)
297    */
298  1 fc.setAutoScaled(false);
299  1 fc.setThreshold(12.5f);
300  1 fc.setAboveThreshold(true);
301    // min/max values are output though not used by this scheme
302  1 assertEquals("domain\tlabel|||0.0|0.0|above|12.5",
303    fc.toJalviewFormat("domain"));
304   
305    /*
306    * colour by label (below threshold)
307    */
308  1 fc.setBelowThreshold(true);
309  1 assertEquals("domain\tlabel|||0.0|0.0|below|12.5",
310    fc.toJalviewFormat("domain"));
311   
312    /*
313    * colour by attributes text (below threshold)
314    */
315  1 fc.setBelowThreshold(true);
316  1 fc.setAttributeName("CSQ", "Consequence");
317  1 assertEquals("domain\tattribute|CSQ:Consequence|||0.0|0.0|below|12.5",
318    fc.toJalviewFormat("domain"));
319   
320    /*
321    * graduated colour by score, no threshold
322    * - default constructor sets noValueColor = minColor
323    */
324  1 fc = new FeatureColour(null, Color.GREEN, Color.RED, Color.GREEN, 12f,
325    25f);
326  1 String greenHex = Format.getHexString(Color.GREEN);
327  1 String expected = String.format(
328    "domain\tscore|%s|%s|noValueMin|abso|12.0|25.0|none", greenHex,
329    redHex);
330  1 assertEquals(expected, fc.toJalviewFormat("domain"));
331   
332    /*
333    * graduated colour by score, no threshold, no value gets min colour
334    */
335  1 fc = new FeatureColour(Color.RED, Color.GREEN, Color.RED, Color.GREEN,
336    12f, 25f);
337  1 expected = String.format(
338    "domain\tscore|%s|%s|noValueMin|abso|12.0|25.0|none", greenHex,
339    redHex);
340  1 assertEquals(expected, fc.toJalviewFormat("domain"));
341   
342    /*
343    * graduated colour by score, no threshold, no value gets max colour
344    */
345  1 fc = new FeatureColour(Color.RED, Color.GREEN, Color.RED, Color.RED,
346    12f, 25f);
347  1 expected = String.format(
348    "domain\tscore|%s|%s|noValueMax|abso|12.0|25.0|none", greenHex,
349    redHex);
350  1 assertEquals(expected, fc.toJalviewFormat("domain"));
351   
352    /*
353    * colour ranges over the actual score ranges (not min/max)
354    */
355  1 fc.setAutoScaled(true);
356  1 expected = String.format(
357    "domain\tscore|%s|%s|noValueMax|12.0|25.0|none", greenHex,
358    redHex);
359  1 assertEquals(expected, fc.toJalviewFormat("domain"));
360   
361    /*
362    * graduated colour by score, below threshold
363    */
364  1 fc.setThreshold(12.5f);
365  1 fc.setBelowThreshold(true);
366  1 expected = String.format(
367    "domain\tscore|%s|%s|noValueMax|12.0|25.0|below|12.5",
368    greenHex, redHex);
369  1 assertEquals(expected, fc.toJalviewFormat("domain"));
370   
371    /*
372    * graduated colour by score, above threshold
373    */
374  1 fc.setThreshold(12.5f);
375  1 fc.setAboveThreshold(true);
376  1 fc.setAutoScaled(false);
377  1 expected = String.format(
378    "domain\tscore|%s|%s|noValueMax|abso|12.0|25.0|above|12.5",
379    greenHex, redHex);
380  1 assertEquals(expected, fc.toJalviewFormat("domain"));
381   
382    /*
383    * graduated colour by attribute, above threshold
384    */
385  1 fc.setAttributeName("CSQ", "AF");
386  1 fc.setAboveThreshold(true);
387  1 fc.setAutoScaled(false);
388  1 expected = String.format(
389    "domain\tattribute|CSQ:AF|%s|%s|noValueMax|abso|12.0|25.0|above|12.5",
390    greenHex, redHex);
391  1 assertEquals(expected, fc.toJalviewFormat("domain"));
392    }
393   
394    /**
395    * Test parsing of feature colours from Jalview features file format
396    */
 
397  1 toggle @Test(groups = { "Functional" })
398    public void testParseJalviewFeatureColour()
399    {
400    /*
401    * simple colour by name
402    */
403  1 FeatureColourI fc = FeatureColour.parseJalviewFeatureColour("red");
404  1 assertTrue(fc.isSimpleColour());
405  1 assertEquals(Color.RED, fc.getColour());
406   
407    /*
408    * simple colour by hex code
409    */
410  1 fc = FeatureColour.parseJalviewFeatureColour(Format
411    .getHexString(Color.RED));
412  1 assertTrue(fc.isSimpleColour());
413  1 assertEquals(Color.RED, fc.getColour());
414   
415    /*
416    * simple colour by rgb triplet
417    */
418  1 fc = FeatureColour.parseJalviewFeatureColour("255,0,0");
419  1 assertTrue(fc.isSimpleColour());
420  1 assertEquals(Color.RED, fc.getColour());
421   
422    /*
423    * malformed colour
424    */
425  1 try
426    {
427  1 fc = FeatureColour.parseJalviewFeatureColour("oops");
428  0 fail("expected exception");
429    } catch (IllegalArgumentException e)
430    {
431  1 assertEquals("Invalid colour descriptor: oops", e.getMessage());
432    }
433   
434    /*
435    * colour by label (no threshold)
436    */
437  1 fc = FeatureColour.parseJalviewFeatureColour("label");
438  1 assertTrue(fc.isColourByLabel());
439  1 assertFalse(fc.hasThreshold());
440   
441    /*
442    * colour by label (with threshold)
443    */
444  1 fc = FeatureColour
445    .parseJalviewFeatureColour("label|||0.0|0.0|above|12.0");
446  1 assertTrue(fc.isColourByLabel());
447  1 assertTrue(fc.isAboveThreshold());
448  1 assertEquals(12.0f, fc.getThreshold());
449   
450    /*
451    * colour by attribute text (no threshold)
452    */
453  1 fc = FeatureColour.parseJalviewFeatureColour("attribute|CLIN_SIG");
454  1 assertTrue(fc.isColourByAttribute());
455  1 assertTrue(fc.isColourByLabel());
456  1 assertFalse(fc.hasThreshold());
457  1 assertArrayEquals(new String[] { "CLIN_SIG" }, fc.getAttributeName());
458   
459    /*
460    * colour by attributes text (with score threshold)
461    */
462  1 fc = FeatureColour.parseJalviewFeatureColour(
463    "attribute|CSQ:Consequence|||0.0|0.0|above|12.0");
464  1 assertTrue(fc.isColourByLabel());
465  1 assertTrue(fc.isColourByAttribute());
466  1 assertArrayEquals(new String[] { "CSQ", "Consequence" },
467    fc.getAttributeName());
468  1 assertTrue(fc.isAboveThreshold());
469  1 assertEquals(12.0f, fc.getThreshold());
470   
471    /*
472    * graduated colour by score (with colour names) (no threshold)
473    */
474  1 fc = FeatureColour.parseJalviewFeatureColour("red|green|10.0|20.0");
475  1 assertTrue(fc.isGraduatedColour());
476  1 assertFalse(fc.hasThreshold());
477  1 assertEquals(Color.RED, fc.getMinColour());
478  1 assertEquals(Color.GREEN, fc.getMaxColour());
479  1 assertEquals(Color.RED, fc.getNoColour());
480  1 assertEquals(10f, fc.getMin());
481  1 assertEquals(20f, fc.getMax());
482  1 assertTrue(fc.isAutoScaled());
483   
484    /*
485    * the same, with 'no value colour' specified as max
486    */
487  1 fc = FeatureColour
488    .parseJalviewFeatureColour("red|green|novaluemax|10.0|20.0");
489  1 assertEquals(Color.RED, fc.getMinColour());
490  1 assertEquals(Color.GREEN, fc.getMaxColour());
491  1 assertEquals(Color.GREEN, fc.getNoColour());
492  1 assertEquals(10f, fc.getMin());
493  1 assertEquals(20f, fc.getMax());
494   
495    /*
496    * the same, with 'no value colour' specified as min
497    */
498  1 fc = FeatureColour
499    .parseJalviewFeatureColour("red|green|novalueMin|10.0|20.0");
500  1 assertEquals(Color.RED, fc.getMinColour());
501  1 assertEquals(Color.GREEN, fc.getMaxColour());
502  1 assertEquals(Color.RED, fc.getNoColour());
503  1 assertEquals(10f, fc.getMin());
504  1 assertEquals(20f, fc.getMax());
505   
506    /*
507    * the same, with 'no value colour' specified as none
508    */
509  1 fc = FeatureColour
510    .parseJalviewFeatureColour("red|green|novaluenone|10.0|20.0");
511  1 assertEquals(Color.RED, fc.getMinColour());
512  1 assertEquals(Color.GREEN, fc.getMaxColour());
513  1 assertNull(fc.getNoColour());
514  1 assertEquals(10f, fc.getMin());
515  1 assertEquals(20f, fc.getMax());
516   
517    /*
518    * the same, with invalid 'no value colour'
519    */
520  1 try
521    {
522  1 fc = FeatureColour
523    .parseJalviewFeatureColour("red|green|blue|10.0|20.0");
524  0 fail("expected exception");
525    } catch (IllegalArgumentException e)
526    {
527  1 assertEquals(
528    "Couldn't parse the minimum value for graduated colour ('blue')",
529    e.getMessage());
530    }
531   
532    /*
533    * graduated colour (explicitly by 'score') (no threshold)
534    */
535  1 fc = FeatureColour
536    .parseJalviewFeatureColour("Score|red|green|10.0|20.0");
537  1 assertTrue(fc.isGraduatedColour());
538  1 assertFalse(fc.hasThreshold());
539  1 assertEquals(Color.RED, fc.getMinColour());
540  1 assertEquals(Color.GREEN, fc.getMaxColour());
541  1 assertEquals(10f, fc.getMin());
542  1 assertEquals(20f, fc.getMax());
543  1 assertTrue(fc.isAutoScaled());
544   
545    /*
546    * graduated colour by attribute (no threshold)
547    */
548  1 fc = FeatureColour
549    .parseJalviewFeatureColour("attribute|AF|red|green|10.0|20.0");
550  1 assertTrue(fc.isGraduatedColour());
551  1 assertTrue(fc.isColourByAttribute());
552  1 assertArrayEquals(new String[] { "AF" }, fc.getAttributeName());
553  1 assertFalse(fc.hasThreshold());
554  1 assertEquals(Color.RED, fc.getMinColour());
555  1 assertEquals(Color.GREEN, fc.getMaxColour());
556  1 assertEquals(10f, fc.getMin());
557  1 assertEquals(20f, fc.getMax());
558  1 assertTrue(fc.isAutoScaled());
559   
560    /*
561    * graduated colour by score (colours by hex code) (above threshold)
562    */
563  1 String descriptor = String.format("%s|%s|10.0|20.0|above|15",
564    Format.getHexString(Color.RED),
565    Format.getHexString(Color.GREEN));
566  1 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
567  1 assertTrue(fc.isGraduatedColour());
568  1 assertTrue(fc.hasThreshold());
569  1 assertTrue(fc.isAboveThreshold());
570  1 assertEquals(15f, fc.getThreshold());
571  1 assertEquals(Color.RED, fc.getMinColour());
572  1 assertEquals(Color.GREEN, fc.getMaxColour());
573  1 assertEquals(10f, fc.getMin());
574  1 assertEquals(20f, fc.getMax());
575  1 assertTrue(fc.isAutoScaled());
576   
577    /*
578    * graduated colour by attributes (below threshold)
579    */
580  1 fc = FeatureColour.parseJalviewFeatureColour(
581    "attribute|CSQ:AF|red|green|10.0|20.0|below|13");
582  1 assertTrue(fc.isGraduatedColour());
583  1 assertTrue(fc.isColourByAttribute());
584  1 assertArrayEquals(new String[] { "CSQ", "AF" }, fc.getAttributeName());
585  1 assertTrue(fc.hasThreshold());
586  1 assertTrue(fc.isBelowThreshold());
587  1 assertEquals(13f, fc.getThreshold());
588  1 assertEquals(Color.RED, fc.getMinColour());
589  1 assertEquals(Color.GREEN, fc.getMaxColour());
590  1 assertEquals(10f, fc.getMin());
591  1 assertEquals(20f, fc.getMax());
592  1 assertTrue(fc.isAutoScaled());
593   
594    /*
595    * graduated colour (by RGB triplet) (below threshold), absolute scale
596    */
597  1 descriptor = "255,0,0|0,255,0|abso|10.0|20.0|below|15";
598  1 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
599  1 assertTrue(fc.isGraduatedColour());
600  1 assertFalse(fc.isAutoScaled());
601  1 assertTrue(fc.hasThreshold());
602  1 assertTrue(fc.isBelowThreshold());
603  1 assertEquals(15f, fc.getThreshold());
604  1 assertEquals(Color.RED, fc.getMinColour());
605  1 assertEquals(Color.GREEN, fc.getMaxColour());
606  1 assertEquals(10f, fc.getMin());
607  1 assertEquals(20f, fc.getMax());
608   
609  1 descriptor = "blue|255,0,255|absolute|20.0|95.0|below|66.0";
610  1 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
611  1 assertTrue(fc.isGraduatedColour());
612    }
613   
 
614  1 toggle @Test(groups = { "Functional" })
615    public void testGetColor_colourByAttributeText()
616    {
617  1 FeatureColour fc = new FeatureColour();
618  1 fc.setColourByLabel(true);
619  1 fc.setAttributeName("consequence");
620  1 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 1f,
621    null);
622   
623    /*
624    * if feature has no such attribute, use 'no value' colour
625    */
626  1 assertEquals(FeatureColour.DEFAULT_NO_COLOUR, fc.getColor(sf));
627   
628    /*
629    * if feature has attribute, generate colour from value
630    */
631  1 sf.setValue("consequence", "benign");
632  1 Color expected = ColorUtils.createColourFromName("benign");
633  1 assertEquals(expected, fc.getColor(sf));
634    }
635   
 
636  1 toggle @Test(groups = { "Functional" })
637    public void testGetColor_GraduatedByAttributeValue()
638    {
639    /*
640    * graduated colour based on attribute value for AF
641    * given a min-max range of 0-100
642    */
643  1 FeatureColour fc = new FeatureColour(Color.white,
644    new Color(50, 100, 150), new Color(150, 200, 250), Color.yellow,
645    0f, 100f);
646  1 String attName = "AF";
647  1 fc.setAttributeName(attName);
648   
649    /*
650    * first case: feature lacks the attribute - use 'no value' colour
651    */
652  1 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
653    null);
654  1 assertEquals(Color.yellow, fc.getColor(sf));
655   
656    /*
657    * second case: attribute present but not numeric - treat as if absent
658    */
659  1 sf.setValue(attName, "twelve");
660  1 assertEquals(Color.yellow, fc.getColor(sf));
661   
662    /*
663    * third case: valid attribute value
664    */
665  1 sf.setValue(attName, "20.0");
666  1 Color expected = new Color(70, 120, 170);
667  1 assertEquals(expected, fc.getColor(sf));
668    }
669   
 
670  1 toggle @Test(groups = { "Functional" })
671    public void testIsOutwithThreshold()
672    {
673  1 FeatureColourI fc = new FeatureColour(Color.red);
674  1 SequenceFeature sf = new SequenceFeature("METAL", "desc", 10, 12, 1.2f, "grp");
675  1 assertFalse(fc.isOutwithThreshold(null));
676  1 assertFalse(fc.isOutwithThreshold(sf));
677   
678  1 fc = new FeatureColour(null, Color.white, Color.black, Color.green, 0f,
679    10f);
680  1 assertFalse(fc.isOutwithThreshold(sf)); // no threshold
681   
682  1 fc.setAboveThreshold(true);
683  1 fc.setThreshold(1f);
684  1 assertFalse(fc.isOutwithThreshold(sf)); // feature score 1.2 is above 1
685   
686  1 fc.setThreshold(2f);
687  1 assertTrue(fc.isOutwithThreshold(sf)); // feature score 1.2 is not above 2
688   
689  1 fc.setBelowThreshold(true);
690  1 assertFalse(fc.isOutwithThreshold(sf)); // feature score 1.2 is below 2
691   
692  1 fc.setThreshold(1f);
693  1 assertTrue(fc.isOutwithThreshold(sf)); // feature score 1.2 is not below 1
694   
695    /*
696    * with attribute value threshold
697    */
698  1 fc.setAttributeName("AC");
699  1 assertFalse(fc.isOutwithThreshold(sf)); // missing attribute AC is ignored
700   
701  1 sf.setValue("AC", "-1");
702  1 assertFalse(fc.isOutwithThreshold(sf)); // value -1 is below 1
703   
704  1 sf.setValue("AC", "1");
705  1 assertTrue(fc.isOutwithThreshold(sf)); // value 1 is not below 1
706   
707  1 sf.setValue("AC", "junk");
708  1 assertFalse(fc.isOutwithThreshold(sf)); // bad value is ignored
709    }
710   
711    /**
712    * Test description of feature colour suitable for a tooltip
713    */
 
714  1 toggle @Test(groups = { "Functional" })
715    public void testGetDescription()
716    {
717    /*
718    * plain colour
719    */
720  1 FeatureColour fc = new FeatureColour(Color.RED);
721  1 assertEquals(
722    String.format("r=%d,g=%d,b=%d", Color.RED.getRed(),
723    Color.red.getGreen(), Color.red.getBlue()),
724    fc.getDescription());
725   
726    /*
727    * colour by label (no threshold)
728    */
729  1 fc = new FeatureColour();
730  1 fc.setColourByLabel(true);
731  1 assertEquals("By Label", fc.getDescription());
732   
733    /*
734    * colour by attribute text (no threshold)
735    */
736  1 fc = new FeatureColour();
737  1 fc.setColourByLabel(true);
738  1 fc.setAttributeName("CLIN_SIG");
739  1 assertEquals("By CLIN_SIG", fc.getDescription());
740   
741    /*
742    * colour by label (above score threshold)
743    */
744  1 fc = new FeatureColour();
745  1 fc.setColourByLabel(true);
746  1 fc.setAutoScaled(false);
747  1 fc.setThreshold(12.5f);
748  1 fc.setAboveThreshold(true);
749  1 assertEquals("By Label (Score > 12.5)",
750    fc.getDescription());
751   
752    /*
753    * colour by label (below score threshold)
754    */
755  1 fc.setBelowThreshold(true);
756  1 assertEquals("By Label (Score < 12.5)",
757    fc.getDescription());
758   
759    /*
760    * colour by attributes text (below score threshold)
761    */
762  1 fc.setBelowThreshold(true);
763  1 fc.setAttributeName("CSQ", "Consequence");
764  1 assertEquals(
765    "By CSQ:Consequence (Score < 12.5)",
766    fc.getDescription());
767   
768    /*
769    * graduated colour by score, no threshold
770    */
771  1 fc = new FeatureColour(null, Color.GREEN, Color.RED, null, 12f, 25f);
772  1 assertEquals("By Score", fc.getDescription());
773   
774    /*
775    * graduated colour by score, below threshold
776    */
777  1 fc.setThreshold(12.5f);
778  1 fc.setBelowThreshold(true);
779  1 assertEquals("By Score (< 12.5)",
780    fc.getDescription());
781   
782    /*
783    * graduated colour by score, above threshold
784    */
785  1 fc.setThreshold(12.5f);
786  1 fc.setAboveThreshold(true);
787  1 fc.setAutoScaled(false);
788  1 assertEquals("By Score (> 12.5)",
789    fc.getDescription());
790   
791    /*
792    * graduated colour by attribute, no threshold
793    */
794  1 fc.setAttributeName("CSQ", "AF");
795  1 fc.setAboveThreshold(false);
796  1 fc.setAutoScaled(false);
797  1 assertEquals("By CSQ:AF", fc.getDescription());
798   
799    /*
800    * graduated colour by attribute, above threshold
801    */
802  1 fc.setAboveThreshold(true);
803  1 fc.setAutoScaled(false);
804  1 assertEquals("By CSQ:AF (> 12.5)",
805    fc.getDescription());
806    }
807    }