/*
* Copyright 2015-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opentest4j;
import java.util.
ArrayList;
import java.util.
Collections;
import java.util.
List;
/**
* {@link MultipleFailuresError} is an {@link AssertionError} which
* aggregates multiple {@code AssertionErrors} thrown in a given context
* (i.e., typically within the invocation of a single test).
*
* @author Johannes Link
* @author Sam Brannen
* @author Marc Philipp
* @since 1.0
*/
public class
MultipleFailuresError extends
AssertionError {
private static final long
serialVersionUID = 1L;
private static final
String EOL =
System.
getProperty("line.separator");
private final
String heading;
private final
List<
Throwable>
failures;
public
MultipleFailuresError(
String heading,
List<? extends
Throwable>
failures) {
this.
heading =
isBlank(
heading) ? "Multiple Failures" :
heading.
trim();
this.
failures = new
ArrayList<
Throwable>();
for (
Throwable failure :
failures) {
if (
failure == null) {
throw new
NullPointerException("failures must not contain null elements");
}
this.
failures.
add(
failure);
}
}
@
Override
public
String getMessage() {
int
failureCount = this.
failures.
size();
if (
failureCount == 0) {
return this.
heading;
}
// @formatter:off
StringBuilder builder = new
StringBuilder(this.
heading)
.
append(" (")
.
append(
failureCount).
append(" ")
.
append(
pluralize(
failureCount, "failure", "failures"))
.
append(")")
.
append(
EOL);
// @formatter:on
int
lastIndex =
failureCount - 1;
for (
Throwable failure : this.
failures.
subList(0,
lastIndex)) {
builder.
append("\t").
append(
nullSafeMessage(
failure)).
append(
EOL);
}
builder.
append('\t').
append(
nullSafeMessage(this.
failures.
get(
lastIndex)));
return
builder.
toString();
}
public
List<
Throwable>
getFailures() {
return
Collections.
unmodifiableList(this.
failures);
}
public boolean
hasFailures() {
return !this.
failures.
isEmpty();
}
private static boolean
isBlank(
String str) {
return (
str == null ||
str.
trim().
length() == 0);
}
private static
String pluralize(int
count,
String singular,
String plural) {
return
count == 1 ?
singular :
plural;
}
private static
String nullSafeMessage(
Throwable failure) {
if (
isBlank(
failure.
getMessage())) {
return "<no message> in " +
failure.
getClass().
getName();
}
return
failure.
getMessage();
}
}