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.assertFalse;
25 import static org.testng.Assert.assertNotNull;
26 import static org.testng.Assert.assertNull;
27 import static org.testng.Assert.assertTrue;
30 import java.awt.FontMetrics;
32 import org.testng.annotations.BeforeMethod;
33 import org.testng.annotations.Test;
35 import jalview.bin.Cache;
36 import jalview.datamodel.AlignmentI;
37 import jalview.datamodel.SearchResults;
38 import jalview.datamodel.SearchResultsI;
39 import jalview.io.DataSourceType;
40 import jalview.io.FileLoader;
41 import junit.extensions.PA;
43 public class SeqCanvasTest
45 private AlignFrame af;
48 * Test the method that computes wrapped width in residues, height of wrapped
49 * widths in pixels, and the number of widths visible
51 @Test(groups = "Functional")
52 public void testCalculateWrappedGeometry_noAnnotations()
54 AlignViewport av = af.getViewport();
55 AlignmentI al = av.getAlignment();
56 assertEquals(al.getWidth(), 157);
57 assertEquals(al.getHeight(), 15);
58 av.getRanges().setStartEndSeq(0, 14);
60 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
62 av.setWrapAlignment(true);
63 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
64 int charHeight = av.getCharHeight();
65 int charWidth = av.getCharWidth();
66 assertEquals(charHeight, 17);
67 assertEquals(charWidth, 12);
70 * first with scales above, left, right
72 av.setShowAnnotation(false);
73 av.setScaleAboveWrapped(true);
74 av.setScaleLeftWrapped(true);
75 av.setScaleRightWrapped(true);
76 FontMetrics fm = testee.getFontMetrics(av.getFont());
77 int labelWidth = fm.stringWidth("000") + charWidth;
78 // some leeway for different OS rendering of text
79 assertTrue(labelWidth >= 36 && labelWidth <= 39);
82 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
83 * take the whole multiple of character widths
85 int canvasWidth = 400;
86 int canvasHeight = 300;
87 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
88 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
90 assertEquals(wrappedWidth, residueColumns);
91 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
92 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
93 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
95 int repeatingHeight = (int) PA.getValue(testee,
96 "wrappedRepeatHeightPx");
97 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
98 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
101 * repeat height is 17 * (2 + 15) = 289
102 * make canvas height 2 * 289 + 3 * charHeight so just enough to
103 * draw 2 widths and the first sequence of a third
105 canvasHeight = charHeight * (17 * 2 + 3);
106 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
107 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
110 * reduce canvas height by 1 pixel
111 * - should not be enough height to draw 3 widths
114 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
115 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
118 * turn off scale above - can now fit in 2 and a bit widths
120 av.setScaleAboveWrapped(false);
121 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
122 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
125 * reduce height to enough for 2 widths and not quite a third
126 * i.e. two repeating heights + spacer + sequence - 1 pixel
128 canvasHeight = charHeight * (16 * 2 + 2) - 1;
129 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
130 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
133 * make canvas width enough for scales and 20 residues
135 canvasWidth = 2 * labelWidth + 20 * charWidth;
136 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
138 assertEquals(wrappedWidth, 20);
141 * reduce width by 1 pixel - rounds down to 19 residues
144 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
146 assertEquals(wrappedWidth, 19);
149 * turn off West scale - adds labelWidth (39) to available for residues
150 * which with the 11 remainder makes 50 which is 4 more charWidths rem 2
152 av.setScaleLeftWrapped(false);
153 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
155 // some leeway for different OS rendering of text
156 assertTrue(wrappedWidth >= 22 && wrappedWidth <= 23);
157 int difference = wrappedWidth - 23;
160 * add 10 pixels to width to fit in another whole residue column
163 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
165 assertEquals(wrappedWidth, 23);
167 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
169 assertEquals(wrappedWidth, 24 + difference);
172 * turn off East scale to gain 39 more pixels (3 columns remainder 3)
174 av.setScaleRightWrapped(false);
175 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
177 assertEquals(wrappedWidth, 27 + difference);
180 * add 9 pixels to width to gain a residue column
183 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
185 assertEquals(wrappedWidth, 27); // 8px not enough
187 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
189 assertEquals(wrappedWidth, 28 + difference); // 9px is enough
192 * now West but not East scale - lose 39 pixels or 4 columns
194 av.setScaleLeftWrapped(true);
195 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
197 assertEquals(wrappedWidth, 24);
200 * adding 3 pixels to width regains one column
203 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
205 assertEquals(wrappedWidth, 24); // 2px not enough
207 wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
209 assertEquals(wrappedWidth, 25 + difference); // 3px is enough
212 * turn off scales left and right, make width exactly 157 columns
214 av.setScaleLeftWrapped(false);
215 canvasWidth = al.getWidth() * charWidth;
216 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
217 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
221 * Test the method that computes wrapped width in residues, height of wrapped
222 * widths in pixels, and the number of widths visible
224 @Test(groups = "Functional")
225 public void testCalculateWrappedGeometry_withAnnotations()
227 AlignViewport av = af.getViewport();
228 AlignmentI al = av.getAlignment();
229 assertEquals(al.getWidth(), 157);
230 assertEquals(al.getHeight(), 15);
232 av.setWrapAlignment(true);
233 av.getRanges().setStartEndSeq(0, 14);
234 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
235 int charHeight = av.getCharHeight();
236 int charWidth = av.getCharWidth();
237 assertEquals(charHeight, 17);
238 assertEquals(charWidth, 12);
240 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
243 * first with scales above, left, right
245 av.setShowAnnotation(true);
246 av.setScaleAboveWrapped(true);
247 av.setScaleLeftWrapped(true);
248 av.setScaleRightWrapped(true);
249 FontMetrics fm = testee.getFontMetrics(av.getFont());
250 int labelWidth = fm.stringWidth("000") + charWidth;
251 // some leeway for different OS rendering of text
252 assertTrue(labelWidth >= 36 && labelWidth <= 39);
253 int annotationHeight = testee.getAnnotationHeight();
256 * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
257 * take the whole multiple of character widths
259 int canvasWidth = 400;
260 int canvasHeight = 300;
261 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
262 int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
264 assertEquals(wrappedWidth, residueColumns);
265 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
266 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
267 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
269 int repeatingHeight = (int) PA.getValue(testee,
270 "wrappedRepeatHeightPx");
271 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight())
272 + SeqCanvas.SEQS_ANNOTATION_GAP + annotationHeight);
273 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
276 * repeat height is 17 * (2 + 15) = 289 + 3 + annotationHeight = 510
277 * make canvas height 2 of these plus 3 charHeights
278 * so just enough to draw 2 widths, gap + scale + the first sequence of a third
280 canvasHeight = charHeight * (17 * 2 + 3)
281 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP);
282 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
283 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
286 * reduce canvas height by 1 pixel - should not be enough height
290 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
291 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
294 * turn off scale above - can now fit in 2 and a bit widths
296 av.setScaleAboveWrapped(false);
297 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
298 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
301 * reduce height to enough for 2 widths and not quite a third
302 * i.e. two repeating heights + spacer + sequence - 1 pixel
304 canvasHeight = charHeight * (16 * 2 + 2)
305 + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP) - 1;
306 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
307 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
310 * add 1 pixel to height - should now get 3 widths drawn
313 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
314 assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
318 * Test simulates loading an unwrapped alignment, shrinking it vertically so
319 * not all sequences are visible, then changing to wrapped mode. The ranges
320 * endSeq should be unchanged, but the vertical repeat height should include
323 @Test(groups = "Functional_Failing")
324 public void testCalculateWrappedGeometry_fromScrolled()
326 AlignViewport av = af.getViewport();
327 AlignmentI al = av.getAlignment();
328 assertEquals(al.getWidth(), 157);
329 assertEquals(al.getHeight(), 15);
330 av.getRanges().setStartEndSeq(0, 3);
331 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
332 av.setWrapAlignment(true);
333 av.setShowAnnotation(false);
334 av.setScaleAboveWrapped(true);
336 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
338 int charHeight = av.getCharHeight();
339 int charWidth = av.getCharWidth();
340 assertEquals(charHeight, 17);
341 assertEquals(charWidth, 12);
343 int canvasWidth = 400;
344 int canvasHeight = 300;
345 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
347 assertEquals(av.getRanges().getEndSeq(), 3); // unchanged
348 int repeatingHeight = (int) PA.getValue(testee,
349 "wrappedRepeatHeightPx");
350 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
353 @BeforeMethod(alwaysRun = true)
356 Cache.loadProperties("test/jalview/io/testProps.jvprops");
357 Cache.applicationProperties.setProperty("SHOW_IDENTITY",
358 Boolean.TRUE.toString());
359 af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
360 DataSourceType.FILE);
363 * wait for Consensus thread to complete
370 } catch (InterruptedException x)
373 } while (af.getViewport().getCalcManager().isWorking());
376 @Test(groups = "Functional")
377 public void testClear_HighlightAndSelection()
379 AlignViewport av = af.getViewport();
380 SearchResultsI highlight = new SearchResults();
382 av.getAlignment().getSequenceAt(1).getDatasetSequence(), 50,
384 af.alignPanel.highlightSearchResults(highlight);
385 af.avc.markHighlightedColumns(false, false, false);
386 assertNotNull(av.getSearchResults(),
387 "No highlight was created on alignment");
388 assertFalse(av.getColumnSelection().isEmpty(),
389 "No selection was created from highlight");
390 af.deselectAllSequenceMenuItem_actionPerformed(null);
391 assertTrue(av.getColumnSelection().isEmpty(),
392 "No Selection should be present after deselecting all.");
393 assertNull(av.getSearchResults(),
394 "No higlighted search results should be present after deselecting all.");