Clover icon

Coverage Report

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

File AlignmentPanelTest.java

 

Code metrics

12
162
13
1
487
293
20
0.12
12.46
13
1.54

Classes

Class Line # Actions
AlignmentPanelTest 56 162 20
0.588235358.8%
 

Contributing tests

This file is covered by 11 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.assertNotEquals;
25    import static org.testng.Assert.assertNotNull;
26    import static org.testng.Assert.assertTrue;
27   
28    import java.awt.Container;
29    import java.awt.Dimension;
30    import java.awt.Font;
31    import java.awt.FontMetrics;
32    import java.awt.Graphics2D;
33    import java.awt.event.MouseEvent;
34    import java.awt.image.BufferedImage;
35    import java.awt.print.Printable;
36    import java.lang.reflect.InvocationTargetException;
37    import java.lang.reflect.Method;
38   
39    import javax.swing.SwingUtilities;
40   
41    import org.testng.annotations.BeforeMethod;
42    import org.testng.annotations.DataProvider;
43    import org.testng.annotations.Test;
44   
45    import jalview.api.AlignViewportI;
46    import jalview.bin.Cache;
47    import jalview.bin.Jalview;
48    import jalview.datamodel.AlignmentAnnotation;
49    import jalview.datamodel.SequenceI;
50    import jalview.io.DataSourceType;
51    import jalview.io.FileLoader;
52    import jalview.util.Platform;
53    import jalview.util.Platform;
54    import jalview.viewmodel.ViewportRanges;
55   
 
56    public class AlignmentPanelTest
57    {
58    AlignFrame af;
59   
 
60  10 toggle @BeforeMethod(alwaysRun = true)
61    public void setUp(Method method) throws InvocationTargetException, InterruptedException
62    {
63  10 Jalview.main(
64    new String[]
65    { "--nonews", "--props", "test/jalview/testProps.jvprops" });
66   
67  10 Cache.setPropertyNoSave("SHOW_IDENTITY",
68    Boolean.TRUE.toString());
69  10 if (method.getName().equals("testPrintWrappedAlignment"))
70    {
71  5 af = new FileLoader().LoadFileWaitTillLoaded(
72    "examples/testdata/PLAKN_serpin.jvp", DataSourceType.FILE);
73    }
74    else
75    {
76  5 af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
77    DataSourceType.FILE);
78    }
79    /*
80    * ensure the panel has been repainted and so ViewportRanges set
81    */
82  10 SwingUtilities.invokeAndWait(new Runnable()
83    {
 
84  10 toggle @Override
85    public void run()
86    {
87  10 af.repaint();
88    }
89    });
90   
91    /*
92    * wait for Consensus thread to complete
93    */
94  10 do
95    {
96  10 try
97    {
98  10 Thread.sleep(50);
99    } catch (InterruptedException x)
100    {
101    }
102  10 } while (af.getViewport().getCalcManager().isWorking());
103    }
104   
105    /**
106    * Test side effect that end residue is set correctly by setScrollValues, with
107    * or without hidden columns
108    */
 
