JAL-629 test fixing
[jalview.git] / test / jalview / gui / AlignmentPanelTest.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.Assert.assertEquals;
24 import static org.testng.Assert.assertNotEquals;
25 import static org.testng.Assert.assertNotNull;
26
27 import java.awt.Dimension;
28 import java.awt.Font;
29 import java.awt.FontMetrics;
30 import java.lang.reflect.InvocationTargetException;
31
32 import javax.swing.SwingUtilities;
33
34 import org.testng.annotations.BeforeMethod;
35 import org.testng.annotations.Test;
36
37 import jalview.api.AlignViewportI;
38 import jalview.bin.Cache;
39 import jalview.bin.Jalview;
40 import jalview.datamodel.AlignmentAnnotation;
41 import jalview.datamodel.SequenceI;
42 import jalview.io.DataSourceType;
43 import jalview.io.FileLoader;
44 import jalview.viewmodel.ViewportRanges;
45
46 public class AlignmentPanelTest
47 {
48   AlignFrame af;
49
50   @BeforeMethod(alwaysRun = true)
51   public void setUp() throws InvocationTargetException, InterruptedException
52   {
53     Jalview.main(
54             new String[]
55             { "-nonews", "-props", "test/jalview/testProps.jvprops" });
56
57     Cache.applicationProperties.setProperty("SHOW_IDENTITY",
58             Boolean.TRUE.toString());
59     af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
60             DataSourceType.FILE);
61
62     /*
63      * ensure the panel has been repainted and so ViewportRanges set
64      */
65     SwingUtilities.invokeAndWait(new Runnable()
66     {
67       @Override
68       public void run()
69       {
70         af.repaint();
71       }
72     });
73
74     /*
75      * wait for Consensus thread to complete
76      */
77     do
78     {
79       try
80       {
81         Thread.sleep(50);
82       } catch (InterruptedException x)
83       {
84       }
85     } while (af.getViewport().getCalcManager().isWorking());
86   }
87
88   /**
89    * Test side effect that end residue is set correctly by setScrollValues, with
90    * or without hidden columns
91    */
92   @Test(groups = "Functional")
93   public void testSetScrollValues()
94   {
95     ViewportRanges ranges = af.getViewport().getRanges();
96     af.alignPanel.setScrollValues(0, 0);
97
98     int oldres = ranges.getEndRes();
99     af.alignPanel.setScrollValues(-1, 5);
100
101     // setting -ve x value does not change residue
102     assertEquals(ranges.getEndRes(), oldres);
103
104     af.alignPanel.setScrollValues(0, 5);
105
106     // setting 0 as x value does not change residue
107     assertEquals(ranges.getEndRes(), oldres);
108
109     af.alignPanel.setScrollValues(5, 5);
110     // setting x value to 5 extends endRes by 5 residues
111     assertEquals(ranges.getEndRes(), oldres + 5);
112
113     // scroll to position after hidden columns sets endres to oldres (width) +
114     // position
115     int scrollpos = 60;
116     af.getViewport().hideColumns(30, 50);
117     af.alignPanel.setScrollValues(scrollpos, 5);
118     assertEquals(ranges.getEndRes(), oldres + scrollpos);
119
120     // scroll to position within hidden columns, still sets endres to oldres +
121     // position
122     // not sure if this is actually correct behaviour but this is what Jalview
123     // currently does
124     scrollpos = 40;
125     af.getViewport().showAllHiddenColumns();
126     af.getViewport().hideColumns(30, 50);
127     af.alignPanel.setScrollValues(scrollpos, 5);
128     assertEquals(ranges.getEndRes(), oldres + scrollpos);
129
130     // scroll to position within <width> distance of the end of the alignment
131     // endRes should be set to width of alignment - 1
132     scrollpos = 130;
133     af.getViewport().showAllHiddenColumns();
134     af.alignPanel.setScrollValues(scrollpos, 5);
135     assertEquals(ranges.getEndRes(),
136             af.getViewport().getAlignment().getWidth() - 1);
137
138     // now hide some columns, and scroll to position within <width>
139     // distance of the end of the alignment
140     // endRes should be set to width of alignment - 1 - the number of hidden
141     // columns
142     af.getViewport().hideColumns(30, 50);
143     af.alignPanel.setScrollValues(scrollpos, 5);
144     assertEquals(ranges.getEndRes(),
145             af.getViewport().getAlignment().getWidth() - 1 - 21); // 21 is the
146                                                                   // number of
147                                                                   // hidden
148                                                                   // columns
149   }
150
151   /**
152    * Test that update layout reverts to original (unwrapped) values for endRes
153    * when switching from wrapped back to unwrapped mode (JAL-2739)
154    */
155   @Test(groups = "Functional")
156   public void testUpdateLayout_endRes()
157   {
158     // get details of original alignment dimensions
159     ViewportRanges ranges = af.getViewport().getRanges();
160     int endres = ranges.getEndRes();
161
162     // wrap
163     af.alignPanel.getAlignViewport().setWrapAlignment(true);
164     af.alignPanel.updateLayout();
165
166     // endRes has changed
167     assertNotEquals(ranges.getEndRes(), endres);
168
169     // unwrap
170     af.alignPanel.getAlignViewport().setWrapAlignment(false);
171     af.alignPanel.updateLayout();
172
173     // endRes back to original value
174     assertEquals(ranges.getEndRes(), endres);
175   }
176
177   /**
178    * Test the variant of calculateIdWidth that only recomputes the width if it
179    * is not already saved in the viewport (initial value is -1)
180    */
181   @Test(groups = "Functional")
182   public void testCalculateIdWidth_noArgs()
183   {
184     AlignViewportI av = af.alignPanel.getAlignViewport();
185     av.setShowJVSuffix(true);
186     av.setFont(new Font("Courier", Font.PLAIN, 15), true);
187
188     av.setIdWidth(0);
189     Dimension d = af.alignPanel.calculateIdWidth();
190     assertEquals(d.width, 0);
191     assertEquals(d.height, 0);
192
193     av.setIdWidth(99);
194     d = af.alignPanel.calculateIdWidth();
195     assertEquals(d.width, 99);
196     assertEquals(d.height, 0);
197
198     /*
199      * note 4 pixels padding are added to the longest sequence name width
200      */
201     av.setIdWidth(-1); // force recalculation
202     d = af.alignPanel.calculateIdWidth();
203     assertEquals(d.width, 166); // 4 + pixel width of "Q93Z60_ARATH/1-118"
204     assertEquals(d.height, 12);
205     assertEquals(d.width, av.getIdWidth());
206   }
207
208   /**
209    * Test the variant of calculateIdWidth that computes the longest of any
210    * sequence name or annotation label width
211    */
212   @Test(groups = "Functional")
213   public void testCalculateIdWidth_withMaxWidth()
214   {
215     AlignViewportI av = af.alignPanel.getAlignViewport();
216     av.setShowJVSuffix(true);
217     av.setFont(new Font("Courier", Font.PLAIN, 15), true);
218     av.setShowAnnotation(false);
219     av.setIdWidth(18);
220
221     /*
222      * note 4 pixels 'padding' are added to the longest seq name/annotation label
223      */
224     Dimension d = af.alignPanel.calculateIdWidth(2000);
225     assertEquals(d.width, 166); // 4 + pixel width of "Q93Z60_ARATH/1-118"
226     assertEquals(d.height, 12); // fixed value (not used?)
227     assertEquals(av.getIdWidth(), 18); // not changed by this method
228
229     /*
230      * make the longest sequence name longer
231      */
232     SequenceI seq = af.viewport.getAlignment()
233             .findSequenceMatch("Q93Z60_ARATH")[0];
234     seq.setName(seq.getName() + "MMMMM");
235     d = af.alignPanel.calculateIdWidth(2000);
236     assertEquals(d.width, 211); // 4 + pixel width of "Q93Z60_ARATHMMMMM/1-118"
237     assertEquals(d.height, 12);
238     assertEquals(av.getIdWidth(), 18); // unchanged
239
240     /*
241      * make the longest annotation name even longer
242      * note this is checked even if annotations are not shown
243      */
244     AlignmentAnnotation aa = av.getAlignment().getAlignmentAnnotation()[0];
245     aa.label = "THIS IS A VERY LONG LABEL INDEED";
246     FontMetrics fmfor = af.alignPanel
247             .getFontMetrics(af.alignPanel.getAlabels().getFont());
248     // Assumption ID_WIDTH_PADDING == 4
249     int expwidth = 4 + fmfor.stringWidth(aa.label);
250     d = af.alignPanel.calculateIdWidth(2000);
251     assertEquals(d.width, expwidth); // 228 == ID_WIDTH_PADDING + pixel width of
252                                      // "THIS IS A VERY LONG LABEL INDEED"
253     assertEquals(d.height, 12);
254
255     /*
256      * override with maxwidth
257      * note the 4 pixels padding is added to this value
258      */
259     d = af.alignPanel.calculateIdWidth(213);
260     assertEquals(d.width, 217);
261     assertEquals(d.height, 12);
262   }
263
264   @Test(groups = { "Functional", "Not-bamboo" })
265   public void testGetVisibleWidth()
266   {
267     /*
268      * width for onscreen rendering is IDPanel width
269      */
270     int w = af.alignPanel.getVisibleIdWidth(true);
271     assertEquals(w, af.alignPanel.getIdPanel().getWidth());
272     assertEquals(w, 115);
273
274     /*
275      * width for offscreen rendering is the same
276      * if no fixed id width is specified in preferences
277      */
278     Cache.setProperty("FIGURE_AUTOIDWIDTH", Boolean.FALSE.toString());
279     Cache.removeProperty("FIGURE_FIXEDIDWIDTH");
280     assertEquals(w, af.alignPanel.getVisibleIdWidth(false));
281
282     /*
283      * preference for fixed id width - note 4 pixels padding is added
284      */
285     Cache.setProperty("FIGURE_FIXEDIDWIDTH", "120");
286     assertEquals(124, af.alignPanel.getVisibleIdWidth(false));
287
288     /*
289      * preference for auto id width overrides fixed width
290      */
291     Cache.setProperty("FIGURE_AUTOIDWIDTH", Boolean.TRUE.toString());
292     assertEquals(115, af.alignPanel.getVisibleIdWidth(false));
293   }
294  
295   @Test(groups = "Functional")
296   public void testSetOverviewTitle()
297   {
298     OverviewPanel ov1 = this.af.openOverviewPanel(true);
299     String alignFrameTitle = af.getTitle();
300     assertEquals(ov1.getTitle(), "Overview " + alignFrameTitle);
301     
302     /*
303      * on New View, existing overview should get " Original" added to title
304      * and new view's overview should get " View 1" added
305      */
306     af.newView_actionPerformed(null);
307     assertEquals(ov1.getTitle(), "Overview " + alignFrameTitle + " Original");
308     OverviewPanel ov2 = this.af.openOverviewPanel(true);
309     assertEquals(ov2.getTitle(), "Overview " + alignFrameTitle + " View 1");
310   }
311   
312   @Test(groups = "Functional")
313   public void testSetOverviewTitle_automaticOverview()
314   {
315     Cache.setProperty("SHOW_OVERVIEW",  "true");
316     AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
317             "examples/uniref50.fa", DataSourceType.FILE);
318     OverviewPanel ov1 = alignFrame.alignPanel.getOverviewPanel();
319     assertNotNull(ov1);
320     String alignFrameTitle = alignFrame.getTitle();
321     assertEquals(ov1.getTitle(), "Overview " + alignFrameTitle);
322     
323     /*
324      * on New View, existing overview should get " Original" added to title
325      * and new view's automatic overview should have " View 1" added
326      */
327     alignFrame.newView_actionPerformed(null);
328     assertEquals(ov1.getTitle(), "Overview " + alignFrameTitle + " Original");
329     OverviewPanel ov2 = alignFrame.alignPanel.getOverviewPanel();
330     assertNotNull(ov2);
331     assertEquals(ov2.getTitle(), "Overview " + alignFrameTitle + " View 1");
332   }
333 }