JAL-3493 fix patch for 2.11.1_js (nb - these changes should not be merged to 2.11.2!)
[jalview.git] / test / jalview / gui / SeqCanvasTest.java
index 3722e47..34e88ad 100644 (file)
@@ -1,22 +1,58 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.gui;
 
-import static org.testng.Assert.assertEquals;
-
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
 import jalview.datamodel.AlignmentI;
 import jalview.io.DataSourceType;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.io.FileLoader;
+import jalview.util.Platform;
+import jalview.viewmodel.ViewportRanges;
 
 import java.awt.Font;
 import java.awt.FontMetrics;
 
-import junit.extensions.PA;
-
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
 
-import sun.swing.SwingUtilities2;
+import junit.extensions.PA;
 
 public class SeqCanvasTest
 {
+  @BeforeClass(alwaysRun = true)
+  public void setUp()
+  {
+    Cache.loadProperties(null);
+    Cache.initLogger();
+    Desktop.getInstance().setVisible(false);
+  }
+
   /**
    * Test the method that computes wrapped width in residues, height of wrapped
    * widths in pixels, and the number of widths visible
@@ -26,19 +62,21 @@ public class SeqCanvasTest
   {
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
             "examples/uniref50.fa", DataSourceType.FILE);
+    
     AlignViewport av = af.getViewport();
     AlignmentI al = av.getAlignment();
     assertEquals(al.getWidth(), 157);
     assertEquals(al.getHeight(), 15);
+    av.getRanges().setStartEndSeq(0, 14);
+
+    SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
 
     av.setWrapAlignment(true);
     av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
     int charHeight = av.getCharHeight();
     int charWidth = av.getCharWidth();
-    assertEquals(charHeight, 17);
-    assertEquals(charWidth, 12);
-
-    SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
+    assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
+    assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
 
     /*
      * first with scales above, left, right
@@ -47,9 +85,10 @@ public class SeqCanvasTest
     av.setScaleAboveWrapped(true);
     av.setScaleLeftWrapped(true);
     av.setScaleRightWrapped(true);
-    FontMetrics fm = SwingUtilities2.getFontMetrics(testee, av.getFont());
-    int labelWidth = fm.stringWidth("00000"); // width of 3 digits and 2 spaces
-    assertEquals(labelWidth, 45); // note this is not 5 * charWidth
+    FontMetrics fm = testee.getFontMetrics(av.getFont());
+    int labelWidth = fm.stringWidth("000") + charWidth;
+    assertEquals(labelWidth,
+            !Platform.isWin() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
 
     /*
      * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
@@ -78,8 +117,8 @@ public class SeqCanvasTest
     assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
 
     /*
-     * reduce canvas height by 1 pixel - should not be enough height
-     * to draw 3 widths
+     * reduce canvas height by 1 pixel 
+     * - should not be enough height to draw 3 widths
      */
     canvasHeight -= 1;
     testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
@@ -117,8 +156,8 @@ public class SeqCanvasTest
     assertEquals(wrappedWidth, 19);
 
     /*
-     * turn off West scale - adds labelWidth (45) to available for residues
-     * which with the 11 remainder makes 56 which is 4 more charWidths rem 8
+     * turn off West scale - adds labelWidth (39) to available for residues
+     * which with the 11 remainder makes 50 which is 4 more charWidths rem 2
      */
     av.setScaleLeftWrapped(false);
     wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
@@ -126,9 +165,9 @@ public class SeqCanvasTest
     assertEquals(wrappedWidth, 23);
 
     /*
-     * add 4 pixels to width to fit in another whole residue column
+     * add 10 pixels to width to fit in another whole residue column
      */
-    canvasWidth += 3;
+    canvasWidth += 9;
     wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
             canvasHeight);
     assertEquals(wrappedWidth, 23);
@@ -138,7 +177,7 @@ public class SeqCanvasTest
     assertEquals(wrappedWidth, 24);
 
     /*
-     * turn off East scale to gain 45 more pixels (3 columns remainder 9)
+     * turn off East scale to gain 39 more pixels (3 columns remainder 3)
      */
     av.setScaleRightWrapped(false);
     wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
@@ -146,15 +185,19 @@ public class SeqCanvasTest
     assertEquals(wrappedWidth, 27);
 
     /*
-     * add 3 pixels to width to gain a residue column
+     * add 9 pixels to width to gain a residue column
      */
-    canvasWidth += 3;
+    canvasWidth += 8;
+    wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+            canvasHeight);
+    assertEquals(wrappedWidth, 27); // 8px not enough
+    canvasWidth += 1;
     wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
             canvasHeight);
-    assertEquals(wrappedWidth, 28);
+    assertEquals(wrappedWidth, 28); // 9px is enough
 
     /*
-     * now West but not East scale - lose 45 pixels or 4 columns
+     * now West but not East scale - lose 39 pixels or 4 columns
      */
     av.setScaleLeftWrapped(true);
     wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
@@ -162,16 +205,16 @@ public class SeqCanvasTest
     assertEquals(wrappedWidth, 24);
 
     /*
-     * adding 9 pixels to width regains one column
+     * adding 3 pixels to width regains one column
      */
-    canvasWidth += 8;
+    canvasWidth += 2;
     wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
             canvasHeight);
-    assertEquals(wrappedWidth, 24);
+    assertEquals(wrappedWidth, !Platform.isWin() ? 24 : 25); // 2px not enough
     canvasWidth += 1;
     wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
             canvasHeight);
