1
2package junit.textui;
3
4import java.io.PrintStream;
5// android-changed
6// The following line was removed for compatibility with Android libraries.
7// import java.text.NumberFormat;
8import java.util.Enumeration;
9
10import junit.framework.AssertionFailedError;
11import junit.framework.Test;
12import junit.framework.TestFailure;
13import junit.framework.TestListener;
14import junit.framework.TestResult;
15import junit.runner.BaseTestRunner;
16
17public class ResultPrinter implements TestListener {
18	PrintStream fWriter;
19	int fColumn= 0;
20
21	public ResultPrinter(PrintStream writer) {
22		fWriter= writer;
23	}
24
25	/* API for use by textui.TestRunner
26	 */
27
28	synchronized void print(TestResult result, long runTime) {
29		printHeader(runTime);
30	    printErrors(result);
31	    printFailures(result);
32	    printFooter(result);
33	}
34
35	void printWaitPrompt() {
36		getWriter().println();
37		getWriter().println("<RETURN> to continue");
38	}
39
40	/* Internal methods
41	 */
42
43	protected void printHeader(long runTime) {
44		getWriter().println();
45		getWriter().println("Time: "+elapsedTimeAsString(runTime));
46	}
47
48	protected void printErrors(TestResult result) {
49		printDefects(result.errors(), result.errorCount(), "error");
50	}
51
52	protected void printFailures(TestResult result) {
53		printDefects(result.failures(), result.failureCount(), "failure");
54	}
55
56	protected void printDefects(Enumeration<TestFailure> booBoos, int count, String type) {
57		if (count == 0) return;
58		if (count == 1)
59			getWriter().println("There was " + count + " " + type + ":");
60		else
61			getWriter().println("There were " + count + " " + type + "s:");
62		for (int i= 1; booBoos.hasMoreElements(); i++) {
63			printDefect(booBoos.nextElement(), i);
64		}
65	}
66
67	public void printDefect(TestFailure booBoo, int count) { // only public for testing purposes
68		printDefectHeader(booBoo, count);
69		printDefectTrace(booBoo);
70	}
71
72	protected void printDefectHeader(TestFailure booBoo, int count) {
73		// I feel like making this a println, then adding a line giving the throwable a chance to print something
74		// before we get to the stack trace.
75		getWriter().print(count + ") " + booBoo.failedTest());
76	}
77
78	protected void printDefectTrace(TestFailure booBoo) {
79		getWriter().print(BaseTestRunner.getFilteredTrace(booBoo.trace()));
80	}
81
82	protected void printFooter(TestResult result) {
83		if (result.wasSuccessful()) {
84			getWriter().println();
85			getWriter().print("OK");
86			getWriter().println (" (" + result.runCount() + " test" + (result.runCount() == 1 ? "": "s") + ")");
87
88		} else {
89			getWriter().println();
90			getWriter().println("FAILURES!!!");
91			getWriter().println("Tests run: "+result.runCount()+
92				         ",  Failures: "+result.failureCount()+
93				         ",  Errors: "+result.errorCount());
94		}
95	    getWriter().println();
96	}
97
98
99	/**
100	 * Returns the formatted string of the elapsed time.
101	 * Duplicated from BaseTestRunner. Fix it.
102	 */
103	protected String elapsedTimeAsString(long runTime) {
104		// android-changed
105		// The following line was altered for compatibility with
106		// Android libraries.
107		return Double.toString((double)runTime/1000);
108	}
109
110	public PrintStream getWriter() {
111		return fWriter;
112	}
113	/**
114	 * @see junit.framework.TestListener#addError(Test, Throwable)
115	 */
116	public void addError(Test test, Throwable t) {
117		getWriter().print("E");
118	}
119
120	/**
121	 * @see junit.framework.TestListener#addFailure(Test, AssertionFailedError)
122	 */
123	public void addFailure(Test test, AssertionFailedError t) {
124		getWriter().print("F");
125	}
126
127	/**
128	 * @see junit.framework.TestListener#endTest(Test)
129	 */
130	public void endTest(Test test) {
131	}
132
133	/**
134	 * @see junit.framework.TestListener#startTest(Test)
135	 */
136	public void startTest(Test test) {
137		getWriter().print(".");
138		if (fColumn++ >= 40) {
139			getWriter().println();
140			fColumn= 0;
141		}
142	}
143
144}
145