1eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinpackage junit.runner;
2eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
3eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.io.BufferedReader;
4eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.io.File;
5eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.io.FileInputStream;
6eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.io.FileOutputStream;
7eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.io.IOException;
8eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.io.InputStream;
9eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.io.PrintWriter;
10eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.io.StringReader;
11eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.io.StringWriter;
12eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.lang.reflect.InvocationTargetException;
13eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.lang.reflect.Method;
14eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.lang.reflect.Modifier;
15eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.text.NumberFormat;
16eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport java.util.Properties;
17eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
18eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport junit.framework.AssertionFailedError;
19eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport junit.framework.Test;
20eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport junit.framework.TestListener;
21eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinimport junit.framework.TestSuite;
22eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
23eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin/**
24eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin * Base class for all test runners.
25eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin * This class was born live on stage in Sardinia during XP2000.
26eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin */
27eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffinpublic abstract class BaseTestRunner implements TestListener {
28eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public static final String SUITE_METHODNAME= "suite";
29eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
30eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	private static Properties fPreferences;
31eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	static int fgMaxMessageLength= 500;
32eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	static boolean fgFilterStack= true;
33eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	boolean fLoading= true;
34eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
35eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin    /*
36eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin    * Implementation of TestListener
37eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin    */
38eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public synchronized void startTest(Test test) {
39eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		testStarted(test.toString());
40eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
41eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
42eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	protected static void setPreferences(Properties preferences) {
43eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		fPreferences= preferences;
44eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
45eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
46eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	protected static Properties getPreferences() {
47eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		if (fPreferences == null) {
48eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			fPreferences= new Properties();
49eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 		fPreferences.put("loading", "true");
50eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 			fPreferences.put("filterstack", "true");
51eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin  			readPreferences();
52eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
53eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return fPreferences;
54eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
55eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
56eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public static void savePreferences() throws IOException {
57eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		FileOutputStream fos= new FileOutputStream(getPreferencesFile());
58eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		try {
59eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			getPreferences().store(fos, "");
60eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		} finally {
61eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			fos.close();
62eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
63eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
64eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
65eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	// android-changed remove 'static' qualifier for API compatibility
66eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public void setPreference(String key, String value) {
67eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		getPreferences().put(key, value);
68eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
69eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
70eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public synchronized void endTest(Test test) {
71eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		testEnded(test.toString());
72eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
73eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
74eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public synchronized void addError(final Test test, final Throwable t) {
75eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		testFailed(TestRunListener.STATUS_ERROR, test, t);
76eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
77eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
78eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public synchronized void addFailure(final Test test, final AssertionFailedError t) {
79eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		testFailed(TestRunListener.STATUS_FAILURE, test, t);
80eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
81eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
82eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	// TestRunListener implementation
83eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
84eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public abstract void testStarted(String testName);
85eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
86eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public abstract void testEnded(String testName);
87eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
88eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public abstract void testFailed(int status, Test test, Throwable t);
89eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
90eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/**
91eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * Returns the Test corresponding to the given suite. This is
92eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * a template method, subclasses override runFailed(), clearStatus().
93eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 */
94eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public Test getTest(String suiteClassName) {
95eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		if (suiteClassName.length() <= 0) {
96eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			clearStatus();
97eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			return null;
98eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
99eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		Class<?> testClass= null;
100eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		try {
101eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			testClass= loadSuiteClass(suiteClassName);
102eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		} catch (ClassNotFoundException e) {
103eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			String clazz= e.getMessage();
104eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			if (clazz == null)
105eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin				clazz= suiteClassName;
106eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			runFailed("Class not found \""+clazz+"\"");
107eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			return null;
108eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		} catch(Exception e) {
109eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			runFailed("Error: "+e.toString());
110eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			return null;
111eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
112eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		Method suiteMethod= null;
113eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		try {
114eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			suiteMethod= testClass.getMethod(SUITE_METHODNAME, new Class[0]);
115eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 	} catch(Exception e) {
116eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 		// try to extract a test suite automatically
117eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			clearStatus();
118eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			return new TestSuite(testClass);
119eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
120eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		if (! Modifier.isStatic(suiteMethod.getModifiers())) {
121eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			runFailed("Suite() method must be static");
122eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			return null;
123eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
124eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		Test test= null;
125eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		try {
126eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			test= (Test)suiteMethod.invoke(null, (Object[])new Class[0]); // static method
127eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			if (test == null)
128eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin				return test;
129eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
130eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		catch (InvocationTargetException e) {
131eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			runFailed("Failed to invoke suite():" + e.getTargetException().toString());
132eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			return null;
133eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
134eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		catch (IllegalAccessException e) {
135eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			runFailed("Failed to invoke suite():" + e.toString());
136eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			return null;
137eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
138eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
139eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		clearStatus();
140eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return test;
141eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
142eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
143eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/**
144eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * Returns the formatted string of the elapsed time.
145eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 */
146eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public String elapsedTimeAsString(long runTime) {
147eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return NumberFormat.getInstance().format((double)runTime/1000);
148eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
149eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
150eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/**
151eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * Processes the command line arguments and
152eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * returns the name of the suite class to run or null
153eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 */
154eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	protected String processArguments(String[] args) {
155eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		String suiteName= null;
156eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		for (int i= 0; i < args.length; i++) {
157eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			if (args[i].equals("-noloading")) {
158eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin				setLoading(false);
159eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			} else if (args[i].equals("-nofilterstack")) {
160eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin				fgFilterStack= false;
161eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			} else if (args[i].equals("-c")) {
162eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin				if (args.length > i+1)
163eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin					suiteName= extractClassName(args[i+1]);
164eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin				else
165eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin					System.out.println("Missing Test class name");
166eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin				i++;
167eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			} else {
168eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin				suiteName= args[i];
169eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			}
170eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
171eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return suiteName;
172eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
173eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
174eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/**
175eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * Sets the loading behaviour of the test runner
176eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 */
177eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public void setLoading(boolean enable) {
178eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		fLoading= enable;
179eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
180eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/**
181eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * Extract the class name from a String in VA/Java style
182eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 */
183eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public String extractClassName(String className) {
184eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		if(className.startsWith("Default package for"))
185eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			return className.substring(className.lastIndexOf(".")+1);
186eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return className;
187eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
188eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
189eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/**
190eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * Truncates a String to the maximum length.
191eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 */
192eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public static String truncate(String s) {
193eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		if (fgMaxMessageLength != -1 && s.length() > fgMaxMessageLength)
194eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			s= s.substring(0, fgMaxMessageLength)+"...";
195eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return s;
196eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
197eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
198eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/**
199eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * Override to define how to handle a failed loading of
200eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * a test suite.
201eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 */
202eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	protected abstract void runFailed(String message);
203eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
204eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	// BEGIN android-changed - add back getLoader() for API compatibility
205eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/**
206eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * Returns the loader to be used.
207eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 *
208eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * @deprecated not present in JUnit4.10
209eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 */
210eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public TestSuiteLoader getLoader() {
211eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return new StandardTestSuiteLoader();
212eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
213eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	// END android-changed
214eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
215eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/**
216eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * Returns the loaded Class for a suite name.
217eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 */
218eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	protected Class<?> loadSuiteClass(String suiteClassName) throws ClassNotFoundException {
219eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return Class.forName(suiteClassName);
220eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
221eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
222eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/**
223eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * Clears the status message.
224eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 */
225eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	protected void clearStatus() { // Belongs in the GUI TestRunner class
226eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
227eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
228eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	protected boolean useReloadingTestSuiteLoader() {
229eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return getPreference("loading").equals("true") && fLoading;
230eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
231eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
232eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	private static File getPreferencesFile() {
233eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 	String home= System.getProperty("user.home");
234eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 		return new File(home, "junit.properties");
235eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 	}
236eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
237eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 	private static void readPreferences() {
238eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 		InputStream is= null;
239eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 		try {
240eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 			is= new FileInputStream(getPreferencesFile());
241eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 			setPreferences(new Properties(getPreferences()));
242eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			getPreferences().load(is);
243eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		} catch (IOException e) {
244eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			try {
245eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin				if (is != null)
246eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin					is.close();
247eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			} catch (IOException e1) {
248eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			}
249eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
250eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 	}
251eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
252eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 	public static String getPreference(String key) {
253eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 		return getPreferences().getProperty(key);
254eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 	}
255eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
256eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 	public static int getPreference(String key, int dflt) {
257eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 		String value= getPreference(key);
258eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 		int intValue= dflt;
259eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 		if (value == null)
260eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 			return intValue;
261eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 		try {
262eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 			intValue= Integer.parseInt(value);
263eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 	 	} catch (NumberFormatException ne) {
264eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 		}
265eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 		return intValue;
266eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 	}
267eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
268eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/**
269eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * Returns a filtered stack trace
270eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 */
271eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public static String getFilteredTrace(Throwable t) {
272eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		StringWriter stringWriter= new StringWriter();
273eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		PrintWriter writer= new PrintWriter(stringWriter);
274eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		t.printStackTrace(writer);
275eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		StringBuffer buffer= stringWriter.getBuffer();
276eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		String trace= buffer.toString();
277eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return BaseTestRunner.getFilteredTrace(trace);
278eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
279eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
280eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	// BEGIN android-changed - add back this method for API compatibility
281eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/** @deprecated not present in JUnit4.10 */
282eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public static boolean inVAJava() {
283eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return false;
284eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
285eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	// END android-changed
286eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
287eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	/**
288eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 * Filters stack frames from internal JUnit classes
289eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	 */
290eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	public static String getFilteredTrace(String stack) {
291eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		if (showStackRaw())
292eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			return stack;
293eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
294eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		StringWriter sw= new StringWriter();
295eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		PrintWriter pw= new PrintWriter(sw);
296eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		StringReader sr= new StringReader(stack);
297eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		// BEGIN android-changed
298eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		// Use a sensible default buffer size
299eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		BufferedReader br= new BufferedReader(sr, 1000);
300eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		// END android-changed
301eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
302eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		String line;
303eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		try {
304eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			while ((line= br.readLine()) != null) {
305eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin				if (!filterLine(line))
306eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin					pw.println(line);
307eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			}
308eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		} catch (Exception IOException) {
309eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			return stack; // return the stack unfiltered
310eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
311eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return sw.toString();
312eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
313eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
314eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	protected static boolean showStackRaw() {
315eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return !getPreference("filterstack").equals("true") || fgFilterStack == false;
316eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
317eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
318eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	static boolean filterLine(String line) {
319eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		String[] patterns= new String[] {
320eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			"junit.framework.TestCase",
321eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			"junit.framework.TestResult",
322eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			"junit.framework.TestSuite",
323eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			"junit.framework.Assert.", // don't filter AssertionFailure
324eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			"junit.swingui.TestRunner",
325eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			"junit.awtui.TestRunner",
326eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			"junit.textui.TestRunner",
327eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			"java.lang.reflect.Method.invoke("
328eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		};
329eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		for (int i= 0; i < patterns.length; i++) {
330eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin			if (line.indexOf(patterns[i]) > 0)
331eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin				return true;
332eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		}
333eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin		return false;
334eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin	}
335eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
336eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 	static {
337eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 		fgMaxMessageLength= getPreference("maxmessage", fgMaxMessageLength);
338eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin 	}
339eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin
340eef35dd29ae2cf9d78c052ef8b8a49aa4da55be9Paul Duffin}
341