JAL-3484 unit test for restoring two views' annotation ordering
[jalview.git] / test / jalview / project / Jalview2xmlTests.java
index ea3f00b..d08ae7d 100644 (file)
@@ -23,6 +23,7 @@ package jalview.project;
 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.assertNull;
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
@@ -32,8 +33,10 @@ import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
 import jalview.api.FeatureColourI;
 import jalview.api.ViewStyleI;
+import jalview.bin.Cache;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
 import jalview.datamodel.HiddenSequences;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.PDBEntry.Type;
@@ -70,6 +73,7 @@ import jalview.schemes.TCoffeeColourScheme;
 import jalview.structure.StructureImportSettings;
 import jalview.util.matcher.Condition;
 import jalview.viewmodel.AlignmentViewport;
+import jalview.viewmodel.AlignmentViewport.AutoAnnotation;
 
 import java.awt.Color;
 import java.io.File;
@@ -99,7 +103,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
   }
 
   @Test(groups = { "Functional" })
-  public void testRNAStructureRecovery() throws Exception
+  public void testRestoreRNAStructure() throws Exception
   {
     String inFile = "examples/RF00031_folded.stk";
     String tfile = File.createTempFile("JalviewTest", ".jvp")
@@ -137,7 +141,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
   }
 
   @Test(groups = { "Functional" })
-  public void testTCoffeeScores() throws Exception
+  public void testRestoreTCoffeeColouring() throws Exception
   {
     String inFile = "examples/uniref50.fa",
             inAnnot = "examples/uniref50.score_ascii";
@@ -147,12 +151,13 @@ public class Jalview2xmlTests extends Jalview2xmlBase
             DataSourceType.FILE);
     assertNotNull(af, "Didn't read input file " + inFile);
     af.loadJalviewDataFile(inAnnot, DataSourceType.FILE, null, null);
