/** Creates a {@link TreeComparison} for comparing the two trees. */ public static <E, A> TreeComparison<E, A> of(TreeDef<E> expectedDef, E expectedRoot, TreeDef<A> actualDef, A actualRoot) { return new TreeComparison<>(expectedDef, expectedRoot, actualDef, actualRoot); }
/** * Asserts that the trees are equal, based on `Objects.equals()`. * * @see #isEqualBasedOn(BiPredicate) */ public void assertEqual() { assertEqualBasedOn(Objects::equals); }
/** Asserts that the two trees are equal. */ @Override public void assertEqual() { comparison.assertEqualMappedBy(mapExpected, mapActual); }
/** * Asserts that the trees are equal, by calling {@link Objects#equals(Object, Object)} on the results of both mappers. * * @see #isEqualMappedBy(Function, Function) */ public void assertEqualMappedBy(Function<? super E, ?> expectedMapper, Function<? super A, ?> actualMapper) { if (!isEqualMappedBy(expectedMapper, actualMapper)) { throwAssertionError(); } }
/** * Asserts that the trees are equal, based on the given {@link BiPredicate}. * * @see #isEqualBasedOn(BiPredicate) */ public void assertEqualBasedOn(BiPredicate<E, A> compareFunc) { if (!isEqualBasedOn(compareFunc)) { throwAssertionError(); } }
/** Returns true if the two trees are equal, based on `Objects.equals`. */ public boolean isEqual() { return isEqualBasedOn(Objects::equals); }
SameTypeImp(TreeComparison<E, A> comparison, Function<? super E, ? extends T> mapExpected, Function<? super A, ? extends T> mapActual) { this.comparison = comparison; this.mapExpected = mapExpected; this.mapActual = mapActual; comparison.decorateErrorsWith(mapExpected.andThen(Objects::toString), mapActual.andThen(Objects::toString)); }
/** Returns true if the two trees are equal, based on the given {@link BiPredicate}. */ public boolean isEqualBasedOn(BiPredicate<? super E, ? super A> compareFunc) { return equals(expectedDef, expectedRoot, actualDef, actualRoot, compareFunc); }
/** Returns true if the two trees are equal. */ @Override public boolean isEqual() { return comparison.isEqualMappedBy(mapExpected, mapActual); }
/** Throws an assetion error. */ private void throwAssertionError() { throw createAssertionError(); }
/** * Returns an {@link AssertionError} containing the contents of the * two trees. Attempts to throw a JUnit ComparisonFailure if JUnit * is on the class path, but it fails to a plain old {@code java.lang.AssertionError} * if the reflection calls fail. */ private AssertionError createAssertionError() { // convert both sides to strings String expected = TreeQuery.toString(expectedDef, expectedRoot, expectedToString); String actual = TreeQuery.toString(actualDef, actualRoot, actualToString); // try to create a junit ComparisonFailure for (String exceptionType : Arrays.asList( "org.junit.ComparisonFailure", "junit.framework.ComparisonFailure")) { try { return createComparisonFailure(exceptionType, expected, actual); } catch (Exception e) {} } // we'll have to settle for a plain-jane AssertionError return new AssertionError("Expected:\n" + expected + "\n\nActual:\n" + actual); }
/** Creates a {@link SameType} for comparing a {@link TreeNode} against a generic tree which been mapped. */ public static <T, U> SameType<T> of(TreeNode<T> expected, TreeDef<U> treeDef, U actual, Function<? super U, ? extends T> mapper) { return of(TreeNode.treeDef(), expected, treeDef, actual).mapToSame(TreeNode::getContent, mapper); }
/** Returns true if the two trees are equal, by calling {@link Objects#equals(Object, Object)} on the results of both mappers. */ public boolean isEqualMappedBy(Function<? super E, ?> expectedMapper, Function<? super A, ?> actualMapper) { return isEqualBasedOn((expected, actual) -> { return Objects.equals(expectedMapper.apply(expected), actualMapper.apply(actual)); }); }
/** Decorates errors thrown by assertions with the given function. */ @Override public SameType<T> decorateErrorsWith(Function<? super T, String> toString) { comparison.decorateErrorsWith(toString.compose(mapExpected), toString.compose(mapActual)); return this; }
/** Recursively determines equality between two trees. */ private static <E, A> boolean equals(TreeDef<E> expectedDef, E expectedRoot, TreeDef<A> actualDef, A actualRoot, BiPredicate<? super E, ? super A> compareFunc) { // compare the roots if (!compareFunc.test(expectedRoot, actualRoot)) { return false; } // compare the children lists List<E> expectedChildren = expectedDef.childrenOf(expectedRoot); List<A> actualChildren = actualDef.childrenOf(actualRoot); if (expectedChildren.size() != actualChildren.size()) { return false; } // recurse on each pair of children for (int i = 0; i < expectedChildren.size(); ++i) { E expectedChild = expectedChildren.get(i); A actualChild = actualChildren.get(i); if (!equals(expectedDef, expectedChild, actualDef, actualChild, compareFunc)) { return false; } } return true; }