Clover icon

Coverage Report

  1. Project Clover database Tue Mar 10 2026 14:58:44 GMT
  2. Package jalview.gui

File AnnotationChooserTest.java

 

Code metrics

10
313
27
1
823
519
32
0.1
11.59
27
1.19

Classes

Class Line # Actions
AnnotationChooserTest 61 313 32
0.00%
 

Contributing tests

No tests hitting this source file were found.

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.gui;
22   
23    import static org.testng.AssertJUnit.assertEquals;
24    import static org.testng.AssertJUnit.assertFalse;
25    import static org.testng.AssertJUnit.assertTrue;
26   
27    import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
28    import jalview.bin.Cache;
29    import jalview.datamodel.AlignmentAnnotation;
30    import jalview.datamodel.AlignmentI;
31    import jalview.datamodel.Annotation;
32    import jalview.datamodel.SequenceGroup;
33    import jalview.datamodel.SequenceI;
34    import jalview.io.DataSourceType;
35    import jalview.io.FileFormat;
36    import jalview.io.FormatAdapter;
37    import jalview.util.MessageManager;
38   
39    import java.awt.BorderLayout;
40    import java.awt.Checkbox;
41    import java.awt.Component;
42    import java.awt.Container;
43    import java.awt.FlowLayout;
44    import java.awt.event.ItemEvent;
45    import java.io.IOException;
46    import java.util.List;
47   
48    import javax.swing.JButton;
49    import javax.swing.JPanel;
50   
51    import org.testng.annotations.BeforeClass;
52    import org.testng.annotations.BeforeMethod;
53    import org.testng.annotations.Test;
54   
55    /**
56    * Unit tests for AnnotationChooser
57    *
58    * @author gmcarstairs
59    *
60    */
 
