Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 16:11:35 GMT
  2. Package jalview.gui

File SeqCanvasTest.java

 

Code metrics

16
168
6
1
398
239
15
0.09
28
6
2.5

Classes

Class Line # Actions
SeqCanvasTest 47 168 15
0.847368484.7%
 

Contributing tests

This file is covered by 3 tests. .

Source view

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.assertFalse;
25    import static org.testng.Assert.assertNotNull;
26    import static org.testng.Assert.assertNull;
27    import static org.testng.Assert.assertTrue;
28   
29    import java.awt.Font;
30    import java.awt.FontMetrics;
31   
32    import org.testng.annotations.BeforeClass;
33    import org.testng.annotations.BeforeMethod;
34    import org.testng.annotations.Test;
35   
36    import jalview.bin.Cache;
37    import jalview.datamodel.AlignmentI;
38    import jalview.datamodel.SearchResults;
39    import jalview.datamodel.SearchResultsI;
40    import jalview.io.DataSourceType;
41    import jalview.io.FileLoader;
42   
43    import jalview.util.Platform;
44    import jalview.viewmodel.ViewportRanges;
45    import junit.extensions.PA;
46   
 
47    public class SeqCanvasTest
48    {
 
49  1 toggle @BeforeClass(alwaysRun = true)
50    public void setUp()
51    {
52  1 Cache.loadProperties(null);
53  1 Desktop.getInstance().setVisible(false);
54    }
55   
56    private AlignFrame af;
57   
58   
 
59  3 toggle @BeforeMethod(alwaysRun = true)
60    public void setUpMethod()
61    {
62  3 Cache.loadProperties("test/jalview/io/testProps.jvprops");
63  3 Cache.setOrRemove("SHOW_IDENTITY", Boolean.TRUE.toString());
64  3 af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
65    DataSourceType.FILE);
66   
67    /*
68    * wait for Consensus thread to complete
69    */
70  3 do
71    {
72  3 try
73    {
74  3 Thread.sleep(50);
75    } catch (InterruptedException x)
76    {
77    }
78  3 } while (af.getViewport().getCalcManager().isWorking());
79    }
80   
81    /**
82    * Test the method that computes wrapped width in residues, height of wrapped
83    * widths in pixels, and the number of widths visible
84    */
 
