001/*
002 * (C) Copyright 2014-2015 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Julien Carsique
016 *
017 */
018
019package org.nuxeo.runtime.test;
020
021import java.util.List;
022
023import junit.framework.AssertionFailedError;
024
025import org.apache.commons.logging.Log;
026import org.apache.commons.logging.LogFactory;
027import org.junit.Assert;
028import org.junit.runner.Result;
029import org.junit.runner.notification.Failure;
030
031/**
032 * Utility class for working with {@link org.junit.runner.Result#getFailures()}
033 *
034 * @since 5.9.5
035 */
036public class Failures {
037    private static final Log log = LogFactory.getLog(Failures.class);
038
039    private List<Failure> failures;
040
041    public Failures(List<Failure> failures) {
042        this.failures = failures;
043    }
044
045    public Failures(Result result) {
046        failures = result.getFailures();
047    }
048
049    @Override
050    public String toString() {
051        StringBuffer buffer = new StringBuffer();
052        int i = 1;
053        AssertionFailedError errors = new AssertionFailedError();
054        for (Failure failure : failures) {
055            buffer.append("* Failure " + i + ": ")
056                  .append(failure.getTestHeader())
057                  .append("\n")
058                  .append(failure.getTrace())
059                  .append("\n");
060            errors.addSuppressed(failure.getException());
061            i++;
062        }
063        if (errors.getSuppressed().length > 0) {
064            // Log because JUnit swallows some parts of the stack trace
065            log.debug(errors.getMessage(), errors);
066        }
067        return buffer.toString();
068    }
069
070    /**
071     * Call {@link org.junit.Assert#fail(String)} with a nice expanded string if there are failures. It also replaces
072     * original failure messages with a custom one if originalMessage is not {@code null}.
073     *
074     * @param originalMessage Message to replace if found in a failure
075     * @param customMessage Custom message to use as replacement for originalMessage
076     */
077    public void fail(String originalMessage, String customMessage) {
078        if (failures.isEmpty()) {
079            Assert.fail(customMessage);
080        }
081        StringBuffer buffer = new StringBuffer();
082        int i = 1;
083        AssertionFailedError errors = new AssertionFailedError(customMessage);
084        buffer.append(customMessage);
085        for (Failure failure : failures) {
086            buffer.append("\n* Failure " + i + ": ");
087            String trace = failure.getTrace();
088            if (originalMessage != null && originalMessage.equals(failure.getMessage())) {
089                trace.replaceAll(originalMessage, customMessage);
090            }
091            buffer.append(failure.getTestHeader()).append("\n").append(trace);
092            errors.addSuppressed(failure.getException());
093            i++;
094        }
095        // Log because JUnit swallows some parts of the stack trace
096        log.debug(errors.getMessage(), errors);
097        Assert.fail(buffer.toString());
098    }
099}