package jetbrains.mps.tool.builder.unittest; /*Generated by MPS */ import org.apache.log4j.Logger; import org.apache.log4j.LogManager; import java.io.BufferedWriter; import org.jetbrains.annotations.NotNull; import java.io.OutputStreamWriter; import java.io.IOException; import java.io.InputStream; import java.util.Scanner; import org.apache.log4j.Level; public class UnitTestOutputReader { private static final Logger LOG = LogManager.getLogger(UnitTestOutputReader.class); private final Process myUnitTestProcess; private final UnitTestOutputReader.BaseOutputReader myInputReader; private final UnitTestOutputReader.BaseOutputReader myErrorReader; private final BufferedWriter myOutputWriter; private final UnitTestListener myUnitTestListener; private boolean myInsideTestError = false; private StringBuffer myLastError = new StringBuffer(); private String myLastMessage = ""; private String myCurrentlyRunningTest; public UnitTestOutputReader(@NotNull Process unitTestProcess, @NotNull UnitTestListener unitTestListener) { myUnitTestProcess = unitTestProcess; myUnitTestListener = unitTestListener; myInputReader = new UnitTestOutputReader.BaseOutputReader(myUnitTestProcess.getInputStream()) { @Override protected void addMessage(final String message) { parseMessage(message, false); } }; myErrorReader = new UnitTestOutputReader.BaseOutputReader(myUnitTestProcess.getErrorStream()) { @Override protected void addMessage(final String message) { parseMessage(message, true); } }; myOutputWriter = new BufferedWriter(new OutputStreamWriter(myUnitTestProcess.getOutputStream())); } private void parseMessage(@NotNull String text, boolean error) { String textTrimmed = text.trim(); if (text.startsWith(UnitTestRunner.START_TEST_PREFIX)) { saveLastTestIfNecessary(); myCurrentlyRunningTest = removeTag(text, UnitTestRunner.START_TEST_PREFIX); myUnitTestListener.testStarted(myCurrentlyRunningTest); } else if (text.startsWith(UnitTestRunner.END_TEST_PREFIX)) { myCurrentlyRunningTest = null; myUnitTestListener.testFinished(removeTag(text, UnitTestRunner.END_TEST_PREFIX)); } else if (text.startsWith(UnitTestRunner.FAILURE_TEST_PREFIX)) { myLastMessage = removeTag(text, UnitTestRunner.FAILURE_TEST_PREFIX); myInsideTestError = true; } else if (text.startsWith(UnitTestRunner.FAILURE_TEST_SUFFIX)) { myUnitTestListener.testFailed(removeTag(text, UnitTestRunner.FAILURE_TEST_SUFFIX), myLastMessage, myLastError.toString()); myLastError = new StringBuffer(); myInsideTestError = false; } else if (error) { if (myInsideTestError) { myLastError.append(textTrimmed); myLastError.append("\n"); } else { myUnitTestListener.logError(text); } } else { myUnitTestListener.logMessage(text); } } private void saveLastTestIfNecessary() { if (myCurrentlyRunningTest != null) { myUnitTestListener.testFinished(myCurrentlyRunningTest); myCurrentlyRunningTest = null; } } private String removeTag(String text, String prefix) { return text.substring(prefix.length()); } public int start() { myInputReader.start(); myErrorReader.start(); try { myOutputWriter.newLine(); myOutputWriter.close(); return myUnitTestProcess.waitFor(); } catch (InterruptedException ignored) { } catch (IOException ignored) { } return -1; } private static abstract class BaseOutputReader extends Thread { private final InputStream myIs; public BaseOutputReader(InputStream is) { myIs = is; } @Override public void run() { Scanner s = new Scanner(this.myIs); try { while (!((this.isInterrupted())) && s.hasNextLine()) { addMessage(s.nextLine()); } } catch (Exception e) { if (LOG.isEnabledFor(Level.ERROR)) { LOG.error("", e); } } } protected abstract void addMessage(String message); } }