JAL-4313 Create utilities to test annotations
authorMateusz Warowny <mmzwarowny@dundee.ac.uk>
Wed, 25 Oct 2023 15:43:56 +0000 (17:43 +0200)
committerMateusz Warowny <mmzwarowny@dundee.ac.uk>
Mon, 30 Oct 2023 14:35:18 +0000 (15:35 +0100)
test/jalview/testutils/AnnotationsMatcher.java [new file with mode: 0644]
test/jalview/testutils/AnnotationsMatcherTest.java [new file with mode: 0644]
test/jalview/testutils/Matchers.java

diff --git a/test/jalview/testutils/AnnotationsMatcher.java b/test/jalview/testutils/AnnotationsMatcher.java
new file mode 100644 (file)
index 0000000..aa86d90
--- /dev/null
@@ -0,0 +1,78 @@
+package jalview.testutils;
+
+import java.util.List;
+import java.util.Objects;
+import static java.util.Objects.requireNonNullElse;
+
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
+
+import jalview.datamodel.Annotation;
+
+public class AnnotationsMatcher extends TypeSafeMatcher<Annotation[]>
+{
+  final List<Annotation> annotations;
+
+  public AnnotationsMatcher(List<Annotation> annotations)
+  {
+    this.annotations = annotations;
+  }
+
+  @Override
+  public boolean matchesSafely(Annotation[] items)
+  {
+    if (annotations.size() != items.length)
+      return false;
+    for (int i = 0; i < annotations.size(); i++)
+    {
+      var actual = items[i];
+      var expected = annotations.get(i);
+      if (!annotationsEqual(actual, expected))
+        return false;
+    }
+    return true;
+  }
+
+  static boolean annotationsEqual(Annotation a, Annotation b)
+  {
+    return a.secondaryStructure == b.secondaryStructure && a.value == b.value
+        && Objects.equals(a.colour, b.colour)
+        && Objects
+            .equals(requireNonNullElse(a.displayCharacter, ""),
+                requireNonNullElse(b.displayCharacter, ""))
+        && Objects
+            .equals(requireNonNullElse(a.description, ""),
+                requireNonNullElse(b.description, ""));
+  }
+
+  @Override
+  public void describeTo(Description description)
+  {
+    description.appendText("annotations ").appendValue(annotations);
+  }
+
+  @Override
+  public void describeMismatchSafely(Annotation[] items,
+      Description description)
+  {
+    if (annotations.size() != items.length)
+    {
+      description.appendText("but had length ").appendValue(items.length);
+      return;
+    }
+    boolean first = true;
+    for (int i = 0; i < annotations.size(); i++)
+    {
+      var actual = items[i];
+      var expected = annotations.get(i);
+      if (!annotationsEqual(actual, expected))
+      {
+        description
+            .appendText(first ? "but " : ", ")
+            .appendText("element [" + i + "] was ")
+            .appendValue(items[i]);
+        first = false;
+      }
+    }
+  }
+}
diff --git a/test/jalview/testutils/AnnotationsMatcherTest.java b/test/jalview/testutils/AnnotationsMatcherTest.java
new file mode 100644 (file)
index 0000000..732329b
--- /dev/null
@@ -0,0 +1,136 @@
+package jalview.testutils;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import jalview.datamodel.Annotation;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+
+import java.awt.Color;
+import java.util.*;
+
+public class AnnotationsMatcherTest
+{
+  @DataProvider
+  public Object[][] matchingAnnotationsLists()
+  {
+    return new Object[][] {
+        {
+            new Annotation[] {
+                new Annotation("C", "", 'C', 0.0f),
+                new Annotation("C", "", 'C', 0.1f),
+                new Annotation("B", "", 'B', 0.2f) },
+            new Annotation[] {
+                new Annotation("C", "", 'C', 0.0f),
+                new Annotation("C", "", 'C', 0.1f),
+                new Annotation("B", "", 'B', 0.2f) } },
+        {
+            new Annotation[] {
+                new Annotation("X", "xxx", 'X', 1.3f),
+                new Annotation("V", "vvv", 'V', 1.5f),
+                new Annotation("B", "bbb", 'B', 2.5f) },
+            new Annotation[] {
+                new Annotation("X", "xxx", 'X', 1.3f),
+                new Annotation("V", "vvv", 'V', 1.5f),
+                new Annotation("B", "bbb", 'B', 2.5f) } },
+        {
+            new Annotation[] {
+                new Annotation("A", "", 'A', 0.2f, Color.RED),
+                new Annotation("A", "", 'A', 0.3f, Color.GREEN),
+                new Annotation("C", "", 'C', 0.4f, Color.YELLOW),
+                new Annotation("C", "", 'C', 0.5f) },
+            new Annotation[] {
+                new Annotation("A", "", 'A', 0.2f, Color.RED),
+                new Annotation("A", "", 'A', 0.3f, Color.GREEN),
+                new Annotation("C", "", 'C', 0.4f, Color.YELLOW),
+                new Annotation("C", "", 'C', 0.5f) } },
+        {
+            new Annotation[] {
+                Annotation.EMPTY_ANNOTATION, Annotation.EMPTY_ANNOTATION },
+            new Annotation[] {
+                Annotation.EMPTY_ANNOTATION, Annotation.EMPTY_ANNOTATION } } };
+  }
+
+  @Test(groups = { "Functional" }, dataProvider = "matchingAnnotationsLists")
+  public void testMatchesSafely_matchingAnnotations(Annotation[] template,
+      Annotation[] testdata)
+  {
+    assert new AnnotationsMatcher(Arrays.asList(template))
+        .matchesSafely(testdata);
+  }
+
+  @DataProvider
+  public Object[][] matchingAnnotations()
+  {
+    return new Object[][] {
+        {
+            new Annotation("A", "aaa", 'A', 0.1f),
+            new Annotation("A", "aaa", 'A', 0.1f) },
+        {
+            new Annotation("A", "abcdef", 'A', 0.1f, Color.RED),
+            new Annotation("A", "abcdef", 'A', 0.1f, Color.RED) },
+        {
+            new Annotation("", "xxxx", ' ', 0.0f),
+            new Annotation("", "xxxx", ' ', 0.0f) },
+        {
+            new Annotation("", "", ' ', 0.0f),
+            new Annotation("", "", ' ', 0.0f) },
+        {
+            new Annotation(null, null, ' ', 0.0f),
+            new Annotation(null, null, ' ', 0.0f) },
+        {
+            new Annotation(null, "", ' ', 0.0f),
+            new Annotation("", null, ' ', 0.0f) } };
+  }
+
+  @Test(groups = { "Functional" }, dataProvider = "matchingAnnotations")
+  public void testAnnotationsEqual_matchingAnnotations(Annotation first,
+      Annotation second)
+  {
+    assert AnnotationsMatcher.annotationsEqual(first, second);
+  }
+
+  @Test(groups = { "Functional" })
+  public void testAnnotationsEqual_compareNullDisplayCharToEmpty()
+  {
+    assert AnnotationsMatcher
+        .annotationsEqual(new Annotation("", "description", 'A', 0.1f),
+            new Annotation(null, "description", 'A', 0.1f));
+    assert AnnotationsMatcher
+        .annotationsEqual(new Annotation(null, "description", 'A', 0.1f),
+            new Annotation("", "description", 'A', 0.1f));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testAnnotationsEqual_compareNullDescriptionToEmpty()
+  {
+    assert AnnotationsMatcher
+        .annotationsEqual(new Annotation("A", null, 'A', 0.2f),
+            new Annotation("A", "", 'A', 0.2f));
+    assert AnnotationsMatcher
+        .annotationsEqual(new Annotation("A", "", 'A', 0.2f),
+            new Annotation("A", null, 'A', 0.2f));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testAnnotationsEqual_compareNullDisplayCharToBlank()
+  {
+    assert !AnnotationsMatcher
+        .annotationsEqual(new Annotation(" ", "aaa", 'A', 0.03f),
+            new Annotation(null, "aaa", 'A', 0.03f));
+    assert !AnnotationsMatcher
+        .annotationsEqual(new Annotation(null, "aaa", 'A', 0.04f),
+            new Annotation(" ", "aaa", 'A', 0.04f));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testAnnotationsEqual_compareNullDescriptionToBlank()
+  {
+    assert !AnnotationsMatcher
+        .annotationsEqual(new Annotation("A", null, 'A', 0.0f),
+            new Annotation("A", " ", 'A', 0.0f));
+    assert !AnnotationsMatcher
+        .annotationsEqual(new Annotation("A", " ", 'A', 0.01f),
+            new Annotation("A", null, 'A', 0.01f));
+  }
+}
index ceb07a0..682d1bf 100644 (file)
@@ -1,7 +1,11 @@
 package jalview.testutils;
 
+import java.util.Arrays;
+import java.util.List;
+
 import org.hamcrest.Matcher;
 
+import jalview.datamodel.Annotation;
 import jalview.datamodel.SequenceI;
 
 public class Matchers
@@ -10,4 +14,21 @@ public class Matchers
   {
     return new SequenceStringMatcher(sequence);
   }
+
+  public static Matcher<SequenceI> matchesSequenceString(SequenceI sequence)
+  {
+    return new SequenceStringMatcher(sequence.getSequenceAsString());
+  }
+
+  public static Matcher<Annotation[]> matchesAnnotations(
+      List<Annotation> annotations)
+  {
+    return new AnnotationsMatcher(annotations);
+  }
+
+  public static Matcher<Annotation[]> matchesAnnotations(
+      Annotation... annotations)
+  {
+    return new AnnotationsMatcher(Arrays.asList(annotations));
+  }
 }