Merge branch 'JAL-1601-direct-jpred4-rest-service' into development/Release_2_12_Branch
[jalview.git] / test / jalview / testutils / AnnotationsMatcher.java
diff --git a/test/jalview/testutils/AnnotationsMatcher.java b/test/jalview/testutils/AnnotationsMatcher.java
new file mode 100644 (file)
index 0000000..cc64d27
--- /dev/null
@@ -0,0 +1,82 @@
+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)
+  {
+    if (a == null && b == null)
+      return true;
+    if ((a == null) != (b == null)) // if one is null but the other is not
+      return false;
+    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;
+      }
+    }
+  }
+}