From 833c6a4d80133a4ca5f7e98722acfabbd4ad08c1 Mon Sep 17 00:00:00 2001 From: Jens Halm <3116929+jenshalm@users.noreply.github.com> Date: Mon, 9 Aug 2021 21:16:15 +0100 Subject: [PATCH 1/2] remove --no-stderr and -q options These are unfixably broken for parallel execution which is the default in sbt. Addresses point 1) in #399, see that ticket for more details. --- .../junitinterface/EventDispatcher.java | 28 ------- .../internal/junitinterface/JUnitRunner.java | 15 ++-- .../internal/junitinterface/JUnitTask.java | 16 ---- .../junitinterface/OutputCapture.java | 73 ------------------- .../internal/junitinterface/RunSettings.java | 8 +- 5 files changed, 7 insertions(+), 133 deletions(-) delete mode 100644 junit-interface/src/main/java/munit/internal/junitinterface/OutputCapture.java diff --git a/junit-interface/src/main/java/munit/internal/junitinterface/EventDispatcher.java b/junit-interface/src/main/java/munit/internal/junitinterface/EventDispatcher.java index dae9df13..0f207fa9 100644 --- a/junit-interface/src/main/java/munit/internal/junitinterface/EventDispatcher.java +++ b/junit-interface/src/main/java/munit/internal/junitinterface/EventDispatcher.java @@ -4,9 +4,6 @@ import java.util.Collections; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.io.IOException; -import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.stream.Collectors; import org.junit.runner.Description; import org.junit.runner.Result; @@ -30,7 +27,6 @@ final class EventDispatcher extends RunListener private final Fingerprint fingerprint; private final String taskInfo; private final RunStatistics runStatistics; - private OutputCapture capture; private final static Description TEST_RUN = Description.createTestDescription("Test", "run"); @@ -71,7 +67,6 @@ private abstract class InfoEvent extends Event { @Override public void testAssumptionFailure(final Failure failure) { - uncapture(true); postIfFirst(failure.getDescription(), new ErrorEvent(failure, Status.Skipped) { void logTo(RichLogger logger) { if (settings.verbose) { @@ -96,7 +91,6 @@ public void testFailure(final Failure failure) // Ignore error. } } - uncapture(true); postIfFirst(failure.getDescription(), new ErrorEvent(failure, Status.Failure) { void logTo(RichLogger logger) { logger.error( failure.getDescription(), settings.buildTestResult(Status.Failure) +ansiName+" "+ durationSuffix() + " " + ansiMsg, error); @@ -108,7 +102,6 @@ void logTo(RichLogger logger) { @Override public void testFinished(Description desc) { - uncapture(false); postIfFirst(desc, new InfoEvent(desc, Status.Success) { void logTo(RichLogger logger) { logger.info(desc, settings.buildTestResult(Status.Success) + Ansi.c(desc.getMethodName(), SUCCESS1) + durationSuffix()); @@ -148,7 +141,6 @@ public void testStarted(Description desc) if (settings.verbose) { logger.info(desc, settings.buildPlainName(desc) + " started"); } - capture(); } private void recordStartTime(Description description) { @@ -217,26 +209,6 @@ void post(AbstractEvent e) handler.handle(e); } - private void capture() - { - if(settings.quiet && capture == null) - capture = OutputCapture.start(); - } - - void uncapture(boolean replay) - { - if(settings.quiet && capture != null) - { - capture.stop(); - if(replay) - { - try { capture.replay(); } - catch(IOException ex) { logger.error(TEST_RUN, "Error replaying captured stdio", ex); } - } - capture = null; - } - } - // Removes stack trace elements that reference the reflective invocation in TestLauncher. private static void trimStackTrace(Throwable ex, String fromClassName, String toClassName, Settings settings) { diff --git a/junit-interface/src/main/java/munit/internal/junitinterface/JUnitRunner.java b/junit-interface/src/main/java/munit/internal/junitinterface/JUnitRunner.java index e9b5242e..3cfedc36 100644 --- a/junit-interface/src/main/java/munit/internal/junitinterface/JUnitRunner.java +++ b/junit-interface/src/main/java/munit/internal/junitinterface/JUnitRunner.java @@ -34,10 +34,9 @@ final class JUnitRunner implements Runner { this.customRunners = customRunners; Settings defaults = Settings.defaults(); - boolean quiet = false, nocolor = false, decodeScalaNames = false, + boolean nocolor = false, decodeScalaNames = false, logAssert = true, logExceptionClass = true, useSbtLoggers = false, useBufferedLoggers = true; boolean verbose = false; - boolean suppressSystemError = false; boolean trimStackTraces = defaults.trimStackTraces(); RunSettings.Summary summary = RunSettings.Summary.SBT; HashMap sysprops = new HashMap(); @@ -51,8 +50,7 @@ final class JUnitRunner implements Runner { String ignoreRunners = "org.junit.runners.Suite"; String runListener = null; for(String s : args) { - if("-q".equals(s)) quiet = true; - else if("-v".equals(s) || "--verbose".equals(s)) verbose = true; + if("-v".equals(s) || "--verbose".equals(s)) verbose = true; else if(s.startsWith("--summary=")) summary = RunSettings.Summary.values()[Integer.parseInt(s.substring(10))]; else if("-n".equals(s)) nocolor = true; else if("-s".equals(s)) decodeScalaNames = true; @@ -80,18 +78,15 @@ else if(s.startsWith("-D") && s.contains("=")) { else if(!s.startsWith("-") && !s.startsWith("+")) globPatterns.add(s); } for(String s : args) { - if("+q".equals(s)) quiet = false; - else if("+n".equals(s)) nocolor = false; + if("+n".equals(s)) nocolor = false; else if("+s".equals(s)) decodeScalaNames = false; else if("+a".equals(s)) logAssert = false; else if("+c".equals(s)) logExceptionClass = true; else if("+l".equals(s)) useSbtLoggers = true; - else if("--no-stderr".equals(s)) suppressSystemError = true; - else if("--stderr".equals(s)) suppressSystemError = false; } this.settings = - new RunSettings(!nocolor, decodeScalaNames, quiet, verbose, useSbtLoggers, useBufferedLoggers, trimStackTraces, summary, logAssert, ignoreRunners, logExceptionClass, - suppressSystemError, sysprops, globPatterns, includeCategories, excludeCategories, includeTags, excludeTags, + new RunSettings(!nocolor, decodeScalaNames, verbose, useSbtLoggers, useBufferedLoggers, trimStackTraces, summary, logAssert, ignoreRunners, logExceptionClass, + sysprops, globPatterns, includeCategories, excludeCategories, includeTags, excludeTags, testFilter); this.runListener = createRunListener(runListener); this.runStatistics = new RunStatistics(settings); diff --git a/junit-interface/src/main/java/munit/internal/junitinterface/JUnitTask.java b/junit-interface/src/main/java/munit/internal/junitinterface/JUnitTask.java index 086abe38..a4529ec4 100644 --- a/junit-interface/src/main/java/munit/internal/junitinterface/JUnitTask.java +++ b/junit-interface/src/main/java/munit/internal/junitinterface/JUnitTask.java @@ -1,7 +1,5 @@ package munit.internal.junitinterface; -import java.io.OutputStream; -import java.io.PrintStream; import java.lang.annotation.Annotation; import java.util.HashSet; import java.util.Map; @@ -55,9 +53,7 @@ public Task[] execute(EventHandler eventHandler, Logger[] loggers) { if (runner.runListener != null) ju.addListener(runner.runListener); Map oldprops = settings.overrideSystemProperties(); - PrintStream oldSystemError = System.err; try { - suppressSystemError(); try { Class cl = runner.testClassLoader.loadClass(testClassName); boolean isRun = shouldRun(fingerprint, cl, settings); @@ -84,23 +80,11 @@ public Task[] execute(EventHandler eventHandler, Logger[] loggers) { } } finally { settings.restoreSystemProperties(oldprops); - System.setErr(oldSystemError); } return new Task[0]; // junit tests do not nest } - private static final PrintStream EMPTY_PRINTSTREAM = new PrintStream(new OutputStream() { - @Override - public void write(int b) {} - }); - private void suppressSystemError() { - if (settings.suppressSystemError) { - System.setErr(EMPTY_PRINTSTREAM); - } - } - - private boolean shouldRun(Fingerprint fingerprint, Class clazz, RunSettings settings) { if(JUNIT_FP.equals(fingerprint)) { // Ignore classes which are matched by the other fingerprints diff --git a/junit-interface/src/main/java/munit/internal/junitinterface/OutputCapture.java b/junit-interface/src/main/java/munit/internal/junitinterface/OutputCapture.java deleted file mode 100644 index 6f3af321..00000000 --- a/junit-interface/src/main/java/munit/internal/junitinterface/OutputCapture.java +++ /dev/null @@ -1,73 +0,0 @@ -package munit.internal.junitinterface; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.lang.reflect.Method; - -final class OutputCapture -{ - private final PrintStream originalOut = System.out; - private final PrintStream originalScalaOut = getScalaOut(); - private final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - private final PrintStream prBuffer = new PrintStream(buffer, true); - private final boolean scalaOutSet; - - private OutputCapture() - { - //System.err.println("***** Replacing "+System.out+" with buffer "+prBuffer); - System.out.flush(); - System.setOut(prBuffer); - scalaOutSet = setScalaOut(prBuffer); - } - - static OutputCapture start() { return new OutputCapture(); } - - void stop() - { - //System.err.println("***** Restoring "+originalOut); - System.out.flush(); - System.setOut(originalOut); - if(scalaOutSet) setScalaOut(originalScalaOut); - } - - void replay() throws IOException - { - //System.err.println("***** Replaying to "+System.out); - System.out.write(buffer.toByteArray()); - System.out.flush(); - } - - private static PrintStream getScalaOut() - { - try - { - Class cl = Class.forName("scala.Console"); - Method m = cl.getMethod("out"); - return (PrintStream)m.invoke(null); - } - catch(Throwable t) - { - //System.err.println("Error getting Scala console:"); - //t.printStackTrace(System.err); - return null; - } - } - - private static boolean setScalaOut(PrintStream p) - { - try - { - Class cl = Class.forName("scala.Console"); - Method m = cl.getMethod("setOut", PrintStream.class); - m.invoke(null, p); - return true; - } - catch(Throwable t) - { - //System.err.println("Error setting Scala console:"); - //t.printStackTrace(System.err); - return false; - } - } -} diff --git a/junit-interface/src/main/java/munit/internal/junitinterface/RunSettings.java b/junit-interface/src/main/java/munit/internal/junitinterface/RunSettings.java index 5331bce7..2823310b 100644 --- a/junit-interface/src/main/java/munit/internal/junitinterface/RunSettings.java +++ b/junit-interface/src/main/java/munit/internal/junitinterface/RunSettings.java @@ -25,7 +25,6 @@ class RunSettings implements Settings { private static final Object NULL = new Object(); final boolean color; - final boolean quiet; final boolean logAssert; final boolean logExceptionClass; final Set includeTags, excludeTags; @@ -33,7 +32,6 @@ class RunSettings implements Settings { final boolean useBufferedLoggers; final boolean trimStackTraces; final boolean verbose; - final boolean suppressSystemError; final Summary summary; final ArrayList globPatterns; final Set includeCategories, excludeCategories; @@ -43,23 +41,21 @@ class RunSettings implements Settings { private final HashMap sysprops; private final HashSet ignoreRunners = new HashSet(); - RunSettings(boolean color, boolean decodeScalaNames, boolean quiet, + RunSettings(boolean color, boolean decodeScalaNames, boolean verbose, boolean useSbtLoggers, boolean useBufferedLoggers, boolean trimStackTraces, Summary summary, boolean logAssert, String ignoreRunners, boolean logExceptionClass, - boolean suppressSystemError, HashMap sysprops, + HashMap sysprops, ArrayList globPatterns, Set includeCategories, Set excludeCategories, Set includeTags, Set excludeTags, String testFilter) { this.color = color; this.decodeScalaNames = decodeScalaNames; - this.quiet = quiet; this.verbose = verbose; this.summary = summary; this.logAssert = logAssert; this.logExceptionClass = logExceptionClass; - this.suppressSystemError = suppressSystemError; this.includeTags = includeTags; this.excludeTags = excludeTags; for(String s : ignoreRunners.split(",")) From 4a2fc952dfc576eb74d3cafbabf11dde0d87d7db Mon Sep 17 00:00:00 2001 From: Jens Halm <3116929+jenshalm@users.noreply.github.com> Date: Tue, 10 Aug 2021 00:49:04 +0100 Subject: [PATCH 2/2] remove multi-suite support in EventDispatcher and RichLogger These types map 1:1 to suites/TaskDefs, which means that the complexity of some of the data structures can be avoided. Addresses point 2) in #399, see that ticket for more details. --- .../junitinterface/EventDispatcher.java | 44 +++++------ .../internal/junitinterface/RichLogger.java | 74 ++++++++----------- 2 files changed, 49 insertions(+), 69 deletions(-) diff --git a/junit-interface/src/main/java/munit/internal/junitinterface/EventDispatcher.java b/junit-interface/src/main/java/munit/internal/junitinterface/EventDispatcher.java index 0f207fa9..5f228dbc 100644 --- a/junit-interface/src/main/java/munit/internal/junitinterface/EventDispatcher.java +++ b/junit-interface/src/main/java/munit/internal/junitinterface/EventDispatcher.java @@ -4,6 +4,7 @@ import java.util.Collections; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; import org.junit.runner.Description; import org.junit.runner.Result; @@ -20,7 +21,7 @@ final class EventDispatcher extends RunListener { private final RichLogger logger; private final Set reported = Collections.newSetFromMap(new ConcurrentHashMap()); - private final Set reportedSuites = Collections.newSetFromMap(new ConcurrentHashMap()); + private final AtomicBoolean suiteStartReported = new AtomicBoolean(false); private final ConcurrentHashMap startTimes = new ConcurrentHashMap(); private final EventHandler handler; private final RunSettings settings; @@ -28,8 +29,6 @@ final class EventDispatcher extends RunListener private final String taskInfo; private final RunStatistics runStatistics; - private final static Description TEST_RUN = Description.createTestDescription("Test", "run"); - EventDispatcher(RichLogger logger, EventHandler handler, RunSettings settings, Fingerprint fingerprint, Description taskDescription, RunStatistics runStatistics) { @@ -70,7 +69,7 @@ public void testAssumptionFailure(final Failure failure) postIfFirst(failure.getDescription(), new ErrorEvent(failure, Status.Skipped) { void logTo(RichLogger logger) { if (settings.verbose) { - logger.info(failure.getDescription(), Ansi.c("==> i " + failure.getDescription().getMethodName(), WARNMSG)); + logger.info(Ansi.c("==> i " + failure.getDescription().getMethodName(), WARNMSG)); } } }); @@ -93,7 +92,7 @@ public void testFailure(final Failure failure) } postIfFirst(failure.getDescription(), new ErrorEvent(failure, Status.Failure) { void logTo(RichLogger logger) { - logger.error( failure.getDescription(), settings.buildTestResult(Status.Failure) +ansiName+" "+ durationSuffix() + " " + ansiMsg, error); + logger.error(settings.buildTestResult(Status.Failure) +ansiName+" "+ durationSuffix() + " " + ansiMsg, error); } }); } @@ -104,10 +103,9 @@ public void testFinished(Description desc) { postIfFirst(desc, new InfoEvent(desc, Status.Success) { void logTo(RichLogger logger) { - logger.info(desc, settings.buildTestResult(Status.Success) + Ansi.c(desc.getMethodName(), SUCCESS1) + durationSuffix()); + logger.info(settings.buildTestResult(Status.Success) + Ansi.c(desc.getMethodName(), SUCCESS1) + durationSuffix()); } }); - logger.popCurrentTestClassName(); } @Override @@ -115,7 +113,7 @@ public void testIgnored(Description desc) { postIfFirst(desc, new InfoEvent(desc, Status.Skipped) { void logTo(RichLogger logger) { - logger.warn(desc, settings.buildTestResult(Status.Ignored) + ansiName+" ignored" + durationSuffix()); + logger.warn(settings.buildTestResult(Status.Ignored) + ansiName+" ignored" + durationSuffix()); } }); } @@ -125,8 +123,7 @@ void logTo(RichLogger logger) { public void testSuiteStarted(Description desc) { if (desc == null || desc.getClassName() == null || desc.getClassName().equals("null")) return; - reportedSuites.add(desc.getClassName()); - logger.info(desc, c(desc.getClassName() + ":", SUCCESS1)); + if (suiteStartReported.compareAndSet(false, true)) logger.info(c(desc.getClassName() + ":", SUCCESS1)); } @@ -134,21 +131,18 @@ public void testSuiteStarted(Description desc) public void testStarted(Description desc) { recordStartTime(desc); - if (reportedSuites.add(desc.getClassName())) { - testSuiteStarted(desc); - } - logger.pushCurrentTestClassName(desc.getClassName()); + testSuiteStarted(desc); if (settings.verbose) { - logger.info(desc, settings.buildPlainName(desc) + " started"); + logger.info(settings.buildPlainName(desc) + " started"); } } private void recordStartTime(Description description) { - startTimes.putIfAbsent(settings.buildPlainName(description), System.currentTimeMillis()); + startTimes.putIfAbsent(description.getMethodName(), System.currentTimeMillis()); } private Long elapsedTime(Description description) { - Long startTime = startTimes.get(settings.buildPlainName(description)); + Long startTime = startTimes.get(description.getMethodName()); if( startTime == null ) { return 0l; } else { @@ -160,26 +154,27 @@ private Long elapsedTime(Description description) { public void testRunFinished(Result result) { if (settings.verbose) { - logger.info(TEST_RUN, "Test run " +taskInfo+" finished: "+ + logger.info("Test run " +taskInfo+" finished: "+ result.getFailureCount()+" failed" + ", " + result.getIgnoreCount()+" ignored" + ", "+result.getRunCount()+" total, "+(result.getRunTime()/1000.0)+"s") ; + logger.flush(); } runStatistics.addTime(result.getRunTime()); - logger.flush(TEST_RUN); } @Override - public void testSuiteFinished(Description description) throws Exception { - logger.flush(description); + public void testSuiteFinished(Description desc) throws Exception { + logger.flush(); } @Override public void testRunStarted(Description desc) { if (settings.verbose) { - logger.info(desc, taskInfo + " started"); + logger.info(taskInfo + " started"); + logger.flush(); } } @@ -187,7 +182,8 @@ void testExecutionFailed(String testName, Throwable err) { post(new Event(Ansi.c(testName, Ansi.ERRMSG), settings.buildErrorMessage(err), Status.Error, 0L, err) { void logTo(RichLogger logger) { - logger.error(TEST_RUN, ansiName+" failed: "+ansiMsg, error); + logger.error(ansiName+" failed: "+ansiMsg, error); + logger.flush(); } }); } @@ -220,7 +216,7 @@ private static void trimStackTrace(Throwable ex, String fromClassName, String to int end = stackTrace.length - 1; StackTraceElement last = stackTrace[end]; if (last.getClassName() != null && last.getClassName().equals(fromClassName)) { - for (int i = 0; end >= 0; end--) { + for (; end >= 0; end--) { StackTraceElement e = stackTrace[end]; if (e.getClassName().equals(toClassName)) { break; diff --git a/junit-interface/src/main/java/munit/internal/junitinterface/RichLogger.java b/junit-interface/src/main/java/munit/internal/junitinterface/RichLogger.java index 692b2595..c453353f 100644 --- a/junit-interface/src/main/java/munit/internal/junitinterface/RichLogger.java +++ b/junit-interface/src/main/java/munit/internal/junitinterface/RichLogger.java @@ -1,16 +1,10 @@ package munit.internal.junitinterface; import java.net.URL; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; -import java.util.Stack; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; -import org.junit.runner.Description; import sbt.testing.Logger; import static munit.internal.junitinterface.Ansi.*; @@ -20,91 +14,81 @@ final class RichLogger private final Logger[] loggers; private final RunSettings settings; private final JUnitRunner runner; - /* The top element is the test class of the currently executing test */ - private final Stack currentTestClassName = new Stack(); + private final String testClassName; private final Map highlightedCache = new HashMap<>(); - private final ConcurrentHashMap> buffers = new ConcurrentHashMap<>(); + private final ConcurrentLinkedDeque buffer = new ConcurrentLinkedDeque<>(); RichLogger(Logger[] loggers, RunSettings settings, String testClassName, JUnitRunner runner) { this.loggers = loggers; this.settings = settings; this.runner = runner; - currentTestClassName.push(testClassName); + this.testClassName = testClassName; } - void pushCurrentTestClassName(String s) { currentTestClassName.push(s); } - - void popCurrentTestClassName() - { - if(currentTestClassName.size() > 1) currentTestClassName.pop(); - } - - void error(Description desc, String s) + void error(String s) { if (settings.useSbtLoggers) { for (Logger l : loggers) if (settings.color && l.ansiCodesSupported()) l.error(s); else l.error(filterAnsi(s)); } else if (settings.useBufferedLoggers) { - bufferMessage(desc, s); + bufferMessage(s); } else { System.out.println(s); } } - void error(Description desc, String s, Throwable t) + void error(String s, Throwable t) { - error(desc, s); - if(t != null && (settings.logAssert || !(t instanceof AssertionError))) logStackTrace(desc, t); + error(s); + if(t != null && (settings.logAssert || !(t instanceof AssertionError))) logStackTrace(t); } - void info(Description desc, String s) + void info(String s) { if (settings.useSbtLoggers) { for (Logger l : loggers) if (settings.color && l.ansiCodesSupported()) l.info(s); else l.info(filterAnsi(s)); } else if (settings.useBufferedLoggers) { - bufferMessage(desc, s); + bufferMessage(s); } else { System.out.println(s); } } - void warn(Description desc, String s) + void warn(String s) { if (settings.useSbtLoggers) { for (Logger l : loggers) if (settings.color && l.ansiCodesSupported()) l.warn(s); else l.warn(filterAnsi(s)); } else if (settings.useBufferedLoggers) { - bufferMessage(desc, s); + bufferMessage(s); } else { System.out.println(s); } } - void flush(Description desc) { - ConcurrentLinkedDeque logs = buffers.remove(String.valueOf(desc.getClassName())); - if (logs != null) { - System.out.println(String.join("\n", logs)); + void flush() { + if (!buffer.isEmpty()) { + System.out.println(String.join("\n", buffer)); + buffer.clear(); } } - private void bufferMessage(Description desc, String message) { - ConcurrentLinkedDeque logs = buffers.computeIfAbsent(String.valueOf(desc.getClassName()), d -> new ConcurrentLinkedDeque<>()); - logs.addLast(message); + private void bufferMessage(String message) { + buffer.addLast(message); } - private void logStackTrace(Description desc, Throwable t) + private void logStackTrace(Throwable t) { StackTraceElement[] trace = t.getStackTrace(); - String testClassName = currentTestClassName.peek(); String testFileName = settings.color ? findTestFileName(trace, testClassName) : null; - logStackTracePart(desc, trace, trace.length-1, 0, t, testClassName, testFileName); + logStackTracePart(trace, trace.length-1, 0, t, testFileName); } - private void logStackTracePart(Description desc, StackTraceElement[] trace, int m, int framesInCommon, Throwable t, String testClassName, String testFileName) + private void logStackTracePart(StackTraceElement[] trace, int m, int framesInCommon, Throwable t, String testFileName) { final int m0 = m; int top = 0; @@ -130,22 +114,22 @@ private void logStackTracePart(Description desc, StackTraceElement[] trace, int } for(int i=top; i<=m; i++) { if (!trace[i].getClassName().startsWith("scala.runtime.")) - error(desc, stackTraceElementToString(trace[i], testClassName, testFileName)); + error(stackTraceElementToString(trace[i], testFileName)); } if(m0 != m) { // skip junit-related frames - error(desc, " ..."); + error(" ..."); } else if(framesInCommon != 0) { // skip frames that were in the previous trace too - error(desc, " ... " + framesInCommon + " more"); + error(" ... " + framesInCommon + " more"); } - logStackTraceAsCause(desc, trace, t.getCause(), testClassName, testFileName); + logStackTraceAsCause(trace, t.getCause(), testFileName); } - private void logStackTraceAsCause(Description desc, StackTraceElement[] causedTrace, Throwable t, String testClassName, String testFileName) + private void logStackTraceAsCause(StackTraceElement[] causedTrace, Throwable t, String testFileName) { if(t == null) return; StackTraceElement[] trace = t.getStackTrace(); @@ -155,8 +139,8 @@ private void logStackTraceAsCause(Description desc, StackTraceElement[] causedTr m--; n--; } - error(desc, "Caused by: " + t); - logStackTracePart(desc, trace, m, trace.length-1-m, t, testClassName, testFileName); + error("Caused by: " + t); + logStackTracePart(trace, m, trace.length-1-m, t, testFileName); } private String findTestFileName(StackTraceElement[] trace, String testClassName) @@ -184,7 +168,7 @@ private boolean isHighlighted(String className) { } } - private String stackTraceElementToString(StackTraceElement e, String testClassName, String testFileName) + private String stackTraceElementToString(StackTraceElement e, String testFileName) { boolean highlight = settings.color && ( testClassName.equals(e.getClassName()) ||