Merge branch 'patch/JAL-3700_JAL-3748_JAL-3763_for_2_11_1_3' into releases/Release_2_...
[jalview.git] / test / jalview / gui / SplitFrameTest.java
diff --git a/test/jalview/gui/SplitFrameTest.java b/test/jalview/gui/SplitFrameTest.java
new file mode 100644 (file)
index 0000000..7420e71
--- /dev/null
@@ -0,0 +1,224 @@
+/*
+ * 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.junit.Assert.assertNotEquals;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import jalview.api.FeatureColourI;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.project.Jalview2xmlTests;
+import jalview.renderer.ResidueShaderI;
+import jalview.schemes.BuriedColourScheme;
+import jalview.schemes.FeatureColour;
+import jalview.schemes.HelixColourScheme;
+import jalview.schemes.JalviewColourScheme;
+import jalview.schemes.StrandColourScheme;
+import jalview.schemes.TurnColourScheme;
+import jalview.util.MessageManager;
+
+import java.awt.Color;
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+public class SplitFrameTest
+{
+  AlignFrame dnaAf, proteinAf;
+
+  SplitFrame testSplitFrame;
+
+  @BeforeClass(alwaysRun = true)
+  public static void setUpBeforeClass() throws Exception
+  {
+    setUpJvOptionPane();
+    /*
+     * use read-only test properties file
+     */
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
+    Jalview.main(new String[] { "-nonews" });
+  }
+
+  @AfterMethod(alwaysRun = true)
+  public void tearDown()
+  {
+    Desktop.instance.closeAll_actionPerformed(null);
+  }
+
+  /**
+   * configure (read-only) properties for test to ensure Consensus is computed
+   * for colour Above PID testing
+   */
+  @BeforeMethod(alwaysRun = true)
+  public void setUp()
+  {
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
+    Cache.applicationProperties.setProperty("SHOW_IDENTITY",
+            Boolean.TRUE.toString());
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/testdata/MN908947.jvp", DataSourceType.FILE);
+
+    /*
+     * wait for Consensus thread to complete
+     */
+    synchronized (this)
+    {
+      while (af.getViewport().getConsensusSeq() == null)
+      {
+        try
+        {
+          wait(50);
+        } catch (InterruptedException e)
+        {
+        }
+      }
+    }
+    testSplitFrame = (SplitFrame) af.getSplitViewContainer();
+    proteinAf=af.getViewport().getAlignment().isNucleotide() ? testSplitFrame.getComplementAlignFrame(af) : af;
+    dnaAf=testSplitFrame.getComplementAlignFrame(proteinAf);
+  }
+
+  public static void setUpJvOptionPane()
+  {
+    JvOptionPane.setInteractiveMode(false);
+    JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
+  }
+
+  @Test(groups= {"Functional"})
+  public void testAlignAsSplitFrame()
+  {
+
+    /*
+     * If alignment was requested from one half of a SplitFrame, show in a
+     * SplitFrame with the other pane similarly aligned.
+     */
+    AlignFrame requestedBy = proteinAf;
+    AlignmentI wholeProteinAl = proteinAf.getViewport().getAlignment();
+    SequenceI[] sel = wholeProteinAl.getSequencesArray();
+    // Select 3 sequences, from columns 3-7 inclusive
+    SequenceGroup selRegion = new SequenceGroup(
+            Arrays.asList(sel[0], sel[1], sel[3]));
+    selRegion.setStartRes(3);
+    selRegion.setEndRes(7);
+    proteinAf.getViewport().setSelectionGroup(selRegion);
+    proteinAf.getViewport().sendSelection();
+    assertNotNull(dnaAf.getViewport().getSelectionGroup());
+    AlignmentView inputView = proteinAf.gatherSequencesForAlignment();
+    assertEquals(inputView.getSequences().length, 3);
+    assertEquals(inputView.getWidth(), 5);
+    assertNotNull(inputView.getComplementView());
+
+    Object alAndHidden[] = inputView.getAlignmentAndHiddenColumns(
+            proteinAf.getViewport().getGapCharacter());
+    AlignmentI result = new Alignment((SequenceI[]) alAndHidden[0]);
+    result.setHiddenColumns((HiddenColumns) alAndHidden[1]);
+    // check we are referring to the expected alignment
+    assertEquals(
+            requestedBy.getSplitViewContainer().getComplement(requestedBy),
+            dnaAf.getCurrentView().getAlignment());
+    // and that datasets are consistent (if not, there's a problem elsewhere in
+    // splitframe construction
+    AlignmentI complementDs = requestedBy.getSplitViewContainer()
+            .getComplement(requestedBy).getDataset();
+    assertTrue(complementDs == dnaAf
+            .getViewport().getAlignment().getDataset());
+    assertTrue(complementDs == proteinAf.getViewport().getAlignment()
+            .getDataset());
+
+    char gc = requestedBy.getSplitViewContainer().getComplement(requestedBy)
+            .getGapCharacter();
+
+    AlignmentI complement = inputView.getComplementView()
+            .getVisibleAlignment(gc);
+    String complementTitle = requestedBy.getSplitViewContainer()
+            .getComplementTitle(requestedBy);
+    // becomes null if the alignment window was closed before the alignment
+    // job finished.
+    AlignmentI copyComplement = new Alignment(complement);
+    // todo should this be done by copy constructor?
+    copyComplement.setGapCharacter(complement.getGapCharacter());
+    // share the same dataset (and the mappings it holds)
+    copyComplement.setDataset(complementDs);
+    copyComplement.alignAs(result);
+    // check shape is as expected
+    assertEquals(copyComplement.getWidth(), result.getWidth() * 3);
+    assertEquals(copyComplement.getHeight(), result.getHeight());
+    // specific bug with this set - see same CDS for all distinct products
+    assertTrue(
+            !copyComplement.getSequenceAt(0).getSequenceAsString().equals(
+                    copyComplement.getSequenceAt(1).getSequenceAsString()),
+            "Didn't reconstruct CDS correctly");
+    // now get the result again, do some edits and reconstruct again
+    alAndHidden = inputView.getAlignmentAndHiddenColumns(
+            proteinAf.getViewport().getGapCharacter());
+    AlignmentI newresult = new Alignment((SequenceI[]) alAndHidden[0]);
+    newresult.setHiddenColumns((HiddenColumns) alAndHidden[1]);
+    newresult.setDataset(complementDs);
+    newresult.getSequenceAt(0).insertCharAt(3, 3, '-');
+    newresult.getSequenceAt(1).insertCharAt(0, 3, '-');
+    newresult.padGaps();
+    AlignmentI newcomplement = inputView.getComplementView()
+            .getVisibleAlignment('-');
+    newcomplement.alignAs(newresult);
+    assertEquals(newcomplement.getWidth(), newresult.getWidth() * 3);
+    assertEquals(newcomplement.getHeight(), newresult.getHeight());
+    // if reconstruction worked, the first sequence should not equal the first
+    // sequence in the original CDS 'alignAs'
+    for (int sq = 0; sq < 3; sq++)
+    {
+      // check same CDS in same position
+      assertTrue(newcomplement.getSequenceAt(sq)
+              .getDatasetSequence() == newcomplement.getSequenceAt(sq)
+                      .getDatasetSequence());
+      // verify that sequence strings are different
+      assertTrue(!newcomplement.getSequenceAt(sq).getSequenceAsString()
+              .equals(copyComplement.getSequenceAt(sq)
+                      .getSequenceAsString()));
+    }
+    // JAL-3748 bug manifests as duplicated CDS sequence content, so need to
+    // also check each CDS is distinct.
+    assertTrue(
+            !newcomplement.getSequenceAt(0).getSequenceAsString().equals(
+                    newcomplement.getSequenceAt(1).getSequenceAsString()),
+            "Didn't reconstruct CDS correctly");
+
+  }
+}