Skip to content

Commit e91e5dc

Browse files
authored
Introduce AssertionFailureBuilder (#2972)
Resolves #2967.
1 parent 08b102c commit e91e5dc

24 files changed

+516
-282
lines changed

documentation/src/docs/asciidoc/release-notes/index.adoc

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ authors as well as build tool and IDE vendors.
1616

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

19+
include::{basedir}/release-notes-5.9.0.adoc[]
20+
1921
include::{basedir}/release-notes-5.9.0-RC1.adoc[]
2022

2123
include::{basedir}/release-notes-5.9.0-M1.adoc[]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
[[release-notes-5.9.0]]
2+
== 5.9.0
3+
4+
*Date of Release:* ❓
5+
6+
*Scope:* ❓
7+
8+
For a complete list of all _closed_ issues and pull requests for this release, consult the
9+
link:{junit5-repo}+/milestone/62?closed=1+[5.9.0] milestone page in the JUnit repository on
10+
GitHub.
11+
12+
13+
[[release-notes-5.9.0-junit-platform]]
14+
=== JUnit Platform
15+
16+
==== Bug Fixes
17+
18+
* ❓
19+
20+
==== Deprecations and Breaking Changes
21+
22+
* ❓
23+
24+
==== New Features and Improvements
25+
26+
* ❓
27+
28+
29+
[[release-notes-5.9.0-junit-jupiter]]
30+
=== JUnit Jupiter
31+
32+
==== Bug Fixes
33+
34+
* ❓
35+
36+
==== Deprecations and Breaking Changes
37+
38+
* ❓
39+
40+
==== New Features and Improvements
41+
42+
* `AssertionFailureBuilder` allows reusing Jupiter's logic for creating failure messages
43+
to assist in writing custom assertion methods.
44+
45+
46+
[[release-notes-5.9.0-junit-vintage]]
47+
=== JUnit Vintage
48+
49+
==== Bug Fixes
50+
51+
* ❓
52+
53+
==== Deprecations and Breaking Changes
54+
55+
* ❓
56+
57+
==== New Features and Improvements
58+
59+
* ❓

junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertArrayEquals.java

+21-13
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,8 @@
1010

1111
package org.junit.jupiter.api;
1212

13-
import static org.junit.jupiter.api.AssertionUtils.buildPrefix;
14-
import static org.junit.jupiter.api.AssertionUtils.fail;
13+
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;
1514
import static org.junit.jupiter.api.AssertionUtils.formatIndexes;
16-
import static org.junit.jupiter.api.AssertionUtils.formatValues;
17-
import static org.junit.jupiter.api.AssertionUtils.nullSafeGet;
1815
import static org.junit.platform.commons.util.ReflectionUtils.isArray;
1916

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

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

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

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

419422
if (expected != actual) {
420-
String prefix = buildPrefix(nullSafeGet(messageOrSupplier));
421-
String message = "array lengths differ" + formatIndexes(indexes) + ", expected: <" + expected
422-
+ "> but was: <" + actual + ">";
423-
fail(prefix + message);
423+
assertionFailure() //
424+
.message(messageOrSupplier) //
425+
.reason("array lengths differ" + formatIndexes(indexes)) //
426+
.expected(expected) //
427+
.actual(actual) //
428+
.buildAndThrow();
424429
}
425430
}
426431

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

430-
String prefix = buildPrefix(nullSafeGet(messageOrSupplier));
431-
String message = "array contents differ" + formatIndexes(indexes) + ", " + formatValues(expected, actual);
432-
fail(prefix + message);
435+
assertionFailure() //
436+
.message(messageOrSupplier) //
437+
.reason("array contents differ" + formatIndexes(indexes)) //
438+
.expected(expected) //
439+
.actual(actual) //
440+
.buildAndThrow();
433441
}
434442

435443
private static Deque<Integer> nullSafeIndexes(Deque<Integer> indexes, int newIndex) {

junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertDoesNotThrow.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@
1010

1111
package org.junit.jupiter.api;
1212

13-
import static org.junit.jupiter.api.AssertionUtils.buildPrefix;
14-
import static org.junit.jupiter.api.AssertionUtils.nullSafeGet;
13+
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;
1514

1615
import java.util.function.Supplier;
1716

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

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

8687
private static String buildSuffix(String message) {

junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertEquals.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
package org.junit.jupiter.api;
1212

13+
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;
1314
import static org.junit.jupiter.api.AssertionUtils.doublesAreEqual;
14-
import static org.junit.jupiter.api.AssertionUtils.failNotEqual;
1515
import static org.junit.jupiter.api.AssertionUtils.floatsAreEqual;
1616
import static org.junit.jupiter.api.AssertionUtils.objectsAreEqual;
1717

@@ -189,4 +189,11 @@ static void assertEquals(Object expected, Object actual, Supplier<String> messag
189189
}
190190
}
191191

192+
private static void failNotEqual(Object expected, Object actual, Object messageOrSupplier) {
193+
assertionFailure() //
194+
.message(messageOrSupplier) //
195+
.expected(expected) //
196+
.actual(actual) //
197+
.buildAndThrow();
198+
}
192199
}

junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertFalse.java

+11-7
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@
1010

1111
package org.junit.jupiter.api;
1212

13-
import static org.junit.jupiter.api.AssertionUtils.buildPrefix;
14-
import static org.junit.jupiter.api.AssertionUtils.fail;
15-
import static org.junit.jupiter.api.AssertionUtils.nullSafeGet;
13+
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;
1614

