0N/A/*
2712N/A * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2712N/A * published by the Free Software Foundation. Oracle designates this
2712N/A * particular file as subject to the "Classpath" exception as provided
2712N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
2712N/A
0N/A/*
0N/A *
0N/A *
0N/A * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
0N/A * (C) Copyright IBM Corp. 1996 - 1999 - All Rights Reserved
0N/A *
0N/A * Portions copyright (c) 2007 Sun Microsystems, Inc.
0N/A * All Rights Reserved.
0N/A *
0N/A * The original version of this source code and documentation
0N/A * is copyrighted and owned by Taligent, Inc., a wholly-owned
0N/A * subsidiary of IBM. These materials are provided under terms
0N/A * of a License Agreement between Taligent and Sun. This technology
0N/A * is protected by multiple US and International patents.
0N/A *
0N/A * This notice and attribution to Taligent may not be removed.
0N/A * Taligent is a registered trademark of Taligent, Inc.
0N/A *
0N/A * Permission to use, copy, modify, and distribute this software
0N/A * and its documentation for NON-COMMERCIAL purposes and without
0N/A * fee is hereby granted provided that this copyright notice
0N/A * appears in all copies. Please refer to the file "copyright.html"
0N/A * for further important copyright and licensing information.
0N/A *
0N/A * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
0N/A * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
0N/A * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
0N/A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
0N/A * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
0N/A * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
0N/A *
0N/A */
0N/A
0N/Aimport java.lang.reflect.*;
0N/Aimport java.util.Hashtable;
0N/Aimport java.util.Enumeration;
0N/Aimport java.util.Vector;
0N/Aimport java.io.*;
0N/Aimport java.text.*;
0N/A
0N/A/**
0N/A * LocaleTestFmwk is a base class for tests that can be run conveniently from
0N/A * the command line as well as under the Java test harness.
0N/A * <p>
0N/A * Sub-classes implement a set of methods named Test<something>. Each
0N/A * of these methods performs some test. Test methods should indicate
0N/A * errors by calling either err or errln. This will increment the
0N/A * errorCount field and may optionally print a message to the log.
0N/A * Debugging information may also be added to the log via the log
0N/A * and logln methods. These methods will add their arguments to the
0N/A * log only if the test is being run in verbose mode.
0N/A */
0N/Apublic class LocaleTestFmwk {
0N/A //------------------------------------------------------------------------
0N/A // Everything below here is boilerplate code that makes it possible
0N/A // to add a new test by simply adding a function to an existing class
0N/A //------------------------------------------------------------------------
0N/A
0N/A protected LocaleTestFmwk() {
0N/A // Create a hashtable containing all the test methods.
0N/A testMethods = new Hashtable();
0N/A Method[] methods = getClass().getDeclaredMethods();
0N/A for( int i=0; i<methods.length; i++ ) {
0N/A if( methods[i].getName().startsWith("Test")
0N/A || methods[i].getName().startsWith("test")) {
0N/A testMethods.put( methods[i].getName(), methods[i] );
0N/A }
0N/A }
0N/A }
0N/A
0N/A protected void run(String[] args) throws Exception
0N/A {
0N/A System.out.println(getClass().getName() + " {");
0N/A indentLevel++;
0N/A
0N/A // Set up the log and reference streams. We use PrintWriters in order to
0N/A // take advantage of character conversion. The JavaEsc converter will
0N/A // convert Unicode outside the ASCII range to Java's \\uxxxx notation.
0N/A log = new PrintWriter(System.out,true);
0N/A
0N/A // Parse the test arguments. They can be either the flag
0N/A // "-verbose" or names of test methods. Create a list of
0N/A // tests to be run.
0N/A Vector testsToRun = new Vector( args.length );
0N/A for( int i=0; i<args.length; i++ ) {
0N/A if( args[i].equals("-verbose") ) {
0N/A verbose = true;
0N/A }
0N/A else if( args[i].equals("-prompt") ) {
0N/A prompt = true;
0N/A } else if (args[i].equals("-nothrow")) {
0N/A nothrow = true;
2712N/A } else if (args[i].equals("-exitcode")) {
2712N/A exitcode = true;
0N/A } else {
0N/A Object m = testMethods.get( args[i] );
0N/A if( m != null ) {
0N/A testsToRun.addElement( m );
0N/A }
0N/A else {
0N/A usage();
0N/A return;
0N/A }
0N/A }
0N/A }
0N/A
0N/A // If no test method names were given explicitly, run them all.
0N/A if( testsToRun.size() == 0 ) {
0N/A Enumeration methodNames = testMethods.elements();
0N/A while( methodNames.hasMoreElements() ) {
0N/A testsToRun.addElement( methodNames.nextElement() );
0N/A }
0N/A }
0N/A
0N/A // Run the list of tests given in the test arguments
0N/A for( int i=0; i<testsToRun.size(); i++ ) {
0N/A int oldCount = errorCount;
0N/A
0N/A Method testMethod = (Method)testsToRun.elementAt(i);
0N/A writeTestName(testMethod.getName());
0N/A
0N/A try {
0N/A testMethod.invoke(this, new Object[0]);
0N/A }
0N/A catch( IllegalAccessException e ) {
0N/A errln("Can't acces test method " + testMethod.getName());
0N/A }
0N/A catch( InvocationTargetException e ) {
0N/A errln("Uncaught exception thrown in test method "
0N/A + testMethod.getName());
0N/A e.getTargetException().printStackTrace(this.log);
0N/A }
0N/A writeTestResult(errorCount - oldCount);
0N/A }
0N/A indentLevel--;
0N/A writeTestResult(errorCount);
0N/A
0N/A if (prompt) {
0N/A System.out.println("Hit RETURN to exit...");
0N/A try {
0N/A System.in.read();
0N/A }
0N/A catch (IOException e) {
0N/A System.out.println("Exception: " + e.toString() + e.getMessage());
0N/A }
0N/A }
0N/A if (nothrow) {
2712N/A if (exitcode) {
2712N/A System.exit(errorCount);
2712N/A }
2712N/A if (errorCount > 0) {
2712N/A throw new IllegalArgumentException("encountered " + errorCount + " errors");
2712N/A }
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Adds given string to the log if we are in verbose mode.
0N/A */
0N/A protected void log( String message ) {
0N/A if( verbose ) {
0N/A indent(indentLevel + 1);
0N/A log.print( message );
0N/A }
0N/A }
0N/A
0N/A protected void logln( String message ) {
0N/A log(message + System.getProperty("line.separator"));
0N/A }
0N/A
0N/A /**
0N/A * Report an error
0N/A */
0N/A protected void err( String message ) {
0N/A errorCount++;
0N/A indent(indentLevel + 1);
0N/A log.print( message );
0N/A log.flush();
0N/A
0N/A if (!nothrow) {
0N/A throw new RuntimeException(message);
0N/A }
0N/A }
0N/A
0N/A protected void errln( String message ) {
0N/A err(message + System.getProperty("line.separator"));
0N/A }
0N/A
0N/A
0N/A protected void writeTestName(String testName) {
0N/A indent(indentLevel);
0N/A log.print(testName);
0N/A log.flush();
0N/A needLineFeed = true;
0N/A }
0N/A
0N/A protected void writeTestResult(int count) {
0N/A if (!needLineFeed) {
0N/A indent(indentLevel);
0N/A log.print("}");
0N/A }
0N/A needLineFeed = false;
0N/A
0N/A if (count != 0)
0N/A log.println(" FAILED");
0N/A else
0N/A log.println(" Passed");
0N/A }
0N/A
0N/A private final void indent(int distance) {
0N/A if (needLineFeed) {
0N/A log.println(" {");
0N/A needLineFeed = false;
0N/A }
0N/A log.print(spaces.substring(0, distance * 2));
0N/A }
0N/A
0N/A /**
0N/A * Print a usage message for this test class.
0N/A */
0N/A void usage() {
0N/A System.out.println(getClass().getName() +
2712N/A ": [-verbose] [-nothrow] [-exitcode] [-prompt] [test names]");
0N/A
0N/A System.out.println("test names:");
0N/A Enumeration methodNames = testMethods.keys();
0N/A while( methodNames.hasMoreElements() ) {
0N/A System.out.println("\t" + methodNames.nextElement() );
0N/A }
0N/A }
0N/A
0N/A private boolean prompt = false;
0N/A private boolean nothrow = false;
2712N/A private boolean exitcode = false;
0N/A protected boolean verbose = false;
0N/A
0N/A private PrintWriter log;
0N/A private int indentLevel = 0;
0N/A private boolean needLineFeed = false;
0N/A private int errorCount = 0;
0N/A
0N/A private Hashtable testMethods;
0N/A private final String spaces = " ";
0N/A}