85  1 toggle @Test(groups = "Functional")
86    public void testCalculateWrappedGeometry_noAnnotations()
87    {
88  1 AlignViewport av = af.getViewport();
89  1 AlignmentI al = av.getAlignment();
90  1 assertEquals(al.getWidth(), 157);
91  1 assertEquals(al.getHeight(), 15);
92  1 av.getRanges().setStartEndSeq(0, 14);
93   
94  1 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
95   
96  1 av.setWrapAlignment(true);
97  1 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
98  1 int charHeight = av.getCharHeight();
99  1 int charWidth = av.getCharWidth();
100  1 assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
101  1 assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
102   
103    /*
104    * first with scales above, left, right
105    */
106  1 av.setShowAnnotation(false);
107  1 av.setScaleAboveWrapped(true);
108  1 av.setScaleLeftWrapped(true);
109  1 av.setScaleRightWrapped(true);
110  1 FontMetrics fm = testee.getFontMetrics(av.getFont());
111  1 int labelWidth = fm.stringWidth("000") + charWidth;
112    // some leeway for different OS rendering of text (from 2.11.5)
113  1 assertTrue(labelWidth >= 36 && labelWidth <= 39);
114  1 assertEquals(labelWidth,
115  1 !Platform.isWin() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
116   
117   
118    /*
119    * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
120    * take the whole multiple of character widths
121    */
122  1 int canvasWidth = 400;
123  1 int canvasHeight = 300;
124  1 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
125  1 int wrappedVisibleWidths = testee.calculateWrappedGeometry(canvasWidth,
126    canvasHeight);
127  1 int wrappedWidth = testee.getWrappedCanvasWidth(canvasWidth);
128  1 assertEquals(wrappedWidth, residueColumns);
129  1 assertEquals(wrappedVisibleWidths, 1);
130  1 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
131  1 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
132  1 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
133    2 * charHeight);
134  1 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
135  1 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
136   
137    /*
138    * repeat height is 17 * (2 + 15) = 289
139    * make canvas height 2 * 289 + 3 * charHeight so just enough to
140    * draw 2 widths and the first sequence of a third
141    */
142  1 canvasHeight = charHeight * (17 * 2 + 3);
143  1 wrappedVisibleWidths = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
144  1 assertEquals(wrappedVisibleWidths, 3);
145   
146    /*
147    * reduce canvas height by 1 pixel
148    * - should not be enough height to draw 3 widths
149    */
150  1 canvasHeight -= 1;
151  1 wrappedVisibleWidths = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
152  1 assertEquals(wrappedVisibleWidths, 2);
153   
154    /*
155    * turn off scale above - can now fit in 2 and a bit widths
156    */
157  1 av.setScaleAboveWrapped(false);
158  1 wrappedVisibleWidths = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
159  1 assertEquals(wrappedVisibleWidths, 3);
160   
161    /*
162    * reduce height to enough for 2 widths and not quite a third
163    * i.e. two repeating heights + spacer + sequence - 1 pixel
164    */
165  1 canvasHeight = charHeight * (16 * 2 + 2) - 1;
166  1 wrappedVisibleWidths = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
167  1 assertEquals(wrappedVisibleWidths, 2);
168   
169    /*
170    * make canvas width enough for scales and 20 residues
171    */
172  1 canvasWidth = 2 * labelWidth + 20 * charWidth;
173  1 wrappedWidth = testee.getWrappedCanvasWidth(canvasWidth);
174  1 assertEquals(wrappedWidth, 20);
175   
176    /*
177    * reduce width by 1 pixel - rounds down to 19 residues
178    */
179  1 canvasWidth -= 1;
180  1 wrappedWidth = testee.getWrappedCanvasWidth(canvasWidth);
181  1 assertEquals(wrappedWidth, 19);
182   
183    /*
184    * turn off West scale - adds labelWidth (39) to available for residues
185    * which with the 11 remainder makes 50 which is 4 more charWidths rem 2
186    */
187  1 av.setScaleLeftWrapped(false);
188  1 wrappedWidth = testee.getWrappedCanvasWidth(canvasWidth);
189    // some leeway for different OS rendering of text
190  1 assertTrue(wrappedWidth >= 22 && wrappedWidth <= 23);
191  1 int difference = wrappedWidth - 23;
192   
193    /*
194    * add 10 pixels to width to fit in another whole residue column
195    */
196  1 canvasWidth += 9;
197  1 wrappedWidth = testee.getWrappedCanvasWidth(canvasWidth);
198  1 assertEquals(wrappedWidth, 23);
199  1 canvasWidth += 1;
200  1 wrappedWidth = testee.getWrappedCanvasWidth(canvasWidth);
201  1 assertEquals(wrappedWidth, 24 + difference);
202   
203    /*
204    * turn off East scale to gain 39 more pixels (3 columns remainder 3)
205    */
206  1 av.setScaleRightWrapped(false);
207  1 wrappedWidth = testee.getWrappedCanvasWidth(canvasWidth);
208  1 assertEquals(wrappedWidth, 27 + difference);
209   
210    /*
211    * add 9 pixels to width to gain a residue column
212    */
213  1 canvasWidth += 8;
214  1 wrappedWidth = testee.getWrappedCanvasWidth(canvasWidth);
215  1 assertEquals(wrappedWidth, 27); // 8px not enough
216  1 canvasWidth += 1;
217  1 wrappedWidth = testee.getWrappedCanvasWidth(canvasWidth);
218  1 assertEquals(wrappedWidth, 28 + difference); // 9px is enough
219   
220    /*
221    * now West but not East scale - lose 39 pixels or 4 columns
222    */
223  1 av.setScaleLeftWrapped(true);
224  1 wrappedWidth = testee.getWrappedCanvasWidth(canvasWidth);
225  1 assertEquals(wrappedWidth, 24);
226   
227    /*
228    * adding 3 pixels to width regains one column
229    */
230  1 canvasWidth += 2;
231  1 wrappedWidth = testee.getWrappedCanvasWidth(canvasWidth);
232  1 assertEquals(wrappedWidth, !Platform.isWin() ? 24 : 25); // 2px not enough
233  1 canvasWidth += 1;
234  1 wrappedWidth = testee.getWrappedCanvasWidth(canvasWidth);
235  1 assertEquals(wrappedWidth, 25 + difference); // 3px is enough
236   
237    /*
238    * turn off scales left and right, make width exactly 157 columns
239    */
240  1 av.setScaleLeftWrapped(false);
241  1 canvasWidth = al.getWidth() * charWidth;
242  1 wrappedVisibleWidths = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
243  1 assertEquals(wrappedVisibleWidths, 1);
244    }
245   
246    /**
247    * Test the method that computes wrapped width in residues, height of wrapped
248    * widths in pixels, and the number of widths visible
249    */
 