-    assertEquals(wrappedWidth, 25);
+    assertEquals(wrappedWidth, 25); // 3px is enough
 
     /*
      * turn off scales left and right, make width exactly 157 columns
@@ -197,12 +240,14 @@ public class SeqCanvasTest
     assertEquals(al.getHeight(), 15);
   
     av.setWrapAlignment(true);
+    av.getRanges().setStartEndSeq(0, 14);
     av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
     int charHeight = av.getCharHeight();
     int charWidth = av.getCharWidth();
-    assertEquals(charHeight, 17);
-    assertEquals(charWidth, 12);
-  
+
+    assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
+    assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
+
     SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
   
     /*
@@ -212,9 +257,12 @@ public class SeqCanvasTest
     av.setScaleAboveWrapped(true);
     av.setScaleLeftWrapped(true);
     av.setScaleRightWrapped(true);
-    FontMetrics fm = SwingUtilities2.getFontMetrics(testee, av.getFont());
-    int labelWidth = fm.stringWidth("00000"); // width of 3 digits and 2 spaces
-    assertEquals(labelWidth, 45); // note this is not 5 * charWidth
+
+    FontMetrics fm = testee.getFontMetrics(av.getFont());
+    int labelWidth = fm.stringWidth("000") + charWidth;
+    assertEquals(labelWidth,
+            !Platform.isWin() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
+
     int annotationHeight = testee.getAnnotationHeight();
 
     /*
@@ -232,15 +280,16 @@ public class SeqCanvasTest
             2 * charHeight);
     int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
     assertEquals(repeatingHeight, charHeight * (2 + al.getHeight())
-            + annotationHeight);
+            + SeqCanvas.SEQS_ANNOTATION_GAP + annotationHeight);
     assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
   
     /*
-     * repeat height is 17 * (2 + 15) = 289 + annotationHeight = 507
-     * make canvas height 2 * 289 + 3 * charHeight so just enough to
-     * draw 2 widths and the first sequence of a third
+     * repeat height is 17 * (2 + 15) = 289 + 3 + annotationHeight = 510
+     * make canvas height 2 of these plus 3 charHeights 
+     * so just enough to draw 2 widths, gap + scale + the first sequence of a third
      */
-    canvasHeight = charHeight * (17 * 2 + 3) + 2 * annotationHeight;
+    canvasHeight = charHeight * (17 * 2 + 3)
+            + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP);
     testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
     assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
   
@@ -263,7 +312,8 @@ public class SeqCanvasTest
      * reduce height to enough for 2 widths and not quite a third
      * i.e. two repeating heights + spacer + sequence - 1 pixel
      */
-    canvasHeight = charHeight * (16 * 2 + 2) + 2 * annotationHeight - 1;
+    canvasHeight = charHeight * (16 * 2 + 2)
+            + 2 * (annotationHeight + SeqCanvas.SEQS_ANNOTATION_GAP) - 1;
     testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
     assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
 
@@ -274,4 +324,76 @@ public class SeqCanvasTest
     testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
     assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
   }
+
+  /**
+   * Test simulates loading an unwrapped alignment, shrinking it vertically so
+   * not all sequences are visible, then changing to wrapped mode. The ranges
+   * endSeq should be unchanged, but the vertical repeat height should include
+   * all sequences.
+   */
+  @Test(groups = "Functional")
+  public void testCalculateWrappedGeometry_fromScrolled()
+  {
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/uniref50.fa", DataSourceType.FILE);
+    // 
+    System.out.println("ap dim = " + af.alignPanel.getSize());
+    System.out.println("seqpan dim = " + af.alignPanel.getSeqPanel().getSize());
+    System.out.println("seqcan dim = " + af.alignPanel.getSeqPanel().seqCanvas.getSize());
+
+
+    AlignViewport av = af.getViewport();
+    AlignmentI al = av.getAlignment();
+    assertEquals(al.getWidth(), 157);
+    assertEquals(al.getHeight(), 15);
+
+    ViewportRanges ranges = av.getRanges();
+    System.out.println(ranges + " before setting to 3");
+    ranges.setStartEndSeq(0, 3);
+    int endSeq = ranges.getEndSeq();
+    System.out.println(ranges + " after setting to 3");
+    av.setShowAnnotation(false);
+    av.setScaleAboveWrapped(true);
+
+    SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
+    av.setWrapAlignment(true);
+    av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
+    int charHeight = av.getCharHeight();
+    int charWidth = av.getCharWidth();
+    // Windows h=19, w=11.
+    assertEquals(charHeight, !Platform.isWin() ? 17 : 19);
+    assertEquals(charWidth, !Platform.isWin() ? 12 : 11);
+    
+    int canvasWidth = 400;
+    int canvasHeight = 300;
+    testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+    System.out.println(ranges);
+    assertEquals(ranges.getEndSeq(), endSeq); // unchanged
+    int repeatingHeight = (int) PA.getValue(testee,
+            "wrappedRepeatHeightPx");
+    int h = charHeight * (2 + al.getHeight());
+    assertEquals(repeatingHeight, h);
+  }
+  @Test(groups = "Functional")
+  public void testClear_HighlightAndSelection()
+  {
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/uniref50.fa", DataSourceType.FILE);
+    AlignViewport av = af.getViewport();
+    SearchResultsI highlight = new SearchResults();
+    highlight.addResult(
+            av.getAlignment().getSequenceAt(1).getDatasetSequence(), 50,
+            80);
+    af.alignPanel.highlightSearchResults(highlight);
+    af.avc.markHighlightedColumns(false, false, false);
+    assertNotNull(av.getSearchResults(),
+            "No highlight was created on alignment");
+    assertFalse(av.getColumnSelection().isEmpty(),
+            "No selection was created from highlight");
+    af.deselectAllSequenceMenuItem_actionPerformed(null);
+    assertTrue(av.getColumnSelection().isEmpty(),
+            "No Selection should be present after deselecting all.");
+    assertNull(av.getSearchResults(),
+            "No higlighted search results should be present after deselecting all.");
+  }
 }