61    public class AnnotationChooserTest
62    {
63   
 
64  0 toggle @BeforeClass(alwaysRun = true)
65    public void setUpJvOptionPane()
66    {
67  0 JvOptionPane.setInteractiveMode(false);
68  0 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
69    }
70   
71    // 4 sequences x 13 positions
72    final static String TEST_DATA = ">FER_CAPAA Ferredoxin\n"
73    + "TIETHKEAELVG-\n"
74    + ">FER_CAPAN Ferredoxin, chloroplast precursor\n"
75    + "TIETHKEAELVG-\n"
76    + ">FER1_SOLLC Ferredoxin-1, chloroplast precursor\n"
77    + "TIETHKEEELTA-\n" + ">Q93XJ9_SOLTU Ferredoxin I precursor\n"
78    + "TIETHKEEELTA-\n";
79   
80    AnnotationChooser testee;
81   
82    AlignmentPanel parentPanel;
83   
84    AlignFrame af;
85   
 
86  0 toggle @BeforeMethod(alwaysRun = true)
87    public void setUp() throws IOException
88    {
89  0 Cache.loadProperties("test/jalview/io/testProps.jvprops");
90    // pin down annotation sort order for test
91  0 Cache.setPropertyNoSave(Preferences.SORT_ANNOTATIONS,
92    SequenceAnnotationOrder.NONE.name());
93  0 final String TRUE = Boolean.TRUE.toString();
94  0 Cache.setPropertyNoSave(
95    Preferences.SHOW_AUTOCALC_ABOVE, TRUE);
96  0 Cache.setPropertyNoSave("SHOW_QUALITY", TRUE);
97  0 Cache.setPropertyNoSave("SHOW_CONSERVATION", TRUE);
98  0 Cache.setPropertyNoSave("SHOW_IDENTITY", TRUE);
99   
100  0 AlignmentI al = new FormatAdapter().readFile(TEST_DATA,
101    DataSourceType.PASTE, FileFormat.Fasta);
102  0 af = new AlignFrame(al, 700, 500);
103  0 parentPanel = new AlignmentPanel(af, af.getViewport());
104  0 addAnnotations();
105    }
106   
107    /**
108    * Add 4 annotations, 3 of them sequence-specific.
109    *
110    * <PRE>
111    * ann1 - for sequence 0 - label 'IUPRED'
112    * ann2 - not sequence related - label 'Beauty'
113    * ann3 - for sequence 3 - label 'JMol'
114    * ann4 - for sequence 2 - label 'IUPRED'
115    * ann5 - for sequence 1 - label 'JMol'
116    */
 
117  0 toggle private void addAnnotations()
118    {
119  0 Annotation an = new Annotation(2f);
120  0 Annotation[] anns = new Annotation[] { an, an, an };
121  0 AlignmentAnnotation ann0 = new AlignmentAnnotation("IUPRED", "", anns);
122  0 AlignmentAnnotation ann1 = new AlignmentAnnotation("Beauty", "", anns);
123  0 AlignmentAnnotation ann2 = new AlignmentAnnotation("JMol", "", anns);
124  0 AlignmentAnnotation ann3 = new AlignmentAnnotation("IUPRED", "", anns);
125  0 AlignmentAnnotation ann4 = new AlignmentAnnotation("JMol", "", anns);
126  0 SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray();
127  0 ann0.setSequenceRef(seqs[0]);
128  0 ann2.setSequenceRef(seqs[3]);
129  0 ann3.setSequenceRef(seqs[2]);
130  0 ann4.setSequenceRef(seqs[1]);
131  0 parentPanel.getAlignment().addAnnotation(ann0);
132  0 parentPanel.getAlignment().addAnnotation(ann1);
133  0 parentPanel.getAlignment().addAnnotation(ann2);
134  0 parentPanel.getAlignment().addAnnotation(ann3);
135  0 parentPanel.getAlignment().addAnnotation(ann4);
136    }
137   
138    /**
139    * Test creation of panel with OK and Cancel buttons
140    */
 
141  0 toggle @Test(groups = { "Functional" })
142    public void testBuildActionButtonsPanel()
143    {
144  0 testee = new AnnotationChooser(parentPanel);
145  0 JPanel jp = testee.buildActionButtonsPanel();
146  0 assertTrue("Wrong layout", jp.getLayout() instanceof FlowLayout);
147   
148  0 Component[] comps = jp.getComponents();
149  0 assertEquals("Not 2 action buttons", 2, comps.length);
150   
151  0 final Component jb1 = comps[0];
152  0 final Component jb2 = comps[1];
153   
154  0 assertEquals("Not 'OK' button", MessageManager.getString("action.ok"),
155    ((JButton) jb1).getText());
156  0 assertEquals("Wrong button font", JvSwingUtils.getLabelFont(),
157    jb1.getFont());
158   
159  0 assertEquals("Not 'Cancel' button",
160    MessageManager.getString("action.cancel"),
161    ((JButton) jb2).getText());
162  0 assertEquals("Wrong button font", JvSwingUtils.getLabelFont(),
163    jb2.getFont());
164    }
165   
166    /**
167    * Test 'Apply to' has 3 radio buttons enabled, 'Selected Sequences' selected,
168    * when there is a current selection group.
169    */
 
170  0 toggle @Test(groups = { "Functional" })
171    public void testBuildApplyToOptionsPanel_withSelectionGroup()
172    {
173  0 selectSequences(0, 2, 3);
174  0 testee = new AnnotationChooser(parentPanel);
175   
176  0 JPanel jp = testee.buildApplyToOptionsPanel();
177  0 Component[] comps = jp.getComponents();
178  0 assertEquals("Not 3 radio buttons", 3, comps.length);
179   
180  0 final Checkbox cb1 = (Checkbox) comps[0];
181  0 final Checkbox cb2 = (Checkbox) comps[1];
182  0 final Checkbox cb3 = (Checkbox) comps[2];
183   
184  0 assertTrue("Not enabled", cb1.isEnabled());
185  0 assertTrue("Not enabled", cb2.isEnabled());
186  0 assertTrue("Not enabled", cb3.isEnabled());
187  0 assertEquals("Option not selected", cb2, cb2.getCheckboxGroup()
188    .getSelectedCheckbox());
189   
190    // check state variables match checkbox selection
191  0 assertTrue(testee.isApplyToSelectedSequences());
192  0 assertFalse(testee.isApplyToUnselectedSequences());
193    }
194   
195    /**
196    * Add a sequence group to the alignment with the specified sequences (base 0)
197    * in it
198    *
199    * @param i
200    * @param more
201    */
 
202  0 toggle private void selectSequences(int... selected)
203    {
204  0 SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray();
205  0 SequenceGroup sg = new SequenceGroup();
206  0 for (int i : selected)
207    {
208  0 sg.addSequence(seqs[i], false);
209    }
210  0 parentPanel.av.setSelectionGroup(sg);
211    }
212   
213    /**
214    * Test 'Apply to' has 1 radio button enabled, 'All Sequences' selected, when
215    * there is no current selection group.
216    */
 
217  0 toggle @Test(groups = { "Functional" })
218    public void testBuildApplyToOptionsPanel_noSelectionGroup()
219    {
220  0 testee = new AnnotationChooser(parentPanel);
221  0 JPanel jp = testee.buildApplyToOptionsPanel();
222  0 verifyApplyToOptionsPanel_noSelectionGroup(jp);
223    }
224   
 
225  0 toggle protected void verifyApplyToOptionsPanel_noSelectionGroup(JPanel jp)
226    {
227  0 assertTrue("Wrong layout", jp.getLayout() instanceof FlowLayout);
228  0 Component[] comps = jp.getComponents();
229  0 assertEquals("Not 3 radio buttons", 3, comps.length);
230   
231  0 final Checkbox cb1 = (Checkbox) comps[0];
232  0 final Checkbox cb2 = (Checkbox) comps[1];
233  0 final Checkbox cb3 = (Checkbox) comps[2];
234   
235  0 assertTrue("Not enabled", cb1.isEnabled());
236  0 assertFalse("Enabled", cb2.isEnabled());
237  0 assertFalse("Enabled", cb3.isEnabled());
238  0 assertEquals("Not selected", cb1, cb1.getCheckboxGroup()
239    .getSelectedCheckbox());
240   
241    // check state variables match checkbox selection
242  0 assertTrue(testee.isApplyToSelectedSequences());
243  0 assertTrue(testee.isApplyToUnselectedSequences());
244   
245  0 assertEquals("Wrong text",
246    MessageManager.getString("label.all_sequences"), cb1.getLabel());
247  0 assertEquals("Wrong text",
248    MessageManager.getString("label.selected_sequences"),
249    cb2.getLabel());
250  0 assertEquals("Wrong text",
251    MessageManager.getString("label.except_selected_sequences"),
252    cb3.getLabel());
253    }
254   
255    /**
256    * Test Show and Hide radio buttons created, with Hide initially selected.
257    */
 
258  0 toggle @Test(groups = { "Functional" })
259    public void testBuildShowHidePanel()
260    {
261  0 testee = new AnnotationChooser(parentPanel);
262  0 JPanel jp = testee.buildShowHidePanel();
263  0 verifyShowHidePanel(jp);
264   
265    }
266   
 
267  0 toggle protected void verifyShowHidePanel(JPanel jp)
268    {
269  0 assertTrue("Wrong layout", jp.getLayout() instanceof FlowLayout);
270  0 Component[] comps = jp.getComponents();
271  0 assertEquals("Not 2 radio buttons", 2, comps.length);
272   
273  0 final Checkbox cb1 = (Checkbox) comps[0];
274  0 final Checkbox cb2 = (Checkbox) comps[1];
275   
276  0 assertTrue("Show not enabled", cb1.isEnabled());
277  0 assertTrue("Hide not enabled", cb2.isEnabled());
278   
279    // Hide (button 2) selected; note this may change to none (null)
280  0 assertEquals("Not selected", cb2, cb2.getCheckboxGroup()
281    .getSelectedCheckbox());
282   
283  0 assertTrue("Show is flagged", !testee.isShowSelected());
284   
285  0 assertEquals("Wrong text",
286    MessageManager.getString("label.show_selected_annotations"),
287    cb1.getLabel());
288  0 assertEquals("Wrong text",
289    MessageManager.getString("label.hide_selected_annotations"),
290    cb2.getLabel());
291    }
292   
293    /**
294    * Test construction of panel containing two sub-panels
295    */
 
296  0 toggle @Test(groups = { "Functional" })
297    public void testBuildShowHideOptionsPanel()
298    {
299  0 testee = new AnnotationChooser(parentPanel);
300  0 JPanel jp = testee.buildShowHideOptionsPanel();
301  0 assertTrue("Wrong layout", jp.getLayout() instanceof BorderLayout);
302  0 Component[] comps = jp.getComponents();
303  0 assertEquals("Not 2 sub-panels", 2, comps.length);
304   
305  0 verifyShowHidePanel((JPanel) comps[0]);
306  0 verifyApplyToOptionsPanel_noSelectionGroup((JPanel) comps[1]);
307    }
308   
309    /**
310    * Test that annotation types are (uniquely) identified.
311    *
312    */
 
313  0 toggle @Test(groups = { "Functional" })
314    public void testGetAnnotationTypes()
315    {
316  0 selectSequences(1);
317  0 testee = new AnnotationChooser(parentPanel);
318    // selection group should make no difference to the result
319    // as all annotation types for the alignment are considered
320   
321  0 List<String> types = AnnotationChooser.getAnnotationTypes(
322    parentPanel.getAlignment(), true);
323  0 assertEquals("Not two annotation types", 2, types.size());
324  0 assertTrue("IUPRED missing", types.contains("IUPRED"));
325  0 assertTrue("JMol missing", types.contains("JMol"));
326   
327  0 types = AnnotationChooser.getAnnotationTypes(
328    parentPanel.getAlignment(), false);
329  0 assertEquals("Not six annotation types", 7, types.size());
330  0 assertTrue("IUPRED missing", types.contains("IUPRED"));
331  0 assertTrue("JMol missing", types.contains("JMol"));
332  0 assertTrue("Beauty missing", types.contains("Beauty"));
333    // These are added by viewmodel.AlignViewport.initAutoAnnotation():
334  0 assertTrue("Consensus missing", types.contains("Consensus"));
335  0 assertTrue("Quality missing", types.contains("Quality"));
336  0 assertTrue("Conservation missing", types.contains("Conservation"));
337  0 assertTrue("Occupancy missing", types.contains("Occupancy"));
338    }
339   
340    /**
341    * Test result of selecting an annotation type, with 'Hide for all sequences'.
342    *
343    * We expect all annotations of that type to be set hidden. Other annotations
344    * should be left visible.
345    */
 
346  0 toggle @Test(groups = { "Functional" })
347    public void testSelectType_hideForAll()
348    {
349  0 selectSequences(1, 2);
350  0 testee = new AnnotationChooser(parentPanel);
351  0 final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
352  0 setSelected(hideCheckbox, true);
353   
354  0 final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
355    1, 1, 0);
356  0 setSelected(allSequencesCheckbox, true);
357   
358  0 AlignmentAnnotation[] anns = parentPanel.getAlignment()
359    .getAlignmentAnnotation();
360   
361  0 int autocalc = countAutocalc(anns);
362  0 assertTrue(anns[autocalc + 2].visible); // JMol for seq3
363  0 assertTrue(anns[autocalc + 4].visible); // JMol for seq1
364   
365  0 setSelected(getTypeCheckbox("JMol"), true);
366  0 assertTrue(anns[0].visible); // Conservation
367  0 assertTrue(anns[1].visible); // Quality
368  0 assertTrue(anns[2].visible); // Consensus
369  0 assertTrue(anns[3].visible); // Occupancy
370  0 assertTrue(anns[4].visible); // IUPred for seq0
371  0 assertTrue(anns[5].visible); // Beauty
372  0 assertFalse(anns[6].visible); // JMol for seq3 - not selected but hidden
373  0 assertTrue(anns[7].visible); // IUPRED for seq2
374  0 assertFalse(anns[8].visible); // JMol for seq1 - selected and hidden
375    }
376   
377    /**
378    * Test result of selecting an annotation type, with 'Hide for selected
379    * sequences'.
380    *
381    * We expect the annotations of that type, linked to the sequence group, to be
382    * set hidden. Other annotations should be left visible.
383    */
 