109  1 toggle @Test(groups = "Functional")
110    public void testSetScrollValues()
111    {
112  1 ViewportRanges ranges = af.getViewport().getRanges();
113  1 af.alignPanel.setScrollValues(0, 0);
114   
115  1 int oldres = ranges.getEndRes();
116  1 af.alignPanel.setScrollValues(-1, 5);
117   
118    // setting -ve x value does not change residue
119    // no update necessary now
120  1 assertEquals(ranges.getEndRes(), oldres);
121   
122  1 af.alignPanel.setScrollValues(0, 5);
123   
124    // no update necessary now
125    // setting 0 as x value does not change residue
126    // no update necessary now
127  1 assertEquals(ranges.getEndRes(), oldres);
128   
129  1 af.alignPanel.setScrollValues(5, 5);
130    // setting x value to 5 extends endRes by 5 residues
131  1 System.out.println(ranges);
132    // no update necessary now
133  1 assertEquals(ranges.getEndRes(), oldres + 5);
134   
135    // scroll to position after hidden columns sets endres to oldres (width) +
136    // position
137  1 int scrollpos = 53; // was 60, but this is too high to allow full scrolling
138    // in Windows
139  1 af.getViewport().hideColumns(30, 50);
140  1 af.alignPanel.setScrollValues(scrollpos, 5);
141    // no update necessary now
142  1 assertEquals(ranges.getEndRes(), oldres + scrollpos);
143   
144    // scroll to position within hidden columns, still sets endres to oldres +
145    // position
146    // not sure if this is actually correct behaviour but this is what Jalview
147    // currently does
148  1 scrollpos = 40;
149  1 af.getViewport().showAllHiddenColumns();
150  1 af.getViewport().hideColumns(30, 50);
151  1 af.alignPanel.setScrollValues(scrollpos, 5);
152    // no update necessary now
153  1 assertEquals(ranges.getEndRes(), oldres + scrollpos);
154   
155    // scroll to position within <width> distance of the end of the alignment
156    // endRes should be set to width of alignment - 1
157  1 scrollpos = 130;
158  1 af.getViewport().showAllHiddenColumns();
159  1 af.alignPanel.setScrollValues(scrollpos, 5);
160    // no update necessary now
161  1 assertEquals(ranges.getEndRes(),
162    af.getViewport().getAlignment().getWidth() - 1);
163   
164    // now hide some columns, and scroll to position within <width>
165    // distance of the end of the alignment
166    // endRes should be set to width of alignment - 1 - the number of hidden
167    // columns
168  1 af.getViewport().hideColumns(30, 50);
169  1 af.alignPanel.setScrollValues(scrollpos, 5);
170    // no update necessary now
171  1 assertEquals(ranges.getEndRes(),
172    af.getViewport().getAlignment().getWidth() - 1 - 21); // 21 is the
173    // number of
174    // hidden
175    // columns
176    }
177   
178    /**
179    * Test that update layout reverts to original (unwrapped) values for endRes
180    * when switching from wrapped back to unwrapped mode (JAL-2739)
181    */
 
182  1 toggle @Test(groups = "Functional")
183    public void testUpdateLayout_endRes()
184    {
185    // get details of original alignment dimensions
186  1 ViewportRanges ranges = af.getViewport().getRanges();
187  1 int endres = ranges.getEndRes();
188   
189    // wrap
190  1 af.alignPanel.getAlignViewport().setWrapAlignment(true);
191  1 af.alignPanel.updateLayout();
192   
193    // endRes has changed
194  1 assertNotEquals(ranges.getEndRes(), endres);
195   
196    // unwrap
197  1 af.alignPanel.getAlignViewport().setWrapAlignment(false);
198  1 af.alignPanel.updateLayout();
199   
200    // endRes back to original value
201  1 assertEquals(ranges.getEndRes(), endres);
202    }
203   
204    /**
205    * Test the variant of calculateIdWidth that only recomputes the width if it is
206    * not already saved in the viewport (initial value is -1)
207    */
 
208  1 toggle @Test(groups = "Functional")
209    public void testCalculateIdWidth_noArgs()
210    {
211  1 AlignViewportI av = af.alignPanel.getAlignViewport();
212  1 av.setShowJVSuffix(true);
213  1 av.setFont(new Font("Courier", Font.PLAIN, 15), true);
214   
215  1 av.setIdWidth(0);
216  1 Dimension d = af.alignPanel.calculateIdWidth();
217  1 assertEquals(d.width, 0);
218  1 assertEquals(d.height, 0);
219   
220  1 av.setIdWidth(99);
221  1 d = af.alignPanel.calculateIdWidth();
222  1 assertEquals(d.width, 99);
223  1 assertEquals(d.height, 0);
224   
225    /*
226    * note 4 pixels padding are added to the longest sequence name width
227    */
228  1 av.setIdWidth(-1); // force recalculation
229   
230  1 d = af.alignPanel.calculateIdWidth();
231  1 assertEquals(d.width, Platform.forArch(166).forWin(172).value().intValue()); // 4 + pixel width of "Q93Z60_ARATH/1-118"
232  1 assertEquals(d.height, 12);
233  1 assertEquals(d.width, av.getIdWidth());
234    }
235   
236    /**
237    * Test the variant of calculateIdWidth that computes the longest of any
238    * sequence name or annotation label width FIXME: JAL-4291: test needs
239    * updating for JAL-244 and JAL-4091
240    */
 
