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 { final List annotations; public AnnotationsMatcher(List 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; } } } }