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