384  0 toggle @Test(groups = { "Functional" })
385    public void testSelectType_hideForSelected()
386    {
387  0 selectSequences(1, 2);
388  0 testee = new AnnotationChooser(parentPanel);
389  0 final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
390  0 setSelected(hideCheckbox, true);
391   
392    /*
393    * Don't set the 'selected sequences' radio button since this would trigger
394    * an update, including unselected sequences / annotation types
395    */
396    // setSelected(getSelectedSequencesCheckbox());
397   
398  0 AlignmentAnnotation[] anns = parentPanel.getAlignment()
399    .getAlignmentAnnotation();
400   
401  0 int autocalc = countAutocalc(anns);
402  0 assertTrue(anns[autocalc + 4].visible); // JMol for seq1
403   
404  0 setSelected(getTypeCheckbox("JMol"), true);
405  0 assertTrue(anns[0].visible); // Conservation
406  0 assertTrue(anns[1].visible); // Quality
407  0 assertTrue(anns[2].visible); // Consensus
408  0 assertTrue(anns[3].visible); // Occupancy
409  0 assertTrue(anns[4].visible); // IUPred for seq0
410  0 assertTrue(anns[5].visible); // Beauty
411  0 assertTrue(anns[6].visible); // JMol for seq3 not in selection group
412  0 assertTrue(anns[7].visible); // IUPRED for seq2
413  0 assertFalse(anns[8].visible); // JMol for seq1 in selection group
414    }
415   
416    /**
417    * Test result of deselecting an annotation type, with 'Hide for all
418    * sequences'.
419    *
420    * We expect all annotations of that type to be set visible. Other annotations
421    * should be left unchanged.
422    */
 
