Skip to content

Commit

Permalink
Introduce AssertionFailureBuilder (#2972)
Browse files Browse the repository at this point in the history
Resolves #2967.
  • Loading branch information
marcphilipp committed Jul 17, 2022
1 parent 08b102c commit e91e5dc
Show file tree
Hide file tree
Showing 24 changed files with 516 additions and 282 deletions.
2 changes: 2 additions & 0 deletions documentation/src/docs/asciidoc/release-notes/index.adoc
Expand Up @@ -16,6 +16,8 @@ authors as well as build tool and IDE vendors.

include::{includedir}/link-attributes.adoc[]

include::{basedir}/release-notes-5.9.0.adoc[]

include::{basedir}/release-notes-5.9.0-RC1.adoc[]

include::{basedir}/release-notes-5.9.0-M1.adoc[]
Expand Down
@@ -0,0 +1,59 @@
[[release-notes-5.9.0]]
== 5.9.0

*Date of Release:* ❓

*Scope:* ❓

For a complete list of all _closed_ issues and pull requests for this release, consult the
link:{junit5-repo}+/milestone/62?closed=1+[5.9.0] milestone page in the JUnit repository on
GitHub.


[[release-notes-5.9.0-junit-platform]]
=== JUnit Platform

==== Bug Fixes

* ❓

==== Deprecations and Breaking Changes

* ❓

==== New Features and Improvements

* ❓


[[release-notes-5.9.0-junit-jupiter]]
=== JUnit Jupiter

==== Bug Fixes

* ❓

==== Deprecations and Breaking Changes

* ❓

==== New Features and Improvements

* `AssertionFailureBuilder` allows reusing Jupiter's logic for creating failure messages
to assist in writing custom assertion methods.


[[release-notes-5.9.0-junit-vintage]]
=== JUnit Vintage

==== Bug Fixes

* ❓

==== Deprecations and Breaking Changes

* ❓

==== New Features and Improvements

* ❓
Expand Up @@ -10,11 +10,8 @@

package org.junit.jupiter.api;

import static org.junit.jupiter.api.AssertionUtils.buildPrefix;
import static org.junit.jupiter.api.AssertionUtils.fail;
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;
import static org.junit.jupiter.api.AssertionUtils.formatIndexes;
import static org.junit.jupiter.api.AssertionUtils.formatValues;
import static org.junit.jupiter.api.AssertionUtils.nullSafeGet;
import static org.junit.platform.commons.util.ReflectionUtils.isArray;

import java.util.ArrayDeque;
Expand Down Expand Up @@ -406,30 +403,41 @@ private static void assertArraysNotNull(Object expected, Object actual, Deque<In
}

private static void failExpectedArrayIsNull(Deque<Integer> indexes, Object messageOrSupplier) {
fail(buildPrefix(nullSafeGet(messageOrSupplier)) + "expected array was <null>" + formatIndexes(indexes));
assertionFailure() //
.message(messageOrSupplier) //
.reason("expected array was <null>" + formatIndexes(indexes)) //
.buildAndThrow();
}

private static void failActualArrayIsNull(Deque<Integer> indexes, Object messageOrSupplier) {
fail(buildPrefix(nullSafeGet(messageOrSupplier)) + "actual array was <null>" + formatIndexes(indexes));
assertionFailure() //
.message(messageOrSupplier) //
.reason("actual array was <null>" + formatIndexes(indexes)) //
.buildAndThrow();
}

private static void assertArraysHaveSameLength(int expected, int actual, Deque<Integer> indexes,
Object messageOrSupplier) {

if (expected != actual) {
String prefix = buildPrefix(nullSafeGet(messageOrSupplier));
String message = "array lengths differ" + formatIndexes(indexes) + ", expected: <" + expected
+ "> but was: <" + actual + ">";
fail(prefix + message);
assertionFailure() //
.message(messageOrSupplier) //
.reason("array lengths differ" + formatIndexes(indexes)) //
.expected(expected) //
.actual(actual) //
.buildAndThrow();
}
}

private static void failArraysNotEqual(Object expected, Object actual, Deque<Integer> indexes,
Object messageOrSupplier) {

String prefix = buildPrefix(nullSafeGet(messageOrSupplier));
String message = "array contents differ" + formatIndexes(indexes) + ", " + formatValues(expected, actual);
fail(prefix + message);
assertionFailure() //
.message(messageOrSupplier) //
.reason("array contents differ" + formatIndexes(indexes)) //
.expected(expected) //
.actual(actual) //
.buildAndThrow();
}

private static Deque<Integer> nullSafeIndexes(Deque<Integer> indexes, int newIndex) {
Expand Down
Expand Up @@ -10,8 +10,7 @@

package org.junit.jupiter.api;

import static org.junit.jupiter.api.AssertionUtils.buildPrefix;
import static org.junit.jupiter.api.AssertionUtils.nullSafeGet;
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;

import java.util.function.Supplier;

Expand Down Expand Up @@ -78,9 +77,11 @@ private static <T> T assertDoesNotThrow(ThrowingSupplier<T> supplier, Object mes
}

private static AssertionFailedError createAssertionFailedError(Object messageOrSupplier, Throwable t) {
String message = buildPrefix(nullSafeGet(messageOrSupplier)) + "Unexpected exception thrown: "
+ t.getClass().getName() + buildSuffix(t.getMessage());
return new AssertionFailedError(message, t);
return assertionFailure() //
.message(messageOrSupplier) //
.reason("Unexpected exception thrown: " + t.getClass().getName() + buildSuffix(t.getMessage())) //
.cause(t) //
.build();
}

private static String buildSuffix(String message) {
Expand Down
Expand Up @@ -10,8 +10,8 @@

package org.junit.jupiter.api;

import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;
import static org.junit.jupiter.api.AssertionUtils.doublesAreEqual;
import static org.junit.jupiter.api.AssertionUtils.failNotEqual;
import static org.junit.jupiter.api.AssertionUtils.floatsAreEqual;
import static org.junit.jupiter.api.AssertionUtils.objectsAreEqual;

Expand Down Expand Up @@ -189,4 +189,11 @@ static void assertEquals(Object expected, Object actual, Supplier<String> messag
}
}

private static void failNotEqual(Object expected, Object actual, Object messageOrSupplier) {
assertionFailure() //
.message(messageOrSupplier) //
.expected(expected) //
.actual(actual) //
.buildAndThrow();
}
}
Expand Up @@ -10,9 +10,7 @@

package org.junit.jupiter.api;

import static org.junit.jupiter.api.AssertionUtils.buildPrefix;
import static org.junit.jupiter.api.AssertionUtils.fail;
import static org.junit.jupiter.api.AssertionUtils.nullSafeGet;
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;

import java.util.function.BooleanSupplier;
import java.util.function.Supplier;
Expand All @@ -25,8 +23,6 @@
*/
class AssertFalse {

private static final String EXPECTED_FALSE = "expected: <false> but was: <true>";

private AssertFalse() {
/* no-op */
}
Expand All @@ -37,13 +33,13 @@ static void assertFalse(boolean condition) {

static void assertFalse(boolean condition, String message) {
if (condition) {
fail(buildPrefix(message) + EXPECTED_FALSE, false, true);
failNotFalse(message);
}
}

static void assertFalse(boolean condition, Supplier<String> messageSupplier) {
if (condition) {
fail(buildPrefix(nullSafeGet(messageSupplier)) + EXPECTED_FALSE, false, true);
failNotFalse(messageSupplier);
}
}

Expand All @@ -59,4 +55,12 @@ static void assertFalse(BooleanSupplier booleanSupplier, Supplier<String> messag
assertFalse(booleanSupplier.getAsBoolean(), messageSupplier);
}

private static void failNotFalse(Object messageOrSupplier) {
assertionFailure() //
.message(messageOrSupplier) //
.expected(false) //
.actual(true) //
.buildAndThrow();
}

}
Expand Up @@ -10,14 +10,10 @@

package org.junit.jupiter.api;

import static org.junit.jupiter.api.AssertionUtils.buildPrefix;
import static org.junit.jupiter.api.AssertionUtils.format;
import static org.junit.jupiter.api.AssertionUtils.nullSafeGet;
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;

import java.util.function.Supplier;

import org.opentest4j.AssertionFailedError;

/**
* {@code AssertInstanceOf} is a collection of utility methods that support
* asserting that an object is of an expected type &mdash; in other words, if it
Expand Down Expand Up @@ -45,10 +41,12 @@ static <T> T assertInstanceOf(Class<T> expectedType, Object actualValue, Supplie

private static <T> T assertInstanceOf(Class<T> expectedType, Object actualValue, Object messageOrSupplier) {
if (!expectedType.isInstance(actualValue)) {
String reason = (actualValue == null ? "Unexpected null value" : "Unexpected type");
String message = buildPrefix(nullSafeGet(messageOrSupplier))
+ format(expectedType, actualValue == null ? null : actualValue.getClass(), reason);
throw new AssertionFailedError(message);
assertionFailure() //
.message(messageOrSupplier) //
.reason(actualValue == null ? "Unexpected null value" : "Unexpected type") //
.expected(expectedType) //
.actual(actualValue == null ? null : actualValue.getClass()) //
.buildAndThrow();
}
return expectedType.cast(actualValue);
}
Expand Down
Expand Up @@ -10,11 +10,8 @@

package org.junit.jupiter.api;

import static org.junit.jupiter.api.AssertionUtils.buildPrefix;
import static org.junit.jupiter.api.AssertionUtils.fail;
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;
import static org.junit.jupiter.api.AssertionUtils.formatIndexes;
import static org.junit.jupiter.api.AssertionUtils.formatValues;
import static org.junit.jupiter.api.AssertionUtils.nullSafeGet;

import java.util.ArrayDeque;
import java.util.Deque;
Expand Down Expand Up @@ -139,11 +136,17 @@ private static void assertIterablesNotNull(Object expected, Object actual, Deque
}

private static void failExpectedIterableIsNull(Deque<Integer> indexes, Object messageOrSupplier) {
fail(buildPrefix(nullSafeGet(messageOrSupplier)) + "expected iterable was <null>" + formatIndexes(indexes));
assertionFailure() //
.message(messageOrSupplier) //
.reason("expected iterable was <null>" + formatIndexes(indexes)) //
.buildAndThrow();
}

private static void failActualIterableIsNull(Deque<Integer> indexes, Object messageOrSupplier) {
fail(buildPrefix(nullSafeGet(messageOrSupplier)) + "actual iterable was <null>" + formatIndexes(indexes));
assertionFailure() //
.message(messageOrSupplier) //
.reason("actual iterable was <null>" + formatIndexes(indexes)) //
.buildAndThrow();
}

private static void assertIteratorsAreEmpty(Iterator<?> expected, Iterator<?> actual, int processed,
Expand All @@ -156,19 +159,24 @@ private static void assertIteratorsAreEmpty(Iterator<?> expected, Iterator<?> ac
AtomicInteger actualCount = new AtomicInteger(processed);
actual.forEachRemaining(e -> actualCount.incrementAndGet());

String prefix = buildPrefix(nullSafeGet(messageOrSupplier));
String message = "iterable lengths differ" + formatIndexes(indexes) + ", expected: <" + expectedCount.get()
+ "> but was: <" + actualCount.get() + ">";
fail(prefix + message);
assertionFailure() //
.message(messageOrSupplier) //
.reason("iterable lengths differ" + formatIndexes(indexes)) //
.expected(expectedCount.get()) //
.actual(actualCount.get()) //
.buildAndThrow();
}
}

private static void failIterablesNotEqual(Object expected, Object actual, Deque<Integer> indexes,
Object messageOrSupplier) {

String prefix = buildPrefix(nullSafeGet(messageOrSupplier));
String message = "iterable contents differ" + formatIndexes(indexes) + ", " + formatValues(expected, actual);
fail(prefix + message);
assertionFailure() //
.message(messageOrSupplier) //
.reason("iterable contents differ" + formatIndexes(indexes)) //
.expected(expected) //
.actual(actual) //
.buildAndThrow();
}

private final static class Pair {
Expand Down
Expand Up @@ -12,8 +12,7 @@

import static java.lang.String.format;
import static java.lang.String.join;
import static org.junit.jupiter.api.AssertionUtils.buildPrefix;
import static org.junit.jupiter.api.AssertionUtils.nullSafeGet;
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;
import static org.junit.platform.commons.util.Preconditions.condition;
import static org.junit.platform.commons.util.Preconditions.notNull;

Expand Down Expand Up @@ -195,8 +194,13 @@ String snippet(String line) {

void fail(String format, Object... args) {
String newLine = System.lineSeparator();
String message = buildPrefix(nullSafeGet(messageOrSupplier)) + format(format, args);
AssertionUtils.fail(message, join(newLine, expectedLines), join(newLine, actualLines));
assertionFailure() //
.message(messageOrSupplier) //
.reason(format(format, args)) //
.expected(join(newLine, expectedLines)) //
.actual(join(newLine, actualLines)) //
.includeValuesInMessage(false) //
.buildAndThrow();
}
}

Expand Down

0 comments on commit e91e5dc

Please sign in to comment.