Path: blob/master/test/jdk/java/text/testlib/IntlTest.java
41149 views
/*1* Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.IOException;24import java.io.PrintWriter;25import java.lang.reflect.InvocationTargetException;26import java.lang.reflect.Method;27import java.lang.reflect.Modifier;28import java.util.ArrayList;29import java.util.Map;30import java.util.LinkedHashMap;31import java.util.List;3233/**34* IntlTest is a base class for tests that can be run conveniently from35* the command line as well as under the Java test harness.36* <p>37* Sub-classes implement a set of public void methods named "Test*" or38* "test*" with no arguments. Each of these methods performs some39* test. Test methods should indicate errors by calling either err() or40* errln(). This will increment the errorCount field and may optionally41* print a message to the log. Debugging information may also be added to42* the log via the log and logln methods. These methods will add their43* arguments to the log only if the test is being run in verbose mode.44*/45public abstract class IntlTest {4647//------------------------------------------------------------------------48// Everything below here is boilerplate code that makes it possible49// to add a new test by simply adding a method to an existing class.50//------------------------------------------------------------------------5152protected IntlTest() {53// Populate testMethods with all the test methods.54Method[] methods = getClass().getDeclaredMethods();55for (Method method : methods) {56if (Modifier.isPublic(method.getModifiers())57&& method.getReturnType() == void.class58&& method.getParameterCount() == 0) {59String name = method.getName();60if (name.length() > 4) {61if (name.startsWith("Test") || name.startsWith("test")) {62testMethods.put(name, method);63}64}65}66}67}6869protected void run(String[] args) throws Exception70{71// Set up the log and reference streams. We use PrintWriters in order to72// take advantage of character conversion. The JavaEsc converter will73// convert Unicode outside the ASCII range to Java's \\uxxxx notation.74log = new PrintWriter(System.out, true);7576// Parse the test arguments. They can be either the flag77// "-verbose" or names of test methods. Create a list of78// tests to be run.79List<Method> testsToRun = new ArrayList<>(args.length);80for (String arg : args) {81switch (arg) {82case "-verbose":83verbose = true;84break;85case "-prompt":86prompt = true;87break;88case "-nothrow":89nothrow = true;90break;91case "-exitcode":92exitCode = true;93break;94default:95Method m = testMethods.get(arg);96if (m == null) {97System.out.println("Method " + arg + ": not found");98usage();99return;100}101testsToRun.add(m);102break;103}104}105106// If no test method names were given explicitly, run them all.107if (testsToRun.isEmpty()) {108testsToRun.addAll(testMethods.values());109}110111System.out.println(getClass().getName() + " {");112indentLevel++;113114// Run the list of tests given in the test arguments115for (Method testMethod : testsToRun) {116int oldCount = errorCount;117118writeTestName(testMethod.getName());119120try {121testMethod.invoke(this, new Object[0]);122} catch (IllegalAccessException e) {123errln("Can't acces test method " + testMethod.getName());124} catch (InvocationTargetException e) {125errln("Uncaught exception thrown in test method "126+ testMethod.getName());127e.getTargetException().printStackTrace(this.log);128}129writeTestResult(errorCount - oldCount);130}131indentLevel--;132writeTestResult(errorCount);133134if (prompt) {135System.out.println("Hit RETURN to exit...");136try {137System.in.read();138} catch (IOException e) {139System.out.println("Exception: " + e.toString() + e.getMessage());140}141}142if (nothrow) {143if (exitCode) {144System.exit(errorCount);145}146if (errorCount > 0) {147throw new IllegalArgumentException("encountered " + errorCount + " errors");148}149}150}151152/**153* Adds the given message to the log if we are in verbose mode.154*/155protected void log(String message) {156logImpl(message, false);157}158159protected void logln(String message) {160logImpl(message, true);161}162163protected void logln() {164logImpl(null, true);165}166167private void logImpl(String message, boolean newline) {168if (verbose) {169if (message != null) {170indent(indentLevel + 1);171log.print(message);172}173if (newline) {174log.println();175}176}177}178179protected void err(String message) {180errImpl(message, false);181}182183protected void errln(String message) {184errImpl(message, true);185}186187private void errImpl(String message, boolean newline) {188errorCount++;189indent(indentLevel + 1);190log.print(message);191if (newline) {192log.println();193}194log.flush();195196if (!nothrow) {197throw new RuntimeException(message);198}199}200201protected int getErrorCount() {202return errorCount;203}204205protected void writeTestName(String testName) {206indent(indentLevel);207log.print(testName);208log.flush();209needLineFeed = true;210}211212protected void writeTestResult(int count) {213if (!needLineFeed) {214indent(indentLevel);215log.print("}");216}217needLineFeed = false;218219if (count != 0) {220log.println(" FAILED");221} else {222log.println(" Passed");223}224}225226/*227* Returns a spece-delimited hex String.228*/229protected static String toHexString(String s) {230StringBuilder sb = new StringBuilder(" ");231232for (int i = 0; i < s.length(); i++) {233sb.append(Integer.toHexString(s.charAt(i)));234sb.append(' ');235}236237return sb.toString();238}239240private void indent(int distance) {241if (needLineFeed) {242log.println(" {");243needLineFeed = false;244}245log.print(SPACES.substring(0, distance * 2));246}247248/**249* Print a usage message for this test class.250*/251void usage() {252System.out.println(getClass().getName() +253": [-verbose] [-nothrow] [-exitcode] [-prompt] [test names]");254255System.out.println(" Available test names:");256for (String methodName : testMethods.keySet()) {257System.out.println("\t" + methodName);258}259}260261private boolean prompt;262private boolean nothrow;263protected boolean verbose;264private boolean exitCode;265private PrintWriter log;266private int indentLevel;267private boolean needLineFeed;268private int errorCount;269270private final Map<String, Method> testMethods = new LinkedHashMap<>();271272private static final String SPACES = " ";273}274275276