-    assertSame(af.getViewport().getGlobalColourScheme().getClass(),
+    AlignViewport viewport = af.getViewport();
+    assertSame(viewport.getGlobalColourScheme().getClass(),
             TCoffeeColourScheme.class, "Didn't set T-coffee colourscheme");
     assertNotNull(
-            ColourSchemeProperty.getColourScheme(
-                    af.getViewport().getAlignment(),
-                    af.getViewport().getGlobalColourScheme()
+            ColourSchemeProperty.getColourScheme(viewport,
+                    viewport.getAlignment(),
+                    viewport.getGlobalColourScheme()
                             .getSchemeName()),
             "Recognise T-Coffee score from string");
 
@@ -171,7 +176,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
   }
 
   @Test(groups = { "Functional" })
-  public void testColourByAnnotScores() throws Exception
+  public void testRestoreColourByAnnotion() throws Exception
   {
     String inFile = "examples/uniref50.fa",
             inAnnot = "examples/testdata/uniref50_iupred.jva";
@@ -399,7 +404,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * @throws Exception
    */
   @Test(groups = { "Functional" }, enabled = true)
-  public void testStoreAndRecoverExpandedviews() throws Exception
+  public void testRestoreExpandedviews() throws Exception
   {
     Desktop.instance.closeAll_actionPerformed(null);
 
@@ -418,7 +423,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     int oldviews = Desktop.getAlignFrames().length;
     Assert.assertEquals(Desktop.getAlignFrames().length,
             Desktop.getAlignmentPanels(afid).length);
-    File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
+    File tfile = File.createTempFile("testRestoreExpandedviews", ".jvp");
     try
     {
       new Jalview2XML(false).saveState(tfile);
@@ -453,7 +458,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * @throws Exception
    */
   @Test(groups = { "Functional" })
-  public void testStoreAndRecoverReferenceSeqSettings() throws Exception
+  public void testRestoreReferenceSeqSettings() throws Exception
   {
     Desktop.instance.closeAll_actionPerformed(null);
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
@@ -485,7 +490,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
 
       n++;
     }
-    File tfile = File.createTempFile("testStoreAndRecoverReferenceSeq",
+    File tfile = File.createTempFile("testRestoreReferenceSeqSettings",
             ".jvp");
     try
     {
@@ -586,7 +591,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * @throws Exception
    */
   @Test(groups = { "Functional" })
-  public void testStoreAndRecoverGroupRepSeqs() throws Exception
+  public void testRestoreGroupRepSeqs() throws Exception
   {
     Desktop.instance.closeAll_actionPerformed(null);
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
@@ -654,8 +659,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
 
       n++;
     }
-    File tfile = File.createTempFile("testStoreAndRecoverGroupReps",
-            ".jvp");
+    File tfile = File.createTempFile("testRestoreGroupRepSeqs", ".jvp");
     try
     {
       new Jalview2XML(false).saveState(tfile);
@@ -706,7 +710,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * @throws Exception
    */
   @Test(groups = { "Functional" })
-  public void testStoreAndRecoverPDBEntry() throws Exception
+  public void testRestorePDBEntry() throws Exception
   {
     Desktop.instance.closeAll_actionPerformed(null);
     String exampleFile = "examples/3W5V.pdb";
@@ -749,7 +753,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
             seqs[3].getDatasetSequence().getAllPDBEntries().get(0),
             pdbEntries[3]);
 
-    File tfile = File.createTempFile("testStoreAndRecoverPDBEntry", ".jvp");
+    File tfile = File.createTempFile("testRestorePDBEntry", ".jvp");
     try
     {
       new Jalview2XML(false).saveState(tfile);
@@ -806,7 +810,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * @throws IOException
    */
   @Test(groups = { "Functional" })
-  public void testStoreAndRecoverColourThresholds() throws IOException
+  public void testRestoreColourThresholds() throws IOException
   {
     Desktop.instance.closeAll_actionPerformed(null);
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
@@ -864,7 +868,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
     /*
      * save project, close windows, reload project, verify
      */
-    File tfile = File.createTempFile("testStoreAndRecoverColourThresholds",
+    File tfile = File.createTempFile("testRestoreColourThresholds",
             ".jvp");
     tfile.deleteOnExit();
     new Jalview2XML(false).saveState(tfile);
@@ -900,7 +904,7 @@ public class Jalview2xmlTests extends Jalview2xmlBase
    * @throws IOException
    */
   @Test(groups = { "Functional" })
-  public void testSaveLoadFeatureColoursAndFilters() throws IOException
+  public void testRestoreFeatureColoursAndFilters() throws IOException
   {
     AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
             ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
@@ -1118,12 +1122,13 @@ public class Jalview2xmlTests extends Jalview2xmlBase
   }
 
   @Test(groups = "Functional")
-  public void testPcaViewAssociation() throws IOException
+  public void testRestorePCAViewAssociation() throws IOException
   {
     Desktop.instance.closeAll_actionPerformed(null);
     final String PCAVIEWNAME = "With PCA";
     // create a new tempfile
-    File tempfile = File.createTempFile("jvPCAviewAssoc", "jvp");
+    File tempfile = File.createTempFile("testRestorePCAViewAssociation",
+            "jvp");
 
     {
       String exampleFile = "examples/uniref50.fa";
@@ -1178,4 +1183,215 @@ public class Jalview2xmlTests extends Jalview2xmlBase
                     .getAlignViewport(),
             "Didn't restore correct view association for the PCA view");
   }
+
+  /**
+   * Tests that annotation ordering is faithfully restored, on project reload or
+   * New View, even if preference settings have changed
+   * 
+   * @throws Exception
+   */
+  @Test(groups = { "Functional" })
+  public void testRestoreAnnotationOrdering() throws Exception
+  {
+    Desktop.instance.closeAll_actionPerformed(null);
+    Cache.setProperty("SHOW_ANNOTATION", "true");
+    Cache.setProperty("SHOW_CONSERVATION", "true");
+    Cache.setProperty("SHOW_QUALITY", "false");
+    Cache.setProperty("SHOW_IDENTITY", "false");
+    Cache.setProperty("SHOW_OCCUPANCY", "true");
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/uniref50.fa", DataSourceType.FILE);
+    assertNotNull(af, "Didn't read in the example file correctly.");
+
+    AlignFrame[] afs = Desktop.getAlignFrames();
+    assertEquals(afs.length, 1);
+    AlignmentI alignment = afs[0].getViewport().getAlignment();
+    AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation();
+    assertEquals(anns.length, 2);
+
+    /*
+     * this order is hard wired in AlignmentViewport.initAutoAnnotation()
+     */
+    assertEquals(anns[0].label, "Conservation");
+    assertEquals(anns[1].label, "Occupancy");
+
+    /*
+     * add two user annotations, adjust order, height and visibility
+     */
+    AlignmentAnnotation tmp = anns[0];
+    anns[0] = anns[1];
+    anns[1] = tmp;
+    Annotation[] an1 = new Annotation[] { new Annotation(2f) };
+    Annotation[] an2 = new Annotation[] { new Annotation(3f) };
+    alignment.addAnnotation(new AlignmentAnnotation("hello", "desc1", an1),
+            1);
+    alignment.addAnnotation(new AlignmentAnnotation("world", "desc2", an2),
+            3);
+    anns = alignment.getAlignmentAnnotation();
+    assertEquals(anns[0].label, "Occupancy");
+    assertEquals(anns[1].label, "hello");
+    assertEquals(anns[2].label, "Conservation");
+    assertEquals(anns[3].label, "world");
+    anns[0].graphHeight = 60;
+    anns[0].visible = false;
+    anns[1].graphHeight = 70;
+    anns[2].graphHeight = 80;
+    anns[3].graphHeight = 90;
+    anns[3].visible = false;
+
+    /*
+     * save project to temporary file and reload on to an empty desktop,
+     * verify annotation order, height and visibility is restored
+     */
+    File projectFile = File.createTempFile("jvTest", ".jvp");
+    new Jalview2XML(false).saveState(projectFile);
+    Desktop.instance.closeAll_actionPerformed(null);
+    if (Desktop.getAlignFrames() != null)
+    {
+      Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+    }
+  
+    af = new FileLoader().LoadFileWaitTillLoaded(
+            projectFile.getAbsolutePath(),
+            DataSourceType.FILE);
+    anns = af.getViewport().getAlignment().getAlignmentAnnotation();
+    assertEquals(anns.length, 4);
+    assertEquals(anns[0].label, "Occupancy");
+    assertEquals(anns[1].label, "hello");
+    assertEquals(anns[2].label, "Conservation");
+    assertEquals(anns[3].label, "world");
+    assertEquals(anns[0].graphHeight, 60);
+    assertEquals(anns[1].graphHeight, 70);
+    assertEquals(anns[2].graphHeight, 80);
+    assertEquals(anns[3].graphHeight, 90);
+    assertFalse(anns[0].visible);
+    assertTrue(anns[1].visible);
+    assertTrue(anns[2].visible);
+    assertFalse(anns[3].visible);
+
+    /*
+     * make a new view of the alignment (uses project save/load code)
+     * and verify annotations are ordered the same
+     */
+    AlignmentPanel newPanel = af.newView("new", true);
+    AlignmentAnnotation[] newAnns = newPanel.getAlignment()
+            .getAlignmentAnnotation();
+    assertEquals(newAnns.length, 4);
+    assertEquals(newAnns[0].label, "Occupancy");
+    assertEquals(newAnns[1].label, "hello");
+    assertEquals(newAnns[2].label, "Conservation");
+    assertEquals(newAnns[3].label, "world");
+    assertEquals(newAnns[0].graphHeight, 60);
+    assertEquals(newAnns[1].graphHeight, 70);
+    assertEquals(newAnns[2].graphHeight, 80);
+    assertEquals(newAnns[3].graphHeight, 90);
+    assertFalse(newAnns[0].visible);
+    assertTrue(newAnns[1].visible);
+    assertTrue(newAnns[2].visible);
+    assertFalse(newAnns[3].visible);
+    newPanel.closePanel();
+
+    /*
+     * reload the project with Preferences set to not create Occupancy, but to
+     * create Quality; annotations should still appear as saved in the project;
+     * preferences should be left unchanged (after temporary override)
+     */
+    Desktop.instance.closeAll_actionPerformed(null);
+    Cache.setProperty("SHOW_OCCUPANCY", "false");
+    Cache.removeProperty("SHOW_QUALITY"); // will default to true
+    Map<String, String> originalPreferences = Cache.getProperties(
+            AutoAnnotation.OCCUPANCY.preferenceKey,
+            AutoAnnotation.CONSERVATION.preferenceKey,
+            AutoAnnotation.QUALITY.preferenceKey,
+            AutoAnnotation.CONSENSUS.preferenceKey);
+    af = new FileLoader().LoadFileWaitTillLoaded(
+            projectFile.getAbsolutePath(), DataSourceType.FILE);
+    alignment = af.getViewport().getAlignment();
+    anns = alignment.getAlignmentAnnotation();
+    assertEquals(anns.length, 4);
+    assertEquals(anns[0].label, "Occupancy");
+    assertEquals(anns[1].label, "hello");
+    assertEquals(anns[2].label, "Conservation");
+    assertEquals(anns[3].label, "world");
+    Map<String, String> newPreferences = Cache.getProperties(
+            AutoAnnotation.OCCUPANCY.preferenceKey,
+            AutoAnnotation.CONSERVATION.preferenceKey,
+            AutoAnnotation.QUALITY.preferenceKey,
+            AutoAnnotation.CONSENSUS.preferenceKey);
+    assertEquals(originalPreferences, newPreferences);
+    assertNull(Cache.getProperty(AutoAnnotation.QUALITY.preferenceKey));
+
+    /*
+     * make a new view, reorder its annotations, and delete and hide 
+     * a different annotation in each of the two views
+     */
+    newPanel = af.newView("new", true);
+    af.getViewport().setViewName("Original");
+    
+    /*
+     * just for interest - new view has the same manual annotation objects,
+     * but new auto-calculated annotations
+     */
+    AlignmentI newAlignment = newPanel.getAlignment();
+    newAnns = newAlignment.getAlignmentAnnotation();
+    assertNotSame(anns[0], newAnns[0]);
+    assertSame(anns[1], newAnns[1]);
+    assertNotSame(anns[2], newAnns[2]);
+    assertSame(anns[3], newAnns[3]);
+
+    alignment.deleteAnnotation(anns[2]); // delete Conservation view 1
+    anns[1].visible = false; // hide 'hello' view 1
+
+    tmp = newAnns[0];
+    newAnns[0] = newAnns[3]; // 'world' moved to top of new view
+    newAnns[3] = tmp; // then hello, Conservation, Occupancy
+    newAnns[0].visible = false; // hide 'world' in new view
+    newAnns[3].graphHeight = 99; // set height of Occupancy
+    newAlignment.deleteAnnotation(newAnns[1]); // delete 'hello' in new view
+
+    /*
+     * save, reload and verify annotations in both views
+     */
+    ((AlignViewport) newPanel.getAlignViewport()).setViewName("New View");
+    projectFile = File.createTempFile("jvTest", ".jvp");
+    new Jalview2XML(false).saveState(projectFile);
+    Desktop.instance.closeAll_actionPerformed(null);
+    af = new FileLoader().LoadFileWaitTillLoaded(
+            projectFile.getAbsolutePath(), DataSourceType.FILE);
+    assertEquals(af.getAlignPanels().size(), 2);
+
+    /*
+     * check first view
+     */
+    AlignViewportI firstViewport = af.getAlignPanels().get(0)
+            .getAlignViewport();
+    assertEquals(((AlignViewport) firstViewport).getViewName(), "Original");
+    alignment = firstViewport.getAlignment();
+    anns = alignment.getAlignmentAnnotation();
+    assertEquals(anns.length, 3);
+    assertEquals(anns[0].label, "Occupancy");
+    assertEquals(anns[1].label, "hello");
+    assertEquals(anns[2].label, "world");
+    assertFalse(anns[0].visible);
+    assertFalse(anns[1].visible);
+    assertFalse(anns[2].visible);
+
+    /*
+     * check second view
+     */
+    AlignViewportI secondViewport = af.getAlignPanels().get(1)
+            .getAlignViewport();
+    assertEquals(((AlignViewport) secondViewport).getViewName(),
+            "New View");
+    alignment = secondViewport.getAlignment();
+    anns = alignment.getAlignmentAnnotation();
+    assertEquals(anns.length, 3);
+    assertEquals(anns[0].label, "world");
+    assertEquals(anns[1].label, "Conservation");
+    assertEquals(anns[2].label, "Occupancy");
+    assertFalse(anns[0].visible);
+    assertTrue(anns[1].visible);
+    assertFalse(anns[2].visible);
+    assertEquals(anns[2].graphHeight, 99);
+  }
 }