Clover icon

Coverage Report

  1. Project Clover database Fri Dec 6 2024 13:47:14 GMT
  2. Package jalview.schemes

File FeatureColourTest.java

 

Code metrics

0
366
13
1
802
500
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",
285    fc.toJalviewFormat("domain"));
286   
287    /*
288    * colour by label (autoscaled) (an odd state you can reach by selecting
289    * 'above threshold', then deselecting 'threshold is min/max' then 'colour
290    * by label')
291    */
292  1 fc.setAttributeName((String[]) null);
293  1 fc.setAutoScaled(true);
294  1 assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
295   
296    /*
297    * colour by label (above threshold)
298    */
299  1 fc.setAutoScaled(false);
300  1 fc.setThreshold(12.5f);
301  1 fc.setAboveThreshold(true);
302    // min/max values are output though not used by this scheme
303  1 assertEquals("domain\tlabel|||0.0|0.0|above|12.5",
304    fc.toJalviewFormat("domain"));
305   
306    /*
307    * colour by label (below threshold)
308    */
309  1 fc.setBelowThreshold(true);
310  1 assertEquals("domain\tlabel|||0.0|0.0|below|12.5",
311    fc.toJalviewFormat("domain"));
312   
313    /*
314    * colour by attributes text (below threshold)
315    */
316  1 fc.setBelowThreshold(true);
317  1 fc.setAttributeName("CSQ", "Consequence");
318  1 assertEquals("domain\tattribute|CSQ:Consequence|||0.0|0.0|below|12.5",
319    fc.toJalviewFormat("domain"));
320   
321    /*
322    * graduated colour by score, no threshold
323    * - default constructor sets noValueColor = minColor
324    */
325  1 fc = new FeatureColour(null, Color.GREEN, Color.RED, Color.GREEN, 12f,
326    25f);
327  1 String greenHex = Format.getHexString(Color.GREEN);
328  1 String expected = String.format(
329    "domain\tscore|%s|%s|noValueMin|abso|12.0|25.0|none", greenHex,
330    redHex);
331  1 assertEquals(expected, fc.toJalviewFormat("domain"));
332   
333    /*
334    * graduated colour by score, no threshold, no value gets min colour
335    */
336  1 fc = new FeatureColour(Color.RED, Color.GREEN, Color.RED, Color.GREEN,
337    12f, 25f);
338  1 expected = String.format(
339    "domain\tscore|%s|%s|noValueMin|abso|12.0|25.0|none", greenHex,
340    redHex);
341  1 assertEquals(expected, fc.toJalviewFormat("domain"));
342   
343    /*
344    * graduated colour by score, no threshold, no value gets max colour
345    */
346  1 fc = new FeatureColour(Color.RED, Color.GREEN, Color.RED, Color.RED,
347    12f, 25f);
348  1 expected = String.format(
349    "domain\tscore|%s|%s|noValueMax|abso|12.0|25.0|none", greenHex,
350    redHex);
351  1 assertEquals(expected, fc.toJalviewFormat("domain"));
352   
353    /*
354    * colour ranges over the actual score ranges (not min/max)
355    */
356  1 fc.setAutoScaled(true);
357  1 expected = String.format(
358    "domain\tscore|%s|%s|noValueMax|12.0|25.0|none", greenHex,
359    redHex);
360  1 assertEquals(expected, fc.toJalviewFormat("domain"));
361   
362    /*
363    * graduated colour by score, below threshold
364    */
365  1 fc.setThreshold(12.5f);
366  1 fc.setBelowThreshold(true);
367  1 expected = String.format(
368    "domain\tscore|%s|%s|noValueMax|12.0|25.0|below|12.5", greenHex,
369    redHex);
370  1 assertEquals(expected, fc.toJalviewFormat("domain"));
371   
372    /*
373    * graduated colour by score, above threshold
374    */
375  1 fc.setThreshold(12.5f);
376  1 fc.setAboveThreshold(true);
377  1 fc.setAutoScaled(false);
378  1 expected = String.format(
379    "domain\tscore|%s|%s|noValueMax|abso|12.0|25.0|above|12.5",
380    greenHex, redHex);
381  1 assertEquals(expected, fc.toJalviewFormat("domain"));
382   
383    /*
384    * graduated colour by attribute, above threshold
385    */
386  1 fc.setAttributeName("CSQ", "AF");
387  1 fc.setAboveThreshold(true);
388  1 fc.setAutoScaled(false);
389  1 expected = String.format(
390    "domain\tattribute|CSQ:AF|%s|%s|noValueMax|abso|12.0|25.0|above|12.5",
391    greenHex, redHex);
392  1 assertEquals(expected, fc.toJalviewFormat("domain"));
393    }
394   
395    /**
396    * Test parsing of feature colours from Jalview features file format
397    */
 
