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