• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 package test.java.text.testlib;
25 
26 import java.io.IOException;
27 import java.io.PrintWriter;
28 import java.lang.reflect.InvocationTargetException;
29 import java.lang.reflect.Method;
30 import java.lang.reflect.Modifier;
31 import java.util.ArrayList;
32 import java.util.Map;
33 import java.util.LinkedHashMap;
34 import java.util.List;
35 
36 /**
37  * IntlTest is a base class for tests that can be run conveniently from
38  * the command line as well as under the Java test harness.
39  * <p>
40  * Sub-classes implement a set of public void methods named "Test*" or
41  * "test*" with no arguments. Each of these methods performs some
42  * test. Test methods should indicate errors by calling either err() or
43  * errln().  This will increment the errorCount field and may optionally
44  * print a message to the log.  Debugging information may also be added to
45  * the log via the log and logln methods.  These methods will add their
46  * arguments to the log only if the test is being run in verbose mode.
47  */
48 public abstract class IntlTest {
49 
50     //------------------------------------------------------------------------
51     // Everything below here is boilerplate code that makes it possible
52     // to add a new test by simply adding a method to an existing class.
53     //------------------------------------------------------------------------
54 
IntlTest()55     protected IntlTest() {
56         // Populate testMethods with all the test methods.
57         Method[] methods = getClass().getDeclaredMethods();
58         for (Method method : methods) {
59             if (Modifier.isPublic(method.getModifiers())
60                 && method.getReturnType() == void.class
61                 && method.getParameterCount() == 0) {
62                 String name = method.getName();
63                 if (name.length() > 4) {
64                     if (name.startsWith("Test") || name.startsWith("test")) {
65                         testMethods.put(name, method);
66                     }
67                 }
68             }
69         }
70     }
71 
run(String[] args)72     protected void run(String[] args) throws Exception
73     {
74         // Set up the log and reference streams.  We use PrintWriters in order to
75         // take advantage of character conversion.  The JavaEsc converter will
76         // convert Unicode outside the ASCII range to Java's \\uxxxx notation.
77         log = new PrintWriter(System.out, true);
78 
79         // Parse the test arguments.  They can be either the flag
80         // "-verbose" or names of test methods. Create a list of
81         // tests to be run.
82         List<Method> testsToRun = new ArrayList<>(args.length);
83         for (String arg : args) {
84             switch (arg) {
85             case "-verbose":
86                 verbose = true;
87                 break;
88             case "-prompt":
89                 prompt = true;
90                 break;
91             case "-nothrow":
92                 nothrow = true;
93                 break;
94             case "-exitcode":
95                 exitCode = true;
96                 break;
97             default:
98                 Method m = testMethods.get(arg);
99                 if (m == null) {
100                     System.out.println("Method " + arg + ": not found");
101                     usage();
102                     return;
103                 }
104                 testsToRun.add(m);
105                 break;
106             }
107         }
108 
109         // If no test method names were given explicitly, run them all.
110         if (testsToRun.isEmpty()) {
111             testsToRun.addAll(testMethods.values());
112         }
113 
114         System.out.println(getClass().getName() + " {");
115         indentLevel++;
116 
117         // Run the list of tests given in the test arguments
118         for (Method testMethod : testsToRun) {
119             int oldCount = errorCount;
120 
121             writeTestName(testMethod.getName());
122 
123             try {
124                 testMethod.invoke(this, new Object[0]);
125             } catch (IllegalAccessException e) {
126                 errln("Can't acces test method " + testMethod.getName());
127             } catch (InvocationTargetException e) {
128                 errln("Uncaught exception thrown in test method "
129                         + testMethod.getName());
130                 e.getTargetException().printStackTrace(this.log);
131             }
132             writeTestResult(errorCount - oldCount);
133         }
134         indentLevel--;
135         writeTestResult(errorCount);
136 
137         if (prompt) {
138             System.out.println("Hit RETURN to exit...");
139             try {
140                 System.in.read();
141             } catch (IOException e) {
142                 System.out.println("Exception: " + e.toString() + e.getMessage());
143             }
144         }
145         if (nothrow) {
146             if (exitCode) {
147                 System.exit(errorCount);
148             }
149             if (errorCount > 0) {
150                 throw new IllegalArgumentException("encountered " + errorCount + " errors");
151             }
152         }
153     }
154 
155     /**
156      * Adds the given message to the log if we are in verbose mode.
157      */
log(String message)158     protected void log(String message) {
159         logImpl(message, false);
160     }
161 
logln(String message)162     protected void logln(String message) {
163         logImpl(message, true);
164     }
165 
logln()166     protected void logln() {
167         logImpl(null, true);
168     }
169 
logImpl(String message, boolean newline)170     private void logImpl(String message, boolean newline) {
171         if (verbose) {
172             if (message != null) {
173                 indent(indentLevel + 1);
174                 log.print(message);
175             }
176             if (newline) {
177                 log.println();
178             }
179         }
180     }
181 
err(String message)182     protected void err(String message) {
183         errImpl(message, false);
184     }
185 
errln(String message)186     protected void errln(String message) {
187         errImpl(message, true);
188     }
189 
errImpl(String message, boolean newline)190     private void errImpl(String message, boolean newline) {
191         errorCount++;
192         indent(indentLevel + 1);
193         log.print(message);
194         if (newline) {
195             log.println();
196         }
197         log.flush();
198 
199         if (!nothrow) {
200             throw new RuntimeException(message);
201         }
202     }
203 
getErrorCount()204     protected int getErrorCount() {
205         return errorCount;
206     }
207 
writeTestName(String testName)208     protected void writeTestName(String testName) {
209         indent(indentLevel);
210         log.print(testName);
211         log.flush();
212         needLineFeed = true;
213     }
214 
writeTestResult(int count)215     protected void writeTestResult(int count) {
216         if (!needLineFeed) {
217             indent(indentLevel);
218             log.print("}");
219         }
220         needLineFeed = false;
221 
222         if (count != 0) {
223             log.println(" FAILED");
224         } else {
225             log.println(" Passed");
226         }
227     }
228 
229     /*
230      * Returns a spece-delimited hex String.
231      */
toHexString(String s)232     protected static String toHexString(String s) {
233         StringBuilder sb = new StringBuilder(" ");
234 
235         for (int i = 0; i < s.length(); i++) {
236             sb.append(Integer.toHexString(s.charAt(i)));
237             sb.append(' ');
238         }
239 
240         return sb.toString();
241     }
242 
indent(int distance)243     private void indent(int distance) {
244         if (needLineFeed) {
245             log.println(" {");
246             needLineFeed = false;
247         }
248         log.print(SPACES.substring(0, distance * 2));
249     }
250 
251     /**
252      * Print a usage message for this test class.
253      */
usage()254     void usage() {
255         System.out.println(getClass().getName() +
256                             ": [-verbose] [-nothrow] [-exitcode] [-prompt] [test names]");
257 
258         System.out.println("  Available test names:");
259         for (String methodName : testMethods.keySet()) {
260             System.out.println("\t" + methodName);
261         }
262     }
263 
264     private boolean     prompt;
265     private boolean     nothrow;
266     protected boolean   verbose;
267     private boolean     exitCode;
268     private PrintWriter log;
269     private int         indentLevel;
270     private boolean     needLineFeed;
271     private int         errorCount;
272 
273     private final Map<String, Method> testMethods = new LinkedHashMap<>();
274 
275     private static final String SPACES = "                                          ";
276 }
277