398  1 toggle @Test(groups = { "Functional" })
399    public void testParseJalviewFeatureColour()
400    {
401    /*
402    * simple colour by name
403    */
404  1 FeatureColourI fc = FeatureColour.parseJalviewFeatureColour("red");
405  1 assertTrue(fc.isSimpleColour());
406  1 assertEquals(Color.RED, fc.getColour());
407   
408    /*
409    * simple colour by hex code
410    */
411  1 fc = FeatureColour
412    .parseJalviewFeatureColour(Format.getHexString(Color.RED));
413  1 assertTrue(fc.isSimpleColour());
414  1 assertEquals(Color.RED, fc.getColour());
415   
416    /*
417    * simple colour by rgb triplet
418    */
419  1 fc = FeatureColour.parseJalviewFeatureColour("255,0,0");
420  1 assertTrue(fc.isSimpleColour());
421  1 assertEquals(Color.RED, fc.getColour());
422   
423    /*
424    * malformed colour
425    */
426  1 try
427    {
428  1 fc = FeatureColour.parseJalviewFeatureColour("oops");
429  0 fail("expected exception");
430    } catch (IllegalArgumentException e)
431    {
432  1 assertEquals("Invalid colour descriptor: oops", e.getMessage());
433    }
434   
435    /*
436    * colour by label (no threshold)
437    */
438  1 fc = FeatureColour.parseJalviewFeatureColour("label");
439  1 assertTrue(fc.isColourByLabel());
440  1 assertFalse(fc.hasThreshold());
441   
442    /*
443    * colour by label (with threshold)
444    */
445  1 fc = FeatureColour
446    .parseJalviewFeatureColour("label|||0.0|0.0|above|12.0");
447  1 assertTrue(fc.isColourByLabel());
448  1 assertTrue(fc.isAboveThreshold());
449  1 assertEquals(12.0f, fc.getThreshold());
450   
451    /*
452    * colour by attribute text (no threshold)
453    */
454  1 fc = FeatureColour.parseJalviewFeatureColour("attribute|CLIN_SIG");
455  1 assertTrue(fc.isColourByAttribute());
456  1 assertTrue(fc.isColourByLabel());
457  1 assertFalse(fc.hasThreshold());
458  1 assertArrayEquals(new String[] { "CLIN_SIG" }, fc.getAttributeName());
459   
460    /*
461    * colour by attributes text (with score threshold)
462    */
463  1 fc = FeatureColour.parseJalviewFeatureColour(
464    "attribute|CSQ:Consequence|||0.0|0.0|above|12.0");
465  1 assertTrue(fc.isColourByLabel());
466  1 assertTrue(fc.isColourByAttribute());
467  1 assertArrayEquals(new String[] { "CSQ", "Consequence" },
468    fc.getAttributeName());
469  1 assertTrue(fc.isAboveThreshold());
470  1 assertEquals(12.0f, fc.getThreshold());
471   
472    /*
473    * graduated colour by score (with colour names) (no threshold)
474    */
475  1 fc = FeatureColour.parseJalviewFeatureColour("red|green|10.0|20.0");
476  1 assertTrue(fc.isGraduatedColour());
477  1 assertFalse(fc.hasThreshold());
478  1 assertEquals(Color.RED, fc.getMinColour());
479  1 assertEquals(Color.GREEN, fc.getMaxColour());
480  1 assertEquals(Color.RED, fc.getNoColour());
481  1 assertEquals(10f, fc.getMin());
482  1 assertEquals(20f, fc.getMax());
483  1 assertTrue(fc.isAutoScaled());
484   
485    /*
486    * the same, with 'no value colour' specified as max
487    */
488  1 fc = FeatureColour
489    .parseJalviewFeatureColour("red|green|novaluemax|10.0|20.0");
490  1 assertEquals(Color.RED, fc.getMinColour());
491  1 assertEquals(Color.GREEN, fc.getMaxColour());
492  1 assertEquals(Color.GREEN, fc.getNoColour());
493  1 assertEquals(10f, fc.getMin());
494  1 assertEquals(20f, fc.getMax());
495   
496    /*
497    * the same, with 'no value colour' specified as min
498    */
499  1 fc = FeatureColour
500    .parseJalviewFeatureColour("red|green|novalueMin|10.0|20.0");
501  1 assertEquals(Color.RED, fc.getMinColour());
502  1 assertEquals(Color.GREEN, fc.getMaxColour());
503  1 assertEquals(Color.RED, fc.getNoColour());
504  1 assertEquals(10f, fc.getMin());
505  1 assertEquals(20f, fc.getMax());
506   
507    /*
508    * the same, with 'no value colour' specified as none
509    */
510  1 fc = FeatureColour
511    .parseJalviewFeatureColour("red|green|novaluenone|10.0|20.0");
512  1 assertEquals(Color.RED, fc.getMinColour());
513  1 assertEquals(Color.GREEN, fc.getMaxColour());
514  1 assertNull(fc.getNoColour());
515  1 assertEquals(10f, fc.getMin());
516  1 assertEquals(20f, fc.getMax());
517   
518    /*
519    * the same, with invalid 'no value colour'
520    */
521  1 try
522    {
523  1 fc = FeatureColour
524    .parseJalviewFeatureColour("red|green|blue|10.0|20.0");
525  0 fail("expected exception");
526    } catch (IllegalArgumentException e)
527    {
528  1 assertEquals(
529    "Couldn't parse the minimum value for graduated colour ('blue')",
530    e.getMessage());
531    }
532   
533    /*
534    * graduated colour (explicitly by 'score') (no threshold)
535    */
536  1 fc = FeatureColour
537    .parseJalviewFeatureColour("Score|red|green|10.0|20.0");
538  1 assertTrue(fc.isGraduatedColour());
539  1 assertFalse(fc.hasThreshold());
540  1 assertEquals(Color.RED, fc.getMinColour());
541  1 assertEquals(Color.GREEN, fc.getMaxColour());
542  1 assertEquals(10f, fc.getMin());
543  1 assertEquals(20f, fc.getMax());
544  1 assertTrue(fc.isAutoScaled());
545   
546    /*
547    * graduated colour by attribute (no threshold)
548    */
549  1 fc = FeatureColour
550    .parseJalviewFeatureColour("attribute|AF|red|green|10.0|20.0");
551  1 assertTrue(fc.isGraduatedColour());
552  1 assertTrue(fc.isColourByAttribute());
553  1 assertArrayEquals(new String[] { "AF" }, fc.getAttributeName());
554  1 assertFalse(fc.hasThreshold());
555  1 assertEquals(Color.RED, fc.getMinColour());
556  1 assertEquals(Color.GREEN, fc.getMaxColour());
557  1 assertEquals(10f, fc.getMin());
558  1 assertEquals(20f, fc.getMax());
559  1 assertTrue(fc.isAutoScaled());
560   
561    /*
562    * graduated colour by score (colours by hex code) (above threshold)
563    */
564  1 String descriptor = String.format("%s|%s|10.0|20.0|above|15",
565    Format.getHexString(Color.RED),
566    Format.getHexString(Color.GREEN));
567  1 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
568  1 assertTrue(fc.isGraduatedColour());
569  1 assertTrue(fc.hasThreshold());
570  1 assertTrue(fc.isAboveThreshold());
571  1 assertEquals(15f, fc.getThreshold());
572  1 assertEquals(Color.RED, fc.getMinColour());
573  1 assertEquals(Color.GREEN, fc.getMaxColour());
574  1 assertEquals(10f, fc.getMin());
575  1 assertEquals(20f, fc.getMax());
576  1 assertTrue(fc.isAutoScaled());
577   
578    /*
579    * graduated colour by attributes (below threshold)
580    */
581  1 fc = FeatureColour.parseJalviewFeatureColour(
582    "attribute|CSQ:AF|red|green|10.0|20.0|below|13");
583  1 assertTrue(fc.isGraduatedColour());
584  1 assertTrue(fc.isColourByAttribute());
585  1 assertArrayEquals(new String[] { "CSQ", "AF" }, fc.getAttributeName());
586  1 assertTrue(fc.hasThreshold());
587  1 assertTrue(fc.isBelowThreshold());
588  1 assertEquals(13f, fc.getThreshold());
589  1 assertEquals(Color.RED, fc.getMinColour());
590  1 assertEquals(Color.GREEN, fc.getMaxColour());
591  1 assertEquals(10f, fc.getMin());
592  1 assertEquals(20f, fc.getMax());
593  1 assertTrue(fc.isAutoScaled());
594   
595    /*
596    * graduated colour (by RGB triplet) (below threshold), absolute scale
597    */
598  1 descriptor = "255,0,0|0,255,0|abso|10.0|20.0|below|15";
599  1 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
600  1 assertTrue(fc.isGraduatedColour());
601  1 assertFalse(fc.isAutoScaled());
602  1 assertTrue(fc.hasThreshold());
603  1 assertTrue(fc.isBelowThreshold());
604  1 assertEquals(15f, fc.getThreshold());
605  1 assertEquals(Color.RED, fc.getMinColour());
606  1 assertEquals(Color.GREEN, fc.getMaxColour());
607  1 assertEquals(10f, fc.getMin());
608  1 assertEquals(20f, fc.getMax());
609   
610  1 descriptor = "blue|255,0,255|absolute|20.0|95.0|below|66.0";
611  1 fc = FeatureColour.parseJalviewFeatureColour(descriptor);
612  1 assertTrue(fc.isGraduatedColour());
613    }
614   
 
