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