Clover icon

Coverage Report

  1. Project Clover database Wed Dec 3 2025 13:28:34 GMT
  2. Package jalview.gui

File SeqCanvasTest.java

 
testCalculateWrappedGeometry_noAnnotations: expected [26] but found [1]
testCalculateWrappedGeometry_withAnnotations: Can't get value of wrappedVisibleWidths from jalview.gui....
 

Code metrics

2
163
5
1
397
239
7
0.04
32.6
5
1.4

Classes

Class Line # Actions
SeqCanvasTest 43 163 7
0.1117647111.2%
 

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