615  1 toggle @Test(groups = { "Functional" })
616    public void testGetColor_colourByAttributeText()
617    {
618  1 FeatureColour fc = new FeatureColour();
619  1 fc.setColourByLabel(true);
620  1 fc.setAttributeName("consequence");
621  1 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 1f,
622    null);
623   
624    /*
625    * if feature has no such attribute, use 'no value' colour
626    */
627  1 assertEquals(FeatureColour.DEFAULT_NO_COLOUR, fc.getColor(sf));
628   
629    /*
630    * if feature has attribute, generate colour from value
631    */
632  1 sf.setValue("consequence", "benign");
633  1 Color expected = ColorUtils.createColourFromName("benign");
634  1 assertEquals(expected, fc.getColor(sf));
635    }
636   
 
637  1 toggle @Test(groups = { "Functional" })
638    public void testGetColor_GraduatedByAttributeValue()
639    {
640    /*
641    * graduated colour based on attribute value for AF
642    * given a min-max range of 0-100
643    */
644  1 FeatureColour fc = new FeatureColour(Color.white,
645    new Color(50, 100, 150), new Color(150, 200, 250), Color.yellow,
646    0f, 100f);
647  1 String attName = "AF";
648  1 fc.setAttributeName(attName);
649   
650    /*
651    * first case: feature lacks the attribute - use 'no value' colour
652    */
653  1 SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
654    null);
655  1 assertEquals(Color.yellow, fc.getColor(sf));
656   
657    /*
658    * second case: attribute present but not numeric - treat as if absent
659    */
660  1 sf.setValue(attName, "twelve");
661  1 assertEquals(Color.yellow, fc.getColor(sf));
662   
663    /*
664    * third case: valid attribute value
665    */
666  1 sf.setValue(attName, "20.0");
667  1 Color expected = new Color(70, 120, 170);
668  1 assertEquals(expected, fc.getColor(sf));
669    }
670   
 