250  1 toggle @Test(groups = "Functional")
251    public void testCalculateWrappedGeometry_withAnnotations()
252    {
253  1 AlignViewport av = af.getViewport();
254  1 AlignmentI al = av.getAlignment();
255  1 assertEquals(al.getWidth(), 157);
256  1 assertEquals(al.getHeight(), 15);
257   
258  1 av.setWrapAlignment(true);
259  1 av.getRanges().setStartEndSeq(0, 14);
260  1 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
261  1 int charHeight = av.getCharHeight();
262  1 int charWidth = av.getCharWidth();
263  1 assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
264  1 assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
265  1 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
266   
267    /*
268    * first with scales above, left, right
269    */
270  1 av.setShowAnnotation(true);
271  1 av.setScaleAboveWrapped(true);
272  1 av.setScaleLeftWrapped(true);
273  1 av.setScaleRightWrapped(true);
274  1 FontMetrics fm = testee.getFontMetrics(av.getFont());
275  1 int labelWidth = fm.stringWidth("000") + charWidth;
276    // from 2.11.5 some leeway for different OS rendering of text
277  1 assertTrue(labelWidth >= 36 && labelWidth <= 39);
278  1 assertEquals(labelWidth,
279  1 !Platform.isWin() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
280  1 int annotationHeight = testee.getAnnotationHeight();
281   
282    /*
283    * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
284    * take the whole multiple of character widths
285    */
286  1 int canvasWidth = 400;
287  1 int canvasHeight = 300;
288  1 int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
289  1 int wrappedVisibleWidths = testee.calculateWrappedGeometry(canvasWidth,
290    canvasHeight);
291  1 int wrappedWidth = testee.av.getWrappedWidth();
292  1 assertEquals(wrappedWidth, residueColumns);
293  1 assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
294  1 assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
295  1 assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
296    2 * charHeight);
297  1 int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
298  1 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight())
299    + SeqCanvas.SEQS_ANNOTATION_GAP + annotationHeight);
300  1 assertEquals(wrappedVisibleWidths, 1);
301    /*
302    * repeat height is 17 * (2 + 15) = 289 + 3 + annotationHeight = 510
303    * make canvas height 2 of these plus 3 charHeights
304    * so just enough to draw 2 widths, gap + scale + the first sequence of a third
305    */
306  1 canvasHeight = charHeight * (17 * 2 + 3)
307    + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP);
308  1 wrappedVisibleWidths = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
309  1 assertEquals(wrappedVisibleWidths, 3);
310    /*
311    * reduce canvas height by 1 pixel - should not be enough height
312    * to draw 3 widths
313    */
314  1 canvasHeight -= 1;
315  1 wrappedVisibleWidths = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
316  1 assertEquals(wrappedVisibleWidths, 2);
317    /*
318    * turn off scale above - can now fit in 2 and a bit widths
319    */
320  1 av.setScaleAboveWrapped(false);
321  1 wrappedVisibleWidths = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
322  1 assertEquals(wrappedVisibleWidths, 3);
323    /*
324    * reduce height to enough for 2 widths and not quite a third
325    * i.e. two repeating heights + spacer + sequence - 1 pixel
326    */
327  1 canvasHeight = charHeight * (16 * 2 + 2)
328    + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP) - 1;
329  1 wrappedVisibleWidths = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
330  1 assertEquals(wrappedVisibleWidths, 2);
331   
332    /*
333    * add 1 pixel to height - should now get 3 widths drawn
334    */
335  1 canvasHeight += 1;
336  1 wrappedVisibleWidths = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
337  1 assertEquals(wrappedVisibleWidths, 3);
338    }
339   
340    /**
341    * Test simulates loading an unwrapped alignment, shrinking it vertically so
342    * not all sequences are visible, then changing to wrapped mode. The ranges
343    * endSeq should be unchanged, but the vertical repeat height should include
344    * all sequences.
345    */
 
346  0 toggle @Test(groups = "Functional_Failing")
347    public void testCalculateWrappedGeometry_fromScrolled()
348    {
349  0 AlignViewport av = af.getViewport();
350  0 AlignmentI al = av.getAlignment();
351  0 assertEquals(al.getWidth(), 157);
352  0 assertEquals(al.getHeight(), 15);
353  0 av.getRanges().setStartEndSeq(0, 3);
354  0 av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
355  0 av.setWrapAlignment(true);
356  0 av.setShowAnnotation(false);
357  0 av.setScaleAboveWrapped(true);
358   
359  0 SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
360   
361  0 int charHeight = av.getCharHeight();
362  0 int charWidth = av.getCharWidth();
363  0 assertEquals(charHeight, 17);
364  0 assertEquals(charWidth, 12);
365   
366  0 int canvasWidth = 400;
367  0 int canvasHeight = 300;
368  0 testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
369   
370  0 assertEquals(av.getRanges().getEndSeq(), 3); // unchanged
371  0 int repeatingHeight = (int) PA.getValue(testee,
372    "wrappedRepeatHeightPx");
373  0 assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
374    }
375   
 
376  1 toggle @Test(groups = "Functional")
377    public void testClear_HighlightAndSelection()
378    {
379    // AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
380    // "examples/uniref50.fa", DataSourceType.FILE);
381  1 AlignViewport av = af.getViewport();
382  1 SearchResultsI highlight = new SearchResults();
383  1 highlight.addResult(
384    av.getAlignment().getSequenceAt(1).getDatasetSequence(), 50,
385    80);
386  1 af.alignPanel.highlightSearchResults(highlight);
387  1 af.avc.markHighlightedColumns(false, false, false);
388  1 assertNotNull(av.getSearchResults(),
389    "No highlight was created on alignment");
390  1 assertFalse(av.getColumnSelection().isEmpty(),
391    "No selection was created from highlight");
392  1 af.deselectAllSequenceMenuItem_actionPerformed(null);
393  1 assertTrue(av.getColumnSelection().isEmpty(),
394    "No Selection should be present after deselecting all.");
395  1 assertNull(av.getSearchResults(),
396    "No higlighted search results should be present after deselecting all.");
397    }
398    }