423  0 toggle @Test(groups = { "Functional" })
424    public void testDeselectType_hideForAll()
425    {
426  0 selectSequences(1, 2);
427  0 testee = new AnnotationChooser(parentPanel);
428   
429  0 final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
430  0 setSelected(hideCheckbox, true);
431   
432  0 final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
433    1, 1, 0);
434  0 setSelected(allSequencesCheckbox, true);
435   
436  0 AlignmentAnnotation[] anns = parentPanel.getAlignment()
437    .getAlignmentAnnotation();
438   
439  0 final Checkbox typeCheckbox = getTypeCheckbox("JMol");
440   
441    // select JMol - all hidden
442  0 setSelected(typeCheckbox, true);
443  0 int autocalc = countAutocalc(anns);
444  0 assertFalse(anns[autocalc + 2].visible); // JMol for seq3
445  0 assertFalse(anns[autocalc + 4].visible); // JMol for seq1
446   
447    // deselect JMol - all unhidden
448  0 setSelected(typeCheckbox, false);
449  0 for (AlignmentAnnotation ann : anns)
450    {
451  0 assertTrue(ann.visible);
452    }
453    }
454   
455    /**
456    * Returns a count of autocalculated annotations in the set provided
457    *
458    * @param anns
459    * @return
460    */
 
