JAL-1601 Expand secondary structure prediction tests
[jalview.git] / test / jalview / ws2 / actions / secstructpred / SecStructPredMsaTaskTest.java
diff --git a/test/jalview/ws2/actions/secstructpred/SecStructPredMsaTaskTest.java b/test/jalview/ws2/actions/secstructpred/SecStructPredMsaTaskTest.java
new file mode 100644 (file)
index 0000000..ffadc2f
--- /dev/null
@@ -0,0 +1,194 @@
+package jalview.ws2.actions.secstructpred;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignViewport;
+import jalview.io.DataSourceType;
+import jalview.io.FastaFile;
+import jalview.io.JPredFile;
+import jalview.ws2.api.Credentials;
+import jalview.ws2.api.JobStatus;
+import jalview.ws2.api.WebServiceJobHandle;
+import jalview.ws2.client.api.SecStructPredWebServiceClientI;
+import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import static jalview.testutils.Matchers.matchesAnnotations;
+import static jalview.testutils.Matchers.matchesSequenceString;
+import static jalview.testutils.ScopeFunctions.apply;
+import static java.lang.String.format;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasProperty;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class SecStructPredMsaTaskTest
+{
+  protected SecStructPredWebServiceClientI mockClient;
+
+  @BeforeMethod(alwaysRun = true)
+  public void setupMockClient() throws IOException
+  {
+    mockClient = mock(SecStructPredWebServiceClientI.class);
+    when(mockClient.getUrl()).thenReturn("http://example.org");
+    when(mockClient.getClientName()).thenReturn("mock");
+    when(mockClient.submit(any(), any(), any()))
+            .thenReturn(new WebServiceJobHandle("mock", "mock",
+                    "http://example.org", "0"));
+    when(mockClient.getLog(any())).thenReturn("");
+    when(mockClient.getErrorLog(any())).thenReturn("");
+    when(mockClient.getStatus(any())).thenReturn(JobStatus.COMPLETED);
+  }
+
+  @DataProvider
+  public Object[][] alignmentWithExpectedInput()
+  {
+    return new Object[][] { {
+        new AlignViewport(createAlignment("AAAAAAAAAAAA", "AAAAAAAAAAAA",
+                "AAAAAAAAAAAA")),
+        List.of("AAAAAAAAAAAA", "AAAAAAAAAAAA", "AAAAAAAAAAAA") },
+        { new AlignViewport(createAlignment("AAAA--NNNNAAAA",
+                "AA--AANNNNAAAA", "AA--AARRRRAAAA")),
+            List.of("AAAA--NNNNAAAA", "AA--AANNNNAAAA", "AA--AARRRRAAAA") },
+        { new AlignViewport(createAlignment("AAAANNNNAAAA--",
+                "AAAARRRRAAAA--", "AAAARRRRAAAA--")),
+            List.of("AAAANNNNAAAA--", "AAAARRRRAAAA--", "AAAARRRRAAAA--") },
+        { new AlignViewport(createAlignment("AAAA--NNNNAAAA",
+                "AAAA--NNNNAAAA", "AAAA--NNNNAAAA")),
+            List.of("AAAA--NNNNAAAA", "AAAA--NNNNAAAA", "AAAA--NNNNAAAA") },
+        { new AlignViewport(createAlignment("AAAACCCCNNNN", "------------",
+                "AAAADDDDNNNN")),
+            List.of("AAAACCCCNNNN", "AAAADDDDNNNN") },
+        { new AlignViewport(createAlignment("AAAACC--NNNN", "AAAACCDDNNNN"),
+                apply(new HiddenColumns(), it -> it.hideColumns(6, 7))),
+            List.of("AAAACCNNNN", "AAAACCNNNN") },
+        { new AlignViewport(
+                createAlignment("CCAAAACC--MMMM", "--AAAAGGGGMMMM"),
+                apply(new HiddenColumns(), it -> {
+                  it.hideColumns(0, 1);
+                  it.hideColumns(8, 9);
+                })),
+            List.of("AAAACCMMMM", "AAAAGGMMMM") },
+        { new AlignViewport(
+                createAlignment("CCAAAACC--MMMM", "CCAAAACC--MMMM"),
+                apply(new HiddenColumns(), it -> it.hideColumns(2, 5))),
+            List.of("CCCC--MMMM", "CCCC--MMMM") } };
+  }
+
+  public static AlignmentI createAlignment(String... sequences)
+  {
+    var seqArray = new Sequence[sequences.length];
+    for (int i = 0; i < sequences.length; i++)
+      seqArray[i] = new Sequence(format("Seq%d", i), sequences[i]);
+    return new Alignment(seqArray);
+  }
+
+  @Test(
+    groups =
+    { "Functional" },
+    dataProvider = "alignmentWithExpectedInput")
+  public void testPrepareJobs_checkInputSequences(AlignViewport viewport,
+          List<String> expectedInput) throws Exception
+  {
+    var task = new SecStructPredMsaTask(mockClient, List.of(),
+            Credentials.empty(), viewport);
+    var jobs = task.prepareJobs();
+    List<Matcher<? super SequenceI>> seqMatchers = new ArrayList<>(
+            expectedInput.size());
+    for (var seqStr : expectedInput)
+      seqMatchers.add(matchesSequenceString(seqStr));
+    assertThat(jobs.get(0).getInputSequences(),
+            Matchers.<SequenceI> contains(seqMatchers));
+  }
+
+  @DataProvider
+  public Object[][] viewportWithServiceOutput() throws IOException
+  {
+
+    return new Object[][] {
+      { 
+          new AlignViewport(new Alignment(new FastaFile(
+                  "examples/testdata/secstrpred/alignment0_aln.fa",
+                  DataSourceType.FILE).getSeqsAsArray())),
+          "examples/testdata/secstrpred/alignment0.fa",
+          "examples/testdata/secstrpred/alignment0.concise"
+      },
+      {
+        new AlignViewport(new Alignment(new FastaFile(
+                "examples/testdata/secstrpred/alignment0a_aln.fa",
+                DataSourceType.FILE).getSeqsAsArray()),
+                apply(new HiddenColumns(), it -> it.hideColumns(3, 7))),
+        "examples/testdata/secstrpred/alignment0.fa",
+        "examples/testdata/secstrpred/alignment0.concise"
+      }
+    };
+  }
+  
+  @Test(groups = "Functional", dataProvider = "viewportWithServiceOutput")
+  public void testCollectResults(AlignViewport viewport, String alnFileName, String predFileName) throws Exception
+  {
+    var alnFile = new FastaFile(alnFileName, DataSourceType.FILE);
+    var predFile = new JPredFile(predFileName, DataSourceType.FILE);
+    when(mockClient.getPredictionFile(any())).thenReturn(predFile);
+    when(mockClient.getAlignmentFile(any())).thenReturn(alnFile);
+    
+    var task = new SecStructPredMsaTask(mockClient, List.of(),
+            Credentials.empty(), viewport);
+    task.init();
+    task.poll();
+    task.complete();
+    var resultAlignment = task.getResult();
+    var sequences = resultAlignment.getSequences();
+    
+    // Test output alignment matches original
+    {
+      List<Matcher<? super SequenceI>> matchers = new ArrayList<>();
+      for (var seq : viewport.getAlignment().getSequences())
+        matchers.add(matchesSequenceString(seq));
+      assertThat(sequences, Matchers.contains(matchers));
+    }
+    // Test output sequence names match original
+    {
+      List<Matcher<? super SequenceI>> matchers = new ArrayList<>();
+      for (var seq : viewport.getAlignment().getSequences())
+        matchers.add(hasProperty("name", equalTo(seq.getName())));
+      assertThat(sequences, Matchers.contains(matchers));
+    }
+    // Test hidden columns
+    {
+      var originalHidden = viewport.getAlignment().getHiddenColumns();
+      var resultHidden = resultAlignment.getHiddenColumns();
+      assertThat(resultHidden, equalTo(originalHidden));
+    }
+    // Test annotations present on the alignment
+    {
+      var hiddenColumns = viewport.getAlignment().getHiddenColumns();
+      List<Matcher<? super AlignmentAnnotation>> matchers = new ArrayList<>();
+      for (var annot : predFile.getAnnotations())
+        matchers.add(allOf(
+                hasProperty("label", equalTo(annot.label)),
+                hasProperty("annotations", matchesAnnotations(annot.annotations))
+        ));
+      List<AlignmentAnnotation> annotations = new ArrayList<>();
+      for (var annot : resultAlignment.getAlignmentAnnotation())
+        annotations.add(new AlignmentAnnotation(annot, hiddenColumns));
+      assertThat(annotations, containsInAnyOrder(matchers));
+    }
+    
+  }
+}