Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
PopupMenuTest | 69 | 325 | 26 |
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 jalview.util.UrlConstants.DB_ACCESSION; | |
24 | import static jalview.util.UrlConstants.SEQUENCE_ID; | |
25 | import static org.testng.AssertJUnit.assertEquals; | |
26 | import static org.testng.AssertJUnit.assertFalse; | |
27 | import static org.testng.AssertJUnit.assertNotNull; | |
28 | import static org.testng.AssertJUnit.assertNull; | |
29 | import static org.testng.AssertJUnit.assertTrue; | |
30 | ||
31 | import java.awt.Component; | |
32 | import java.awt.Container; | |
33 | import java.io.IOException; | |
34 | import java.util.ArrayList; | |
35 | import java.util.Collections; | |
36 | import java.util.Iterator; | |
37 | import java.util.List; | |
38 | ||
39 | import javax.swing.JMenu; | |
40 | import javax.swing.JMenuItem; | |
41 | import javax.swing.JPopupMenu; | |
42 | import javax.swing.JSeparator; | |
43 | ||
44 | import org.testng.annotations.BeforeClass; | |
45 | import org.testng.annotations.BeforeMethod; | |
46 | import org.testng.annotations.Test; | |
47 | ||
48 | import jalview.bin.Cache; | |
49 | import jalview.bin.Console; | |
50 | import jalview.datamodel.AlignmentAnnotation; | |
51 | import jalview.datamodel.AlignmentI; | |
52 | import jalview.datamodel.Annotation; | |
53 | import jalview.datamodel.ColumnSelection; | |
54 | import jalview.datamodel.DBRefEntry; | |
55 | import jalview.datamodel.DBRefSource; | |
56 | import jalview.datamodel.HiddenColumns; | |
57 | import jalview.datamodel.Sequence; | |
58 | import jalview.datamodel.SequenceFeature; | |
59 | import jalview.datamodel.SequenceGroup; | |
60 | import jalview.datamodel.SequenceI; | |
61 | import jalview.io.DataSourceType; | |
62 | import jalview.io.FileFormat; | |
63 | import jalview.io.FormatAdapter; | |
64 | import jalview.urls.api.UrlProviderFactoryI; | |
65 | import jalview.urls.desktop.DesktopUrlProviderFactory; | |
66 | import jalview.util.MessageManager; | |
67 | import jalview.util.UrlConstants; | |
68 | ||
69 | public class PopupMenuTest | |
70 | { | |
71 | ||
72 | 1 | @BeforeClass(alwaysRun = true) |
73 | public void setUpJvOptionPane() | |
74 | { | |
75 | 1 | JvOptionPane.setInteractiveMode(false); |
76 | 1 | JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); |
77 | } | |
78 | ||
79 | // 4 sequences x 13 positions | |
80 | final static String TEST_DATA = ">FER_CAPAA Ferredoxin\n" | |
81 | + "TIETHKEAELVG-\n" | |
82 | + ">FER_CAPAN Ferredoxin, chloroplast precursor\n" | |
83 | + "TIETHKEAELVG-\n" | |
84 | + ">FER1_SOLLC Ferredoxin-1, chloroplast precursor\n" | |
85 | + "TIETHKEEELTA-\n" + ">Q93XJ9_SOLTU Ferredoxin I precursor\n" | |
86 | + "TIETHKEEELTA-\n"; | |
87 | ||
88 | AlignmentI alignment; | |
89 | ||
90 | AlignmentPanel parentPanel; | |
91 | ||
92 | PopupMenu testee = null; | |
93 | ||
94 | 13 | @BeforeMethod(alwaysRun = true) |
95 | public void setUp() throws IOException | |
96 | { | |
97 | 13 | Cache.loadProperties("test/jalview/io/testProps.jvprops"); |
98 | 13 | Console.initLogger(); |
99 | ||
100 | 13 | String inMenuString = ("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$" |
101 | + SEQUENCE_ID + "$" + "|" | |
102 | + "UNIPROT | http://www.uniprot.org/uniprot/$" + DB_ACCESSION | |
103 | + "$") + "|" | |
104 | + ("INTERPRO | http://www.ebi.ac.uk/interpro/entry/$" | |
105 | + DB_ACCESSION + "$") | |
106 | + "|" + | |
107 | // Gene3D entry tests for case (in)sensitivity | |
108 | ("Gene3D | http://gene3d.biochem.ucl.ac.uk/Gene3D/search?sterm=$" | |
109 | + DB_ACCESSION + "$&mode=protein"); | |
110 | ||
111 | 13 | UrlProviderFactoryI factory = new DesktopUrlProviderFactory( |
112 | UrlConstants.DEFAULT_LABEL, inMenuString, ""); | |
113 | 13 | Preferences.sequenceUrlLinks = factory.createUrlProvider(); |
114 | ||
115 | 13 | alignment = new FormatAdapter().readFile(TEST_DATA, |
116 | DataSourceType.PASTE, FileFormat.Fasta); | |
117 | 13 | AlignFrame af = new AlignFrame(alignment, 700, 500); |
118 | 13 | parentPanel = new AlignmentPanel(af, af.getViewport()); |
119 | 13 | testee = new PopupMenu(parentPanel, alignment.getSequenceAt(0), null); |
120 | 13 | int i = 0; |
121 | 13 | for (SequenceI seq : alignment.getSequences()) |
122 | { | |
123 | 52 | final AlignmentAnnotation annotation = new AlignmentAnnotation( |
124 | "label" + i, "desc" + i, i); | |
125 | 52 | annotation.setCalcId("calcId" + i); |
126 | 52 | seq.addAlignmentAnnotation(annotation); |
127 | 52 | annotation.setSequenceRef(seq); |
128 | } | |
129 | } | |
130 | ||
131 | 1 | @Test(groups = { "Functional" }) |
132 | public void testConfigureReferenceAnnotationsMenu_noSequenceSelected() | |
133 | { | |
134 | 1 | JMenuItem menu = new JMenuItem(); |
135 | 1 | List<SequenceI> seqs = new ArrayList<>(); |
136 | 1 | testee.configureReferenceAnnotationsMenu(menu, seqs); |
137 | 1 | assertFalse(menu.isEnabled()); |
138 | // now try null list | |
139 | 1 | menu.setEnabled(true); |
140 | 1 | testee.configureReferenceAnnotationsMenu(menu, null); |
141 | 1 | assertFalse(menu.isEnabled()); |
142 | } | |
143 | ||
144 | /** | |
145 | * Test building the 'add reference annotations' menu for the case where there | |
146 | * are no reference annotations to add to the alignment. The menu item should | |
147 | * be disabled. | |
148 | */ | |
149 | 1 | @Test(groups = { "Functional" }) |
150 | public void testConfigureReferenceAnnotationsMenu_noReferenceAnnotations() | |
151 | { | |
152 | 1 | JMenuItem menu = new JMenuItem(); |
153 | ||
154 | /* | |
155 | * Initial state is that sequences have annotations, and have dataset | |
156 | * sequences, but the dataset sequences have no annotations. Hence nothing | |
157 | * to add. | |
158 | */ | |
159 | 1 | List<SequenceI> seqs = parentPanel.getAlignment().getSequences(); |
160 | ||
161 | 1 | testee.configureReferenceAnnotationsMenu(menu, seqs); |
162 | 1 | assertFalse(menu.isEnabled()); |
163 | } | |
164 | ||
165 | /** | |
166 | * Test building the 'add reference annotations' menu for the case where all | |
167 | * reference annotations are already on the alignment. The menu item should be | |
168 | * disabled. | |
169 | */ | |
170 | 1 | @Test(groups = { "Functional" }) |
171 | public void testConfigureReferenceAnnotationsMenu_alreadyAdded() | |
172 | { | |
173 | 1 | JMenuItem menu = new JMenuItem(); |
174 | 1 | List<SequenceI> seqs = parentPanel.getAlignment().getSequences(); |
175 | ||
176 | // make up new annotations and add to dataset sequences, sequences and | |
177 | // alignment | |
178 | 1 | attachReferenceAnnotations(seqs, true, true); |
179 | ||
180 | 1 | testee.configureReferenceAnnotationsMenu(menu, seqs); |
181 | 1 | assertFalse(menu.isEnabled()); |
182 | } | |
183 | ||
184 | /** | |
185 | * Test building the 'add reference annotations' menu for the case where | |
186 | * several reference annotations are on the dataset but not on the sequences. | |
187 | * The menu item should be enabled, and acquire a tooltip which lists the | |
188 | * annotation sources (calcIds) and type (labels). | |
189 | */ | |
190 | 1 | @Test(groups = { "Functional" }) |
191 | public void testConfigureReferenceAnnotationsMenu() | |
192 | { | |
193 | 1 | JMenuItem menu = new JMenuItem(); |
194 | 1 | List<SequenceI> seqs = parentPanel.getAlignment().getSequences(); |
195 | ||
196 | // make up new annotations and add to dataset sequences | |
197 | 1 | attachReferenceAnnotations(seqs, false, false); |
198 | ||
199 | 1 | testee.configureReferenceAnnotationsMenu(menu, seqs); |
200 | 1 | assertTrue(menu.isEnabled()); |
201 | 1 | String s = MessageManager.getString("label.add_annotations_for"); |
202 | 1 | String expected = "<html><style> div.ttip {width:350px;white-space:pre-wrap;padding:2px;overflow-wrap:break-word;}</style>" |
203 | + "<div class=\"ttip\">" + s | |
204 | + "<br/>Jmol/secondary structure<br/>PDB/Temp </div></html>"; | |
205 | 1 | assertEquals(expected, menu.getToolTipText()); |
206 | } | |
207 | ||
208 | /** | |
209 | * Test building the 'add reference annotations' menu for the case where | |
210 | * several reference annotations are on the dataset and the sequences but not | |
211 | * on the alignment. The menu item should be enabled, and acquire a tooltip | |
212 | * which lists the annotation sources (calcIds) and type (labels). | |
213 | */ | |
214 | 1 | @Test(groups = { "Functional" }) |
215 | public void testConfigureReferenceAnnotationsMenu_notOnAlignment() | |
216 | { | |
217 | 1 | JMenuItem menu = new JMenuItem(); |
218 | 1 | List<SequenceI> seqs = parentPanel.getAlignment().getSequences(); |
219 | ||
220 | // make up new annotations and add to dataset sequences and sequences | |
221 | 1 | attachReferenceAnnotations(seqs, true, false); |
222 | ||
223 | 1 | testee.configureReferenceAnnotationsMenu(menu, seqs); |
224 | 1 | assertTrue(menu.isEnabled()); |
225 | 1 | String s = MessageManager.getString("label.add_annotations_for"); |
226 | 1 | String expected = "<html><style> div.ttip {width:350px;white-space:pre-wrap;padding:2px;overflow-wrap:break-word;}</style>" |
227 | + "<div class=\"ttip\">" + s | |
228 | + "<br/>Jmol/secondary structure<br/>PDB/Temp </div></html>"; | |
229 | 1 | assertEquals(expected, menu.getToolTipText()); |
230 | } | |
231 | ||
232 | /** | |
233 | * Generate annotations and add to dataset sequences and (optionally) | |
234 | * sequences and/or alignment | |
235 | * | |
236 | * @param seqs | |
237 | * @param addToSequence | |
238 | * @param addToAlignment | |
239 | */ | |
240 | 3 | private void attachReferenceAnnotations(List<SequenceI> seqs, |
241 | boolean addToSequence, boolean addToAlignment) | |
242 | { | |
243 | // PDB.secondary structure on Sequence0 | |
244 | 3 | AlignmentAnnotation annotation = new AlignmentAnnotation( |
245 | "secondary structure", "", 0); | |
246 | 3 | annotation.setCalcId("PDB"); |
247 | 3 | seqs.get(0).getDatasetSequence().addAlignmentAnnotation(annotation); |
248 | 3 | if (addToSequence) |
249 | { | |
250 | 2 | seqs.get(0).addAlignmentAnnotation(annotation); |
251 | } | |
252 | 3 | if (addToAlignment) |
253 | { | |
254 | 1 | this.alignment.addAnnotation(annotation); |
255 | } | |
256 | ||
257 | // PDB.Temp on Sequence1 | |
258 | 3 | annotation = new AlignmentAnnotation("Temp", "", 0); |
259 | 3 | annotation.setCalcId("PDB"); |
260 | 3 | seqs.get(1).getDatasetSequence().addAlignmentAnnotation(annotation); |
261 | 3 | if (addToSequence) |
262 | { | |
263 | 2 | seqs.get(1).addAlignmentAnnotation(annotation); |
264 | } | |
265 | 3 | if (addToAlignment) |
266 | { | |
267 | 1 | this.alignment.addAnnotation(annotation); |
268 | } | |
269 | ||
270 | // JMOL.secondary structure on Sequence0 | |
271 | 3 | annotation = new AlignmentAnnotation("secondary structure", "", 0); |
272 | 3 | annotation.setCalcId("Jmol"); |
273 | 3 | seqs.get(0).getDatasetSequence().addAlignmentAnnotation(annotation); |
274 | 3 | if (addToSequence) |
275 | { | |
276 | 2 | seqs.get(0).addAlignmentAnnotation(annotation); |
277 | } | |
278 | 3 | if (addToAlignment) |
279 | { | |
280 | 1 | this.alignment.addAnnotation(annotation); |
281 | } | |
282 | } | |
283 | ||
284 | /** | |
285 | * Test building the 'add reference annotations' menu for the case where there | |
286 | * are two alignment views: | |
287 | * <ul> | |
288 | * <li>in one view, reference annotations have been added (are on the | |
289 | * datasets, sequences and alignment)</li> | |
290 | * <li>in the current view, reference annotations are on the dataset and | |
291 | * sequence, but not the alignment</li> | |
292 | * </ul> | |
293 | * The menu item should be enabled, and acquire a tooltip which lists the | |
294 | * annotation sources (calcIds) and type (labels). | |
295 | */ | |
296 | 1 | @Test(groups = { "Functional" }) |
297 | public void testConfigureReferenceAnnotationsMenu_twoViews() | |
298 | { | |
299 | } | |
300 | ||
301 | /** | |
302 | * Test for building menu options including 'show' and 'hide' annotation | |
303 | * types. | |
304 | */ | |
305 | 1 | @Test(groups = { "Functional" }) |
306 | public void testBuildAnnotationTypesMenus() | |
307 | { | |
308 | 1 | JMenu showMenu = new JMenu(); |
309 | 1 | JMenu hideMenu = new JMenu(); |
310 | 1 | List<SequenceI> seqs = parentPanel.getAlignment().getSequences(); |
311 | ||
312 | // make up new annotations and add to sequences and to the alignment | |
313 | ||
314 | // PDB.secondary structure on Sequence0 | |
315 | 1 | AlignmentAnnotation annotation = new AlignmentAnnotation( |
316 | "secondary structure", "", new Annotation[] {}); | |
317 | 1 | annotation.setCalcId("PDB"); |
318 | 1 | annotation.visible = true; |
319 | 1 | seqs.get(0).addAlignmentAnnotation(annotation); |
320 | 1 | parentPanel.getAlignment().addAnnotation(annotation); |
321 | ||
322 | // JMOL.secondary structure on Sequence0 - hidden | |
323 | 1 | annotation = new AlignmentAnnotation("secondary structure", "", |
324 | new Annotation[] {}); | |
325 | 1 | annotation.setCalcId("JMOL"); |
326 | 1 | annotation.visible = false; |
327 | 1 | seqs.get(0).addAlignmentAnnotation(annotation); |
328 | 1 | parentPanel.getAlignment().addAnnotation(annotation); |
329 | ||
330 | // Jpred.SSP on Sequence0 - hidden | |
331 | 1 | annotation = new AlignmentAnnotation("SSP", "", new Annotation[] {}); |
332 | 1 | annotation.setCalcId("JPred"); |
333 | 1 | annotation.visible = false; |
334 | 1 | seqs.get(0).addAlignmentAnnotation(annotation); |
335 | 1 | parentPanel.getAlignment().addAnnotation(annotation); |
336 | ||
337 | // PDB.Temp on Sequence1 | |
338 | 1 | annotation = new AlignmentAnnotation("Temp", "", new Annotation[] {}); |
339 | 1 | annotation.setCalcId("PDB"); |
340 | 1 | annotation.visible = true; |
341 | 1 | seqs.get(1).addAlignmentAnnotation(annotation); |
342 | 1 | parentPanel.getAlignment().addAnnotation(annotation); |
343 | ||
344 | /* | |
345 | * Expect menu options to show "secondary structure" and "SSP", and to hide | |
346 | * "secondary structure" and "Temp". Tooltip should be calcId. | |
347 | */ | |
348 | 1 | testee.buildAnnotationTypesMenus(showMenu, hideMenu, seqs); |
349 | ||
350 | 1 | assertTrue(showMenu.isEnabled()); |
351 | 1 | assertTrue(hideMenu.isEnabled()); |
352 | ||
353 | 1 | Component[] showOptions = showMenu.getMenuComponents(); |
354 | 1 | Component[] hideOptions = hideMenu.getMenuComponents(); |
355 | ||
356 | 1 | assertEquals(4, showOptions.length); // includes 'All' and separator |
357 | 1 | assertEquals(4, hideOptions.length); |
358 | 1 | String all = MessageManager.getString("label.all"); |
359 | 1 | assertEquals(all, ((JMenuItem) showOptions[0]).getText()); |
360 | 1 | assertTrue(showOptions[1] instanceof JPopupMenu.Separator); |
361 | 1 | assertEquals(JSeparator.HORIZONTAL, |
362 | ((JSeparator) showOptions[1]).getOrientation()); | |
363 | 1 | assertEquals("secondary structure", |
364 | ((JMenuItem) showOptions[2]).getText()); | |
365 | 1 | assertEquals("JMOL", ((JMenuItem) showOptions[2]).getToolTipText()); |
366 | 1 | assertEquals("SSP", ((JMenuItem) showOptions[3]).getText()); |
367 | 1 | assertEquals("JPred", ((JMenuItem) showOptions[3]).getToolTipText()); |
368 | ||
369 | 1 | assertEquals(all, ((JMenuItem) hideOptions[0]).getText()); |
370 | 1 | assertTrue(hideOptions[1] instanceof JPopupMenu.Separator); |
371 | 1 | assertEquals(JSeparator.HORIZONTAL, |
372 | ((JSeparator) hideOptions[1]).getOrientation()); | |
373 | 1 | assertEquals("secondary structure", |
374 | ((JMenuItem) hideOptions[2]).getText()); | |
375 | 1 | assertEquals("PDB", ((JMenuItem) hideOptions[2]).getToolTipText()); |
376 | 1 | assertEquals("Temp", ((JMenuItem) hideOptions[3]).getText()); |
377 | 1 | assertEquals("PDB", ((JMenuItem) hideOptions[3]).getToolTipText()); |
378 | } | |
379 | ||
380 | /** | |
381 | * Test for building menu options with only 'hide' annotation types enabled. | |
382 | */ | |
383 | 1 | @Test(groups = { "Functional" }) |
384 | public void testBuildAnnotationTypesMenus_showDisabled() | |
385 | { | |
386 | 1 | JMenu showMenu = new JMenu(); |
387 | 1 | JMenu hideMenu = new JMenu(); |
388 | 1 | List<SequenceI> seqs = parentPanel.getAlignment().getSequences(); |
389 | ||
390 | // make up new annotations and add to sequences and to the alignment | |
391 | ||
392 | // PDB.secondary structure on Sequence0 | |
393 | 1 | AlignmentAnnotation annotation = new AlignmentAnnotation( |
394 | "secondary structure", "", new Annotation[] {}); | |
395 | 1 | annotation.setCalcId("PDB"); |
396 | 1 | annotation.visible = true; |
397 | 1 | seqs.get(0).addAlignmentAnnotation(annotation); |
398 | 1 | parentPanel.getAlignment().addAnnotation(annotation); |
399 | ||
400 | // PDB.Temp on Sequence1 | |
401 | 1 | annotation = new AlignmentAnnotation("Temp", "", new Annotation[] {}); |
402 | 1 | annotation.setCalcId("PDB"); |
403 | 1 | annotation.visible = true; |
404 | 1 | seqs.get(1).addAlignmentAnnotation(annotation); |
405 | 1 | parentPanel.getAlignment().addAnnotation(annotation); |
406 | ||
407 | /* | |
408 | * Expect menu options to hide "secondary structure" and "Temp". Tooltip | |
409 | * should be calcId. 'Show' menu should be disabled. | |
410 | */ | |
411 | 1 | testee.buildAnnotationTypesMenus(showMenu, hideMenu, seqs); |
412 | ||
413 | 1 | assertFalse(showMenu.isEnabled()); |
414 | 1 | assertTrue(hideMenu.isEnabled()); |
415 | ||
416 | 1 | Component[] showOptions = showMenu.getMenuComponents(); |
417 | 1 | Component[] hideOptions = hideMenu.getMenuComponents(); |
418 | ||
419 | 1 | assertEquals(2, showOptions.length); // includes 'All' and separator |
420 | 1 | assertEquals(4, hideOptions.length); |
421 | 1 | String all = MessageManager.getString("label.all"); |
422 | 1 | assertEquals(all, ((JMenuItem) showOptions[0]).getText()); |
423 | 1 | assertTrue(showOptions[1] instanceof JPopupMenu.Separator); |
424 | 1 | assertEquals(JSeparator.HORIZONTAL, |
425 | ((JSeparator) showOptions[1]).getOrientation()); | |
426 | ||
427 | 1 | assertEquals(all, ((JMenuItem) hideOptions[0]).getText()); |
428 | 1 | assertTrue(hideOptions[1] instanceof JPopupMenu.Separator); |
429 | 1 | assertEquals(JSeparator.HORIZONTAL, |
430 | ((JSeparator) hideOptions[1]).getOrientation()); | |
431 | 1 | assertEquals("secondary structure", |
432 | ((JMenuItem) hideOptions[2]).getText()); | |
433 | 1 | assertEquals("PDB", ((JMenuItem) hideOptions[2]).getToolTipText()); |
434 | 1 | assertEquals("Temp", ((JMenuItem) hideOptions[3]).getText()); |
435 | 1 | assertEquals("PDB", ((JMenuItem) hideOptions[3]).getToolTipText()); |
436 | } | |
437 | ||
438 | /** | |
439 | * Test for building menu options with only 'show' annotation types enabled. | |
440 | */ | |
441 | 1 | @Test(groups = { "Functional" }) |
442 | public void testBuildAnnotationTypesMenus_hideDisabled() | |
443 | { | |
444 | 1 | JMenu showMenu = new JMenu(); |
445 | 1 | JMenu hideMenu = new JMenu(); |
446 | 1 | List<SequenceI> seqs = parentPanel.getAlignment().getSequences(); |
447 | ||
448 | // make up new annotations and add to sequences and to the alignment | |
449 | ||
450 | // PDB.secondary structure on Sequence0 | |
451 | 1 | AlignmentAnnotation annotation = new AlignmentAnnotation( |
452 | "secondary structure", "", new Annotation[] {}); | |
453 | 1 | annotation.setCalcId("PDB"); |
454 | 1 | annotation.visible = false; |
455 | 1 | seqs.get(0).addAlignmentAnnotation(annotation); |
456 | 1 | parentPanel.getAlignment().addAnnotation(annotation); |
457 | ||
458 | // PDB.Temp on Sequence1 | |
459 | 1 | annotation = new AlignmentAnnotation("Temp", "", new Annotation[] {}); |
460 | 1 | annotation.setCalcId("PDB2"); |
461 | 1 | annotation.visible = false; |
462 | 1 | seqs.get(1).addAlignmentAnnotation(annotation); |
463 | 1 | parentPanel.getAlignment().addAnnotation(annotation); |
464 | ||
465 | /* | |
466 | * Expect menu options to show "secondary structure" and "Temp". Tooltip | |
467 | * should be calcId. 'hide' menu should be disabled. | |
468 | */ | |
469 | 1 | testee.buildAnnotationTypesMenus(showMenu, hideMenu, seqs); |
470 | ||
471 | 1 | assertTrue(showMenu.isEnabled()); |
472 | 1 | assertFalse(hideMenu.isEnabled()); |
473 | ||
474 | 1 | Component[] showOptions = showMenu.getMenuComponents(); |
475 | 1 | Component[] hideOptions = hideMenu.getMenuComponents(); |
476 | ||
477 | 1 | assertEquals(4, showOptions.length); // includes 'All' and separator |
478 | 1 | assertEquals(2, hideOptions.length); |
479 | 1 | String all = MessageManager.getString("label.all"); |
480 | 1 | assertEquals(all, ((JMenuItem) showOptions[0]).getText()); |
481 | 1 | assertTrue(showOptions[1] instanceof JPopupMenu.Separator); |
482 | 1 | assertEquals(JSeparator.HORIZONTAL, |
483 | ((JSeparator) showOptions[1]).getOrientation()); | |
484 | 1 | assertEquals("secondary structure", |
485 | ((JMenuItem) showOptions[2]).getText()); | |
486 | 1 | assertEquals("PDB", ((JMenuItem) showOptions[2]).getToolTipText()); |
487 | 1 | assertEquals("Temp", ((JMenuItem) showOptions[3]).getText()); |
488 | 1 | assertEquals("PDB2", ((JMenuItem) showOptions[3]).getToolTipText()); |
489 | ||
490 | 1 | assertEquals(all, ((JMenuItem) hideOptions[0]).getText()); |
491 | 1 | assertTrue(hideOptions[1] instanceof JPopupMenu.Separator); |
492 | 1 | assertEquals(JSeparator.HORIZONTAL, |
493 | ((JSeparator) hideOptions[1]).getOrientation()); | |
494 | } | |
495 | ||
496 | /** | |
497 | * Test for adding sequence id, dbref and feature links | |
498 | */ | |
499 | 1 | @Test(groups = { "Functional" }) |
500 | public void testBuildLinkMenu() | |
501 | { | |
502 | 1 | List<SequenceI> seqs = parentPanel.getAlignment().getSequences(); |
503 | 1 | final SequenceI seq0 = seqs.get(0); |
504 | 1 | final SequenceI seq1 = seqs.get(1); |
505 | 1 | final List<SequenceFeature> noFeatures = Collections |
506 | .<SequenceFeature> emptyList(); | |
507 | 1 | final String linkText = MessageManager.getString("action.link"); |
508 | ||
509 | 1 | seq0.addDBRef(new DBRefEntry(DBRefSource.UNIPROT, "1", "P83527")); |
510 | 1 | seq0.addDBRef(new DBRefEntry("INTERPRO", "1", "IPR001041")); |
511 | 1 | seq0.addDBRef(new DBRefEntry("INTERPRO", "1", "IPR012675")); |
512 | 1 | seq0.addDBRef(new DBRefEntry("INTERPRO", "1", "IPR006058")); |
513 | 1 | seq1.addDBRef(new DBRefEntry(DBRefSource.UNIPROT, "1", "Q9ZTS2")); |
514 | 1 | seq1.addDBRef(new DBRefEntry("GENE3D", "1", "3.10.20.30")); |
515 | ||
516 | /* | |
517 | * check the Link Menu for the first sequence | |
518 | */ | |
519 | 1 | JMenu linkMenu = PopupMenu.buildLinkMenu(seq0, noFeatures); |
520 | 1 | assertEquals(linkText, linkMenu.getText()); |
521 | 1 | Component[] linkItems = linkMenu.getMenuComponents(); |
522 | ||
523 | /* | |
524 | * menu items are ordered: SEQUENCE_ID search first, then dbrefs in order | |
525 | * of database name (and within that by order of dbref addition) | |
526 | */ | |
527 | 1 | assertEquals(5, linkItems.length); |
528 | 1 | assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText()); |
529 | 1 | assertEquals("INTERPRO|IPR001041", |
530 | ((JMenuItem) linkItems[1]).getText()); | |
531 | 1 | assertEquals("INTERPRO|IPR012675", |
532 | ((JMenuItem) linkItems[2]).getText()); | |
533 | 1 | assertEquals("INTERPRO|IPR006058", |
534 | ((JMenuItem) linkItems[3]).getText()); | |
535 | 1 | assertEquals("UNIPROT|P83527", ((JMenuItem) linkItems[4]).getText()); |
536 | ||
537 | /* | |
538 | * check the Link Menu for the second sequence | |
539 | * note dbref GENE3D is matched to link Gene3D, the latter is displayed | |
540 | */ | |
541 | 1 | linkMenu = PopupMenu.buildLinkMenu(seq1, noFeatures); |
542 | 1 | linkItems = linkMenu.getMenuComponents(); |
543 | 1 | assertEquals(3, linkItems.length); |
544 | 1 | assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText()); |
545 | 1 | assertEquals("Gene3D|3.10.20.30", ((JMenuItem) linkItems[1]).getText()); |
546 | 1 | assertEquals("UNIPROT|Q9ZTS2", ((JMenuItem) linkItems[2]).getText()); |
547 | ||
548 | /* | |
549 | * if there are no valid links the Links submenu is still shown, but | |
550 | * reduced to the EMBL-EBI lookup only (inserted by | |
551 | * CustomUrlProvider.choosePrimaryUrl()) | |
552 | */ | |
553 | 1 | String unmatched = "NOMATCH|http://www.uniprot.org/uniprot/$" |
554 | + DB_ACCESSION + "$"; | |
555 | 1 | UrlProviderFactoryI factory = new DesktopUrlProviderFactory(null, |
556 | unmatched, ""); | |
557 | 1 | Preferences.sequenceUrlLinks = factory.createUrlProvider(); |
558 | ||
559 | 1 | linkMenu = PopupMenu.buildLinkMenu(seq1, noFeatures); |
560 | 1 | linkItems = linkMenu.getMenuComponents(); |
561 | 1 | assertEquals(1, linkItems.length); |
562 | 1 | assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText()); |
563 | ||
564 | /* | |
565 | * if sequence is null, only feature links are shown (alignment popup submenu) | |
566 | */ | |
567 | 1 | linkMenu = PopupMenu.buildLinkMenu(null, noFeatures); |
568 | 1 | linkItems = linkMenu.getMenuComponents(); |
569 | 1 | assertEquals(0, linkItems.length); |
570 | ||
571 | 1 | List<SequenceFeature> features = new ArrayList<>(); |
572 | 1 | SequenceFeature sf = new SequenceFeature("type", "desc", 1, 20, null); |
573 | 1 | features.add(sf); |
574 | 1 | linkMenu = PopupMenu.buildLinkMenu(null, features); |
575 | 1 | linkItems = linkMenu.getMenuComponents(); |
576 | 1 | assertEquals(0, linkItems.length); // feature has no links |
577 | ||
578 | 1 | sf.addLink("Pfam family|http://pfam.xfam.org/family/PF00111"); |
579 | 1 | linkMenu = PopupMenu.buildLinkMenu(null, features); |
580 | 1 | linkItems = linkMenu.getMenuComponents(); |
581 | 1 | assertEquals(1, linkItems.length); |
582 | 1 | JMenuItem item = (JMenuItem) linkItems[0]; |
583 | 1 | assertEquals("Pfam family", item.getText()); |
584 | // ? no way to verify URL, compiled into link's actionListener | |
585 | } | |
586 | ||
587 | 1 | @Test(groups = { "Functional" }) |
588 | public void testHideInsertions() | |
589 | { | |
590 | // get sequences from the alignment | |
591 | 1 | List<SequenceI> seqs = parentPanel.getAlignment().getSequences(); |
592 | ||
593 | // add our own seqs to avoid problems with changes to existing sequences | |
594 | // (gap at end of sequences varies depending on how tests are run!) | |
595 | 1 | Sequence seqGap1 = new Sequence("GappySeq", |
596 | "AAAA----AA-AAAAAAA---AAA-----------AAAAAAAAAA--"); | |
597 | 1 | seqGap1.createDatasetSequence(); |
598 | 1 | seqs.add(seqGap1); |
599 | 1 | Sequence seqGap2 = new Sequence("LessGappySeq", |
600 | "AAAAAA-AAAAA---AAA--AAAAA--AAAAAAA-AAAAAA"); | |
601 | 1 | seqGap2.createDatasetSequence(); |
602 | 1 | seqs.add(seqGap2); |
603 | 1 | Sequence seqGap3 = new Sequence("AnotherGapSeq", |
604 | "AAAAAA-AAAAAA--AAAAAA-AAAAAAAAAAA---AAAAAAAA"); | |
605 | 1 | seqGap3.createDatasetSequence(); |
606 | 1 | seqs.add(seqGap3); |
607 | 1 | Sequence seqGap4 = new Sequence("NoGaps", |
608 | "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); | |
609 | 1 | seqGap4.createDatasetSequence(); |
610 | 1 | seqs.add(seqGap4); |
611 | ||
612 | 1 | ColumnSelection sel = new ColumnSelection(); |
613 | 1 | parentPanel.av.getAlignment().getHiddenColumns() |
614 | .revealAllHiddenColumns(sel); | |
615 | ||
616 | // get the Popup Menu for 7th sequence - no insertions | |
617 | 1 | testee = new PopupMenu(parentPanel, seqs.get(7), null); |
618 | 1 | testee.hideInsertions_actionPerformed(null); |
619 | ||
620 | 1 | HiddenColumns hidden = parentPanel.av.getAlignment().getHiddenColumns(); |
621 | 1 | Iterator<int[]> it = hidden.iterator(); |
622 | 1 | assertFalse(it.hasNext()); |
623 | ||
624 | // get the Popup Menu for GappySeq - this time we have insertions | |
625 | 1 | testee = new PopupMenu(parentPanel, seqs.get(4), null); |
626 | 1 | testee.hideInsertions_actionPerformed(null); |
627 | 1 | hidden = parentPanel.av.getAlignment().getHiddenColumns(); |
628 | 1 | it = hidden.iterator(); |
629 | ||
630 | 1 | assertTrue(it.hasNext()); |
631 | 1 | int[] region = it.next(); |
632 | 1 | assertEquals(region[0], 4); |
633 | 1 | assertEquals(region[1], 7); |
634 | ||
635 | 1 | assertTrue(it.hasNext()); |
636 | 1 | region = it.next(); |
637 | 1 | assertEquals(region[0], 10); |
638 | 1 | assertEquals(region[1], 10); |
639 | ||
640 | 1 | assertTrue(it.hasNext()); |
641 | 1 | region = it.next(); |
642 | 1 | assertEquals(region[0], 18); |
643 | 1 | assertEquals(region[1], 20); |
644 | ||
645 | 1 | assertTrue(it.hasNext()); |
646 | 1 | region = it.next(); |
647 | 1 | assertEquals(region[0], 24); |
648 | 1 | assertEquals(region[1], 34); |
649 | ||
650 | 1 | assertTrue(it.hasNext()); |
651 | 1 | region = it.next(); |
652 | 1 | assertEquals(region[0], 45); |
653 | 1 | assertEquals(region[1], 46); |
654 | ||
655 | 1 | assertFalse(it.hasNext()); |
656 | ||
657 | 1 | sel = new ColumnSelection(); |
658 | 1 | hidden.revealAllHiddenColumns(sel); |
659 | ||
660 | // make a sequence group and hide insertions within the group | |
661 | 1 | SequenceGroup sg = new SequenceGroup(); |
662 | 1 | sg.setStartRes(8); |
663 | 1 | sg.setEndRes(42); |
664 | 1 | sg.addSequence(seqGap2, false); |
665 | 1 | sg.addSequence(seqGap3, false); |
666 | 1 | parentPanel.av.setSelectionGroup(sg); |
667 | ||
668 | // hide columns outside and within selection | |
669 | // only hidden columns outside the collection will be retained (unless also | |
670 | // gaps in the selection) | |
671 | 1 | hidden.hideColumns(1, 10); |
672 | 1 | hidden.hideColumns(31, 40); |
673 | ||
674 | // get the Popup Menu for LessGappySeq in the sequence group | |
675 | 1 | testee = new PopupMenu(parentPanel, seqs.get(5), null); |
676 | 1 | testee.hideInsertions_actionPerformed(null); |
677 | 1 | hidden = parentPanel.av.getAlignment().getHiddenColumns(); |
678 | 1 | it = hidden.iterator(); |
679 | ||
680 | 1 | assertTrue(it.hasNext()); |
681 | 1 | region = it.next(); |
682 | 1 | assertEquals(region[0], 1); |
683 | 1 | assertEquals(region[1], 7); |
684 | ||
685 | 1 | assertTrue(it.hasNext()); |
686 | 1 | region = it.next(); |
687 | 1 | assertEquals(region[0], 13); |
688 | 1 | assertEquals(region[1], 14); |
689 | ||
690 | 1 | assertTrue(it.hasNext()); |
691 | 1 | region = it.next(); |
692 | 1 | assertEquals(region[0], 34); |
693 | 1 | assertEquals(region[1], 34); |
694 | } | |
695 | ||
696 | 1 | @Test(groups = { "Functional" }) |
697 | public void testAddFeatureDetails() | |
698 | { | |
699 | 1 | String menuText = MessageManager.getString("label.feature_details"); |
700 | ||
701 | /* | |
702 | * with no features, sub-menu should not be created | |
703 | */ | |
704 | 1 | List<SequenceFeature> features = new ArrayList<>(); |
705 | 1 | SequenceI seq = this.alignment.getSequenceAt(0); // FER_CAPAA/1-12 |
706 | 1 | testee.addFeatureDetails(features, seq, 10); |
707 | 1 | JMenu menu = findMenu(testee, menuText); |
708 | 1 | assertNull(menu); |
709 | ||
710 | /* | |
711 | * add some features; the menu item text is wrapped in html, and includes | |
712 | * feature type, position, description, group (if not null) | |
713 | */ | |
714 | 1 | SequenceFeature sf1 = new SequenceFeature("helix", "curly", 2, 6, null); |
715 | 1 | SequenceFeature sf2 = new SequenceFeature("chain", "straight", 1, 1, |
716 | "uniprot"); | |
717 | 1 | features.add(sf1); |
718 | 1 | features.add(sf2); |
719 | 1 | testee.addFeatureDetails(features, seq, 10); |
720 | 1 | menu = findMenu(testee, menuText); |
721 | 1 | assertNotNull(menu); |
722 | 1 | assertEquals(2, menu.getItemCount()); |
723 | 1 | JMenuItem item = menu.getItem(0); |
724 | 1 | assertEquals("<html>helix 2-6 curly</html>", item.getText()); |
725 | 1 | item = menu.getItem(1); |
726 | 1 | assertEquals("<html>chain 1 straight (uniprot)</html>", item.getText()); |
727 | ||
728 | /* | |
729 | * long feature descriptions are truncated to 40 characters | |
730 | */ | |
731 | 1 | sf1.setDescription("this is a quite extraordinarily long description"); |
732 | 1 | testee.remove(menu); // don't create the sub-menu twice |
733 | 1 | testee.addFeatureDetails(features, seq, 10); |
734 | 1 | menu = findMenu(testee, menuText); |
735 | 1 | item = menu.getItem(0); |
736 | 1 | assertEquals( |
737 | "<html>helix 2-6 this is a quite extraordinarily long des...</html>", | |
738 | item.getText()); | |
739 | } | |
740 | ||
741 | /** | |
742 | * Returns the first component which is a JMenu with the given text | |
743 | * | |
744 | * @param c | |
745 | * @param text | |
746 | * @return | |
747 | */ | |
748 | 3 | private JMenu findMenu(Container c, String text) |
749 | { | |
750 | 18 | for (int i = 0; i < c.getComponentCount(); i++) |
751 | { | |
752 | 17 | Component comp = c.getComponent(i); |
753 | 17 | if ((comp instanceof JMenu) && ((JMenu) comp).getText().equals(text)) |
754 | { | |
755 | 2 | return (JMenu) comp; |
756 | } | |
757 | } | |
758 | 1 | return null; |
759 | } | |
760 | ||
761 | 1 | @Test(groups = { "Functional" }) |
762 | public void testAddFeatureDetails_linkedFeatures() | |
763 | { | |
764 | // todo tests that verify menu items for complement features | |
765 | } | |
766 | } |