1/* 2 * Copyright (c) 2007, 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 24import java.lang.reflect.*; 25import java.util.Hashtable; 26import java.util.Enumeration; 27import java.util.Vector; 28import java.io.*; 29import java.text.*; 30 31/** 32 * IntlTest is a base class for tests that can be run conveniently from 33 * the command line as well as under the Java test harness. 34 * <p> 35 * Sub-classes implement a set of methods named Test<something>. Each 36 * of these methods performs some test. Test methods should indicate 37 * errors by calling either err or errln. This will increment the 38 * errorCount field and may optionally print a message to the log. 39 * Debugging information may also be added to the log via the log 40 * and logln methods. These methods will add their arguments to the 41 * log only if the test is being run in verbose mode. 42 */ 43public class IntlTest { 44 45 //------------------------------------------------------------------------ 46 // Everything below here is boilerplate code that makes it possible 47 // to add a new test by simply adding a function to an existing class 48 //------------------------------------------------------------------------ 49 50 protected IntlTest() { 51 // Create a hashtable containing all the test methods. 52 testMethods = new Hashtable(); 53 Method[] methods = getClass().getDeclaredMethods(); 54 for( int i=0; i<methods.length; i++ ) { 55 if( methods[i].getName().startsWith("Test") ) { 56 testMethods.put( methods[i].getName(), methods[i] ); 57 } 58 } 59 } 60 61 protected void run(String[] args) throws Exception 62 { 63 System.out.println(getClass().getName() + " {"); 64 indentLevel++; 65 66 // Set up the log and reference streams. We use PrintWriters in order to 67 // take advantage of character conversion. The JavaEsc converter will 68 // convert Unicode outside the ASCII range to Java's \\uxxxx notation. 69 log = new PrintWriter(System.out,true); 70 71 // Parse the test arguments. They can be either the flag 72 // "-verbose" or names of test methods. Create a list of 73 // tests to be run. 74 Vector testsToRun = new Vector( args.length ); 75 for( int i=0; i<args.length; i++ ) { 76 if( args[i].equals("-verbose") ) { 77 verbose = true; 78 } 79 else if( args[i].equals("-prompt") ) { 80 prompt = true; 81 } else if (args[i].equals("-nothrow")) { 82 nothrow = true; 83 } else { 84 Object m = testMethods.get( args[i] ); 85 if( m != null ) { 86 testsToRun.addElement( m ); 87 } 88 else { 89 usage(); 90 return; 91 } 92 } 93 } 94 95 // If no test method names were given explicitly, run them all. 96 if( testsToRun.size() == 0 ) { 97 Enumeration methodNames = testMethods.elements(); 98 while( methodNames.hasMoreElements() ) { 99 testsToRun.addElement( methodNames.nextElement() ); 100 } 101 } 102 103 // Run the list of tests given in the test arguments 104 for( int i=0; i<testsToRun.size(); i++ ) { 105 int oldCount = errorCount; 106 107 Method testMethod = (Method)testsToRun.elementAt(i); 108 writeTestName(testMethod.getName()); 109 110 try { 111 testMethod.invoke(this, new Object[0]); 112 } 113 catch( IllegalAccessException e ) { 114 errln("Can't acces test method " + testMethod.getName()); 115 } 116 catch( InvocationTargetException e ) { 117 errln("Uncaught exception thrown in test method " 118 + testMethod.getName()); 119 e.getTargetException().printStackTrace(this.log); 120 } 121 writeTestResult(errorCount - oldCount); 122 } 123 indentLevel--; 124 writeTestResult(errorCount); 125 126 if (prompt) { 127 System.out.println("Hit RETURN to exit..."); 128 try { 129 System.in.read(); 130 } 131 catch (IOException e) { 132 System.out.println("Exception: " + e.toString() + e.getMessage()); 133 } 134 } 135 if (nothrow) { 136 System.exit(errorCount); 137 } 138 } 139 140 /** 141 * Adds given string to the log if we are in verbose mode. 142 */ 143 protected void log( String message ) { 144 if( verbose ) { 145 indent(indentLevel + 1); 146 log.print( message ); 147 } 148 } 149 150 protected void logln( String message ) { 151 log(message + System.getProperty("line.separator")); 152 } 153 154 /** 155 * Report an error 156 */ 157 protected void err( String message ) { 158 errorCount++; 159 indent(indentLevel + 1); 160 log.print( message ); 161 log.flush(); 162 163 if (!nothrow) { 164 throw new RuntimeException(message); 165 } 166 } 167 168 protected void errln( String message ) { 169 err(message + System.getProperty("line.separator")); 170 } 171 172 173 protected void writeTestName(String testName) { 174 indent(indentLevel); 175 log.print(testName); 176 log.flush(); 177 needLineFeed = true; 178 } 179 180 protected void writeTestResult(int count) { 181 if (!needLineFeed) { 182 indent(indentLevel); 183 log.print("}"); 184 } 185 needLineFeed = false; 186 187 if (count != 0) 188 log.println(" FAILED"); 189 else 190 log.println(" Passed"); 191 } 192 193 private final void indent(int distance) { 194 if (needLineFeed) { 195 log.println(" {"); 196 needLineFeed = false; 197 } 198 log.print(spaces.substring(0, distance * 2)); 199 } 200 201 /** 202 * Print a usage message for this test class. 203 */ 204 void usage() { 205 System.out.println(getClass().getName() + 206 ": [-verbose] [-nothrow] [-prompt] [test names]"); 207 208 System.out.println("test names:"); 209 Enumeration methodNames = testMethods.keys(); 210 while( methodNames.hasMoreElements() ) { 211 System.out.println("\t" + methodNames.nextElement() ); 212 } 213 } 214 215 private boolean prompt = false; 216 private boolean nothrow = false; 217 protected boolean verbose = false; 218 219 private PrintWriter log; 220 private int indentLevel = 0; 221 private boolean needLineFeed = false; 222 private int errorCount = 0; 223 224 private Hashtable testMethods; 225 private final String spaces = " "; 226} 227 228//eof 229