Bamboo test #4 (possibly) - intentional SeqCanvasTest fail for debugging
[jalview.git] / test / jalview / gui / SeqCanvasTest.java
index 3722e47..445be13 100644 (file)
@@ -1,7 +1,29 @@
+/*
+ * 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.io.FileLoader;
@@ -9,14 +31,21 @@ import jalview.io.FileLoader;
 import java.awt.Font;
 import java.awt.FontMetrics;
 
-import junit.extensions.PA;
-
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import sun.swing.SwingUtilities2;
+import junit.extensions.PA;
 
 public class SeqCanvasTest
 {
+  @BeforeClass(alwaysRun = true)
+  public void setUp()
+  {
+    Cache.initLogger();
+    Jalview.setSynchronous(true);
+  }
+
   /**
    * Test the method that computes wrapped width in residues, height of wrapped
    * widths in pixels, and the number of widths visible
@@ -30,15 +59,20 @@ public class SeqCanvasTest
     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;
+    Assert.assertTrue(charHeight == 17 && charWidth == 12
+            || charHeight == 19 && charWidth == 11,
+            "char height/width " + charHeight + "/" + charWidth);
+    //
+    // assertEquals(charHeight, Platform.isMac() ? 17 : 19);
+    // assertEquals(charWidth, Platform.isMac() ? 12 : 11);
 
     /*
      * first with scales above, left, right
@@ -47,9 +81,26 @@ 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;
+    // BH 2020.03.22 It is not really necessary to be this detailed. Different
+    // OS-based UIs will
+    // always have slightly different parameters. StringgWidths are not
+    // necessarily linear sums of the letters involved.
+    // for example, the calculation for JavaScript is a float that has to be
+    // rounded.
+    // ..............................mac................PC................linux?
+    Assert.assertTrue(
+            labelWidth == 39 || labelWidth == 35 || labelWidth == 36);// 3 * 9 +
+                                                                      // charWidth
+                                                                      // ||
+                                                                      // labelWidth
+                                                                      // == 3 *
+                                                                      // 8 +
+                                                                      // charWidth,
+                                                                      // "labelWidth
+                                                                      // 36 or
+                                                                      // 39");
 
     /*
      * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
@@ -78,8 +129,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 +168,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 +177,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 +189,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 +197,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, 28);
+    assertEquals(wrappedWidth, 27); // 8px not enough
+    canvasWidth += 1;
+    wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+            canvasHeight);
+    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 +217,19 @@ 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);
+    Assert.assertTrue(wrappedWidth == 24 || wrappedWidth == 25,
+            "WrappedWidth [" + wrappedWidth + "] should be 24 or 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 +255,18 @@ 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);
-  
+
+    Assert.assertTrue(
+            charHeight == 17 && charWidth == 12
+                    || charHeight == 19 && charWidth == 11,
+            "char height/width " + charHeight + "/" + charWidth);
+    // assertEquals(charHeight, Platform.isMac() ? 17 : 19);
+    // assertEquals(charWidth, Platform.isMac() ? 12 : 11);
+
     SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
   
     /*
@@ -212,9 +276,31 @@ 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;
+    // BH 2020.03.22 It is not really necessary to be this detailed. Different
+    // OS-based UIs will
+    // always have slightly different parameters. StringgWidths are not
+    // necessarily linear sums of the letters involved.
+    // for example, the calculation for JavaScript is a float that has to be
+    // rounded.
+    // ..............................mac................PC................linux?
+    Assert.assertTrue(
+            labelWidth == 39 || labelWidth == 35 || labelWidth == 36);// 3 * 9 +
+                                                                      // charWidth
+                                                                      // ||
+                                                                      // labelWidth
+                                                                      // == 3 *
+                                                                      // 8 +
+                                                                      // charWidth,
+                                                                      // "labelWidth
+                                                                      // 36 or
+                                                                      // 39");
+    // int labelWidth = fm.stringWidth("000") + charWidth;
+    // assertEquals(labelWidth,
+    // Platform.isMac() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
+
     int annotationHeight = testee.getAnnotationHeight();
 
     /*
@@ -232,15 +318,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 +350,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 +362,49 @@ 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);
+    AlignViewport av = af.getViewport();
+    AlignmentI al = av.getAlignment();
+    assertEquals(al.getWidth(), 157);
+    assertEquals(al.getHeight(), 15);
+    String ss = "";
+    av.getRanges().setStartEndSeq(0, 3);
+
+    String s = "";
+    s += " SC1 " + av.getRanges();
+    av.setShowAnnotation(false);
+    s += " SC2 " + av.getRanges();
+    av.setScaleAboveWrapped(true);
+    s += " SC3 " + av.getRanges();
+    SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
+    av.setWrapAlignment(true);
+    s += " SC4 " + av.getRanges();
+    av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
+    int charHeight = av.getCharHeight();
+    int charWidth = av.getCharWidth();
+    // Windows h=19, w=11; Mac (and Linux?) 17,11
+    Assert.assertTrue(charHeight == 17 && charWidth == 12
+            || charHeight == 19 && charWidth == 11,
+            "char height/width " + charHeight + "/" + charWidth);
+    int canvasWidth = 400;
+    int canvasHeight = 300;
+    testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+
+    s += " SC5 " + av.getRanges();
+    int repeatingHeight = (int) PA.getValue(testee,
+            "wrappedRepeatHeightPx");
+    assertEquals(av.getRanges().getEndSeq(), 0, "endSeq should be 3 " + s); // unchanged
+    assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
+  }
 }