JAL-1264 unit tests
[jalview.git] / test / jalview / gui / PopupMenuTest.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.SequenceGroup;
9 import jalview.datamodel.SequenceI;
10 import jalview.io.AppletFormatAdapter;
11
12 import java.io.IOException;
13 import java.util.BitSet;
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Map;
17
18 import org.junit.Before;
19 import org.junit.Test;
20
21 /**
22  * Unit tests for PopupMenu
23  * 
24  * @author gmcarstairs
25  *
26  */
27 public class PopupMenuTest
28 {
29   // 4 sequences x 13 positions
30   final static String TEST_DATA = ">FER_CAPAA Ferredoxin\n"
31           + "TIETHKEAELVG-\n"
32           + ">FER_CAPAN Ferredoxin, chloroplast precursor\n"
33           + "TIETHKEAELVG-\n"
34           + ">FER1_SOLLC Ferredoxin-1, chloroplast precursor\n"
35           + "TIETHKEEELTA-\n" + ">Q93XJ9_SOLTU Ferredoxin I precursor\n"
36           + "TIETHKEEELTA-\n";
37
38   private static final int SEQ_ANN_COUNT = 10;
39
40   private static final int AUTO_ANNS = 3;
41
42   AlignmentI alignment;
43
44   AlignmentPanel parentPanel;
45
46   @Before
47   public void setUp() throws IOException
48   {
49     AlignmentI al = new jalview.io.FormatAdapter().readFile(TEST_DATA,
50             AppletFormatAdapter.PASTE, "FASTA");
51     AlignFrame af = new AlignFrame(al, 700, 500);
52     parentPanel = new AlignmentPanel(af, af.getViewport());
53     alignment = parentPanel.getAlignment();
54
55     AlignmentAnnotation[] anns = new AlignmentAnnotation[SEQ_ANN_COUNT];
56     for (int i = 0; i < anns.length; i++)
57     {
58       anns[i] = new AlignmentAnnotation("Label" + i, null, 0d);
59       anns[i].setCalcId("CalcId" + i);
60       anns[i].visible = true;
61       alignment.addAnnotation(anns[i]);
62     }
63   }
64
65   /**
66    * Test method that determines visible graph groups.
67    */
68   @Test
69   public void testGetVisibleGraphGroups()
70   {
71     AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
72     /*
73      * a bar graph group is not included
74      */
75     anns[0].graph = AlignmentAnnotation.BAR_GRAPH;
76     anns[0].graphGroup = 1;
77     anns[0].visible = true;
78
79     /*
80      * a line graph group is included as long as one of its members is visible
81      */
82     anns[1].graph = AlignmentAnnotation.LINE_GRAPH;
83     anns[1].graphGroup = 5;
84     anns[1].visible = false;
85     anns[2].graph = AlignmentAnnotation.LINE_GRAPH;
86     anns[2].graphGroup = 5;
87     anns[2].visible = true;
88
89     /*
90      * a line graph group with no visible rows is not included
91      */
92     anns[3].graph = AlignmentAnnotation.LINE_GRAPH;
93     anns[3].graphGroup = 3;
94     anns[3].visible = false;
95
96     // a visible line graph with no graph group is not included
97     anns[4].graph = AlignmentAnnotation.LINE_GRAPH;
98     anns[4].graphGroup = -1;
99     anns[4].visible = true;
100
101     BitSet result = PopupMenu.getVisibleLineGraphGroups(anns);
102     assertTrue(result.get(5));
103     assertFalse(result.get(0));
104     assertFalse(result.get(1));
105     assertFalse(result.get(2));
106     assertFalse(result.get(3));
107   }
108
109   /**
110    * Test a mixture of show/hidden annotations in/outside selection group.
111    */
112   @Test
113   public void testGetAnnotationTypesForShowHide_forSelectionGroup()
114   {
115     Map<String, List<List<String>>> shownTypes = new HashMap<String, List<List<String>>>();
116     Map<String, List<List<String>>> hiddenTypes = new HashMap<String, List<List<String>>>();
117     AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
118     BitSet visibleGraphGroups = new BitSet();
119     selectSequences(0, 3);
120     SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray();
121
122     /*
123      * Configure annotation properties for test (offsetting for auto-calculated
124      * rows).
125      */
126     // not in selection group (should be ignored):
127     // hidden annotation Label4 not in selection group
128     anns[AUTO_ANNS + 4].sequenceRef = seqs[2];
129     anns[AUTO_ANNS + 4].visible = false;
130     anns[AUTO_ANNS + 7].sequenceRef = seqs[1];
131     anns[AUTO_ANNS + 7].visible = true;
132
133     /*
134      * in selection group, hidden:
135      */
136     anns[AUTO_ANNS + 2].sequenceRef = seqs[3]; // CalcId2/Label2
137     anns[AUTO_ANNS + 2].visible = false;
138     anns[AUTO_ANNS + 3].sequenceRef = seqs[3]; // CalcId3/Label2
139     anns[AUTO_ANNS + 3].visible = false;
140     anns[AUTO_ANNS + 3].label = "Label2";
141     anns[AUTO_ANNS + 4].sequenceRef = seqs[3]; // CalcId2/Label3
142     anns[AUTO_ANNS + 4].visible = false;
143     anns[AUTO_ANNS + 4].label = "Label3";
144     anns[AUTO_ANNS + 4].setCalcId("CalcId2");
145     anns[AUTO_ANNS + 8].sequenceRef = seqs[0]; // CalcId9/Label9
146     anns[AUTO_ANNS + 8].visible = false;
147     anns[AUTO_ANNS + 8].label = "Label9";
148     anns[AUTO_ANNS + 8].setCalcId("CalcId9");
149     /*
150      * in selection group, visible
151      */
152     anns[AUTO_ANNS + 6].sequenceRef = seqs[0]; // CalcId6/Label6
153     anns[AUTO_ANNS + 6].visible = true;
154     anns[AUTO_ANNS + 9].sequenceRef = seqs[3]; // CalcId9/Label9
155     anns[AUTO_ANNS + 9].visible = true;
156
157     PopupMenu.getAnnotationTypesForShowHide(shownTypes, hiddenTypes,
158             visibleGraphGroups, anns, parentPanel.av.getSelectionGroup());
159
160     // check results; note CalcId9/Label9 is both hidden and shown (for
161     // different sequences) so should be in both
162     // shown: CalcId6/Label6 and CalcId9/Label9
163     assertEquals(2, shownTypes.size());
164     assertEquals(1, shownTypes.get("CalcId6").size());
165     assertEquals(1, shownTypes.get("CalcId6").get(0).size());
166     assertEquals("Label6", shownTypes.get("CalcId6").get(0).get(0));
167     assertEquals(1, shownTypes.get("CalcId9").size());
168     assertEquals(1, shownTypes.get("CalcId9").get(0).size());
169     assertEquals("Label9", shownTypes.get("CalcId9").get(0).get(0));
170
171     // hidden: CalcId2/Label2, CalcId2/Label3, CalcId3/Label2, CalcId9/Label9
172     assertEquals(3, hiddenTypes.size());
173     assertEquals(2, hiddenTypes.get("CalcId2").size());
174     assertEquals(1, hiddenTypes.get("CalcId2").get(0).size());
175     assertEquals("Label2", hiddenTypes.get("CalcId2").get(0).get(0));
176     assertEquals(1, hiddenTypes.get("CalcId2").get(1).size());
177     assertEquals("Label3", hiddenTypes.get("CalcId2").get(1).get(0));
178     assertEquals(1, hiddenTypes.get("CalcId3").size());
179     assertEquals(1, hiddenTypes.get("CalcId3").get(0).size());
180     assertEquals("Label2", hiddenTypes.get("CalcId3").get(0).get(0));
181     assertEquals(1, hiddenTypes.get("CalcId9").size());
182     assertEquals(1, hiddenTypes.get("CalcId9").get(0).size());
183     assertEquals("Label9", hiddenTypes.get("CalcId9").get(0).get(0));
184
185     consoleDebug(shownTypes, hiddenTypes);
186   }
187
188   /**
189    * This output is not part of the test but may help make sense of it...
190    * 
191    * @param shownTypes
192    * @param hiddenTypes
193    */
194   protected void consoleDebug(Map<String, List<List<String>>> shownTypes,
195           Map<String, List<List<String>>> hiddenTypes)
196   {
197     for (String calcId : shownTypes.keySet())
198     {
199       System.out.println("Visible annotation types for calcId=" + calcId);
200       for (List<String> type : shownTypes.get(calcId))
201       {
202         System.out.println("   " + type);
203       }
204     }
205     for (String calcId : hiddenTypes.keySet())
206     {
207       System.out.println("Hidden annotation types for calcId=" + calcId);
208       for (List<String> type : hiddenTypes.get(calcId))
209       {
210         System.out.println("   " + type);
211       }
212     }
213   }
214
215   /**
216    * Test case where there are 'grouped' annotations, visible and hidden, within
217    * and without the selection group.
218    */
219   @Test
220   public void testGetAnnotationTypesForShowHide_withGraphGroups()
221   {
222     final int GROUP_4 = 4;
223     final int GROUP_5 = 5;
224     final int GROUP_6 = 6;
225
226     Map<String, List<List<String>>> shownTypes = new HashMap<String, List<List<String>>>();
227     Map<String, List<List<String>>> hiddenTypes = new HashMap<String, List<List<String>>>();
228     AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
229     BitSet visibleGraphGroups = new BitSet();
230     visibleGraphGroups.set(GROUP_4);
231     visibleGraphGroups.set(GROUP_6);
232     selectSequences(0, 3);
233     SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray();
234
235     /*
236      * Configure annotation properties for test (offsetting for auto-calculated
237      * rows).
238      */
239     // annotations for selection group and graph group
240     // hidden annotations Label2, Label3, in (hidden) group 5
241     anns[AUTO_ANNS + 2].sequenceRef = seqs[3];
242     anns[AUTO_ANNS + 2].visible = false;
243     anns[AUTO_ANNS + 2].graph = AlignmentAnnotation.LINE_GRAPH;
244     anns[AUTO_ANNS + 2].graphGroup = GROUP_5; // not a visible group
245     anns[AUTO_ANNS + 3].sequenceRef = seqs[0];
246     anns[AUTO_ANNS + 3].visible = false;
247     anns[AUTO_ANNS + 3].graph = AlignmentAnnotation.LINE_GRAPH;
248     anns[AUTO_ANNS + 3].graphGroup = GROUP_5;
249     // need to ensure annotations have the same calcId as well
250     anns[AUTO_ANNS + 3].setCalcId("CalcId2");
251
252     // annotations Label1 (hidden), Label5 (visible) in group 6 (visible)
253     anns[AUTO_ANNS + 1].sequenceRef = seqs[3];
254     // being in a visible group should take precedence over this visibility
255     anns[AUTO_ANNS + 1].visible = false;
256     anns[AUTO_ANNS + 1].graph = AlignmentAnnotation.LINE_GRAPH;
257     anns[AUTO_ANNS + 1].graphGroup = GROUP_6;
258     anns[AUTO_ANNS + 5].sequenceRef = seqs[0];
259     anns[AUTO_ANNS + 5].visible = true; // visibleGraphGroups overrides this
260     anns[AUTO_ANNS + 5].graph = AlignmentAnnotation.LINE_GRAPH;
261     anns[AUTO_ANNS + 5].graphGroup = GROUP_6;
262     anns[AUTO_ANNS + 5].setCalcId("CalcId1");
263
264     // annotations outwith selection group - should be ignored
265     // hidden grouped annotations
266     anns[AUTO_ANNS + 6].sequenceRef = seqs[2];
267     anns[AUTO_ANNS + 6].visible = false;
268     anns[AUTO_ANNS + 6].graph = AlignmentAnnotation.LINE_GRAPH;
269     anns[AUTO_ANNS + 6].graphGroup = GROUP_4;
270     anns[AUTO_ANNS + 8].sequenceRef = seqs[1];
271     anns[AUTO_ANNS + 8].visible = false;
272     anns[AUTO_ANNS + 8].graph = AlignmentAnnotation.LINE_GRAPH;
273     anns[AUTO_ANNS + 8].graphGroup = GROUP_4;
274     // visible grouped annotations Label7, Label9
275     anns[AUTO_ANNS + 7].sequenceRef = seqs[2];
276     anns[AUTO_ANNS + 7].visible = true;
277     anns[AUTO_ANNS + 7].graph = AlignmentAnnotation.LINE_GRAPH;
278     anns[AUTO_ANNS + 7].graphGroup = GROUP_4;
279     anns[AUTO_ANNS + 9].sequenceRef = seqs[1];
280     anns[AUTO_ANNS + 9].visible = true;
281     anns[AUTO_ANNS + 9].graph = AlignmentAnnotation.LINE_GRAPH;
282     anns[AUTO_ANNS + 9].graphGroup = GROUP_4;
283
284     PopupMenu.getAnnotationTypesForShowHide(shownTypes, hiddenTypes,
285             visibleGraphGroups, anns, parentPanel.av.getSelectionGroup());
286
287     consoleDebug(shownTypes, hiddenTypes);
288
289     // CalcId1 / Label1, Label5 (only) should be 'shown', as a compound type
290     assertEquals(1, shownTypes.get("CalcId1").size());
291     assertEquals(2, shownTypes.get("CalcId1").get(0).size());
292     assertEquals("Label1", shownTypes.get("CalcId1").get(0).get(0));
293     assertEquals("Label5", shownTypes.get("CalcId1").get(0).get(1));
294
295     // CalcId2 / Label2, Label3 (only) should be 'hidden'
296     assertEquals(1, hiddenTypes.get("CalcId2").size());
297     assertEquals(2, hiddenTypes.get("CalcId2").get(0).size());
298     assertEquals("Label2", hiddenTypes.get("CalcId2").get(0).get(0));
299     assertEquals("Label3", hiddenTypes.get("CalcId2").get(0).get(1));
300   }
301
302   /**
303    * Add a sequence group to the alignment with the specified sequences (base 0)
304    * in it
305    * 
306    * @param i
307    * @param more
308    */
309   private void selectSequences(int... selected)
310   {
311     SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray();
312     SequenceGroup sg = new SequenceGroup();
313     for (int i : selected)
314     {
315       sg.addSequence(seqs[i], false);
316     }
317     parentPanel.av.setSelectionGroup(sg);
318   }
319 }