671  1 toggle @Test(groups = { "Functional" })
672    public void testIsOutwithThreshold()
673    {
674  1 FeatureColourI fc = new FeatureColour(Color.red);
675  1 SequenceFeature sf = new SequenceFeature("METAL", "desc", 10, 12, 1.2f,
676    "grp");
677  1 assertFalse(fc.isOutwithThreshold(null));
678  1 assertFalse(fc.isOutwithThreshold(sf));
679   
680  1 fc = new FeatureColour(null, Color.white, Color.black, Color.green, 0f,
681    10f);
682  1 assertFalse(fc.isOutwithThreshold(sf)); // no threshold
683   
684  1 fc.setAboveThreshold(true);
685  1 fc.setThreshold(1f);
686  1 assertFalse(fc.isOutwithThreshold(sf)); // feature score 1.2 is above 1
687   
688  1 fc.setThreshold(2f);
689  1 assertTrue(fc.isOutwithThreshold(sf)); // feature score 1.2 is not above 2
690   
691  1 fc.setBelowThreshold(true);
692  1 assertFalse(fc.isOutwithThreshold(sf)); // feature score 1.2 is below 2
693   
694  1 fc.setThreshold(1f);
695  1 assertTrue(fc.isOutwithThreshold(sf)); // feature score 1.2 is not below 1
696   
697    /*
698    * with attribute value threshold
699    */
700  1 fc.setAttributeName("AC");
701  1 assertFalse(fc.isOutwithThreshold(sf)); // missing attribute AC is ignored
702   
703  1 sf.setValue("AC", "-1");
704  1 assertFalse(fc.isOutwithThreshold(sf)); // value -1 is below 1
705   
706  1 sf.setValue("AC", "1");
707  1 assertTrue(fc.isOutwithThreshold(sf)); // value 1 is not below 1
708   
709  1 sf.setValue("AC", "junk");
710  1 assertFalse(fc.isOutwithThreshold(sf)); // bad value is ignored
711    }
712   
713    /**
714    * Test description of feature colour suitable for a tooltip
715    */
 
