001    package junit.textui;
002    
003    import java.io.PrintStream;
004    import java.text.NumberFormat;
005    import java.util.Enumeration;
006    
007    import junit.framework.AssertionFailedError;
008    import junit.framework.Test;
009    import junit.framework.TestFailure;
010    import junit.framework.TestListener;
011    import junit.framework.TestResult;
012    import junit.runner.BaseTestRunner;
013    
014    public class ResultPrinter implements TestListener {
015        PrintStream fWriter;
016        int fColumn = 0;
017    
018        public ResultPrinter(PrintStream writer) {
019            fWriter = writer;
020        }
021    
022        /* API for use by textui.TestRunner */
023    
024        synchronized void print(TestResult result, long runTime) {
025            printHeader(runTime);
026            printErrors(result);
027            printFailures(result);
028            printFooter(result);
029        }
030    
031        void printWaitPrompt() {
032            getWriter().println();
033            getWriter().println("<RETURN> to continue");
034        }
035    
036        /* Internal methods */
037    
038        protected void printHeader(long runTime) {
039            getWriter().println();
040            getWriter().println("Time: " + elapsedTimeAsString(runTime));
041        }
042    
043        protected void printErrors(TestResult result) {
044            printDefects(result.errors(), result.errorCount(), "error");
045        }
046    
047        protected void printFailures(TestResult result) {
048            printDefects(result.failures(), result.failureCount(), "failure");
049        }
050    
051        protected void printDefects(Enumeration<TestFailure> booBoos, int count, String type) {
052            if (count == 0) return;
053            if (count == 1) {
054                getWriter().println("There was " + count + " " + type + ":");
055            } else {
056                getWriter().println("There were " + count + " " + type + "s:");
057            }
058            for (int i = 1; booBoos.hasMoreElements(); i++) {
059                printDefect(booBoos.nextElement(), i);
060            }
061        }
062    
063        public void printDefect(TestFailure booBoo, int count) { // only public for testing purposes
064            printDefectHeader(booBoo, count);
065            printDefectTrace(booBoo);
066        }
067    
068        protected void printDefectHeader(TestFailure booBoo, int count) {
069            // I feel like making this a println, then adding a line giving the throwable a chance to print something
070            // before we get to the stack trace.
071            getWriter().print(count + ") " + booBoo.failedTest());
072        }
073    
074        protected void printDefectTrace(TestFailure booBoo) {
075            getWriter().print(BaseTestRunner.getFilteredTrace(booBoo.trace()));
076        }
077    
078        protected void printFooter(TestResult result) {
079            if (result.wasSuccessful()) {
080                getWriter().println();
081                getWriter().print("OK");
082                getWriter().println(" (" + result.runCount() + " test" + (result.runCount() == 1 ? "" : "s") + ")");
083    
084            } else {
085                getWriter().println();
086                getWriter().println("FAILURES!!!");
087                getWriter().println("Tests run: " + result.runCount() +
088                        ",  Failures: " + result.failureCount() +
089                        ",  Errors: " + result.errorCount());
090            }
091            getWriter().println();
092        }
093    
094        /**
095         * Returns the formatted string of the elapsed time.
096         * Duplicated from BaseTestRunner. Fix it.
097         */
098        protected String elapsedTimeAsString(long runTime) {
099            return NumberFormat.getInstance().format((double) runTime / 1000);
100        }
101    
102        public PrintStream getWriter() {
103            return fWriter;
104        }
105    
106        /**
107         * @see junit.framework.TestListener#addError(Test, Throwable)
108         */
109        public void addError(Test test, Throwable e) {
110            getWriter().print("E");
111        }
112    
113        /**
114         * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError)
115         */
116        public void addFailure(Test test, AssertionFailedError t) {
117            getWriter().print("F");
118        }
119    
120        /**
121         * @see junit.framework.TestListener#endTest(Test)
122         */
123        public void endTest(Test test) {
124        }
125    
126        /**
127         * @see junit.framework.TestListener#startTest(Test)
128         */
129        public void startTest(Test test) {
130            getWriter().print(".");
131            if (fColumn++ >= 40) {
132                getWriter().println();
133                fColumn = 0;
134            }
135        }
136    
137    }