461  0 toggle private int countAutocalc(AlignmentAnnotation[] anns)
462    {
463  0 int count = 0;
464  0 for (AlignmentAnnotation ann : anns)
465    {
466  0 if (ann.autoCalculated)
467    {
468  0 count++;
469    }
470    }
471  0 return count;
472    }
473   
474    /**
475    * Test result of deselecting an annotation type, with 'Hide for selected
476    * sequences'.
477    *
478    * We expect the annotations of that type, linked to the sequence group, to be
479    * set visible. Other annotations should be left unchanged.
480    */
 
481  0 toggle @Test(groups = { "Functional" })
482    public void testDeselectType_hideForSelected()
483    {
484  0 selectSequences(1, 2);
485  0 testee = new AnnotationChooser(parentPanel);
486  0 final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
487  0 setSelected(hideCheckbox, true);
488   
489    /*
490    * Don't set the 'selected sequences' radio button since this would trigger
491    * an update, including unselected sequences / annotation types
492    */
493    // setSelected(getSelectedSequencesCheckbox());
494   
495  0 setSelected(getTypeCheckbox("JMol"), true);
496  0 setSelected(getTypeCheckbox("JMol"), false);
497   
498  0 AlignmentAnnotation[] anns = parentPanel.getAlignment()
499    .getAlignmentAnnotation();
500  0 assertTrue(anns[0].visible); // Conservation
501  0 assertTrue(anns[1].visible); // Quality
502  0 assertTrue(anns[2].visible); // Consensus
503  0 assertTrue(anns[3].visible); // IUPred for seq0
504  0 assertTrue(anns[4].visible); // Beauty
505  0 assertTrue(anns[5].visible); // JMol for seq3 not in selection group
506  0 assertTrue(anns[6].visible); // IUPRED for seq2
507  0 assertTrue(anns[7].visible); // JMol for seq1 in selection group
508    }
509   
510    /**
511    * Test result of selecting an annotation type, with 'Show for all sequences'.
512    *
513    * We expect all annotations of that type to be set visible. Other annotations
514    * should be left unchanged
515    */
 