716  1 toggle @Test(groups = { "Functional" })
717    public void testGetDescription()
718    {
719    /*
720    * plain colour
721    */
722  1 FeatureColour fc = new FeatureColour(Color.RED);
723  1 assertEquals(
724    String.format("r=%d,g=%d,b=%d", Color.RED.getRed(),
725    Color.red.getGreen(), Color.red.getBlue()),
726    fc.getDescription());
727   
728    /*
729    * colour by label (no threshold)
730    */
731  1 fc = new FeatureColour();
732  1 fc.setColourByLabel(true);
733  1 assertEquals("By Label", fc.getDescription());
734   
735    /*
736    * colour by attribute text (no threshold)
737    */
738  1 fc = new FeatureColour();
739  1 fc.setColourByLabel(true);
740  1 fc.setAttributeName("CLIN_SIG");
741  1 assertEquals("By CLIN_SIG", fc.getDescription());
742   
743    /*
744    * colour by label (above score threshold)
745    */
746  1 fc = new FeatureColour();
747  1 fc.setColourByLabel(true);
748  1 fc.setAutoScaled(false);
749  1 fc.setThreshold(12.5f);
750  1 fc.setAboveThreshold(true);
751  1 assertEquals("By Label (Score > 12.5)", fc.getDescription());
752   
753    /*
754    * colour by label (below score threshold)
755    */
756  1 fc.setBelowThreshold(true);
757  1 assertEquals("By Label (Score < 12.5)", 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("By CSQ:Consequence (Score < 12.5)", fc.getDescription());
765   
766    /*
767    * graduated colour by score, no threshold
768    */
769  1 fc = new FeatureColour(null, Color.GREEN, Color.RED, null, 12f, 25f);
770  1 assertEquals("By Score", fc.getDescription());
771   
772    /*
773    * graduated colour by score, below threshold
774    */
775  1 fc.setThreshold(12.5f);
776  1 fc.setBelowThreshold(true);
777  1 assertEquals("By Score (< 12.5)", fc.getDescription());
778   
779    /*
780    * graduated colour by score, above threshold
781    */
782  1 fc.setThreshold(12.5f);
783  1 fc.setAboveThreshold(true);
784  1 fc.setAutoScaled(false);
785  1 assertEquals("By Score (> 12.5)", fc.getDescription());
786   
787    /*
788    * graduated colour by attribute, no threshold
789    */
790  1 fc.setAttributeName("CSQ", "AF");
791  1 fc.setAboveThreshold(false);
792  1 fc.setAutoScaled(false);
793  1 assertEquals("By CSQ:AF", fc.getDescription());
794   
795    /*
796    * graduated colour by attribute, above threshold
797    */
798  1 fc.setAboveThreshold(true);
799  1 fc.setAutoScaled(false);
800  1 assertEquals("By CSQ:AF (> 12.5)", fc.getDescription());
801    }
802    }