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