2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
23 import static org.testng.Assert.assertEquals;
24 import static org.testng.Assert.assertNotEquals;
26 import java.awt.Dimension;
28 import java.awt.FontMetrics;
29 import java.lang.reflect.InvocationTargetException;
31 import javax.swing.SwingUtilities;
33 import org.testng.annotations.BeforeMethod;
34 import org.testng.annotations.Test;
36 import jalview.api.AlignViewportI;
37 import jalview.bin.Cache;
38 import jalview.bin.Jalview;
39 import jalview.datamodel.AlignmentAnnotation;
40 import jalview.datamodel.SequenceI;
41 import jalview.io.DataSourceType;
42 import jalview.io.FileLoader;
43 import jalview.util.Platform;
44 import jalview.viewmodel.ViewportRanges;
46 public class AlignmentPanelTest
50 @BeforeMethod(alwaysRun = true)
51 public void setUp() throws InvocationTargetException, InterruptedException
53 Jalview.main(new String[] { "-nonews",
54 "-props", "test/jalview/testProps.jvprops",
57 Cache.setPropertyNoSave("SHOW_IDENTITY",
58 Boolean.TRUE.toString());
59 af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
63 * ensure the panel has been repainted and so ViewportRanges set
65 SwingUtilities.invokeAndWait(new Runnable() {
72 * wait for Consensus thread to complete
79 } catch (InterruptedException x)
82 } while (af.getViewport().getCalcManager().isWorking());
86 * Test side effect that end residue is set correctly by setScrollValues, with
87 * or without hidden columns
89 @Test(groups = "Functional")
90 public void testSetScrollValues()
92 ViewportRanges ranges = af.getViewport().getRanges();
93 af.alignPanel.setScrollValues(0, 0);
95 int oldres = ranges.getEndRes();
96 af.alignPanel.setScrollValues(-1, 5);
98 // setting -ve x value does not change residue
99 // no update necessary now
100 assertEquals(ranges.getEndRes(), oldres);
102 af.alignPanel.setScrollValues(0, 5);
103 // no update necessary now
104 // setting 0 as x value does not change residue
105 // no update necessary now
106 assertEquals(ranges.getEndRes(), oldres);
108 af.alignPanel.setScrollValues(5, 5);
109 // setting x value to 5 extends endRes by 5 residues
110 System.out.println(ranges);
111 // no update necessary now
112 assertEquals(ranges.getEndRes(), oldres + 5);
114 // scroll to position after hidden columns sets endres to oldres (width) +
117 int scrollpos = 53; // was 60, but this is too high to allow full scrolling
119 af.getViewport().hideColumns(30, 50);
120 af.alignPanel.setScrollValues(scrollpos, 5);
121 // no update necessary now
122 assertEquals(ranges.getEndRes(), oldres + scrollpos);
124 // scroll to position within hidden columns, still sets endres to oldres +
126 // not sure if this is actually correct behaviour but this is what Jalview
129 af.getViewport().showAllHiddenColumns();
130 af.getViewport().hideColumns(30, 50);
131 af.alignPanel.setScrollValues(scrollpos, 5);
132 // no update necessary now
133 assertEquals(ranges.getEndRes(), oldres + scrollpos);
135 // scroll to position within <width> distance of the end of the alignment
136 // endRes should be set to width of alignment - 1
138 af.getViewport().showAllHiddenColumns();
139 af.alignPanel.setScrollValues(scrollpos, 5);
140 // no update necessary now
141 assertEquals(ranges.getEndRes(),
142 af.getViewport().getAlignment().getWidth() - 1);
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
148 af.getViewport().hideColumns(30, 50);
149 af.alignPanel.setScrollValues(scrollpos, 5);
150 // no update necessary now
151 assertEquals(ranges.getEndRes(),
152 af.getViewport().getAlignment().getWidth() - 1 - 21); // 21 is the
159 * Test that update layout reverts to original (unwrapped) values for endRes
160 * when switching from wrapped back to unwrapped mode (JAL-2739)
162 @Test(groups = "Functional")
163 public void testUpdateLayout_endRes()
165 // get details of original alignment dimensions
166 ViewportRanges ranges = af.getViewport().getRanges();
167 int endres = ranges.getEndRes();
170 af.alignPanel.getAlignViewport().setWrapAlignment(true);
171 af.alignPanel.updateLayout();
173 // endRes has changed
174 assertNotEquals(ranges.getEndRes(), endres);
177 af.alignPanel.getAlignViewport().setWrapAlignment(false);
178 af.alignPanel.updateLayout();
180 // endRes back to original value
181 assertEquals(ranges.getEndRes(), endres);
185 * Test the variant of calculateIdWidth that only recomputes the width if it is
186 * not already saved in the viewport (initial value is -1)
188 @Test(groups = "Functional")
189 public void testCalculateIdWidth_noArgs()
191 AlignViewportI av = af.alignPanel.getAlignViewport();
192 av.setShowJVSuffix(true);
193 av.setFont(new Font("Courier", Font.PLAIN, 15), true);
196 Dimension d = af.alignPanel.calculateIdWidth();
197 assertEquals(d.width, 0);
198 assertEquals(d.height, 0);
201 d = af.alignPanel.calculateIdWidth();
202 assertEquals(d.width, 99);
203 assertEquals(d.height, 0);
206 * note 4 pixels padding are added to the longest sequence name width
208 av.setIdWidth(-1); // force recalculation
210 d = af.alignPanel.calculateIdWidth();
211 assertEquals(d.width, Platform.isWin() ? 172 : 166); // 4 + pixel width of "Q93Z60_ARATH/1-118"
212 assertEquals(d.height, 12);
213 assertEquals(d.width, av.getIdWidth());
217 * Test the variant of calculateIdWidth that computes the longest of any
218 * sequence name or annotation label width
220 @Test(groups = "Functional")
221 public void testCalculateIdWidth_withMaxWidth()
223 AlignViewportI av = af.alignPanel.getAlignViewport();
224 av.setShowJVSuffix(true);
225 av.setFont(new Font("Courier", Font.PLAIN, 15), true);
226 av.setShowAnnotation(false);
230 * note 4 pixels 'padding' are added to the longest seq name/annotation label
232 Dimension d = af.alignPanel.calculateIdWidth(2000);
233 assertEquals(d.width, Platform.isWin() ? 172 : 166); // 4 + pixel width of "Q93Z60_ARATH/1-118"
234 assertEquals(d.height, 12); // fixed value (not used?)
235 assertEquals(av.getIdWidth(), 18); // not changed by this method
238 * make the longest sequence name longer
240 SequenceI seq = af.viewport.getAlignment()
241 .findSequenceMatch("Q93Z60_ARATH")[0];
242 String orig = seq.getName();
243 seq.setName(orig + "MMMMM");
244 d = af.alignPanel.calculateIdWidth(2000);
245 assertEquals(d.width, Platform.isWin() ? 219 : 211); // 4 + pixel width of "Q93Z60_ARATHMMMMM/1-118"
246 assertEquals(d.height, 12);
247 assertEquals(av.getIdWidth(), 18); // unchanged
252 * make the longest annotation name even longer
253 * note this is checked even if annotations are not shown
255 AlignmentAnnotation aa = av.getAlignment().getAlignmentAnnotation()[0];
256 aa.label = "THIS IS A VERY LONG LABEL INDEED";
257 FontMetrics fmfor = af.alignPanel
258 .getFontMetrics(af.alignPanel.getAlabels().getFont());
259 // Assumption ID_WIDTH_PADDING == 4
260 // AH! But with those added MMMM above, this was NOT the longest label!
261 int expwidth = 4 + fmfor.stringWidth(aa.label);
262 d = af.alignPanel.calculateIdWidth(2000);
263 assertEquals(d.width, expwidth); // 191 == ID_WIDTH_PADDING + pixel width of "THIS IS A VERY LONG LABEL INDEED"
264 assertEquals(d.height, 12);
267 * override with maxwidth
268 * note the 4 pixels padding is added to this value
270 // BH but we have to be under the max width
271 d = af.alignPanel.calculateIdWidth(180);
272 assertEquals(d.width, 184);
273 assertEquals(d.height, 12);
276 @Test(groups = { "Functional", "Not-bamboo" })
277 public void testGetVisibleWidth()
280 * width for onscreen rendering is IDPanel width
282 int w = af.alignPanel.getVisibleIdWidth(true);
283 assertEquals(w, af.alignPanel.getIdPanel().getWidth());
284 assertEquals(w, Platform.isWin() ? 112 : 115);
287 * width for offscreen rendering is the same
288 * if no fixed id width is specified in preferences
290 Cache.setProperty("FIGURE_AUTOIDWIDTH", Boolean.FALSE.toString());
291 Cache.removeProperty("FIGURE_FIXEDIDWIDTH");
292 assertEquals(w, af.alignPanel.getVisibleIdWidth(false));
295 * preference for fixed id width - note 4 pixels padding is added
297 Cache.setProperty("FIGURE_FIXEDIDWIDTH", "120");
298 assertEquals(124, af.alignPanel.getVisibleIdWidth(false));
301 * preference for auto id width overrides fixed width
303 Cache.setProperty("FIGURE_AUTOIDWIDTH", Boolean.TRUE.toString());
304 assertEquals(Platform.isWin() ? 106 : 115, af.alignPanel.getVisibleIdWidth(false));