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;
+import jalview.viewmodel.ViewportRanges;
import java.awt.Font;
import java.awt.FontMetrics;
+import java.awt.Toolkit;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
-import junit.extensions.PA;
-
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
+import junit.extensions.PA;
+
+@Test(singleThreaded = true)
public class SeqCanvasTest
{
+ @BeforeClass(alwaysRun = true)
+ public void setUp()
+ {
+ Thread.currentThread().setName("SeqCanvasTest Setup " + ++nTest);
+
+ Cache.loadProperties("test/jalview/io/testProps.jvprops");
+ 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
@Test(groups = "Functional")
public void testCalculateWrappedGeometry_noAnnotations()
{
+ Thread.currentThread().setName("SeqCanvasTest noAnn " + ++nTest);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
AlignViewport av = af.getViewport();
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);
/*
* first with scales above, left, right
av.setScaleRightWrapped(true);
FontMetrics fm = testee.getFontMetrics(av.getFont());
int labelWidth = fm.stringWidth("000") + charWidth;
- assertEquals(labelWidth, 39); // 3 x 9 + 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
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);
canvasWidth += 8;
wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
canvasHeight);
- assertEquals(wrappedWidth, 27);
+ 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 39 pixels or 4 columns
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
@Test(groups = "Functional")
public void testCalculateWrappedGeometry_withAnnotations()
{
+ Thread.currentThread().setName("SeqCanvasTest wAnn " + ++nTest);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
AlignViewport av = af.getViewport();
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;
/*
av.setScaleAboveWrapped(true);
av.setScaleLeftWrapped(true);
av.setScaleRightWrapped(true);
+
FontMetrics fm = testee.getFontMetrics(av.getFont());
int labelWidth = fm.stringWidth("000") + charWidth;
- assertEquals(labelWidth, 39); // 3 x 9 + 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();
/*
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);
* 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);
assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
}
+ private static int nTest = 0;
/**
* Test simulates loading an unwrapped alignment, shrinking it vertically so
* not all sequences are visible, then changing to wrapped mode. The ranges
@Test(groups = "Functional")
public void testCalculateWrappedGeometry_fromScrolled()
{
+ // debugOut("12]", new Runnable()
+ // {
+ //
+ // @Override
+ // public void run()
+ // {
+ //
+ // String s = Arrays
+ // .toString(new NullPointerException().getStackTrace())
+ // .replace(',', '\n') + "\n\n";
+ //
+ // System.err.println(s);
+ //
+ // }
+ //
+ // });
+ //
+ ViewportRanges.sTest = "";
+ Thread.currentThread().setName("SeqCanvasTest fromScrolled " + ++nTest);
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/uniref50.fa", DataSourceType.FILE);
+ // note that this frame is unpacked, with w = h = 0;
AlignViewport av = af.getViewport();
AlignmentI al = av.getAlignment();
assertEquals(al.getWidth(), 157);
assertEquals(al.getHeight(), 15);
+ String s = "";
+ s += "flushing events";
+ flushEvents();
+ s += "events flushed";
av.getRanges().setStartEndSeq(0, 3);
+ s += " SC1 " + av.getRanges() + " " + ViewportRanges.sTest;
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();
- assertEquals(charHeight, 17);
- assertEquals(charWidth, 12);
-
+ // 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);
-
- assertEquals(av.getRanges().getEndSeq(), 3); // unchanged
int repeatingHeight = (int) PA.getValue(testee,
"wrappedRepeatHeightPx");
+ assertEquals(av.getRanges().getEndSeq(), 3, "endSeq should be 3 " + s); // unchanged
assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
}
+
+ /**
+ * Let me know when the output indicates the specified message.
+ *
+ * @param msg
+ * @param r
+ */
+ private void debugOut(String msg, Runnable r)
+ {
+ int len = msg.length();
+ int c0 = msg.charAt(0);
+ boolean[] recording = new boolean[1];
+ System.setOut(new PrintStream(new OutputStream()
+ {
+
+ StringBuffer out = new StringBuffer();
+
+ @Override
+ public void write(int b) throws IOException
+ {
+
+ if (recording[0])
+ {
+ out.append((char) b);
+ if (out.length() == len)
+ {
+ if (out.toString().equals(msg))
+ {
+ r.run();
+ }
+ recording[0] = false;
+ out.setLength(0);
+ }
+ }
+ else if (b == c0)
+ {
+ out.append((char) b);
+ recording[0] = true;
+ }
+ }
+
+ }));
+
+ // TODO Auto-generated method stub
+
+ }
+
+ private static void flushEvents()
+ {
+ ((sun.awt.SunToolkit) Toolkit.getDefaultToolkit()).flushPendingEvents();
+ }
}