516  0 toggle @Test(groups = { "Functional" })
517    public void testSelectType_showForAll()
518    {
519  0 selectSequences(1, 2);
520  0 testee = new AnnotationChooser(parentPanel);
521  0 final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0);
522  0 final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
523   
524  0 final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
525    1, 1, 0);
526   
527  0 AlignmentAnnotation[] anns = parentPanel.getAlignment()
528    .getAlignmentAnnotation();
529   
530    // hide all JMol annotations
531  0 setSelected(allSequencesCheckbox, true);
532  0 setSelected(hideCheckbox, true);
533  0 setSelected(getTypeCheckbox("JMol"), true);
534  0 int autocalc = countAutocalc(anns);
535  0 assertFalse(anns[autocalc + 2].visible); // JMol for seq3
536  0 assertFalse(anns[autocalc + 4].visible); // JMol for seq1
537    // ...now show them...
538  0 setSelected(showCheckbox, true);
539  0 for (AlignmentAnnotation ann : anns)
540    {
541  0 assertTrue(ann.visible);
542    }
543    }
544   
545    /**
546    * Test result of selecting an annotation type, with 'Show for selected
547    * sequences'.
548    *
549    * We expect all annotations of that type, linked to the sequence group, to be
550    * set visible. Other annotations should be left unchanged
551    */
 
552  0 toggle @Test(groups = { "Functional" })
553    public void testSelectType_showForSelected()
554    {
555    // sequences 1 and 2 have annotations IUPred and Jmol
556  0 selectSequences(1, 2);
557  0 testee = new AnnotationChooser(parentPanel);
558  0 final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0);
559  0 final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
560   
561  0 final Checkbox selectedSequencesCheckbox = (Checkbox) getComponent(
562    testee, 1, 1, 1);
563   
564  0 AlignmentAnnotation[] anns = parentPanel.getAlignment()
565    .getAlignmentAnnotation();
566   
567    // hide all JMol annotations in the selection region (== annotation 7)
568  0 setSelected(selectedSequencesCheckbox, true);
569  0 setSelected(hideCheckbox, true);
570  0 setSelected(getTypeCheckbox("JMol"), true);
571   
572  0 int autocalc = countAutocalc(anns);
573  0 assertTrue(anns[autocalc + 2].visible); // JMol for seq3
574  0 assertFalse(anns[autocalc + 4].visible); // JMol for seq1
575    // ...now show them...
576  0 setSelected(showCheckbox, true);
577   
578  0 for (AlignmentAnnotation ann : anns)
579    {
580  0 assertTrue(ann.visible);
581    }
582    }
583   
584    /**
585    * Test result of deselecting an annotation type, with 'Show for all
586    * sequences'.
587    *
588    * We expect all annotations of that type to be set hidden. Other annotations
589    * should be left unchanged.
590    */
 
591  0 toggle @Test(groups = { "Functional" })
592    public void testDeselectType_showForAll()
593    {
594  0 selectSequences(1, 2);
595  0 testee = new AnnotationChooser(parentPanel);
596   
597  0 final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0);
598  0 setSelected(showCheckbox, true);
599   
600  0 final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
601    1, 1, 0);
602  0 setSelected(allSequencesCheckbox, true);
603   
604  0 AlignmentAnnotation[] anns = parentPanel.getAlignment()
605    .getAlignmentAnnotation();
606   
607  0 final Checkbox typeCheckbox = getTypeCheckbox("JMol");
608    // select JMol - all shown
609  0 setSelected(typeCheckbox, true);
610  0 int autocalc = countAutocalc(anns);
611  0 assertTrue(anns[autocalc + 2].visible); // JMol for seq3
612  0 assertTrue(anns[autocalc + 4].visible); // JMol for seq1
613   
614    // deselect JMol - all hidden
615  0 setSelected(typeCheckbox, false);
616  0 assertTrue(anns[0].visible); // Conservation
617  0 assertTrue(anns[1].visible); // Quality
618  0 assertTrue(anns[2].visible); // Consensus
619  0 assertTrue(anns[3].visible); // Occupancy
620  0 assertTrue(anns[4].visible); // IUPred for seq0
621  0 assertTrue(anns[5].visible); // Beauty
622  0 assertFalse(anns[6].visible); // JMol for seq3
623  0 assertTrue(anns[7].visible); // IUPRED for seq2
624  0 assertFalse(anns[8].visible); // JMol for seq1
625    }
626   
627    /**
628    * Test result of deselecting an annotation type, with 'Show for selected
629    * sequences'.
630    *
631    * We expect the annotations of that type, linked to the sequence group, to be
632    * set hidden. Other annotations should be left unchanged.
633    */
 
