111f11fbaa2451058e0e4505003c2a60c2db0966
[jalview.git] / test / jalview / gui / PopupMenuTest.java
1 package jalview.gui;
2
3 import static org.testng.AssertJUnit.assertEquals;
4 import static org.testng.AssertJUnit.assertFalse;
5 import static org.testng.AssertJUnit.assertTrue;
6
7 import jalview.datamodel.AlignmentAnnotation;
8 import jalview.datamodel.AlignmentI;
9 import jalview.datamodel.Annotation;
10 import jalview.datamodel.SequenceI;
11 import jalview.io.AppletFormatAdapter;
12 import jalview.io.FormatAdapter;
13 import jalview.util.MessageManager;
14
15 import java.awt.Component;
16 import java.io.IOException;
17 import java.util.ArrayList;
18 import java.util.List;
19
20 import javax.swing.JMenu;
21 import javax.swing.JMenuItem;
22 import javax.swing.JPopupMenu;
23 import javax.swing.JSeparator;
24
25 import org.testng.annotations.BeforeMethod;
26 import org.testng.annotations.Test;
27
28 public class PopupMenuTest
29 {
30   // 4 sequences x 13 positions
31   final static String TEST_DATA = ">FER_CAPAA Ferredoxin\n"
32           + "TIETHKEAELVG-\n"
33           + ">FER_CAPAN Ferredoxin, chloroplast precursor\n"
34           + "TIETHKEAELVG-\n"
35           + ">FER1_SOLLC Ferredoxin-1, chloroplast precursor\n"
36           + "TIETHKEEELTA-\n" + ">Q93XJ9_SOLTU Ferredoxin I precursor\n"
37           + "TIETHKEEELTA-\n";
38
39   AlignmentI alignment;
40
41   AlignmentPanel parentPanel;
42
43   PopupMenu testee = null;
44
45   @BeforeMethod(alwaysRun = true)
46   public void setUp() throws IOException
47   {
48     alignment = new FormatAdapter().readFile(TEST_DATA,
49             AppletFormatAdapter.PASTE, "FASTA");
50     AlignFrame af = new AlignFrame(alignment, 700, 500);
51     parentPanel = new AlignmentPanel(af, af.getViewport());
52     testee = new PopupMenu(parentPanel, null, null);
53     int i = 0;
54     for (SequenceI seq : alignment.getSequences())
55     {
56       final AlignmentAnnotation annotation = new AlignmentAnnotation(
57               "label" + i, "desc" + i, i);
58       annotation.setCalcId("calcId" + i);
59       seq.addAlignmentAnnotation(annotation);
60       annotation.setSequenceRef(seq);
61     }
62   }
63
64   @Test(groups = { "Functional" })
65   public void testConfigureReferenceAnnotationsMenu_noSequenceSelected()
66   {
67     JMenuItem menu = new JMenuItem();
68     List<SequenceI> seqs = new ArrayList<SequenceI>();
69     testee.configureReferenceAnnotationsMenu(menu, seqs);
70     assertFalse(menu.isEnabled());
71     // now try null list
72     menu.setEnabled(true);
73     testee.configureReferenceAnnotationsMenu(menu, null);
74     assertFalse(menu.isEnabled());
75   }
76
77   /**
78    * Test building the 'add reference annotations' menu for the case where there
79    * are no reference annotations to add to the alignment. The menu item should
80    * be disabled.
81    */
82   @Test(groups = { "Functional" })
83   public void testConfigureReferenceAnnotationsMenu_noReferenceAnnotations()
84   {
85     JMenuItem menu = new JMenuItem();
86
87     /*
88      * Initial state is that sequences have annotations, and have dataset
89      * sequences, but the dataset sequences have no annotations. Hence nothing
90      * to add.
91      */
92     List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
93
94     testee.configureReferenceAnnotationsMenu(menu, seqs);
95     assertFalse(menu.isEnabled());
96   }
97
98   /**
99    * Test building the 'add reference annotations' menu for the case where all
100    * reference annotations are already on the alignment. The menu item should be
101    * disabled.
102    */
103   @Test(groups = { "Functional" })
104   public void testConfigureReferenceAnnotationsMenu_alreadyAdded()
105   {
106     JMenuItem menu = new JMenuItem();
107     List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
108
109     // make up new annotations and add to dataset sequences, sequences and
110     // alignment
111     attachReferenceAnnotations(seqs, true, true);
112
113     testee.configureReferenceAnnotationsMenu(menu, seqs);
114     assertFalse(menu.isEnabled());
115   }
116
117   /**
118    * Test building the 'add reference annotations' menu for the case where
119    * several reference annotations are on the dataset but not on the sequences.
120    * The menu item should be enabled, and acquire a tooltip which lists the
121    * annotation sources (calcIds) and type (labels).
122    */
123   @Test(groups = { "Functional" })
124   public void testConfigureReferenceAnnotationsMenu()
125   {
126     JMenuItem menu = new JMenuItem();
127     List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
128
129     // make up new annotations and add to dataset sequences
130     attachReferenceAnnotations(seqs, false, false);
131
132     testee.configureReferenceAnnotationsMenu(menu, seqs);
133     assertTrue(menu.isEnabled());
134     String s = MessageManager.getString("label.add_annotations_for");
135     String expected = "<html><style> p.ttip {width: 350; text-align: justify; word-wrap: break-word;}</style><p class=\"ttip\">"
136             + s + "<br/>Jmol/secondary structure<br/>PDB/Temp</p></html>";
137     assertEquals(expected, menu.getToolTipText());
138   }
139
140   /**
141    * Test building the 'add reference annotations' menu for the case where
142    * several reference annotations are on the dataset and the sequences but not
143    * on the alignment. The menu item should be enabled, and acquire a tooltip
144    * which lists the annotation sources (calcIds) and type (labels).
145    */
146   @Test(groups = { "Functional" })
147   public void testConfigureReferenceAnnotationsMenu_notOnAlignment()
148   {
149     JMenuItem menu = new JMenuItem();
150     List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
151
152     // make up new annotations and add to dataset sequences and sequences
153     attachReferenceAnnotations(seqs, true, false);
154
155     testee.configureReferenceAnnotationsMenu(menu, seqs);
156     assertTrue(menu.isEnabled());
157     String s = MessageManager.getString("label.add_annotations_for");
158     String expected = "<html><style> p.ttip {width: 350; text-align: justify; word-wrap: break-word;}</style><p class=\"ttip\">"
159             + s + "<br/>Jmol/secondary structure<br/>PDB/Temp</p></html>";
160     assertEquals(expected, menu.getToolTipText());
161   }
162
163   /**
164    * Generate annotations and add to dataset sequences and (optionally)
165    * sequences and/or alignment
166    * 
167    * @param seqs
168    * @param addToSequence
169    * @param addToAlignment
170    */
171   private void attachReferenceAnnotations(List<SequenceI> seqs,
172           boolean addToSequence, boolean addToAlignment)
173   {
174     // PDB.secondary structure on Sequence0
175     AlignmentAnnotation annotation = new AlignmentAnnotation(
176             "secondary structure", "", 0);
177     annotation.setCalcId("PDB");
178     seqs.get(0).getDatasetSequence().addAlignmentAnnotation(annotation);
179     if (addToSequence)
180     {
181       seqs.get(0).addAlignmentAnnotation(annotation);
182     }
183     if (addToAlignment)
184     {
185       this.alignment.addAnnotation(annotation);
186     }
187
188     // PDB.Temp on Sequence1
189     annotation = new AlignmentAnnotation("Temp", "", 0);
190     annotation.setCalcId("PDB");
191     seqs.get(1).getDatasetSequence().addAlignmentAnnotation(annotation);
192     if (addToSequence)
193     {
194       seqs.get(1).addAlignmentAnnotation(annotation);
195     }
196     if (addToAlignment)
197     {
198       this.alignment.addAnnotation(annotation);
199     }
200
201     // JMOL.secondary structure on Sequence0
202     annotation = new AlignmentAnnotation("secondary structure", "", 0);
203     annotation.setCalcId("Jmol");
204     seqs.get(0).getDatasetSequence().addAlignmentAnnotation(annotation);
205     if (addToSequence)
206     {
207       seqs.get(0).addAlignmentAnnotation(annotation);
208     }
209     if (addToAlignment)
210     {
211       this.alignment.addAnnotation(annotation);
212     }
213   }
214
215   /**
216    * Test building the 'add reference annotations' menu for the case where there
217    * are two alignment views:
218    * <ul>
219    * <li>in one view, reference annotations have been added (are on the
220    * datasets, sequences and alignment)</li>
221    * <li>in the current view, reference annotations are on the dataset and
222    * sequence, but not the alignment</li>
223    * </ul>
224    * The menu item should be enabled, and acquire a tooltip which lists the
225    * annotation sources (calcIds) and type (labels).
226    */
227   @Test(groups = { "Functional" })
228   public void testConfigureReferenceAnnotationsMenu_twoViews()
229   {
230   }
231
232   /**
233    * Test for building menu options including 'show' and 'hide' annotation
234    * types.
235    */
236   @Test(groups = { "Functional" })
237   public void testBuildAnnotationTypesMenus()
238   {
239     JMenu showMenu = new JMenu();
240     JMenu hideMenu = new JMenu();
241     List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
242
243     // make up new annotations and add to sequences and to the alignment
244
245     // PDB.secondary structure on Sequence0
246     AlignmentAnnotation annotation = new AlignmentAnnotation(
247             "secondary structure", "", new Annotation[] {});
248     annotation.setCalcId("PDB");
249     annotation.visible = true;
250     seqs.get(0).addAlignmentAnnotation(annotation);
251     parentPanel.getAlignment().addAnnotation(annotation);
252
253     // JMOL.secondary structure on Sequence0 - hidden
254     annotation = new AlignmentAnnotation("secondary structure", "",
255             new Annotation[] {});
256     annotation.setCalcId("JMOL");
257     annotation.visible = false;
258     seqs.get(0).addAlignmentAnnotation(annotation);
259     parentPanel.getAlignment().addAnnotation(annotation);
260
261     // Jpred.SSP on Sequence0 - hidden
262     annotation = new AlignmentAnnotation("SSP", "", new Annotation[] {});
263     annotation.setCalcId("JPred");
264     annotation.visible = false;
265     seqs.get(0).addAlignmentAnnotation(annotation);
266     parentPanel.getAlignment().addAnnotation(annotation);
267
268     // PDB.Temp on Sequence1
269     annotation = new AlignmentAnnotation("Temp", "", new Annotation[] {});
270     annotation.setCalcId("PDB");
271     annotation.visible = true;
272     seqs.get(1).addAlignmentAnnotation(annotation);
273     parentPanel.getAlignment().addAnnotation(annotation);
274
275     /*
276      * Expect menu options to show "secondary structure" and "SSP", and to hide
277      * "secondary structure" and "Temp". Tooltip should be calcId.
278      */
279     testee.buildAnnotationTypesMenus(showMenu, hideMenu, seqs);
280
281     assertTrue(showMenu.isEnabled());
282     assertTrue(hideMenu.isEnabled());
283
284     Component[] showOptions = showMenu.getMenuComponents();
285     Component[] hideOptions = hideMenu.getMenuComponents();
286
287     assertEquals(4, showOptions.length); // includes 'All' and separator
288     assertEquals(4, hideOptions.length);
289     assertEquals("All", ((JMenuItem) showOptions[0]).getText());
290     assertTrue(showOptions[1] instanceof JPopupMenu.Separator);
291     assertEquals(JSeparator.HORIZONTAL,
292             ((JSeparator) showOptions[1]).getOrientation());
293     assertEquals("secondary structure",
294             ((JMenuItem) showOptions[2]).getText());
295     assertEquals("JMOL", ((JMenuItem) showOptions[2]).getToolTipText());
296     assertEquals("SSP", ((JMenuItem) showOptions[3]).getText());
297     assertEquals("JPred", ((JMenuItem) showOptions[3]).getToolTipText());
298
299     assertEquals("All", ((JMenuItem) hideOptions[0]).getText());
300     assertTrue(hideOptions[1] instanceof JPopupMenu.Separator);
301     assertEquals(JSeparator.HORIZONTAL,
302             ((JSeparator) hideOptions[1]).getOrientation());
303     assertEquals("secondary structure",
304             ((JMenuItem) hideOptions[2]).getText());
305     assertEquals("PDB", ((JMenuItem) hideOptions[2]).getToolTipText());
306     assertEquals("Temp", ((JMenuItem) hideOptions[3]).getText());
307     assertEquals("PDB", ((JMenuItem) hideOptions[3]).getToolTipText());
308   }
309
310   /**
311    * Test for building menu options with only 'hide' annotation types enabled.
312    */
313   @Test(groups = { "Functional" })
314   public void testBuildAnnotationTypesMenus_showDisabled()
315   {
316     JMenu showMenu = new JMenu();
317     JMenu hideMenu = new JMenu();
318     List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
319
320     // make up new annotations and add to sequences and to the alignment
321
322     // PDB.secondary structure on Sequence0
323     AlignmentAnnotation annotation = new AlignmentAnnotation(
324             "secondary structure", "", new Annotation[] {});
325     annotation.setCalcId("PDB");
326     annotation.visible = true;
327     seqs.get(0).addAlignmentAnnotation(annotation);
328     parentPanel.getAlignment().addAnnotation(annotation);
329
330     // PDB.Temp on Sequence1
331     annotation = new AlignmentAnnotation("Temp", "", new Annotation[] {});
332     annotation.setCalcId("PDB");
333     annotation.visible = true;
334     seqs.get(1).addAlignmentAnnotation(annotation);
335     parentPanel.getAlignment().addAnnotation(annotation);
336
337     /*
338      * Expect menu options to hide "secondary structure" and "Temp". Tooltip
339      * should be calcId. 'Show' menu should be disabled.
340      */
341     testee.buildAnnotationTypesMenus(showMenu, hideMenu, seqs);
342
343     assertFalse(showMenu.isEnabled());
344     assertTrue(hideMenu.isEnabled());
345
346     Component[] showOptions = showMenu.getMenuComponents();
347     Component[] hideOptions = hideMenu.getMenuComponents();
348
349     assertEquals(2, showOptions.length); // includes 'All' and separator
350     assertEquals(4, hideOptions.length);
351     assertEquals("All", ((JMenuItem) showOptions[0]).getText());
352     assertTrue(showOptions[1] instanceof JPopupMenu.Separator);
353     assertEquals(JSeparator.HORIZONTAL,
354             ((JSeparator) showOptions[1]).getOrientation());
355
356     assertEquals("All", ((JMenuItem) hideOptions[0]).getText());
357     assertTrue(hideOptions[1] instanceof JPopupMenu.Separator);
358     assertEquals(JSeparator.HORIZONTAL,
359             ((JSeparator) hideOptions[1]).getOrientation());
360     assertEquals("secondary structure",
361             ((JMenuItem) hideOptions[2]).getText());
362     assertEquals("PDB", ((JMenuItem) hideOptions[2]).getToolTipText());
363     assertEquals("Temp", ((JMenuItem) hideOptions[3]).getText());
364     assertEquals("PDB", ((JMenuItem) hideOptions[3]).getToolTipText());
365   }
366
367   /**
368    * Test for building menu options with only 'show' annotation types enabled.
369    */
370   @Test(groups = { "Functional" })
371   public void testBuildAnnotationTypesMenus_hideDisabled()
372   {
373     JMenu showMenu = new JMenu();
374     JMenu hideMenu = new JMenu();
375     List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
376
377     // make up new annotations and add to sequences and to the alignment
378
379     // PDB.secondary structure on Sequence0
380     AlignmentAnnotation annotation = new AlignmentAnnotation(
381             "secondary structure", "", new Annotation[] {});
382     annotation.setCalcId("PDB");
383     annotation.visible = false;
384     seqs.get(0).addAlignmentAnnotation(annotation);
385     parentPanel.getAlignment().addAnnotation(annotation);
386
387     // PDB.Temp on Sequence1
388     annotation = new AlignmentAnnotation("Temp", "", new Annotation[] {});
389     annotation.setCalcId("PDB2");
390     annotation.visible = false;
391     seqs.get(1).addAlignmentAnnotation(annotation);
392     parentPanel.getAlignment().addAnnotation(annotation);
393
394     /*
395      * Expect menu options to show "secondary structure" and "Temp". Tooltip
396      * should be calcId. 'hide' menu should be disabled.
397      */
398     testee.buildAnnotationTypesMenus(showMenu, hideMenu, seqs);
399
400     assertTrue(showMenu.isEnabled());
401     assertFalse(hideMenu.isEnabled());
402
403     Component[] showOptions = showMenu.getMenuComponents();
404     Component[] hideOptions = hideMenu.getMenuComponents();
405
406     assertEquals(4, showOptions.length); // includes 'All' and separator
407     assertEquals(2, hideOptions.length);
408     assertEquals("All", ((JMenuItem) showOptions[0]).getText());
409     assertTrue(showOptions[1] instanceof JPopupMenu.Separator);
410     assertEquals(JSeparator.HORIZONTAL,
411             ((JSeparator) showOptions[1]).getOrientation());
412     assertEquals("secondary structure",
413             ((JMenuItem) showOptions[2]).getText());
414     assertEquals("PDB", ((JMenuItem) showOptions[2]).getToolTipText());
415     assertEquals("Temp", ((JMenuItem) showOptions[3]).getText());
416     assertEquals("PDB2", ((JMenuItem) showOptions[3]).getToolTipText());
417
418     assertEquals("All", ((JMenuItem) hideOptions[0]).getText());
419     assertTrue(hideOptions[1] instanceof JPopupMenu.Separator);
420     assertEquals(JSeparator.HORIZONTAL,
421             ((JSeparator) hideOptions[1]).getOrientation());
422   }
423 }