1715
import java.util.function.BooleanSupplier;
1816
import java.util.function.Supplier;
@@ -25,8 +23,6 @@
2523
*/
2624
class AssertFalse {
2725

28-
private static final String EXPECTED_FALSE = "expected: <false> but was: <true>";
29-
3026
private AssertFalse() {
3127
/* no-op */
3228
}
@@ -37,13 +33,13 @@ static void assertFalse(boolean condition) {
3733

3834
static void assertFalse(boolean condition, String message) {
3935
if (condition) {
40-
fail(buildPrefix(message) + EXPECTED_FALSE, false, true);
36+
failNotFalse(message);
4137
}
4238
}
4339

4440
static void assertFalse(boolean condition, Supplier<String> messageSupplier) {
4541
if (condition) {
46-
fail(buildPrefix(nullSafeGet(messageSupplier)) + EXPECTED_FALSE, false, true);
42+
failNotFalse(messageSupplier);
4743
}
4844
}
4945

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

58+
private static void failNotFalse(Object messageOrSupplier) {
59+
assertionFailure() //
60+
.message(messageOrSupplier) //
61+
.expected(false) //
62+
.actual(true) //
63+
.buildAndThrow();
64+
}
65+
6266
}

junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertInstanceOf.java

+7-9
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,10 @@
1010

1111
package org.junit.jupiter.api;
1212

13-
import static org.junit.jupiter.api.AssertionUtils.buildPrefix;
14-
import static org.junit.jupiter.api.AssertionUtils.format;
15-
import static org.junit.jupiter.api.AssertionUtils.nullSafeGet;
13+
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;
1614

1715
import java.util.function.Supplier;
1816

19-
import org.opentest4j.AssertionFailedError;
20-
2117
/**
2218
* {@code AssertInstanceOf} is a collection of utility methods that support
2319
* asserting that an object is of an expected type &mdash; in other words, if it
@@ -45,10 +41,12 @@ static <T> T assertInstanceOf(Class<T> expectedType, Object actualValue, Supplie
4541

4642
private static <T> T assertInstanceOf(Class<T> expectedType, Object actualValue, Object messageOrSupplier) {
4743
if (!expectedType.isInstance(actualValue)) {
48-
String reason = (actualValue == null ? "Unexpected null value" : "Unexpected type");
49-
String message = buildPrefix(nullSafeGet(messageOrSupplier))
50-
+ format(expectedType, actualValue == null ? null : actualValue.getClass(), reason);
51-
throw new AssertionFailedError(message);
44+
assertionFailure() //
45+
.message(messageOrSupplier) //
46+
.reason(actualValue == null ? "Unexpected null value" : "Unexpected type") //
47+
.expected(expectedType) //
48+
.actual(actualValue == null ? null : actualValue.getClass()) //
49+
.buildAndThrow();
5250
}
5351
return expectedType.cast(actualValue);
5452
}

junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertIterableEquals.java

+21-13
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,8 @@
1010

1111
package org.junit.jupiter.api;
1212

13-
import static org.junit.jupiter.api.AssertionUtils.buildPrefix;
14-
import static org.junit.jupiter.api.AssertionUtils.fail;
13+
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;
1514
import static org.junit.jupiter.api.AssertionUtils.formatIndexes;
16-
import static org.junit.jupiter.api.AssertionUtils.formatValues;
17-
import static org.junit.jupiter.api.AssertionUtils.nullSafeGet;
1815

1916
import java.util.ArrayDeque;
2017
import java.util.Deque;
@@ -139,11 +136,17 @@ private static void assertIterablesNotNull(Object expected, Object actual, Deque
139136
}
140137

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

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

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

159-
String prefix = buildPrefix(nullSafeGet(messageOrSupplier));
160-
String message = "iterable lengths differ" + formatIndexes(indexes) + ", expected: <" + expectedCount.get()
161-
+ "> but was: <" + actualCount.get() + ">";
162-
fail(prefix + message);
162+
assertionFailure() //
163+
.message(messageOrSupplier) //
164+
.reason("iterable lengths differ" + formatIndexes(indexes)) //
165+
.expected(expectedCount.get()) //
166+
.actual(actualCount.get()) //
167+
.buildAndThrow();
163168
}
164169
}
165170

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

169-
String prefix = buildPrefix(nullSafeGet(messageOrSupplier));
170-
String message = "iterable contents differ" + formatIndexes(indexes) + ", " + formatValues(expected, actual);
171-
fail(prefix + message);
174+
assertionFailure() //
175+
.message(messageOrSupplier) //
176+
.reason("iterable contents differ" + formatIndexes(indexes)) //
177+
.expected(expected) //
178+
.actual(actual) //
179+
.buildAndThrow();
172180
}
173181

174182
private final static class Pair {

junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertLinesMatch.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212

1313
import static java.lang.String.format;
1414
import static java.lang.String.join;
15-
import static org.junit.jupiter.api.AssertionUtils.buildPrefix;
16-
import static org.junit.jupiter.api.AssertionUtils.nullSafeGet;
15+
import static org.junit.jupiter.api.AssertionFailureBuilder.assertionFailure;
1716
import static org.junit.platform.commons.util.Preconditions.condition;
1817
import static org.junit.platform.commons.util.Preconditions.notNull;
1918

@@ -195,8 +194,13 @@ String snippet(String line) {
195194

196195
void fail(String format, Object... args) {
197196
String newLine = System.lineSeparator();
198-
String message = buildPrefix(nullSafeGet(messageOrSupplier)) + format(format, args);
199-
AssertionUtils.fail(message, join(newLine, expectedLines), join(newLine, actualLines));
197+
assertionFailure() //
198+
.message(messageOrSupplier) //
199+
.reason(format(format, args)) //
200+
.expected(join(newLine, expectedLines)) //
201+
.actual(join(newLine, actualLines)) //
202+
.includeValuesInMessage(false) //
203+
.buildAndThrow();
200204
}
201205
}
202206

0 commit comments

Comments
 (0)