634  0 toggle @Test(groups = { "Functional" })
635    public void testDeselectType_showForSelected()
636    {
637  0 selectSequences(1, 2);
638  0 testee = new AnnotationChooser(parentPanel);
639  0 final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0);
640  0 setSelected(showCheckbox, true);
641   
642    /*
643    * Don't set the 'selected sequences' radio button since this would trigger
644    * an update, including unselected sequences / annotation types
645    */
646    // setSelected(getSelectedSequencesCheckbox());
647   
648  0 AlignmentAnnotation[] anns = parentPanel.getAlignment()
649    .getAlignmentAnnotation();
650   
651    // select JMol - should remain visible
652  0 setSelected(getTypeCheckbox("JMol"), true);
653  0 int autocalc = countAutocalc(anns);
654  0 assertTrue(anns[autocalc + 2].visible); // JMol for seq3
655  0 assertTrue(anns[autocalc + 4].visible); // JMol for seq1
656   
657    // deselect JMol - should be hidden for selected sequences only
658  0 setSelected(getTypeCheckbox("JMol"), false);
659  0 assertTrue(anns[0].visible); // Conservation
660  0 assertTrue(anns[1].visible); // Quality
661  0 assertTrue(anns[2].visible); // Consensus
662  0 assertTrue(anns[3].visible); // Occupancy
663  0 assertTrue(anns[4].visible); // IUPred for seq0
664  0 assertTrue(anns[5].visible); // Beauty
665  0 assertTrue(anns[6].visible); // JMol for seq3 not in selection group
666  0 assertTrue(anns[7].visible); // IUPRED for seq2
667  0 assertFalse(anns[8].visible); // JMol for seq1 in selection group
668    }
669   
670    /**
671    * Helper method to drill down to a sub-component in a Container hierarchy.
672    *
673    * @param cont
674    * @param i
675    * @param j
676    * @param k
677    * @return
678    */
 
679  0 toggle public static Component getComponent(Container cont, int... positions)
680    {
681  0 Component comp = cont;
682  0 for (int i : positions)
683    {
684  0 comp = ((Container) comp).getComponent(i);
685    }
686  0 return comp;
687    }
688   
689    /**
690    * Helper method to set or unset a checkbox and fire its action listener.
691    *
692    * @param cb
693    * @param select
694    */
 
695  0 toggle protected void setSelected(Checkbox cb, boolean select)
696    {
697    // TODO refactor to a test utility class
698  0 cb.setState(select);
699    // have to manually fire the action listener
700  0 cb.getItemListeners()[0].itemStateChanged(new ItemEvent(cb,
701  0 ItemEvent.ITEM_STATE_CHANGED, cb, select ? ItemEvent.SELECTED
702    : ItemEvent.DESELECTED));
703    }
704   
705    /**
706    * Helper method to drill down to the 'Annotation type' checkbox with given
707    * label.
708    *
709    * @return
710    */
 
711  0 toggle private Checkbox getTypeCheckbox(String forLabel)
712    {
713  0 Component[] cbs = ((JPanel) testee.getComponent(0)).getComponents();
714  0 for (Component comp : cbs)
715    {
716  0 final Checkbox cb = (Checkbox) comp;
717  0 if (cb.getLabel().equals(forLabel))
718    {
719  0 return cb;
720    }
721    }
722  0 return null;
723    }
724   
725    /**
726    * Test isInActionScope for the case where the scope is selected sequences.
727    * Test cases include sequences in the selection group, and others not in the
728    * group.
729    */
 
