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