1package junit.textui;
2
3import java.io.PrintStream;
4import java.text.NumberFormat;
5import java.util.Enumeration;
6
7import junit.framework.AssertionFailedError;
8import junit.framework.Test;
9import junit.framework.TestFailure;
10import junit.framework.TestListener;
11import junit.framework.TestResult;
12import junit.runner.BaseTestRunner;
13
14public class ResultPrinter implements TestListener {
15    PrintStream fWriter;
16    int fColumn = 0;
17
18    public ResultPrinter(PrintStream writer) {
19        fWriter = writer;
20    }
21
22    /* API for use by textui.TestRunner */
23
24    synchronized void print(TestResult result, long runTime) {
25        printHeader(runTime);
26        printErrors(result);
27        printFailures(result);
28        printFooter(result);
29    }
30
31    void printWaitPrompt() {
32        getWriter().println();
33        getWriter().println("<RETURN> to continue");
34    }
35
36    /* Internal methods */
37
38    protected void printHeader(long runTime) {
39        getWriter().println();
40        getWriter().println("Time: " + elapsedTimeAsString(runTime));
41    }
42
43    protected void printErrors(TestResult result) {
44        printDefects(result.errors(), result.errorCount(), "error");
45    }
46
47    protected void printFailures(TestResult result) {
48        printDefects(result.failures(), result.failureCount(), "failure");
49    }
50
51    protected void printDefects(Enumeration<TestFailure> booBoos, int count, String type) {
52        if (count == 0) return;
53        if (count == 1) {
54            getWriter().println("There was " + count + " " + type + ":");
55        } else {
56            getWriter().println("There were " + count + " " + type + "s:");
57        }
58        for (int i = 1; booBoos.hasMoreElements(); i++) {
59            printDefect(booBoos.nextElement(), i);
60        }
61    }
62
63    public void printDefect(TestFailure booBoo, int count) { // only public for testing purposes
64        printDefectHeader(booBoo, count);
65        printDefectTrace(booBoo);
66    }
67
68    protected void printDefectHeader(TestFailure booBoo, int count) {
69        // I feel like making this a println, then adding a line giving the throwable a chance to print something
70        // before we get to the stack trace.
71        getWriter().print(count + ") " + booBoo.failedTest());
72    }
73
74    protected void printDefectTrace(TestFailure booBoo) {
75        getWriter().print(BaseTestRunner.getFilteredTrace(booBoo.trace()));
76    }
77
78    protected void printFooter(TestResult result) {
79        if (result.wasSuccessful()) {
80            getWriter().println();
81            getWriter().print("OK");
82            getWriter().println(" (" + result.runCount() + " test" + (result.runCount() == 1 ? "" : "s") + ")");
83
84        } else {
85            getWriter().println();
86            getWriter().println("FAILURES!!!");
87            getWriter().println("Tests run: " + result.runCount() +
88                    ",  Failures: " + result.failureCount() +
89                    ",  Errors: " + result.errorCount());
90        }
91        getWriter().println();
92    }
93
94    /**
95     * Returns the formatted string of the elapsed time.
96     * Duplicated from BaseTestRunner. Fix it.
97     */
98    protected String elapsedTimeAsString(long runTime) {
99        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}
138