730  0 toggle @Test(groups = { "Functional" })
731    public void testIsInActionScope_selectedScope()
732    {
733    // sequences 1 and 2 have annotations 4 and 3 respectively
734  0 selectSequences(1, 2);
735  0 testee = new AnnotationChooser(parentPanel);
736   
737  0 final Checkbox selectedSequencesCheckbox = (Checkbox) getComponent(
738    testee, 1, 1, 1);
739  0 setSelected(selectedSequencesCheckbox, true);
740   
741  0 AlignmentAnnotation[] anns = parentPanel.getAlignment()
742    .getAlignmentAnnotation();
743  0 int autocalc = countAutocalc(anns);
744  0 assertFalse(testee.isInActionScope(anns[autocalc]));
745  0 assertFalse(testee.isInActionScope(anns[autocalc + 1]));
746  0 assertFalse(testee.isInActionScope(anns[autocalc + 2]));
747  0 assertTrue(testee.isInActionScope(anns[autocalc + 3]));
748  0 assertTrue(testee.isInActionScope(anns[autocalc + 4]));
749    }
750   
751    /**
752    * Test isInActionScope for the case where the scope is unselected sequences.
753    * Test cases include sequences in the selection group, and others not in the
754    * group.
755    */
 
756  0 toggle @Test(groups = { "Functional" })
757    public void testIsInActionScope_unselectedScope()
758    {
759    // sequences 1 and 2 have annotations 4 and 3 respectively
760  0 selectSequences(1, 2);
761  0 testee = new AnnotationChooser(parentPanel);
762   
763  0 final Checkbox unselectedSequencesCheckbox = (Checkbox) getComponent(
764    testee, 1, 1, 2);
765  0 setSelected(unselectedSequencesCheckbox, true);
766   
767  0 AlignmentAnnotation[] anns = parentPanel.getAlignment()
768    .getAlignmentAnnotation();
769  0 int autocalc = countAutocalc(anns);
770  0 assertTrue(testee.isInActionScope(anns[autocalc]));
771  0 assertTrue(testee.isInActionScope(anns[autocalc + 1]));
772  0 assertTrue(testee.isInActionScope(anns[autocalc + 2]));
773  0 assertFalse(testee.isInActionScope(anns[autocalc + 3]));
774  0 assertFalse(testee.isInActionScope(anns[autocalc + 4]));
775    }
776   
777    /**
778    * Test that the reset method restores previous visibility flags.
779    */
 
780  0 toggle @Test(groups = { "Functional" })
781    public void testResetOriginalState()
782    {
783  0 testee = new AnnotationChooser(parentPanel);
784   
785  0 AlignmentAnnotation[] anns = parentPanel.getAlignment()
786    .getAlignmentAnnotation();
787    // all start visible
788  0 for (int i = 0; i < anns.length; i++)
789    {
790  0 assertTrue(i + "'th sequence not visible", anns[i].visible);
791    }
792   
793    /*
794    * check options to hide JMol and IUPRED annotations for all sequences
795    */
796  0 final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
797  0 setSelected(hideCheckbox, true);
798   
799  0 final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
800    1, 1, 0);
801  0 setSelected(allSequencesCheckbox, true);
802   
803  0 setSelected(getTypeCheckbox("JMol"), true);
804  0 setSelected(getTypeCheckbox("IUPRED"), true);
805   
806  0 assertTrue(anns[0].visible); // Conservation
807  0 assertTrue(anns[1].visible); // Quality
808  0 assertTrue(anns[2].visible); // Consensus
809  0 assertTrue(anns[3].visible); // Occupancy
810  0 assertFalse(anns[4].visible); // IUPRED
811  0 assertTrue(anns[5].visible); // Beauty (not seq-related)
812  0 assertFalse(anns[6].visible); // JMol
813  0 assertFalse(anns[7].visible); // IUPRED
814  0 assertFalse(anns[8].visible); // JMol
815   
816    // reset - should all be visible
817  0 testee.resetOriginalState();
818  0 for (int i = 0; i < anns.length; i++)
819    {
820  0 assertTrue(i + "'th sequence not visible", anns[i].visible);
821    }
822    }
823    }