241  0 toggle @Test(groups = "Functional", enabled = false)
242    public void testCalculateIdWidth_withMaxWidth()
243    {
244  0 AlignViewportI av = af.alignPanel.getAlignViewport();
245  0 av.setShowJVSuffix(true);
246  0 av.setFont(new Font("Courier", Font.PLAIN, 15), true);
247  0 av.setShowAnnotation(false);
248  0 av.setIdWidth(18);
249   
250  0 FontMetrics fmfor = new Container()
251    .getFontMetrics(new Font(af.viewport.font.getName(),
252    Font.ITALIC, af.viewport.font.getSize()));
253   
254    /*
255    * note 4 pixels 'padding' are added to the longest seq name/annotation label
256    */
257  0 Dimension d = af.alignPanel.calculateIdWidth(2000);
258    // Assumption ID_WIDTH_PADDING == 4
259  0 int expwidth = 3 + fmfor.stringWidth("Conservation");
260   
261  0 assertEquals(d.width, Platform.forArch(166).forWin(172).value().intValue()); // 4 + pixel width of "Q93Z60_ARATH/1-118"
262  0 assertEquals(d.height, 12); // fixed value (not used?)
263  0 assertEquals(av.getIdWidth(), expwidth); // not changed by this method
264   
265    /*
266    * make the longest sequence name longer
267    */
268  0 SequenceI seq = af.viewport.getAlignment()
269    .findSequenceMatch("Q93Z60_ARATH")[0];
270  0 String orig = seq.getName();
271  0 seq.setName(orig + "MMMMM");
272  0 d = af.alignPanel.calculateIdWidth(2000);
273  0 assertEquals(d.width, Platform.forArch(211).forWin(219).value().intValue()); // 4 + pixel width of "Q93Z60_ARATHMMMMM/1-118"
274  0 assertEquals(d.height, 12);
275  0 assertEquals(av.getIdWidth(), 18); // unchanged
276    // for next test:
277  0 seq.setName(orig);
278   
279    /*
280    * make the longest annotation name even longer
281    * note this is checked even if annotations are not shown
282    */
283  0 AlignmentAnnotation aa = av.getAlignment().getAlignmentAnnotation()[0];
284  0 aa.label = "THIS IS A VERY LONG LABEL INDEED";
285  0 d = af.alignPanel.calculateIdWidth(2000);
286    // Assumption ID_WIDTH_PADDING == 3
287  0 expwidth = 3 + fmfor.stringWidth(aa.label);
288   
289  0 assertEquals(d.width, expwidth); // 228 == ID_WIDTH_PADDING + pixel width of
290    // "THIS IS A VERY LONG LABEL INDEED"
291  0 assertEquals(d.height, 12);
292   
293    /*
294    * override with maxwidth
295    * note the 4 pixels padding is added to this value
296    */
297    // BH but we have to be under the max width
298  0 d = af.alignPanel.calculateIdWidth(180);
299  0 assertEquals(d.width, 184);
300  0 assertEquals(d.height, 12);
301    }
302   
 
303  0 toggle private int computeExpectedWidth(double scaling)
304    {
305  0 return Platform.isMac() ? 115 : scaling == 1.0 ? 112 : 107;
306    }
307   
308   
 
