001/*
002 * (C) Copyright 2014-2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Julien Carsique
018 *
019 */
020
021package org.nuxeo.runtime.test;
022
023import java.util.List;
024
025import junit.framework.AssertionFailedError;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029import org.junit.Assert;
030import org.junit.runner.Result;
031import org.junit.runner.notification.Failure;
032
033/**
034 * Utility class for working with {@link org.junit.runner.Result#getFailures()}
035 *
036 * @since 5.9.5
037 */
038public class Failures {
039    private static final Log log = LogFactory.getLog(Failures.class);
040
041    private List<Failure> failures;
042
043    public Failures(List<Failure> failures) {
044        this.failures = failures;
045    }
046
047    public Failures(Result result) {
048        failures = result.getFailures();
049    }
050
051    @Override
052    public String toString() {
053        StringBuffer buffer = new StringBuffer();
054        int i = 1;
055        AssertionFailedError errors = new AssertionFailedError();
056        for (Failure failure : failures) {
057            buffer.append("* Failure " + i + ": ")
058                  .append(failure.getTestHeader())
059                  .append("\n")
060                  .append(failure.getTrace())
061                  .append("\n");
062            errors.addSuppressed(failure.getException());
063            i++;
064        }
065        if (errors.getSuppressed().length > 0) {
066            // Log because JUnit swallows some parts of the stack trace
067            log.debug(errors.getMessage(), errors);
068        }
069        return buffer.toString();
070    }
071
072    /**
073     * Call {@link org.junit.Assert#fail(String)} with a nice expanded string if there are failures. It also replaces
074     * original failure messages with a custom one if originalMessage is not {@code null}.
075     *
076     * @param originalMessage Message to replace if found in a failure
077     * @param customMessage Custom message to use as replacement for originalMessage
078     */
079    public void fail(String originalMessage, String customMessage) {
080        if (failures.isEmpty()) {
081            Assert.fail(customMessage);
082        }
083        StringBuffer buffer = new StringBuffer();
084        int i = 1;
085        AssertionFailedError errors = new AssertionFailedError(customMessage);
086        buffer.append(customMessage);
087        for (Failure failure : failures) {
088            buffer.append("\n* Failure " + i + ": ");
089            String trace = failure.getTrace();
090            if (originalMessage != null && originalMessage.equals(failure.getMessage())) {
091                trace.replaceAll(originalMessage, customMessage);
092            }
093            buffer.append(failure.getTestHeader()).append("\n").append(trace);
094            errors.addSuppressed(failure.getException());
095            i++;
096        }
097        // Log because JUnit swallows some parts of the stack trace
098        log.debug(errors.getMessage(), errors);
099        Assert.fail(buffer.toString());
100    }
101}