309  0 toggle @Test(groups = { "Functional", "Not-bamboo" })
310    public void testGetVisibleWidth()
311    {
312  0 double scaling = jalview.gui.JvSwingUtilsTest.getScaling(af.alignPanel);
313    /*
314    * width for onscreen rendering is IDPanel width
315    */
316  0 int w = af.alignPanel.getVisibleIdWidth(true);
317  0 assertEquals(w, af.alignPanel.getIdPanel().getWidth());
318   
319    // different scaling (1.0, 2.0) gives different results
320  0 int expectedWidth = computeExpectedWidth(scaling);
321  0 assertEquals(w, Platform.forArch(115).forWin(112).forMac(expectedWidth)
322    .forLinux(114).value().intValue());
323   
324    /*
325    * width for offscreen rendering is the same
326    * if no fixed id width is specified in preferences
327    */
328  0 Cache.setProperty("FIGURE_AUTOIDWIDTH", Boolean.FALSE.toString());
329  0 Cache.removeProperty("FIGURE_FIXEDIDWIDTH");
330  0 assertEquals(w, af.alignPanel.getVisibleIdWidth(false));
331   
332    /*
333    * preference for fixed id width - note 4 pixels padding is added
334    */
335  0 Cache.setProperty("FIGURE_FIXEDIDWIDTH", "120");
336  0 assertEquals(124, af.alignPanel.getVisibleIdWidth(false));
337   
338    /*
339    * preference for auto id width overrides fixed width
340    */
341  0 Cache.setProperty("FIGURE_AUTOIDWIDTH", Boolean.TRUE.toString());
342  0 w = af.alignPanel.getVisibleIdWidth(false);
343    // allow some leeway for different OS renderings
344  0 assertTrue(w > 105 && w < 120);
345    // different scaling (1.0, 2.0) gives different results
346  0 assertEquals(af.alignPanel.getVisibleIdWidth(false),
347    Platform.forArch(115).forWin(106).forMac(expectedWidth).forLinux(114)
348    .value().intValue());
349    }
350   
351   
 
352  0 toggle @Test(groups = { "Functional", "Not-bamboo" })
353    public void testresetIdWidth()
354    {
355  0 double scaling = jalview.gui.JvSwingUtilsTest.getScaling(af.alignPanel);
356    /*
357    * width for onscreen rendering is IDPanel width
358    */
359  0 int w = af.alignPanel.getVisibleIdWidth(true);
360  0 int actual = af.alignPanel.getIdPanel().getWidth();
361  0 assertEquals(w, actual);
362    // allow some leeway for different OS renderings
363  0 assertTrue(w > 105 && w < 120);
364    // different scaling (1.0, 2.0) gives different results
365  0 int expectedWidth = computeExpectedWidth(scaling);
366  0 assertEquals(w, expectedWidth);
367   
368    // manually adjust
369  0 af.viewport.setIdWidth(200);
370    // fake mouse drag sets manuallyAdjusted to true (0,0 not moving mouse)
371  0 MouseEvent drag = new MouseEvent(af.alignPanel,
372    MouseEvent.MOUSE_DRAGGED, System.currentTimeMillis(), 0, 0, 0,
373    MouseEvent.BUTTON1, false);
374  0 af.alignPanel.idwidthAdjuster.mouseDragged(drag);
375  0 af.alignPanel.paintComponent(af.alignPanel.getGraphics());
376  0 w = af.alignPanel.calculateIdWidth().width;
377  0 assertTrue(
378    af.alignPanel.getIdPanel().getIdCanvas().isManuallyAdjusted());
379  0 actual = af.alignPanel.getIdPanel().getWidth();
380  0 assertEquals(w, actual);
381   
382  0 af.viewport.setIdWidth(-1);
383  0 af.alignPanel.calculateIdWidth();
384  0 af.alignPanel.getIdPanel().getIdCanvas().setManuallyAdjusted(false);
385  0 w = af.alignPanel.calculateIdWidth().width;
386  0 af.alignPanel.paintComponent(af.alignPanel.getGraphics());
387   
388  0 actual = af.alignPanel.getIdPanel().getWidth();
389  0 assertEquals(w, actual);
390   
391    // setting a negative IdWidth and then running calculateIdWidth resets width
392    // to optimal id width
393    // allow some leeway for different OS renderings
394  0 assertTrue(w > 105 && w < 120);
395    // different scaling (1.0, 2.0) gives different results
396  0 assertEquals(w, expectedWidth);
397    }
398   
 
399  1 toggle @Test(groups = "Functional")
400    public void testSetOverviewTitle()
401    {
402  1 OverviewPanel ov1 = this.af.openOverviewPanel(true);
403  1 String alignFrameTitle = af.getTitle();
404  1 assertEquals(ov1.getTitle(), "Overview " + alignFrameTitle);
405   
406    /*
407    * on New View, existing overview should get " Original" added to title
408    * and new view's overview should get " View 1" added
409    */
410  1 af.newView_actionPerformed(null);
411  1 assertEquals(ov1.getTitle(),
412    "Overview " + alignFrameTitle + " Original");
413  1 OverviewPanel ov2 = this.af.openOverviewPanel(true);
414  1 assertEquals(ov2.getTitle(), "Overview " + alignFrameTitle + " View 1");
415    }
416   
 
417  1 toggle @Test(groups = "Functional")
418    public void testSetOverviewTitle_automaticOverview()
419    {
420  1 Cache.setProperty("SHOW_OVERVIEW", "true");
421  1 AlignFrame alignFrame = new FileLoader().LoadFileWaitTillLoaded(
422    "examples/uniref50.fa", DataSourceType.FILE);
423  1 OverviewPanel ov1 = alignFrame.alignPanel.getOverviewPanel();
424  1 assertNotNull(ov1);
425  1 String alignFrameTitle = alignFrame.getTitle();
426  1 assertEquals(ov1.getTitle(), "Overview " + alignFrameTitle);
427   
428    /*
429    * on New View, existing overview should get " Original" added to title
430    * and new view's automatic overview should have " View 1" added
431    */
432  1 alignFrame.newView_actionPerformed(null);
433  1 assertEquals(ov1.getTitle(),
434    "Overview " + alignFrameTitle + " Original");
435  1 OverviewPanel ov2 = alignFrame.alignPanel.getOverviewPanel();
436  1 assertNotNull(ov2);
437  1 assertEquals(ov2.getTitle(), "Overview " + alignFrameTitle + " View 1");
438    }
439   
 
440  1 toggle @DataProvider(name = "testPrintWrappedAlignmentData")
441    public Object[][] testPrintWrappedAlignmentData()
442    {
443  1 return new Object[][] { { 3, 300, 800 }, { 2, 400, 800 },
444    { 2, 300, 900 },
445    { 1, 676, 698 },
446    { 1, 910, 335 } };
447    }
448   
 
449  5 toggle @Test(
450    groups = "Functional",
451    dataProvider = "testPrintWrappedAlignmentData")
452    public void testPrintWrappedAlignment(int expectedPages, int pageWidth,
453    int pageHeight) throws Exception
454    {
455   
456  5 AlignViewportI av = af.alignPanel.getAlignViewport();
457  5 av.setWrapAlignment(true);
458  5 av.setShowAnnotation(false);
459  5 av.setScaleAboveWrapped(false);
460  5 av.setFont(new Font("Courier", Font.PLAIN, 12), true);
461  5 av.setShowAnnotation(false);
462   
463    // Count actual pages
464  5 BufferedImage img = new BufferedImage(pageWidth, pageHeight,
465    BufferedImage.TYPE_INT_ARGB);
466  5 Graphics2D g = img.createGraphics();
467   
468  5 int resultPages = 0;
469  14 for (int page = 0; page < expectedPages + 2; page++)
470    {
471  14 int result = af.alignPanel.printWrappedAlignment(pageWidth,
472    pageHeight, page, g);
473  14 if (result == Printable.PAGE_EXISTS)
474    {
475  9 resultPages++;
476    }
477    else
478    {
479  5 break;
480    }
481    }
482  5 g.dispose();
483   
484  5 assertEquals(resultPages, expectedPages, "Page count mismatch");
485    }
486   
487    }