This commit is contained in:
rginda%netscape.com 2000-02-02 00:22:23 +00:00
Родитель 7065652faa
Коммит a1985df10f
19 изменённых файлов: 4026 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,289 @@
package com.netscape.javascript.qa.drivers;
//import netscape.javascript.*;
//import org.mozilla.javascript.*;
import java.io.*;
/**
* LiveConnectDrv is an application that drives the testing of the LiveConnect
* API test suite. This driver runs the stand-alone JavaScript engine in C.
* To run the LiveConnectTest API suite in Navigator, use XXX an as yet unwritten
* driver, which will depend on a generated HTML file to create the test applet.
*
* <p>
* The application requires the following arguments:
*
* <table>
* <tr>
* <td> -d
* <td> directory in which LiveConnect test applications are located
* </tr>
* <tr>
* <td> -s
* <td> list of suites to execute (optional)
* </tr>
* <tr>
* <td> -o
* <td> directory in which log files will be written
* </tr>
* <tr>
* <td> -e
* <td> path to the LiveConnect shell executable
* </table>
*
* LiveConnectDrv checks the directory, finds the suites in that directory,
* and in each suite a list of all the class files in that suite. For each
* class file found, LiveConnectDrv creates a new LiveConnectEnv object,
* which runs the test.
*
* <p>
*
* LiveConnectDrv also generates a helper file that is passed to the JavaScript
* shell. The helper file contains statements that allow the shell to run the
* test class.
*
*
* The contents of the helper file look something like this:
*
* <pre>
* var OUTPUT_DIRECTORY = <i>value of OUTPUT_DIRECTORY</i>
* TestClassName = arguments[0];
* TestClass = eval( TestClassName );
* testclass = new TestClass();
* quit();
* </pre>
*
* <p> Each test class creates JavaScript TestCase objects through LiveConnect,
* and prints results to standard output, just like the JavaScript language
* tests do. Additionally, test logs are created.
*
* <p> The parent test class, LiveConnectTest, contains methods from
* com.netscape.javascript.qa.drivers.TestDriver that allow it to write
* test results directly to the log files.
*
* @see com.netscape.javascript.qa.liveconnect.LiveConnectTest
* @see LiveConnectEnv
*
* @author christine@netscape.com
*
*/
public class LiveConnectDrv extends TestDriver {
public LiveConnectDrv( String[] args ) {
super( args );
setSuffix( ".class");
}
public static void main ( String[] args ) {
LiveConnectDrv d = new LiveConnectDrv( args );
d.start();
}
public boolean processOptions() {
int length = ARGS.length;
if (ARGS[0].startsWith("-")) {
//XXX need to verify that we at least get valid d and -h options
for (int i=0; i < ARGS.length; i++ ) {
if ( ARGS[i].equals("-d") ) {
this.TEST_DIRECTORY =
ARGS[i].endsWith(File.separator)
? new File( ARGS[++i] )
: new File( ARGS[++i] + File.separator );
if ( ! ( this.TEST_DIRECTORY ).isDirectory() ) {
p( "error: " +
this.TEST_DIRECTORY.getAbsolutePath() +
" is not a directory." );
return false;
} else {
continue;
}
}
if ( ARGS[i].equals("-s") ) {
FILES = new String[20] ;
for ( int j = ++i, k=0; j < ARGS.length; j++ ) {
if ( ARGS[j].startsWith("-") ){
break;
}
FILES[k++] = ARGS[j];
}
}
if ( ARGS[i].equals("-h") ) {
this.HELPER_FUNCTIONS = new File( ARGS[++i] );
if ( ! (this.HELPER_FUNCTIONS ).isFile() ) {
p( "error: "+
this.HELPER_FUNCTIONS.getAbsolutePath()+
" file not found." );
return false;
}
}
if ( ARGS[i].equals("-o") ) {
String odir = ARGS[++i];
OUTPUT_DIRECTORY = new File(
(odir.endsWith(File.separator) ? odir :
odir+File.separator));
OUTPUT_DIRECTORY.mkdirs();
if ( !OUTPUT_DIRECTORY.exists() ||
!OUTPUT_DIRECTORY.isDirectory() )
{
p( "error: "+
OUTPUT_DIRECTORY.getAbsolutePath()+
" could not create directory.");
return false;
}
}
if ( ARGS[i].equals("-p") ) {
OPT_LEVEL = Integer.parseInt( ARGS[++i] );
}
if ( ARGS[i].equals("-db" )) {
DEBUG_LEVEL = Integer.parseInt( ARGS[++i] );
OPT_LEVEL = 0;
}
if ( ARGS[i].equals("-e")) {
EXECUTABLE = ARGS[++i];
}
}
return true;
} else {
switch ( ARGS.length ) {
case 0:
p( "error: specify location of JavaScript "+
"tests" );
return false;
case 1:
p( "error: specify location of JavaScript "+
"HELPER_FUNCTIONS file" );
return false;
case 2:
this.TEST_DIRECTORY = ARGS[0].endsWith(File.separator)
? new File( ARGS[0] )
: new File( ARGS[0] + File.separator );
this.HELPER_FUNCTIONS = new File( ARGS[1] );
if ( ! ( this.TEST_DIRECTORY ).isDirectory() ) {
p( "error: " +
this.TEST_DIRECTORY.getAbsolutePath() +
" is not a directory." );
return false;
}
if ( ! (this.HELPER_FUNCTIONS ).isFile() ) {
p( "error: "+
this.HELPER_FUNCTIONS.getAbsolutePath()+
" file not found." );
return false;
}
return true;
default:
p( "could not understand arguments." );
return false;
}
}
}
public synchronized void executeSuite( TestSuite suite ) {
p( "LiveConnectDrv.executeSuite " + suite.name );
TestEnvironment context;
TestFile file;
if ( EXECUTABLE != null ) {
generateHelperFile();
}
for ( int i = 0; i < suite.size(); i++ ) {
synchronized ( suite ) {
file = (TestFile) suite.elementAt( i );
p( file.name );
// if ( EXECUTABLE != null ) {
context = new LiveConnectEnv( file, suite, this );
// } else {
// context = new LiveRhinoEnv( file, suite, this );
// }
synchronized( context ) {
context.runTest();
/*
* The following two lines are used by the other test drivers,
* but are not used by LiveConnectDrv, since each
* LiveConnecTest writes its results to these log files.
*/
// writeFileResult( file, suite, OUTPUT_DIRECTORY );
// writeCaseResults(file, suite, OUTPUT_DIRECTORY );
context.close();
context = null;
if ( ! file.passed ) {
suite.passed = false;
}
}
}
}
writeSuiteResult( suite, OUTPUT_DIRECTORY );
writeSuiteSummary( suite, OUTPUT_DIRECTORY );
}
public void generateHelperFile() {
try {
this.HELPER_FUNCTIONS = new File( OUTPUT_DIRECTORY, "helper.js" );
p( "HELPER FUNCTIONS FILE IS " + HELPER_FUNCTIONS );
FileOutputStream fos = new FileOutputStream( HELPER_FUNCTIONS );
fos.write( ("var OUTPUT_DIRECTORY = \"" + OUTPUT_DIRECTORY + "\";").getBytes());
fos.write( ("var OUTPUT_FILE = arguments[1];").getBytes() );
fos.write( ("var TestClassName = arguments[0];" ).getBytes());
fos.write( ("var TestClass = eval( TestClassName );" ).getBytes());
fos.write( ("var testclass = new TestClass();" ).getBytes());
fos.write( ("testclass.run();").getBytes() );
fos.write( ("quit();" ).getBytes());
fos.close();
} catch ( Exception e ) {
p( "generateHelperFile threw " + e.toString() );
e.printStackTrace();
}
}
/**
* For each class file in the suite directory, create a TestFile object.
* For LiveConnect, the test class name needs to be the name of the class
* and the file path needs to be the full package name, prepended with the
* JavaScript keyword "Packages", and without the ".class" suffix.
*/
public void getCases( TestSuite suite ) {
enablePrivileges();
File dir = new File ( suite.filePath );
String[] files = dir.list();
// XXX hardcoded package name. need to fix this.
String filename = "Packages.com.netscape.javascript.qa.liveconnect." +
suite.name +".";
for ( int i = 0; i < files.length; i++ ) {
if ( files[i].endsWith( getSuffix() )) {
TestFile item = new TestFile( files[i],
filename + (files[i].substring(0,files[i].length() -
getSuffix().length())));
p( item.filePath );
suite.addElement(item);
}
}
}
}

Просмотреть файл

@ -0,0 +1,206 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
import com.netscape.javascript.qa.liveconnect.LiveConnectTest;
import java.lang.*;
import java.io.*;
import java.util.Vector;
/**
* The LiveConnect test environment. Creates a new LiveConnect enabled
* JavaScript shell, and passes it three arguments
*
* <pre>
* jsshell helper.js Packages.com.netscape.javascript.qa.liveconnect.LiveConnectTestClass js00000.tmp
* </pre>
* where helper.js contains some statements that allow the shell to run
* the test, and js00000.tmp is the temporary file whose name is generated
* by this class, and specifies where test results should be written.
*
* Unlike the other TestEnvironments, LiveConnectEnv does not parse the test
* result. The LiveConnectEnv uses LiveConnect to get and parse the test
* result, using LiveConnect to get the JSObject that contains the testcases.
*
* The LiveConnectEnv gets File and Suite result information from a
* temporary file that the test applet writes to the output directory
* the test
*
* @see com.netscape.javascript.qa.drivers.TestEnvironment
* @see com.netscape.javascript.qa.drivers.ObservedTask
* @see com.netscape.javascript.qa.drivers.LiveConnectDrv
* @see com.netscape.javascript.qa.liveconnect.LiveConnectTest
*
* @author christine@netscape.com
*/
public class LiveConnectEnv implements TestEnvironment {
TestFile file;
TestSuite suite;
LiveConnectDrv driver;
ObservedTask task;
String TEMP_LOG_NAME;
File helper;
/**
* Create a new LiveConnectEnv.
*/
public LiveConnectEnv( TestFile f, TestSuite s, LiveConnectDrv d) {
this.file = f;
this.suite = s;
this.driver = d;
this.TEMP_LOG_NAME = "js" + getRandomFileName() +".tmp";
}
/**
* Called by the driver to execute the test program.
*/
public synchronized void runTest() {
try {
createContext();
file.startTime = driver.getCurrentTime();
executeTestFile();
file.endTime = driver.getCurrentTime();
if (task.getExitValue() != 0) {
System.out.println( "Abmormal program termination. "+
"Exit value: " + task.getExitValue() );
if ( file.name.endsWith( "-n.js" )) {
file.passed = true;
} else {
file.exception = "Process exit value: " + task.getExitValue();
suite.passed = false;
file.passed = false;
}
}
parseResult();
} catch ( Exception e ) {
suite.passed = false;
file.passed = false;
e.printStackTrace();
}
}
/**
* Instantiate a new JavaScript shell, passing the helper file and the
* name of the test class as arguments.
*/
public Object createContext() {
task = new ObservedTask( driver.EXECUTABLE + " " +
driver.HELPER_FUNCTIONS.getAbsolutePath() + " " +
file.filePath +" "+
TEMP_LOG_NAME,
this );
return (Object) task;
}
/**
* Start the shell process.
*/
public Object executeTestFile() {
try {
task.exec();
} catch ( IOException e ) {
System.err.println( e );
file.exception = e.toString();
}
return null;
}
/**
* Parse the results file for this test. The which contains data in the
* following format:
* <pre>
* CLASSNAME LiveConnectTest
* PASSED [true, false]
* LENGTH [number of testcases in this test]
* NO_PASSED [number of testcases that passed]
* NO_FAILED [number of testcases that failed]
* </pre>
*
* @see com.netscape.javascript.qa.liveconnect.LiveConnectTest#writeResultsToTempFile
*/
public synchronized boolean parseResult() {
String line;
BufferedReader buf = new BufferedReader(new StringReader(
new String(task.getInput())));
try {
do {
line = buf.readLine();
System.out.println( line );
} while( line != null ) ;
} catch ( IOException e ) {
System.err.println( "Exception reading process output:" +
e.toString() );
file.exception = e.toString();
return false;
}
Vector label = null;
Vector value = null;
String t = null;
try {
FileReader fr = new FileReader(
driver.OUTPUT_DIRECTORY.getAbsolutePath()+
TEMP_LOG_NAME );
BufferedReader br = new BufferedReader( fr );
String classname = br.readLine();
boolean passed = (new Boolean(br.readLine())).booleanValue();
int length = (new Double(br.readLine())).intValue();
int no_passed = (new Double(br.readLine())).intValue();
int no_failed = (new Double(br.readLine())).intValue();
String bugnumber = br.readLine();
if ( ! passed ) {
this.file.passed = false;
this.suite.passed = false;
}
this.file.totalCases += length;
this.suite.totalCases += length;
this.file.casesPassed += no_passed;
this.suite.casesPassed += no_passed;
this.file.casesFailed += no_failed;
this.suite.casesFailed += no_failed;
this.file.bugnumber = bugnumber;
} catch ( IOException e ) {
System.err.println( e );
e.printStackTrace();
}
return true;
}
public String getRandomFileName() {
return (Integer.toString((new Double(Math.random()*100000)).intValue()));
}
/**
* Delete the temp log associated with this context.
*
*/
public void close(){
String templog = driver.OUTPUT_DIRECTORY + TEMP_LOG_NAME;
try {
File f = new File ( templog );
if ( f.exists() ) {
f.delete();
}
} catch ( Exception e ) {
e.printStackTrace();
}
return;
}
void p( String s ) {
System.out.println( s );
}
}

Просмотреть файл

@ -0,0 +1,75 @@
package com.netscape.javascript.qa.drivers;
import netscape.security.PrivilegeManager;
import netscape.javascript.JSObject;
import java.util.Vector;
import java.util.Date;
import java.io.*;
import java.applet.Applet;
/**
* LiveNavDrv is a test driver for running the JSObject test applets in Netscape
* Navigator.
*
* The only difference between LiveNavDrv and NavDrv is that it creates a
* LiveNavEnv object (rather than a NavEnv) in which the LiveConnect tests
* are evaluated.
*
* @see NavDrv
* @see LiveNavEnv
*
* @author christine@netscape.com
*/
public class LiveNavDrv extends NavDrv {
JSObject window;
String SUFFIX;
public LiveNavDrv() {
super();
setSuffix(".java");
}
public static void main ( String[] args ) {
System.out.println( "main" );
LiveNavDrv d = new LiveNavDrv();
d.start();
}
/**
* Iterate through suites. For each file in each suite, create a
* LiveNavEnv (in this case a Navigator window) that can load and
* evaluate the test result.
*
* @see LiveNavEnv#parseResult
*/
public synchronized void executeSuite( TestSuite suite ) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
LiveNavEnv context;
TestFile file;
for ( int i = 0; i < suite.size(); i++ ) {
synchronized ( suite ) {
file = (TestFile) suite.elementAt( i );
context = new LiveNavEnv( file, suite, this );
context.runTest();
writeFileResult( file, suite, OUTPUT_DIRECTORY );
writeCaseResults(file, suite, OUTPUT_DIRECTORY );
context.close();
context = null;
if ( ! file.passed ) {
suite.passed = false;
}
}
}
writeSuiteResult( suite, OUTPUT_DIRECTORY );
writeSuiteSummary( suite, OUTPUT_DIRECTORY );
}
}

Просмотреть файл

@ -0,0 +1,208 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
import java.io.*;
import java.applet.Applet;
import java.util.Vector;
import netscape.security.PrivilegeManager;
import netscape.javascript.JSObject;
import com.netscape.javascript.qa.liveconnect.LiveConnectTest;
import com.netscape.javascript.qa.liveconnect.jsobject.JSObject_001;
/**
* TestEnvironment for running JSObject test applets in Navigator. LiveNavDrv
* uses LiveConnect to create Navigator windows in which JavaScript tests are
* opened and evaluated.
*
* @see com.netscape.javascript.qa.drivers.LiveNavDrv
* @see com.netscape.javascript.qa.drivers.NavDrv
* @see com.netscape.javascript.qa.drivers.NavEnv
*
* @author christine@netscape.com
*
*/
public class LiveNavEnv extends NavEnv {
TestFile file;
TestSuite suite;
LiveNavDrv driver;
private JSObject result;
JSObject opener;
JSObject testcases;
JSObject location;
boolean evaluatedSuccessfully = false;
JSObject window;
Applet applet;
private String WINDOW_NAME;
/**
* Construct a new LiveNavEnv.
*
* @param file TestFile whose program will be evaluated in this
* environment
* @param suite TestSuite which this TestFile belongs to
* @param driver TestDriver that is currently running
*/
public LiveNavEnv( TestFile file, TestSuite suite, LiveNavDrv driver ) {
super( file, suite, driver );
}
/**
* Open the current TestFile in the window by using LiveConnect to set the
* window's location.href property to a URL where the TestFile can be
* found.
*
* XXX need to generate HTML file on the fly.
*/
public Object executeTestFile() {
try {
location = (JSObject) window.getMember( "location" );
driver.p( file.name );
// we need to look for the html file in the test directory.
// the name of the file is the class name + ".html"
String classname = (file.name.substring(0, file.name.length() -
".class".length()) + ".html" );
String s = driver.HTTP_PATH + classname;
System.out.println( "trying to set browser window to " + s );
location.setMember( "href", s );
evaluatedSuccessfully = waitForCompletion();
} catch ( Exception e ) {
driver.p( file.name + " failed with exception: " + e );
file.exception = e.toString();
if ( file.name.endsWith( "-n.js" ) ) {
this.file.passed = true;
evaluatedSuccessfully = true;
} else {
this.file.passed = false;
this.suite.passed = false;
evaluatedSuccessfully = false;
}
}
return null;
}
/**
* Get a reference to the LiveConnectTest applet. Unfortunately, due
* to reasons I don't understand, we can't just get the TestFile object
* from the LiveConnectTest via LiveConnect. Attempting to cast the
* applet to LiveConnectTest fails with a java.lang.ClassCastException,
* so we continue to use the temporary file hack in Navigator. Need a
* reference to the applet so we can properly destroy it before closing
* the Navigator window.
*
* This is http://scopus/bugsplat/show_bug.cgi?id=300350, and when that's
* fixed we can ue the getAppletClass method below to directly access
* the LiveConnectTest's TestFile file object so we don't have use the
* temporary file hack.
*
*/
public Applet getApplet() {
Object document = (Object) window.getMember("document");
Object applets = ((JSObject) document).getMember("applets");
return (Applet) ((JSObject) applets).getSlot( 0 );
}
/**
* Currently does not work.
*
* @see #getApplet
*/
public void getAppletClass(Applet applet) {
try {
driver.p( "the class of applet is " +
applet.getClass().toString() );
driver.p( "is it a JSObject_001? " +
(applet instanceof JSObject_001 ));
driver.p( "is it a LiveConnectTest? " +
(applet instanceof LiveConnectTest ));
driver.p( "is it an Applet? " +
(applet instanceof Applet ));
driver.p( "Try to cast applet to JSObject_001" );
// this throws the ClassCastException
driver.p( ((JSObject_001) applet).toString() );
} catch ( Exception e ) {
driver.p( "parseResult threw exception: " + e );
}
}
/**
* Parse the results file for this test. The which contains data in the
* following format:
* <pre>
* CLASSNAME [LiveConnectTest class name]
* PASSED [true, false]
* LENGTH [number of testcases in this test]
* NO_PASSED [number of testcases that passed]
* NO_FAILED [number of testcases that failed]
* </pre>
*
* @see com.netscape.javascript.qa.liveconnect.LiveConnectTest#writeResultsToTempFile
*/
public boolean parseResult() {
applet = getApplet();
Vector label = null;
Vector value = null;
try {
FileReader fr = new FileReader(
driver.OUTPUT_DIRECTORY.getAbsolutePath()+
(driver.OUTPUT_DIRECTORY.getAbsolutePath().endsWith(File.separator)
? ""
: File.separator ) +
LiveConnectTest.TEMP_LOG_NAME);
BufferedReader br = new BufferedReader( fr );
String classname = br.readLine();
boolean passed = (new Boolean(br.readLine())).booleanValue();
int length = (new Double(br.readLine())).intValue();
int no_passed = (new Double(br.readLine())).intValue();
int no_failed = (new Double(br.readLine())).intValue();
if ( ! passed ) {
this.file.passed = false;
this.suite.passed = false;
}
this.file.totalCases += length;
this.file.casesPassed += no_passed;
this.suite.casesPassed += no_passed;
this.file.casesFailed += no_failed;
this.suite.casesFailed += no_failed;
} catch ( IOException e ) {
driver.p( e.toString() );
return false;
}
return true;
}
/**
* Destroy the test applet, close Navigator window, and delete the
* reference to the test applet's window.
*/
public void close() {
applet.destroy();
opener.eval( WINDOW_NAME +".close()" );
opener.eval( "delete " + WINDOW_NAME );
}
}

Просмотреть файл

@ -0,0 +1,18 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
import java.util.Vector;
import java.util.Date;
import java.io.*;
import java.applet.Applet;
/**
* Test driver for running the JavaScript language tests on the Macintosh.
*
*
*/

Просмотреть файл

@ -0,0 +1,361 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
import java.util.Vector;
import java.util.Date;
import java.io.*;
import java.applet.Applet;
/**
* Test environment for running the JavaScript language tests on the Macintosh.
* On the Macintosh, we have to use JBindery, a MRJ tool, to run the tests.
*
* <p>
*
* In order to get tests to run on the Mac, the shell must be built with
* MAC_TEST_HACK defined. When MAC_TEST_HACK is defined, the shell expects
* to find file called "testargs.txt" in the directory where the shell
* executable is. The shell expects testargs.txt to have one argument per line.
* Legal arguments in testargs.txt are the same as the command line arguments
* to the shell (although we only use the -f argument, which tells the shell
* to evaluate files).
*
* <p>
*
* The shell writes any output generated by the print statement to a file
* called "results.txt". The test environment parses the results.txt file
* in the same way that RefEnv parses the output stream of the JavaScript
* shell process.
*
* <p>
*/
public class MacRefEnv implements TestEnvironment {
TestFile file;
TestSuite suite;
RefDrv driver;
String directoryName;
TestLog testargs;
File results;
Process task;
/**
* Create a new MacRefEnv
*
*/
public MacRefEnv ( TestFile f, TestSuite s, RefDrv d ) {
this.file = f;
this.suite = s;
this.driver = d;
}
/**
* This implementation does nothing, since creating the JS shell
* automatically runs the test on the Mac.
*
*/
public Object executeTestFile() {
return null;
}
/**
* Instantiate a new JavaScript shell which has been built with
* MAC_TEST_HACK defined.
*/
public Object createContext() {
try {
// look for a file called flagfile.flg
File flag = new File ( "flagfile.flg" );
if ( flag.exists() ) {
flag.delete();
}
task = Runtime.getRuntime().exec(driver.EXECUTABLE);
// wait a maximum of five minutes
int i = 0;
while ( (! flag.exists()) && i++ <= 60 ) {
Thread.currentThread().sleep(5000);
}
} catch (IOException x) {
System.out.println("IOException in RunJS : " + x);
} catch (InterruptedException x) {
System.out.println("InterruptedException in RunJS : " + x);
}
return null;
}
public boolean setupMacFiles() {
boolean result1 = getDirectoryName();
deleteResultsFile();
boolean result3 = createTestargsFile();
boolean result4 = writeTestargsFile();
if ( result1 && result3 && result4 ) {
return true;
} else {
return false;
}
}
public synchronized void runTest() {
try {
if ( setupMacFiles() ) {
file.startTime = driver.getCurrentTime();
createContext();
file.endTime = driver.getCurrentTime();
}
/*
if (task.getExitValue() != 0) {
if ( file.name.endsWith( "-n.js" )) {
file.passed = true;
} else {
suite.passed = false;
file.passed = false;
}
}
*/
if ( ! parseResult() ) {
if ( file.name.endsWith( "-n.js" ) ) {
file.passed = true;
} else {
suite.passed = false;
file.passed = false;
}
// file.exception = new String(task.getError());
}
} catch ( Exception e ) {
suite.passed = false;
file.passed = false;
file.exception = "Unknown process exception.";
/*
file.exception = new String(task.getError())
+ " exit value: " + task.getExitValue()
+ "\nThrew Exception:" + e;
*/
}
}
public boolean parseResult() {
String line;
int i, j;
results = new File( "results.txt");
if (! results.exists()) {
return false;
}
// spit out all the lines we find in the result file
try {
FileReader fr = new FileReader(results);
LineNumberReader lnr = new LineNumberReader(fr);
do {
line = lnr.readLine();
driver.p( line );
if (line == null) {
driver.p("\tERROR: No lines to read");
return false;
}
} while (!line.equals(sizeTag));
if ((line = lnr.readLine()) == null) {
return false;
}
file.totalCases = Integer.valueOf(line).intValue();
if ((line = lnr.readLine()) == null) {
driver.p("\tERROR: No lines after " + sizeTag);
return false;
}
for ( i = 0; i < file.totalCases; i++) {
String values[] = new String[tags.length];
try {
for ( j = 0; j < tags.length; j++) {
values[j] = null;
if (!line.startsWith(tags[j])) {
driver.p("line didn't start with " + tags[j] +":"+line);
return false;
}
while (((line = lnr.readLine()) != null) &&
(!(line.startsWith(startTag))))
{
values[j] = (values[j] == null) ? line : (values[j] +
"\n" + line);
}
if (values[j] == null) values[j] = "";
}
if ((line == null) && (i < file.totalCases - 1)) {
driver.p("line == null and " + i + "<" +
(file.totalCases - 1));
return false;
}
} catch ( IOException e ) {
driver.p( "Exception reading process output: " + e );
file.exception = e.toString();
return false;
}
TestCase rt = new TestCase(values[0],values[1],values[4],values[2],
values[3],values[5]);
file.bugnumber = values[6];
file.caseVector.addElement( rt );
if ( rt.passed.equals("false") ) {
if ( file.name.endsWith( "-n.js" ) ) {
this.file.passed = true;
} else {
this.file.passed = false;
this.suite.passed = false;
}
}
}
try {
lnr.close();
fr.close();
} catch (IOException x) {
System.out.println("IOException in RunJS : " + x);
return false;
}
} catch (NumberFormatException nfe) {
System.out.println("\tERROR: No integer after " + sizeTag);
return false;
} catch ( IOException e ) {
System.out.println( "Exception reading process output:" + e.toString() );
file.exception = e.toString();
return false;
}
return true;
}
/**
* Get the executable's directory, which is where we will write testargs.txt
* and from where we will get results.txt.
*/
public boolean getDirectoryName() {
directoryName = ":";
return true;
}
/**
* Called by the driver to execute the test program.
*
*/
/**
* Check to see whether testargs.txt exists. If so, delete it.
*/
public boolean createTestargsFile() {
String testargsname = "testargs.txt";
File testargsfile = new File( testargsname );
if ( testargsfile.exists() ) {
testargsfile.delete();
}
testargs = new TestLog( "testargs.txt", "" );
return true;
}
public boolean deleteResultsFile() {
String resultsname = "results.txt";
File resultsfile = new File( resultsname );
if ( resultsfile.exists() ) {
resultsfile.delete();
}
return true;
}
/**
* Write testargs.txt to the directory where the executable is.
*/
public boolean writeTestargsFile() {
String helper = getMacFileString( ":"+ driver.HELPER_STRING );
String testfile = getMacFileString( ":"+file.filePath );
testargs.writeLine( "-f" );
testargs.writeLine( helper );
testargs.writeLine( "-f" );
testargs.writeLine( testfile );
testargs.closeLog();
return true;
}
public void close() {
return;
}
/**
* Replace slashes in a string with colons.
*
*/
public String getMacFileString( String path ) {
StringBuffer buffer = new StringBuffer();
int i;
for ( i = 0; i < path.length(); i++ ) {
if ( path.charAt(i) == '/' ) {
buffer.append(":");
} else {
buffer.append( path.charAt(i) );
}
}
return buffer.toString();
}
/**
* array of in output file to get attributes of a specific TestCase
*/
public static final String tags[];
/**
* tag to specify the number of TestCases
*/
public static final String sizeTag = "<#TEST CASES SIZE>";
/**
* beginning of a tag
*/
public static final String startTag = "<#TEST CASE";
/**
* end of a tag
*/
public static final String endTag = ">";
/**
* creating of String tags[]
*/
static {
String fields[] = { "PASSED", "NAME", "EXPECTED", "ACTUAL", "DESCRIPTION", "REASON",
"BUGNUMBER" };
tags = new String[fields.length];
for (int i = 0; i < fields.length; ++i) {
tags[i] = startTag + " " + fields[i] + endTag;
}
}
}

Просмотреть файл

@ -0,0 +1,243 @@
package com.netscape.javascript.qa.drivers;
import netscape.security.PrivilegeManager;
import netscape.javascript.JSObject;
import java.util.Vector;
import java.util.Date;
import java.io.*;
import java.applet.Applet;
import com.netscape.javascript.qa.drivers.*;
/**
* NavDrv is a test driver for running JavaScript tests in Netscape
* Navigator.
*
* NavDrv expects to find test files locally, as well as on an HTTP server,
* since in some tests, JavaScript applications may behave differently with
* local versus cached files.
*
* To run the test without signing the classfiles, add this to the test
* machine's preferences:
* <pre>
* user_pref("signed.applets.codebase_principal_support", true);
* </pre>
*
* The HTML file in which the applet is defined needs to define the following
* parameters:
* <table>
* <tr>
* <th> Parameter
* <th> Value
* </tr>
*
* <tr>
* <td> directory
* <td> full path to the directory in which tests are installed
* </tr>
* <tr>
* <td> output
* <td> full path to the directory in which log files should be written
* </tr>
* <tr>
* <td> http_path
* <td> location on an http server in which test files are installed
* </tr>
* </table>
*
* @see RhinoDrv
* @author christine@netscape.com
*/
public class NavDrv extends com.netscape.javascript.qa.drivers.TestDriver {
JSObject window;
String SUFFIX = ".html";
public NavDrv() {
super(null);
System.out.println( "constructor");
setSuffix(".html");
}
public static void main ( String[] args ) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
System.out.println( "main" );
NavDrv d = new NavDrv();
d.start();
}
public boolean processOptions( ) {
System.out.println( "NavDrv.processOptions()" );
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
window = (JSObject) JSObject.getWindow( this );
// Get parameters
String d = getParameter("directory");
String o = getParameter("output");
HTTP_PATH = getParameter("http_path");
TEST_DIRECTORY = new File( d );
OUTPUT_DIRECTORY = new File( o );
System.out.println( "http_path: " + HTTP_PATH );
System.out.println( "directory: " + TEST_DIRECTORY );
System.out.println( "output: " + OUTPUT_DIRECTORY );
if ( ! TEST_DIRECTORY.isDirectory() ) {
System.err.println( "error: " +
TEST_DIRECTORY.getAbsolutePath() +" is not a directory." );
return false;
}
if ( ! OUTPUT_DIRECTORY.isDirectory() ) {
System.err.println( "error: " +
OUTPUT_DIRECTORY.getAbsolutePath() +" is not a directory." );
return false;
}
return true;
}
public static void openLogFiles( File o ) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
TestDriver.openLogFiles( o );
}
public Vector getSuites( String[] files ) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
return ( super.getSuites( files ));
}
public void getCases( TestSuite suite ) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
super.getCases( suite );
}
public static TestLog getLog(File output, String filename ) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
return TestDriver.getLog( output, filename );
}
public void writeLogHeaders( File output ) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
super.writeLogHeaders( output );
}
public static void writeSuiteResult( TestSuite suite, File output) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
TestDriver.writeSuiteResult( suite, output );
}
public static void writeSuiteSummary( TestSuite suite, File output) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
TestDriver.writeSuiteSummary( suite, output );
}
public static void writeFileResult( TestFile file, TestSuite suite, File output) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
TestDriver.writeFileResult( file, suite, output );
}
public static void writeCaseResults( TestFile file, TestSuite suite, File output) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
TestDriver.writeCaseResults( file, suite, output );
}
public static void writeDateToLogs( String separator, File output) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
TestDriver.writeDateToLogs( separator, output);
}
public synchronized void executeSuite( TestSuite suite ) {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
NavEnv context;
TestFile file;
for ( int i = 0; i < suite.size(); i++ ) {
synchronized ( suite ) {
file = (TestFile) suite.elementAt( i );
context = new NavEnv( file, suite, this );
context.runTest();
writeFileResult( file, suite, OUTPUT_DIRECTORY );
writeCaseResults(file, suite, OUTPUT_DIRECTORY );
context.close();
context = null;
if ( ! file.passed ) {
suite.passed = false;
}
}
}
writeSuiteResult( suite, OUTPUT_DIRECTORY );
writeSuiteSummary( suite, OUTPUT_DIRECTORY );
}
public void stop() {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
super.stop();
}
public void start() {
PrivilegeManager.enablePrivilege( "UniversalFileAccess" );
PrivilegeManager.enablePrivilege( "UniversalFileRead" );
PrivilegeManager.enablePrivilege( "UniversalFileWrite" );
PrivilegeManager.enablePrivilege( "UniversalPropertyRead" );
super.start();
}
}

Просмотреть файл

@ -0,0 +1,224 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
import java.io.*;
import netscape.javascript.JSObject;
import com.netscape.javascript.qa.drivers.*;
/**
* TestEnvironment for running JavaScript tests in Navigator. NavDrv uses
* LiveConnect to create Navigator windows in which JavaScript tests are
* opened and evaluated.
*
*
* @see com.netscape.javascript.qa.drivers.NavDrv
*
* @author christine@netscape.com
*
*/
public class NavEnv implements TestEnvironment {
TestFile file;
TestSuite suite;
NavDrv driver;
private JSObject result;
JSObject opener;
JSObject testcases;
JSObject location;
boolean evaluatedSuccessfully = false;
JSObject window;
private String WINDOW_NAME;
/**
* Constructor a new NavEnv.
*/
public NavEnv( TestFile f, TestSuite s, NavDrv d ) {
this.file = f;
this.suite = s;
this.driver =d;
this.opener = (JSObject) JSObject.getWindow( d );
this.window = null;
this.WINDOW_NAME = "js" + getRandomWindowName();
}
/**
* Called by NavDrv to run the current TestFile.
*/
public synchronized void runTest() {
int i = 0;
System.out.println( file.name );
try {
createContext();
file.startTime = driver.getCurrentTime();
System.out.println( i++ );
executeTestFile();
System.out.println( i++ );
if ( evaluatedSuccessfully ) {
System.out.println( i++ );
parseResult();
System.out.println( i++ );
}
file.endTime = driver.getCurrentTime();
} catch ( Exception e ) {
suite.passed = false;
file.passed = false;
file.exception = "file failed with exception: " + e ;
}
}
/**
* Creates a new JavaScript context, in this case a Navigator window, and
* returns the JSObject associated with that window.
*/
public Object createContext() {
System.out.println( "opening window" );
opener.eval( WINDOW_NAME +" = window.open( '', '" + WINDOW_NAME + "' )" );
window = (JSObject) opener.getMember( WINDOW_NAME );
return window;
}
/**
* Open the current TestFile in the window by using LiveConnect to set the
* window's location.href property to a URL where the TestFile can be
* found.
*/
public Object executeTestFile() {
System.out.println( "executeTestFile()" );
try {
location = (JSObject) window.getMember( "location" );
System.out.println( file.name );
String s = driver.HTTP_PATH + suite.name +"/" + file.name;
location.setMember( "href", driver.HTTP_PATH + suite.name +"/" +
file.name );
evaluatedSuccessfully = waitForCompletion();
} catch ( Exception e ) {
System.err.println( file.name + " failed with exception: " + e );
file.exception = e.toString();
if ( file.name.endsWith( "-n.js" ) ) {
this.file.passed = true;
evaluatedSuccessfully = true;
} else {
this.file.passed = false;
this.suite.passed = false;
evaluatedSuccessfully = false;
}
}
return null;
}
/**
* Checks the value of the variable "completed", which is set by the
* stopTest() function in each test.
*
* If the stopTest() function is not called in 20 seconds, the test
* fails.
*
* Negative tests will still succeed, since the onerror handler should
* call the stopTest() function.
*
*/
public boolean waitForCompletion() {
int counter = 0;
if ( ! window.getMember( "completed" ).toString().equals("true") ) {
while (!window.getMember("completed").toString().equals("true")) {
try {
if ( counter > 20 ) {
file.passed = false;
file.exception += "test failed to complete";
System.out.println( "test failed to complete" );
return false;
}
System.out.println(".");
driver.sleep( 1000 );
counter++;
} catch ( Exception e ) {
System.out.println( "sleep failed: " + e );
return false;
}
}
}
return true;
}
/**
* Use LiveConnect to get the Navigator window's testcases property, which
* is defined in all tests. Parse the testcases array, and create a new
* TestCase object for each TestCase object it finds.
*/
public synchronized boolean parseResult() {
try {
JSObject testcases = (JSObject) window.getMember("testcases");
file.totalCases = ((Number) ((JSObject) testcases).getMember("length")).intValue();
System.out.println( "testcases.length is " + file.totalCases );
for ( int i = 0; i < file.totalCases; i++ ) {
JSObject tc = (JSObject) ((JSObject) testcases).getSlot(i);
TestCase nc = new TestCase(
tc.getMember("passed") == null ? "null" : tc.getMember("passed").toString(),
tc.getMember("name") == null ? "null " : tc.getMember("name").toString(),
tc.getMember("description") == null ? "null " : tc.getMember("description").toString(),
tc.getMember("expect") == null ? "null " : tc.getMember("expect").toString(),
tc.getMember("actual") == null ? "null " : tc.getMember("actual").toString(),
tc.getMember("reason") == null ? "null " : tc.getMember("reason").toString()
);
file.caseVector.addElement( nc );
if ( nc.passed.equals("false") ) {
if ( file.name.endsWith( "-n.js" ) ) {
this.file.passed = true;
} else {
this.file.passed = false;
this.suite.passed = false;
}
}
}
} catch ( Exception e ) {
System.out.println( e );
file.exception = e.toString();
if ( file.name.endsWith( "-n.html" ) ) {
file.passed = true;
} else {
file.passed = false;
suite.passed = false;
}
}
// if the file failed, try to get the file's BUGNUMBER.
if ( this.file.passed == false ) {
try {
this.file.bugnumber = window.getMember("BUGNUMBER").toString();
} catch ( Exception e ) {
// do nothing
}
}
return true;
}
/**
* Close Navigator window.
*/
public void close() {
opener.eval( WINDOW_NAME +".close()" );
opener.eval( "delete " + WINDOW_NAME );
}
/**
* Generate a random window name, so that each test is associated with a
* unique window.
*/
public String getRandomWindowName() {
return (Integer.toString((new Double(Math.random()*100000)).intValue()));
}
}

Просмотреть файл

@ -0,0 +1,158 @@
package com.netscape.javascript.qa.drivers;
import java.io.*;
/**
* This class is simple utility class that is used to run a process
* which expects no user input. ObserverdTask stores the exit status of
* the process along with standard output and error.
*
* This class is used by the harness only when testing the C version
* of the JavaScript Engine. It is not used by Rhino (JavaScript in
* Java).
*
* @author christine@netscape.com
* @author Nick Lerissa
*/
public class ObservedTask {
public String commandLine;
public StringBuffer input = new StringBuffer();
public StringBuffer error = new StringBuffer();
int exitValue;
public Object observer;
public ObservedTask(String cl, Object observer) {
this.commandLine = cl;
this.observer = observer;
}
public StringBuffer getInput() {
return input;
}
public StringBuffer getError() {
return error;
}
int getExitValue() {
return exitValue;
}
/**
* Execute the process and return when the process is complete.
*
*/
public void exec() throws IOException {
Runtime rt = Runtime.getRuntime();
try {
Process proc = rt.exec(commandLine);
OutputStream os = rt.getLocalizedOutputStream(proc.getOutputStream());
if ( this.observer instanceof RefEnv ) {
os.write("quit();\n".getBytes());
}
os.flush();
os.close();
InputStreamReader is;
is = new InputStreamReader(proc.getErrorStream());
(new Thread(new StreamReader(error,is))).start();
is = new InputStreamReader(proc.getInputStream());
(new Thread(new StreamReader(input,is))).start();
proc.waitFor();
exitValue = proc.exitValue();
// unfortunately the following pause seems to
// need to be here otherwise we get a crash
// On AIX, Process.waitFor() doesn't seem to wait for
// the process to complete before continuing. Bad.
// Need to find a workaround.
if ( System.getProperty("os.name").startsWith("AIX") ||
System.getProperty("os.name").startsWith("HP") ) {
pause(20000);
} else {
pause( 10000 );
}
} catch ( Exception e ) {
java.lang.System.out.println( e );
e.printStackTrace();
}
}
/**
* Simple print method used for debugging
*/
public void print() {
System.out.println("Input Stream of Process:");
System.out.println(input);
System.out.println("Error Stream of Process:");
System.out.println(error);
System.out.println("Exit Value of Process: " + exitValue);
}
/**
* Simple pause method used for debugging.
*/
static void pause(int length) {
try {
Thread.currentThread().sleep(length);
} catch (InterruptedException ex) {
System.err.println( ex );
}
}
/**
* main used for debugging.
*/
static public void main(String args[]) {
if (args.length < 1) {
System.err.println("USAGE: java RunIt <command line>");
System.exit(1);
}
try {
ObservedTask task = new ObservedTask(args[0], null);
task.exec();
task.print();
pause(10000);
} catch (Exception e) {
System.err.println("ERROR Exception thrown: " + e);
System.exit(2);
}
}
/**
* A simple class that reads the contents of and InputStreamReader
* This class is used to read the output and error streams of the process.
*/
class StreamReader implements Runnable {
StringBuffer buffer;
InputStreamReader inputStreamReader;
StreamReader(StringBuffer b, InputStreamReader i) {
buffer = b;
inputStreamReader = i;
}
public void run() {
try {
int ch;
while ((ch = inputStreamReader.read()) != -1) {
buffer.append((char) ch);
}
} catch (IOException ex) {
System.err.println("Error IOException thrown " + ex);
ex.printStackTrace();
}
}
}
}

Просмотреть файл

@ -0,0 +1,256 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
import java.util.Vector;
import java.util.Date;
import java.io.*;
import java.applet.Applet;
/**
* TestDriver for running the JavaScript conformance tests against the
* JavaScript engine implemenation in C, A.K.A. js/ref, Monkey.
*
* <p>
*
* For each test program, RefDrv creates a RefEnv. RefEnv in turn calls the
* JavaScript shell executable (jsshell.exe), passing the helper file and the
* test file as arguments.
*
* <p>
*
* RefEnv reads the output of the jsshell process. You must use the <b><tt>
* jsref.js</b></tt> helper file, which formats the printed output of each
* test in a way that RefEnv can parse.
*
* <p> RefEnv expects the following command line options:
<pre>
-c 1 or 0; whether or not to use code coverage
-e Full path to jsshell.exe
-d Path to the directory where the tests are installed
-h Path to the helper file (jsref.js)
-s List of suites to execute (optional)
-o Directory in which log files should be written (optional)
-t
</pre>
* For example, the following command line will run the tests in
* c:\src\ns\js\tests\ecma\Math and c:\src\ns\js\tests\ecma\Number against
* the jsshell executable found in c:\src\js\ref
*
<pre>
java -classpath %CLASSPATH% com.netscape.javascript.qa.drivers.RefDrv
-d c:\src\ns\js\tests\ecma\ -h c:\src\ns\js\tests\ecma\jsref.js
-e c:\src\js\ref\jsshell.exe -s Math Number
</pre>
* @see com.netscape.javascript.qa.drivers.TestDriver
* @see com.netscape.javascript.qa.drivers.RhinoDrv
*
* @author christine@netscape.com
* @author Nick Lerissa
*
*/
public class RefDrv extends TestDriver {
String SUFFIX = ".js";
boolean CODE_COVERAGE = false;
String HELPER_STRING;
/**
* Create a new RefDrv.
*
* @param args the arguments passed to the main method.
*/
public RefDrv( String[] args) {
super( args );
setSuffix( ".js");
}
/**
* RefDrv expects the following options:
<pre>
-e full path to the JavaScript executable
-d directory in which tests are installed
-h path to helper functions file (jsref.js)
-o directory in which log files will be written
-s list of Suites that should be executed
</pre>
*/
public static void main ( String[] args ) {
RefDrv d = new RefDrv( args );
d.start();
}
/**
* Process command line options.
*
* @see com.netscape.javascript.qa.drivers.RhinoDrv#processOptions
*/
public boolean processOptions() {
int length = ARGS.length;
if (ARGS[0].startsWith("-")) {
//XXX need to verify that we at least get valid d and -h options
for (int i=0; i < ARGS.length; i++ ) {
if ( ARGS[i].equals("-d") ) {
p( "-d " );
this.TEST_DIRECTORY = ARGS[i].endsWith(File.separator)
? new File( ARGS[++i] )
: new File( ARGS[++i] + File.separator );
p( "-d " +this.TEST_DIRECTORY );
if ( ! ( this.TEST_DIRECTORY ).isDirectory() ) {
p( "error: " +
this.TEST_DIRECTORY.getAbsolutePath() +
" is not a TEST_DIRECTORY." );
return false;
} else {
continue;
}
}
if ( ARGS[i].equals("-s") ) {
p( "-s ");
FILES = new String[20] ;
for ( int j = ++i, k=0; j < ARGS.length; j++ ) {
if ( ARGS[j].startsWith("-") ){
break;
}
FILES[k++] = ARGS[j];
}
}
if ( ARGS[i].equals("-h") ) {
p( "-h" );
this.HELPER_STRING = new String( ARGS[++i] );
this.HELPER_FUNCTIONS = new File( HELPER_STRING );
if ( ! (this.HELPER_FUNCTIONS ).isFile() ) {
p( "error: "+
this.HELPER_FUNCTIONS.getAbsolutePath()+
" file not found." );
return false;
}
p( "-h " +this.HELPER_FUNCTIONS );
}
if ( ARGS[i].equals("-c")) {
p("-c");
this.CODE_COVERAGE = new Boolean( ARGS[++i] ).booleanValue();
}
if ( ARGS[i].equals("-o") ) {
p( "-o" );
OUTPUT_DIRECTORY = new File(ARGS[++i]+File.separator);
if ( !OUTPUT_DIRECTORY.exists() ||
!OUTPUT_DIRECTORY.isDirectory() )
{
p( "error: "+
OUTPUT_DIRECTORY.getAbsolutePath()+
" is not a directory.");
return false;
}
}
if ( ARGS[i].equals("-p") ) {
this.OPT_LEVEL = Integer.parseInt( ARGS[++i] );
}
if ( ARGS[i].equals("-db" )) {
this.DEBUG_LEVEL = Integer.parseInt( ARGS[++i] );
this.OPT_LEVEL = 0;
}
if ( ARGS[i].equals("-e")) {
this.EXECUTABLE = ARGS[++i];
}
if ( ARGS[i].equals("-t")) {
String __tinderbox = ARGS[++i];
if ( __tinderbox.equals("true") || __tinderbox.equals("1")){
this.TINDERBOX = true;
} else {
this.TINDERBOX = false;
}
}
}
return true;
} else {
switch ( ARGS.length ) {
case 0:
p( "error: specify location of JavaScript "+
"tests" );
return false;
case 1:
p( "error: specify location of JavaScript "+
"HELPER_FUNCTIONS file" );
return false;
case 2:
this.TEST_DIRECTORY = ARGS[0].endsWith(File.separator)
? new File( ARGS[0] )
: new File( ARGS[0] + File.separator );
this.HELPER_FUNCTIONS = new File( ARGS[1] );
if ( ! ( this.TEST_DIRECTORY ).isDirectory() ) {
p( "error: " +
this.TEST_DIRECTORY.getAbsolutePath() +" is not a directory." );
return false;
}
if ( ! (this.HELPER_FUNCTIONS ).isFile() ) {
p( "error: "+
this.HELPER_FUNCTIONS.getAbsolutePath()+
" file not found." );
return false;
}
return true;
default:
p( "could not understand arguments." );
return false;
}
}
}
/**
* For each TestFile in each TestSuite, create a new RefEnv, run the
* test, parse its results, and close the RefEnv.
*/
public synchronized void executeSuite( TestSuite suite ) {
TestEnvironment context;
TestFile file;
p("executing suite" );
try {
for ( int i = 0; i < suite.size(); i++ ) {
synchronized ( suite ) {
file = (TestFile) suite.elementAt( i );
if ( getSystemInformation()[0].startsWith( "Mac" )) {
context = new MacRefEnv( file, suite, this );
((MacRefEnv) context).runTest();
} else {
context = new RefEnv( file, suite, this );
((RefEnv) context).runTest();
}
}
writeFileResult( file, suite, OUTPUT_DIRECTORY );
writeCaseResults(file, suite, OUTPUT_DIRECTORY );
context.close();
context = null;
if ( ! file.passed ) {
suite.passed = false;
}
}
} catch ( Exception e ) {
e.printStackTrace() ;
}
writeSuiteResult( suite, OUTPUT_DIRECTORY );
writeSuiteSummary( suite, OUTPUT_DIRECTORY );
}
}

Просмотреть файл

@ -0,0 +1,295 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
import java.io.*;
import java.util.StringTokenizer;
/**
* RefEnv is used to run a JavaScript test in the JavaScript engine
* implemented in C. RefEnv creates a new ObservedTask and processes
* the standard output and standard error of the tests to determine the
* test result. The RefDrv expects the process output to contain the
* following content:
*
* <p>
* 1 - anything (before the formatted output can be unstructured.
*
* <p>
*
* 2 - the number of test cases output in the following way.
* <pre>
* <#TEST CASES SIZE>
* int
* </pre>
*
* 3 - the results of each test formatted in the following way
* (name, expected, actual, description, and reason can all be multilines)
* <pre>
* <#TEST CASE PASSED>
* true|false
* <#TEST CASE NAME>
* text
* <#TEST CASE EXPECTED>
* text
* <#TEST CASE ACTUAL>
* text
* <#TEST CASE DESCRIPTION>
* text
* <#TEST CASE REASON>
* text
* <#TEST CASE BUGNUMBER>
* text
* </pre>
*
* 4 - a marker that signifies the end of the tests
*
* <pre>
* <#TEST CASES DONE>
* </pre>
* 5 - after the end of the tests you can have more unstructed text.
* <p>
* The test case output is generated by the stopTest function, which is in
* the shared functions file, jsref.js.
*
* @see com.netscape.javascript.qa.drivers.TestEnvironment
* @see ObservedTask
*
* @author christine@netscape.com
* @author Nick Lerissa
*/
public class RefEnv implements TestEnvironment {
TestFile file;
TestSuite suite;
RefDrv driver;
ObservedTask task;
/**
* Create a new RefEnv.
*/
public RefEnv( TestFile f, TestSuite s, RefDrv d) {
this.file = f;
this.suite = s;
this.driver = d;
}
/**
* Called by the driver to execute the test program.
*/
public void runTest() {
driver.p( file.name );
try {
file.startTime = driver.getCurrentTime();
createContext();
executeTestFile();
file.endTime = driver.getCurrentTime();
if (task.getExitValue() != 0) {
if ( file.name.endsWith( "-n.js" )) {
file.passed = true;
} else {
suite.passed = false;
file.passed = false;
}
}
if ( ! parseResult() ) {
if ( file.name.endsWith( "-n.js" ) ) {
file.passed = true;
} else {
suite.passed = false;
file.passed = false;
}
file.exception = new String(task.getError());
}
} catch ( Exception e ) {
suite.passed = false;
file.passed = false;
file.exception = "Unknown process exception.";
/*
file.exception = new String(task.getError())
+ " exit value: " + task.getExitValue()
+ "\nThrew Exception:" + e;
*/
}
}
/**
* Instantiate a new JavaScript shell, passing the TestFile as an
* argument.
*
*/
public Object createContext() {
if ( driver.CODE_COVERAGE ) {
String command = "coverage " +
"/SaveMergeData /SaveMergeTextData "+
driver.EXECUTABLE + " -f " +
driver.HELPER_FUNCTIONS.getAbsolutePath() + " -f " +
file.filePath;
System.out.println( "command is " + command );
task = new ObservedTask( command, this );
} else {
task = new ObservedTask( driver.EXECUTABLE + " -f " +
driver.HELPER_FUNCTIONS.getAbsolutePath() + " -f " +
file.filePath, this);
}
return (Object) task;
}
/**
* Start the shell process.
*
*/
public Object executeTestFile() {
try {
task.exec();
} catch ( IOException e ) {
driver.p( e.toString() );
file.exception = e.toString();
e.printStackTrace();
}
return null;
}
/**
* Parse the standard output of the process, and try to create new
* TestCase objects.
*/
public boolean parseResult() {
String line;
int i,j;
BufferedReader br = new BufferedReader(new StringReader(
new String(task.getInput())));
try {
do {
line = br.readLine();
driver.p( line );
if (line == null) {
driver.p("\tERROR: No lines to read");
return false;
}
} while (!line.equals(sizeTag));
if ((line = br.readLine()) == null)
return false;
file.totalCases = Integer.valueOf(line).intValue();
if ((line = br.readLine()) == null) {
driver.p("\tERROR: No lines after " + sizeTag);
return false;
}
} catch (NumberFormatException nfe) {
driver.p("\tERROR: No integer after " + sizeTag);
return false;
} catch ( IOException e ) {
driver.p( "Exception reading process output:" + e.toString() );
file.exception = e.toString();
return false;
}
for ( i = 0; i < file.totalCases; i++) {
String values[] = new String[tags.length];
try {
for ( j = 0; j < tags.length; j++) {
values[j] = null;
if (!line.startsWith(tags[j])) {
driver.p("line didn't start with " + tags[j] +":"+line);
return false;
}
while (((line = br.readLine()) != null) &&
(!(line.startsWith(startTag))))
{
values[j] = (values[j] == null) ? line : (values[j] +
"\n" + line);
}
if (values[j] == null) values[j] = "";
}
if ((line == null) && (i < file.totalCases - 1)) {
driver.p("line == null and " + i + "<" +
(file.totalCases - 1));
return false;
}
} catch ( IOException e ) {
driver.p( "Exception reading process output: " + e );
file.exception = e.toString();
return false;
}
TestCase rt = new TestCase(values[0],values[1],values[4],values[2],
values[3],values[5]);
file.bugnumber = values[6];
file.caseVector.addElement( rt );
if ( rt.passed.equals("false") ) {
if ( file.name.endsWith( "-n.js" ) ) {
this.file.passed = true;
} else {
this.file.passed = false;
this.suite.passed = false;
}
}
}
if ( file.totalCases == 0 ) {
if ( file.name.endsWith( "-n.js" ) ) {
this.file.passed = true;
} else {
this.file.reason = "File contains no testcases. " + this.file.reason;
this.file.passed = false;
this.suite.passed = false;
}
}
return true;
}
/**
* Method required by TestEnvironment; this implemenation does nothing.
*
*/
public void close(){
return;
}
/**
* array of in output file to get attributes of a specific TestCase
*/
public static final String tags[];
/**
* tag to specify the number of TestCases
*/
public static final String sizeTag = "<#TEST CASES SIZE>";
/**
* beginning of a tag
*/
public static final String startTag = "<#TEST CASE";
/**
* end of a tag
*/
public static final String endTag = ">";
/**
* creating of String tags[]
*/
static {
String fields[] = { "PASSED", "NAME", "EXPECTED", "ACTUAL", "DESCRIPTION", "REASON",
"BUGNUMBER" };
tags = new String[fields.length];
for (int i = 0; i < fields.length; ++i) {
tags[i] = startTag + " " + fields[i] + endTag;
}
}
}

Просмотреть файл

@ -0,0 +1,219 @@
/* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
import java.io.File;
import org.mozilla.javascript.*;
/**
RhinoDrv is an application for executing JavaScript tests against the
JavaScript engine implemented in Java.
<p>
The application requires two arguments:
<ul >
<li > the full path to the JavaScript test suite directory
<li > the full path to a file of shared JavaScript functions that
should be evaluated by the JavaScript Context before each
JavaScript test is evaluated. See the file <b>shell.js</b>
included in the test suite.
</ul>
For example:
<pre>
java -classpath /tmp/Rhino/:/tmp/tests COM.netscape.javascript.qa.RhinoDrv
/tmp/tests/ecma/ /tmp/tests/ecma/shell.js
</pre>
<p>
Alternatively, you can specify one or many of the suites by using the
following command-line options:
<pre >
-d Directory in which suites are located
-s Names of suites to execute
-h Name of helper file
-p Optimization level
-o Output directory
-db Debug level
-t Whether or not we're using tinderbox
</pre>
For example:
<pre>
java -classpath $CLASSPATH com.netscape.javascript.qa.drivers.RhinoDrv -d c:\src\ns\js\tests\ecma\ -s Math Number Function -h shell.js -p 2 -db 0
</pre>
@see TestDriver
@author christine@netscape.com
*/
public class RhinoDrv extends TestDriver {
public final String SUFFIX = ".js";
/**
*
*
*/
public RhinoDrv( String[] args) {
super( args );
setSuffix(".js");
}
public static void main ( String[] args ) {
RhinoDrv d = new RhinoDrv( args );
d.start();
}
public boolean processOptions() {
int length = ARGS.length;
if (ARGS[0].startsWith("-")) {
//XXX need to verify that we at least get valid d and -h options
for (int i=0; i < ARGS.length; i++ ) {
if ( ARGS[i].equals("-t")) {
String __tinderbox = ARGS[++i];
if ( __tinderbox.equals("true") || __tinderbox.equals("1")){
TestDriver.TINDERBOX = true;
} else {
TestDriver.TINDERBOX = false;
}
}
if ( ARGS[i].equals("-d") ) {
p( "-d " );
this.TEST_DIRECTORY = ARGS[i].endsWith(File.separator)
? new File( ARGS[++i] )
: new File( ARGS[++i] + File.separator );
p( "-d " +this.TEST_DIRECTORY );
if ( ! ( this.TEST_DIRECTORY ).isDirectory() ) {
System.err.println( "error: " +
this.TEST_DIRECTORY.getAbsolutePath() +" is not a TEST_DIRECTORY." );
return false;
} else {
continue;
}
}
if ( ARGS[i].equals("-s") ) {
p( "-s ");
FILES = new String[20] ;
for ( int j = ++i, k=0; j < ARGS.length; j++ ) {
if ( ARGS[j].startsWith("-") ){
break;
}
FILES[k++] = ARGS[j];
}
}
if ( ARGS[i].equals("-h") ) {
p( "-h" );
this.HELPER_FUNCTIONS = new File( ARGS[++i] );
if ( ! (this.HELPER_FUNCTIONS ).isFile() ) {
System.err.println( "error: "+ this.HELPER_FUNCTIONS.getAbsolutePath()+
" file not found." );
return false;
}
}
if ( ARGS[i].equals("-o") ) {
p( "-o" );
OUTPUT_DIRECTORY = new File(ARGS[++i]+File.separator);
if ( !OUTPUT_DIRECTORY.exists() || !OUTPUT_DIRECTORY.isDirectory() ) {
System.err.println( "error: "+OUTPUT_DIRECTORY.getAbsolutePath()+
" is not a directory.");
return false;
}
}
if ( ARGS[i].equals("-p") ) {
OPT_LEVEL = Integer.parseInt( ARGS[++i] );
}
if ( ARGS[i].equals("-db" )) {
DEBUG_LEVEL = Integer.parseInt( ARGS[++i] );
OPT_LEVEL = 0;
}
if ( ARGS[i].equals("-e")) {
EXECUTABLE = ARGS[++i];
}
}
return true;
} else {
switch ( ARGS.length ) {
case 0:
System.err.println( "error: specify location of JavaScript "+
"tests" );
return false;
case 1:
System.err.println( "error: specify location of JavaScript "+
"HELPER_FUNCTIONS file" );
return false;
case 2:
this.TEST_DIRECTORY = ARGS[0].endsWith(File.separator)
? new File( ARGS[0] )
: new File( ARGS[0] + File.separator );
this.HELPER_FUNCTIONS = new File( ARGS[1] );
if ( ! ( this.TEST_DIRECTORY ).isDirectory() ) {
System.err.println( "error: " +
this.TEST_DIRECTORY.getAbsolutePath() +" is not a directory." );
return false;
}
if ( ! (this.HELPER_FUNCTIONS ).isFile() ) {
System.err.println( "error: "+ this.HELPER_FUNCTIONS.getAbsolutePath()+
" file not found." );
return false;
}
return true;
default:
System.err.println( "could not understand arguments." );
return false;
}
}
}
/**
* For each file in each suite, create a new RhinoEnv.
*/
public synchronized void executeSuite( TestSuite suite ) {
RhinoEnv context;
TestFile file;
for ( int i = 0; i < suite.size(); i++ ) {
synchronized ( suite ) {
file = (TestFile) suite.elementAt( i );
context = new RhinoEnv( file, suite, this );
context.runTest();
writeFileResult( file, suite, OUTPUT_DIRECTORY );
writeCaseResults(file, suite, OUTPUT_DIRECTORY );
context.close();
context = null;
if ( ! file.passed ) {
suite.passed = false;
}
}
}
writeSuiteResult( suite, OUTPUT_DIRECTORY );
writeSuiteSummary( suite, OUTPUT_DIRECTORY );
}
}

Просмотреть файл

@ -0,0 +1,257 @@
package com.netscape.javascript.qa.drivers;
import java.io.*;
import com.netscape.javascript.*;
import org.mozilla.javascript.*;
import org.mozilla.javascript.tools.shell.Main;
/**
This class creates a javax.javascript.Context, which evaluates
the helper and RhinoFile and returns a result.
<p>
If the test throws a Java exception or JavaScript runtime or
compilation error, the RhinoFile fails, and the exception is stored
in that RhinoFile's exception variable.
<p>
If the test succeeds, the result is parsed and the RhinoFile's test
result variables are populated.
@author christine@netscape.com
*/
public class RhinoEnv implements TestEnvironment {
public Main global;
Object cx;
Object result;
TestDriver driver;
TestSuite suite;
TestFile file;
/**
@param f RhinoFile that will be executed in this RhinoEnv
@param s the RhinoFile's test suite
@param d the RhinoDrv applet that created this RhinoEnv
*/
public RhinoEnv( TestFile f, TestSuite s, TestDriver d) {
this.file = f;
this.suite = s;
this.driver = d;
}
/**
Creates the JavaScript Context, which evaluates the contents of a
RhinoFile and returns a result. The RhinoEnv parses the test
result, and sets values of the RhinoFile test result properties.
@see com.netscape.javascript.Context#setOptimizationLevel
@see com.netscape.javascript.Context#setDebugLevel
*/
public synchronized void runTest() {
this.driver.p( file.name );
try {
cx = createContext();
((Context) cx).setOptimizationLevel( driver.OPT_LEVEL );
((Context) cx).setDebugLevel( driver.DEBUG_LEVEL );
Object loadFn = executeTestFile(driver.HELPER_FUNCTIONS.getAbsolutePath());
file.startTime = driver.getCurrentTime();
result = executeTestFile( file.filePath );
file.endTime = driver.getCurrentTime();
parseResult();
} catch ( Exception e ) {
suite.passed = false;
file.passed = false;
file.exception += "file failed with exception: " + e ;
}
}
/**
* Create a new com.netscape.javascript.Context.
*
* @return the newly instantiated Context
*
*/
public Object createContext() {
// this is stolen from Main.java
cx = new Context();
((Context) cx).enter();
global = new Main();
((Context) cx).initStandardObjects(global);
String[] names = { "print", "quit", "version", "load", "help",
"loadClass" };
try {
global.defineFunctionProperties(names, Main.class,
ScriptableObject.DONTENUM);
} catch (PropertyException e) {
throw new Error(e.getMessage());
}
return cx;
}
public Object executeTestFile() {
return null;
}
/**
Given a filename, evaluate the file's contents as a JavaScript
program. Return the value of the program. If the test throws
a Java exception or JavaScript runtime or compilation error,
return the string value of the error message.
@param s full path to the file that will be exectued.
@return test result object. If the test is positive, result
should be an instance of Scriptable. if the test is negative,
the result should be a String, whose value is the message in the
JavaScript error or Java exception.
*/
public Object executeTestFile( String s ) {
// this bit is stolen from Main.java
FileReader in = null;
try {
in = new FileReader( s );
} catch (FileNotFoundException ex) {
driver.p("couldn't open file " + s);
}
Object result = null;
try {
// Here we evalute the entire contents of the file as
// as script. Text is printed only if the print() function
// is called.
// cx.evaluateReader((Scriptable) global, in, args[i], 1, null);
result = ((Scriptable) (((Context) cx).evaluateReader(
(Scriptable) global, (Reader) in, s, 1, null)));
} catch (WrappedException we) {
driver.p("Wrapped Exception: "+
we.getWrappedException().toString());
result = we.getWrappedException().toString();
} catch (Exception jse) {
driver.p("JavaScriptException: " + jse.getMessage());
result = jse.getMessage();
}
return ( result );
}
/**
Evaluates the RhinoFile result. If the result is an instance of
javax.javascript.Scriptable, assume it is a JavaScript Array of
TestCase objects, as described in RhinoDrv.java. For each test case in
the array, add an element to the RhinoFile's test case vector. If all
test cases passed, set the RhinoFile's passed value to true; else set
its passed value to false.
<p>
If the result is not a Scriptable object, the test failed. Set the the
RhinoFile's exception property to the string value of the result.
However, negative tests, which should have a "-n.js" extension, are
expected to fail.
*/
public boolean parseResult() {
FlattenedObject fo = null;
if ( result instanceof Scriptable ) {
fo = new FlattenedObject( (Scriptable) result );
try {
file.totalCases = ((Number) fo.getProperty("length")).intValue();
for ( int i = 0; i < file.totalCases; i++ ) {
Scriptable tc = (Scriptable) ((Scriptable) result).get( i,
(Scriptable) result);
TestCase rt = new TestCase(
getString(tc.get( "passed", tc )),
getString(tc.get( "name", tc )),
getString(tc.get( "description", tc )),
getString(tc.get( "expect", tc )),
getString(tc.get( "actual", tc )),
getString(tc.get( "reason", tc ))
);
file.bugnumber=
(getString(tc.get("bugnumber", tc))).startsWith
("com.netscape.javascript")
? file.bugnumber
: getString(tc.get("bugnumber", tc));
file.caseVector.addElement( rt );
if ( rt.passed.equals("false") ) {
this.file.passed = false;
this.suite.passed = false;
}
}
if ( file.totalCases == 0 ) {
if ( file.name.endsWith( "-n.js" ) ) {
this.file.passed = true;
} else {
this.file.reason = "File contains no testcases. " + this.file.reason;
this.file.passed = false;
this.suite.passed = false;
}
}
} catch ( Exception e ) {
this.file.exception = "Got a Scriptable result, but failed "+
"parsing its arguments. Exception: " + e.toString() +
" Flattened Object is: " + fo.toString();
this.file.passed = false;
this.suite.passed = false;
return false;
}
} else {
// if it's not a scriptable object, test failed. set the file's
// exception to the string value of whatever result we did get.
this.file.exception = result.toString();
// if the file's name ends in "-n", the test expected an error.
if ( file.name.endsWith( "-n.js" ) ) {
this.file.passed = true;
} else {
this.file.passed = false;
this.suite.passed = false;
return false;
}
}
return true;
}
/**
Close the context.
*/
public void close() {
try {
((Context) cx).exit();
} catch ( Exception e ) {
suite.passed = false;
file.passed = false;
file.exception = "file failed with exception: " + e ;
}
}
/**
* Get the JavaScript string associated with a JavaScript object.
*
* @param object a Java identifier for a JavaScript object
* @return the JavaScript string representation of the object
*/
public String getString( Object object ) {
return (((Context) cx).toString( object ));
}
}

Просмотреть файл

@ -0,0 +1,52 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
/**
* Equivalent to the JavaScript TestCase object as described in
* TestDriver.java. For each test case in a TestFile, a TestCase object is
* created and added to the TestFile's caseVector.
*
* @see com.netscape.javascript.qa.drivers.TestDriver
* @see com.netscape.javascript.qa.drivers.TestEnvironment
*
* @author christine@netscape.com
*/
public class TestCase {
public String passed;
public String name;
public String description;
public String expect;
public String actual;
public String reason;
/**
* Create a new TestCase object.
*
* @param passed "true" if the test case passed, otherwise "false"
* @param name label associated with the test case
* @param description string showing what got tested, usually JavaScript
* code
* @param expect string representation of the expected result
* @param actual string representation of the actual result
* @param reason reason for test failure
*
* @see com.netscape.javascript.qa.drivers.TestDriver
* @see com.netscape.javascript.qa.drivers.TestEnvironment
*
*/
public TestCase( String passed, String name, String description,
String expect, String actual, String reason ) {
this.passed = passed;
this.name = name;
this.description = description;
this.expect = expect;
this.actual = actual;
this.reason = reason;
}
}

Просмотреть файл

@ -0,0 +1,907 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
import java.util.Vector;
import java.util.Date;
import java.io.*;
import java.applet.Applet;
/**
* Parent class for JavaScript test drivers. Subclasses run tests against
* the JavaScript engine in C, Java, and its embedding in Navigator.
*
* <p>
*
* The default implementation does nothing, but contains methods that are
* used by all subclasses.
<p>
The JavaScript test suite is extendable. To write a new JavaScript test,
your test program must call a function that returns array of TestCase objects.
The TestCase object is defined in <b>shell.js</b>:
<pre>
function TestCase( n, d, e, a ) {
this.name = n;
this.description = d;
this.expect = e;
this.actual = a;
this.passed = true;
this.reason = "";
this.passed = getTestCaseResult( this.expect, this.actual );
}
</pre>
In your test program you should:
<ul>
<li> Create an array of TestCase objects.
<li> The last function call in your test must return the array of TestCase
objects.
</ul>
To add new test to the suite:
<ul >
<li > Create a subdirectory of the JavaScript test suite directory.
<li > Add tests, which must have the file extension ".js" to this
directory.
</ul>
*/
public class TestDriver extends Applet implements Runnable {
Thread THREAD = null;
String[] SYSTEM;
File TEST_DIRECTORY;
File HELPER_FUNCTIONS;
File OUTPUT_DIRECTORY;
String HTTP_PATH;
String SUFFIX;
int OPT_LEVEL;
int DEBUG_LEVEL;
String[] ARGS;
String EXECUTABLE = null;
Vector SUITES;
String[] FILES;
public static boolean TINDERBOX = false;
public static final boolean DEBUG = true;
public static final boolean TCMS = false;
Runtime RUNTIME;
long FREE_MEMORY;
long TOTAL_MEMORY;
public TestDriver( String[] args ) {
this.ARGS = args;
if ( THREAD == null ) {
THREAD = new Thread(this);
THREAD.start();
}
}
public void run() {
}
public void start() {
this.FILES = null;
this.OUTPUT_DIRECTORY = null;
this.OPT_LEVEL = 0;
this.DEBUG_LEVEL=0;
this.RUNTIME = Runtime.getRuntime();
this.FREE_MEMORY = RUNTIME.freeMemory();
this.TOTAL_MEMORY = RUNTIME.totalMemory();
if ( processOptions() ) {
openLogFiles( OUTPUT_DIRECTORY == null ? TEST_DIRECTORY :
OUTPUT_DIRECTORY);
writeDateToLogs("<hr>", OUTPUT_DIRECTORY );
writeLogHeaders( OUTPUT_DIRECTORY );
if (FILES == null) {
FILES = TEST_DIRECTORY.list();
}
if ( TestDriver.TINDERBOX ) {
writeTinderboxHeader(EXECUTABLE);
}
SUITES = getSuites( FILES );
for ( int i = 0; i < SUITES.size(); i++ ) {
getCases((TestSuite) SUITES.elementAt(i));
}
for ( int i = 0; i < SUITES.size(); i++ ) {
if (TestDriver.TINDERBOX) {
writeTinderboxSuiteName((TestSuite) SUITES.elementAt(i));
}
executeSuite((TestSuite) SUITES.elementAt(i));
if (TestDriver.TINDERBOX) {
writeTinderboxSuiteResult((TestSuite) SUITES.elementAt(i));
}
RUNTIME.gc();
}
}
stop();
}
/**
* Close all logs.
*/
public void stop() {
closeLogs();
RUNTIME.gc();
long NEW_FREE_MEMORY = RUNTIME.freeMemory();
long NEW_TOTAL_MEMORY = RUNTIME.totalMemory();
String string = "<tt>"+
"Free Memory " + NEW_FREE_MEMORY + "\n<br>"+
"Total Memory " + NEW_TOTAL_MEMORY +"\n<br>"+
"Free Leaked " + (FREE_MEMORY - NEW_FREE_MEMORY) +"\n<br>"+
"Total Leaked " + (TOTAL_MEMORY- NEW_TOTAL_MEMORY) +"\n<br>"+
"</tt>";
p( string );
p("done!");
if ( THREAD != null ) {
THREAD.stop();
THREAD = null;
}
}
public void closeLogs() {
writeDateToLogs( "", OUTPUT_DIRECTORY );
getLog( OUTPUT_DIRECTORY, SUMMARY_LOG_NAME ).closeLog();
getLog( OUTPUT_DIRECTORY, SUITE_LOG_NAME ).closeLog();
getLog( OUTPUT_DIRECTORY, FILE_LOG_NAME).closeLog();
getLog( OUTPUT_DIRECTORY, CASE_LOG_NAME).closeLog();
if ( DEBUG ) {
getLog( OUTPUT_DIRECTORY, DEBUG_LOG_NAME ).closeLog();
}
}
/**
* Get information about the operating system.
*/
public static String[] getSystemInformation() {
String [] SYSTEM = { System.getProperty( "os.name" ),
System.getProperty( "os.arch" ),
System.getProperty( "os.version" ) };
return SYSTEM;
}
/**
*
*
* @return a file object with the specified in the output directory.
*/
public static TestLog getLog(File output, String filename ) {
enablePrivileges();
TestLog log = null;
String[] SYSTEM = getSystemInformation();
// String platform = ( SYSTEM[0].length() < 4 ) ? SYSTEM[0] : SYSTEM[0].substring(0,4);
String platform = SYSTEM[0];
try {
File logdir = new File(
output.getAbsolutePath() +
(output.getAbsolutePath().endsWith(File.separator) ? "" : File.separator) +
platform +
SYSTEM[1] +"-"+ SYSTEM[2],
getCurrentDate("_") );
logdir.mkdirs();
log = new TestLog( logdir.getAbsolutePath() + File.separator +
filename, TERMINATOR );
} catch ( Exception e ) {
p( "TestDriver.getLog threw " + e.toString() );
p( "platform " + platform );
p( "output" + output.toString() );
p( "filename " + filename.toString() );
p( "File.separator " + File.separator.toString() );
p( "SYSTEM[0] " + SYSTEM[0] );
p( "SYSTEM[1] " + SYSTEM[1] );
p( "SYSTEM[2] " + SYSTEM[2] );
p( "date " +getCurrentDate("_") );
e.printStackTrace();
}
return log;
}
/**
* Create and write headers to log files.
*
* @param output directory in which output files are written.
*/
public static void openLogFiles( File output ) {
enablePrivileges();
TestLog SUMMARY_LOG = getLog( output, SUMMARY_LOG_NAME );
TestLog FILE_LOG = getLog( output, FILE_LOG_NAME );
TestLog SUITE_LOG = getLog( output, SUITE_LOG_NAME );
TestLog CASE_LOG = getLog( output, CASE_LOG_NAME );
if ( DEBUG ) {
TestLog DEBUG_LOG = getLog( output, DEBUG_LOG_NAME );
}
return;
}
public void writeLogHeaders( File output ) {
String header = "<table>"+
"<tr><th>Test Driver <td>" + this.getClass().toString() +"</tr>" +
"<tr><th>Output Directory <td>" + OUTPUT_DIRECTORY +"</tr>" +
( EXECUTABLE == null
? "<tr><th>OptLevel <td>" + OPT_LEVEL +"</tr>" +
"<tr><th>DebugLevel <td>" + DEBUG_LEVEL+"</tr>"
: "<tr><th>Executable <td>" + EXECUTABLE +"</tr>"
) +
"<tr><th>Java Version <td>" + System.getProperty("java.vendor")+
" "+ System.getProperty( "java.version" ) +"</tr>"+
"<tr><th>Test File Directory <td>" + TEST_DIRECTORY +"</tr>"+
"<tr><th>Helper Functions <td>" + HELPER_FUNCTIONS +"</tr>"+
"<tr><th>Free Memory <td>" + FREE_MEMORY +"</tr>"+
"<tr><th>Total JVM Memory <td>" + TOTAL_MEMORY +"</tr>"+
"</table>";
getLog( OUTPUT_DIRECTORY, SUITE_LOG_NAME ).writeLine( header );
getLog( OUTPUT_DIRECTORY, CASE_LOG_NAME ).writeLine( header );
getLog( OUTPUT_DIRECTORY, FILE_LOG_NAME ).writeLine( header );
getLog( OUTPUT_DIRECTORY, SUMMARY_LOG_NAME ).writeLine( header );
getLog( OUTPUT_DIRECTORY, SUMMARY_LOG_NAME ).writeLine(
"<table width=100%>" +
"<tr bgColor=#ffffcc >" +
"<th rowspan=2 width=15%> Suite" +
"<th rowspan=2 width=20%> Files" +
"<th rowspan=2 width=10%> Cases" +
"<th colspan=2 width=20% > Passed" +
"<th colspan=2 width=20%> Failed" +
"<th rowspan=2 width=15%> Result" +
"</tr>" +
"<tr>" +
"<th width=10%> #" +
"<th width=10%> %" +
"<th width=10%> #" +
"<th width=10%> %" +
"</tr></table>" );
return;
}
/**
* For each subdirectory of the main test directory, create a new
* TestSuite object.
*/
public Vector getSuites( String[] files ) {
Vector suites = new Vector();
for ( int i = 0; i < files.length; i++ ) {
String filename = stripDoubleSlashes( TEST_DIRECTORY +
File.separator + files[i] );
File fileobject = new File( filename );
if ( fileobject.isDirectory() ) {
TestSuite s = new TestSuite( fileobject.getName(),
filename );
suites.addElement( s );
}
}
return suites;
}
/**
* If two slashes in a row are found, one slash is stripped out.
* Mac client has trouble if we don't do this.
* xxx this doesn't work and needs to be fixed.
*/
public static String stripDoubleSlashes( String string ) {
StringBuffer buffer = new StringBuffer();
for ( int letter = 0; letter < string.length(); letter++ ) {
char current_char = string.charAt(letter);
if ( current_char != File.separatorChar ) {
buffer.append(current_char);
} else {
while ( string.charAt(++letter) ==
File.separatorChar )
{
;
}
// only add one slash
buffer.append( File.separatorChar );
--letter;
}
}
/*
if ((new Character(string.charAt(letter))).toString().equals("/")){
if (!(new Character(
string.charAt(letter+1))).toString().equals("/"))
{
// only got one, leave it alone
buffer.append( string.charAt( letter ) );
}
} else {
buffer.append( string.charAt( letter ) );
}
*/
return buffer.toString();
}
/**
* For each test file in the suite directory, create a TestFile object.
*
*/
public void getCases( TestSuite suite ) {
enablePrivileges();
File dir = new File ( suite.filePath );
String[] files = dir.list();
for ( int i = 0; i < files.length; i++ ) {
TestFile item = new TestFile( files[i],
suite.filePath + File.separator+ files[i] );
if ( item.isFile()
&& (item.getName().toLowerCase()).endsWith(getSuffix())
&& (!item.isDirectory()) ) {
suite.addElement(item);
p( item +"" );
}
}
}
/**
* Subclasses should override this method to iterate through all TestFiles
* in the TestSuite, create a new TestEnvironment, run the test, and close
* the TestEnvironment.
*
* For examples,
* @see com.netscape.javascript.qa.drivers.RhinoDrv and
* @see com.netscape.javascript.qa.drivers.RefDrv
*/
public synchronized void executeSuite( TestSuite suite ) {
}
/**
* If the environment uses a Security Manager and requires privileges to
* access system properties, override this method to enable privileges.
* The default method does nothing.
*
*/
public static void enablePrivileges() {
}
/*
* Begin functions that write to logs
*
* These methods are static so that LiveConnectTest objects can call them
* directly.
*
*/
/**
* Write the suite result to the Tinderbox log.
*
*
* XXX need machine, branch, startTime, endTime
*/
public void writeTinderboxHeader( String executable ) {
String dottedLine =
"--------------------------------------------------------------";
String product = ( executable == null ) ? "ns/js/rhino" : "ns/js/ref";
String osInfo = System.getProperty( "os.name" ) +" " +
System.getProperty( "os.arch" ) +" " +
System.getProperty( "os.version" );
String javaInfo=System.getProperty( "java.vendor" ) +" "+
System.getProperty( "java.version" );
// Create the log string;
System.out.println( dottedLine );
System.out.println( "Product " + product );
// System.out.println( "Machine " + machine );
System.out.println( "Operating System " + osInfo );
System.out.println( "Java Version " + javaInfo);
System.out.println( "Free Memory " + FREE_MEMORY );
System.out.println( "Total JVM Memory " + TOTAL_MEMORY );
System.out.println( "Test Driver " + this.getClass().getName());
System.out.println( "Output Directory " + OUTPUT_DIRECTORY );
System.out.println( "Path to Executable " + EXECUTABLE );
if ( product.equals( "ns/js/rhino" ) ){
System.out.println( "Optimization Level " + OPT_LEVEL );
System.out.println( "Debug level " + DEBUG_LEVEL );
}
System.out.println( "Test Directory " + TEST_DIRECTORY );
System.out.println( dottedLine );
}
public void writeTinderboxSuiteName( TestSuite suite ) {
System.out.println( "Suite " + suite.name );
}
public void writeTinderboxSuiteResult( TestSuite suite ) {
String dottedLine =
"--------------------------------------------------------------";
System.out.println( "Result " + ( suite.passed
? "PASSED" : "FAILED"));
if ( ! suite.passed ) {
System.out.println( "Failed Files " );
for ( int i = 0; i < suite.size(); i++ ) {
TestFile file = (TestFile) suite.elementAt(i);
if ( ! file.passed ) {
System.out.println( file.name +
(file.bugnumber.equals("") ? "" :
" http://scopus.mcom.com/bugsplat/show_bug.cgi?id="+
file.bugnumber +" "));
}
}
}
System.out.println( dottedLine );
}
/**
* Write an HTML-formatted string to SUITE_LOG.
*/
public static void writeSuiteResult( TestSuite suite, File output ) {
if ( ! (suite.size() > 0) ) {
return;
}
String buffer = "";
buffer += ( "<tt>" +
( suite.passed
? "<font color=#00dd00>passed</font>"
: "<font color=#dd0000>FAILED</font>"
) +
"&nbsp;" +
"<a href='./../../" + suite.name +"'>"+
suite.name +"</a></b>" );
if ( ! suite.passed ) {
for ( int i = 0; i < suite.size(); i++ ) {
TestFile file = (TestFile) suite.elementAt(i);
if ( ! file.passed ) {
buffer += ( "&nbsp;" +
"<a href='case.html#"+ suite.name +"-"+ file.name + "'>" +
file.name + "</a>" );
if ( ! file.bugnumber.equals("") ) {
buffer += ( "&nbsp;"+
"(<a href='http://scopus.mcom.com/bugsplat/show_bug.cgi?id="+
file.bugnumber+"'>"+file.bugnumber+"</a>)" );
}
}
}
}
buffer += ( "</tt><br >" );
getLog( output, SUITE_LOG_NAME).writeLine( buffer.toString() );
}
/**
* Write an HTML-formatted string to the SUMMARY_LOG that looks like
* this:
* <pre >
* Suite Number of Number of Passed Failed Result
* Name Files Cases # % # %
*
* </pre>
*/
public static void writeSuiteSummary( TestSuite suite, File output ) {
if ( ! (suite.size() > 0) ) {
return;
}
String buffer = "";
p( "total :"+ suite.totalCases );
p("passed :"+ suite.casesPassed );
p("failed :"+ suite.casesFailed );
double percentPassed = Math.round((double) suite.casesPassed /
(double) suite.totalCases * 10000)/100 ;
double percentFailed = Math.round((double) suite.casesFailed /
(double) suite.totalCases * 10000)/100 ;
buffer += ( "<table width=100%>" );
buffer += ( "<th bgcolor=#ffffcc width=15%>" +
suite.name );
buffer += ( "<th width=15% bgcolor=#ffffcc >" + suite.size() +
"<th width=10% bgcolor=#ffffcc >" + suite.totalCases +
"<th width=10% bgcolor=#ffffcc >" + suite.casesPassed +
"<th width=10% bgcolor=#ffffcc >" + percentPassed +
"<th width=10% bgcolor=#ffffcc >" + suite.casesFailed +
"<th width=10% bgcolor=#ffffcc >" + percentFailed +
"<th width=15% bgcolor=#ffffcc >" +
( ( suite.passed == true )
? "<font color=#006600 >PASSED</font >"
: "<font color=#990000 >FAILED</font >"
) + "</tr></table>" );
for ( int i = 0; i < suite.size(); i++ ) {
TestFile file= ((TestFile) suite.elementAt(i));
double pPassed = 0;
double pFailed = 0;
if ( file.totalCases > 0 ) {
pPassed = (Math.round((double) file.casesPassed /
(double) file.totalCases * 10000))/100 ;
pFailed = (Math.round((double) file.casesFailed /
(double) file.totalCases * 10000))/100 ;
}
buffer += ( "<table width=100%>" +
"<tr>" +
"<td width=15%>" +
"<td width=15% ><a href='case.html#"+ suite.name +
"-"+ file.name + "'>" + file.name + "</a>" +
"<td width=10%>" + file.totalCases +
"<td width=10% bgColor=#ccffcc >" + file.casesPassed +
"<td width=10% bgColor=#ccffcc >" + pPassed +
"<td width=10% bgColor=#ffcccc >" + file.casesFailed +
"<td width=10% bgColor=#ffcccc >" + pFailed +
"<td width=15%>" +
( ( file.passed == true )
? "<font color=#006600 >PASSED</font >"
: "<font color=#990000 >FAILED</font >"
) +
( ( file.reason.equals("") )
? ""
: ": "+ file.reason
) +
( ( file.exception.equals("") )
? ""
: ":<br>"+ file.exception
) +
"<tr ></table>" );
}
getLog( output, SUMMARY_LOG_NAME ).writeLine( buffer.toString() );
}
/**
* Write the result of the current file to the FILE_LOG.
* If the file threw an exception, print the exception.
*
*/
public static void writeFileResult( TestFile file, TestSuite suite, File output ) {
String suitename = ( suite == null ) ? "" : suite.name;
if ( !file.passed ) {
String buffer = "";
buffer += ( "<tt ><font color=" +
( (file.passed )
? "#00dd00>PASSED</font>&nbsp;"
: "#dd0000>FAILED</font>&nbsp;" ) +
"<a href='case.html#" + suitename +"-"+ file.name + "'>" +
suitename+" "+file.name + "</a > " +
file.exception + "\n" );
if ( ! file.bugnumber.equals("") ) {
buffer += ( "&nbsp;"+
"(<a href='http://scopus.mcom.com/bugsplat/show_bug.cgi?id="+
file.bugnumber+"'>"+file.bugnumber+"</a>)" );
}
getLog( output, FILE_LOG_NAME ).writeLine( buffer.toString() );
}
}
/**
* Read the contents of a file into a string.
*/
public static String readFile( String filePath ) {
File jsFile = new File( filePath );
int length = new Long( jsFile.length()).intValue();
byte[] b = new byte[length];
StringBuffer contents = new StringBuffer();
try {
FileInputStream fis = new FileInputStream( jsFile );
int read = fis.read( b );
contents.append( new String( b ) );
} catch ( Exception e ) {
p( e.toString() );
}
return ( contents.toString() );
}
/**
Test Case Management System (TCMS) requires the following
information:
(MachineID), -pass- or *FAIL*, TestFileName/Beaker,
TestFileName,Date Run in MM/DD/YY, Start Time HH:MM:SS,
End Time HH:MM:SS, ExpectedResults String
(quite often null), Actual Result String, Reason For Failure
Tests can provide this information. we expected it to be
in an object called "TestCase" with the following structure:
<pre >
function TestCase( passed, name, expect, actual, reason ) {
this.passed = passed;
this.name = "Description of the Test Case";
this.expect = ( theExpectedResult );
this.actual = ( theActualResult );
this.reason = ( reasonForFailure );
}
</pre >
we will generate machineID, pass/fail, date run, start time,
end time.
If TCMS == false, omit unnecessary log id.
*/
public static void writeCaseResults( TestFile file, TestSuite suite,
File output )
{
suite.totalCases += file.totalCases;
String[] SYSTEM = getSystemInformation();
String buffer = "";
for ( int i = 0; i < file.caseVector.size(); i++ ) {
TestCase tcase = (TestCase) (file.caseVector.elementAt(i));
// format and write test case results to CASE_LOG
if ( !tcase.passed.equals("true")) {
if ( !file.passed ) {
buffer += ("<a name=" + suite.name +"-"+ file.name +">");
buffer += ("<tt>");
buffer += ( "(" + SYSTEM[0] + "), " );
}
}
if ( tcase.passed.equals("true")) {
if (!file.passed)
buffer += ( "-pass-, " );
suite.casesPassed += 1;
file.casesPassed += 1;
} else {
if (!file.passed)
buffer += ( "*FAIL*, ");
suite.casesFailed += 1;
file.casesFailed += 1;
}
if ( TCMS ) {
buffer += ( tcase.name + "-" + tcase.description + "/Beaker, " +
tcase.name + "-" + tcase.description + ", " +
getCurrentDate("/") + ", " +
file.startTime + ", " +
file.endTime + ", " +
tcase.expect +", " +
tcase.actual +", " +
tcase.reason + "\n" );
} else {
buffer += ( tcase.name +","+
tcase.description +","+
tcase.expect +","+
tcase.actual +","+
tcase.reason +"\n" );
}
if (!tcase.passed.equals("true")) {
buffer += ("</tt><br>\n");
getLog( output, CASE_LOG_NAME ).writeLine( buffer.toString() );
} else {
buffer = "";
}
}
}
/**
* Short version of writing test case results to the CASE_LOG, used by
* LiveConnecTest subclasses.
*
* @param cases vector of testcases whose results should be written
* to the CASE_LOG. LiveConnectTest sends a vector of failed TestCase
* objects.
* @param classname name of the LiveConnectTest class
* @param output directory in which output is written.
*
* @see
* com.netscape.javascript.qa.liveconnect.LiveConnectTest#writeResultsToCaseLog
*
*/
public static void writeCaseResults( TestFile file, String classname,
File output )
{
String[] system = getSystemInformation();
String buffer = "";
for ( int i = 0; i < file.caseVector.size(); i++ ) {
TestCase tcase = (TestCase) (file.caseVector.elementAt(i));
if ( tcase.passed.equals("true")) {
// buffer += ( "-pass-, " );
} else {
buffer += ("<tt>");
buffer += ( "(" + system[0] + "), " );
buffer += ( "*FAIL*, ");
buffer += ( tcase.name +","+
tcase.description +","+
tcase.expect +","+
tcase.actual +","+
tcase.reason +"\n" );
buffer += ("</tt><br>\n");
getLog( output, CASE_LOG_NAME ).writeLine( buffer.toString() );
}
}
}
/**
Write system information and current date to the SUMMARY_LOG,
FILE_LOG, and SUITE_LOG.
XXX need to fix this to output all test information.
*/
public static void writeDateToLogs( String separator, File output ) {
Date today = new Date();
String[] SYSTEM = getSystemInformation();
// long NEW_FREE_MEMORY = RUNTIME.freeMemory();
// long NEW_TOTAL_MEMORY = RUNTIME.totalMemory();
String string = "<tt>"+
// "Free Memory " + NEW_FREE_MEMORY + "\n<br>"+
// "Total Memory " + NEW_TOTAL_MEMORY +"\n<br>"+
// "Free Leaked " + FREE_MEMORY - NEW_FREE_MEMORY +"\n<br>"+
// "Total Leaked " + TOTAL_MEMORY-NEW_TOTAL_MEMORY +"\n<br>"+
"</tt>"+
separator + SYSTEM[0] +" "+ SYSTEM[1] +" "+ SYSTEM[2] +" "+
today.toString();
getLog( output, SUMMARY_LOG_NAME ).writeLine( string );
getLog( output, FILE_LOG_NAME).writeLine( string );
getLog( output, SUITE_LOG_NAME).writeLine( string );
if ( !TCMS ) {
getLog( output, CASE_LOG_NAME ).writeLine( string );
}
}
/**
* Convenience methods.
*/
public static void p( String s ) {
if ( !TestDriver.TINDERBOX ) {
System.out.println( s );
}
}
public static void debug (String s ) {
if ( DEBUG && !TestDriver.TINDERBOX )
System.err.println( s );
}
/**
From the current Date, return a string in the format "DD?MM?YY",
where "/" is specified by the separator argument.
*/
public static String getCurrentDate( String separator ) {
Date today = new Date();
String date = (today.getDate() < 10)
? "0" + String.valueOf( today.getDate() )
: String.valueOf( today.getDate() );
String month = (today.getMonth() + 1 < 10 )
? "0" + String.valueOf( (today.getMonth() +1) )
: String.valueOf( today.getMonth() + 1 );
String year = String.valueOf( today.getYear() );
return ( month + separator + date + separator + year );
}
/**
From the current time, return a string in the format "HH:MM:SS"
*/
public static String getCurrentTime() {
Date now = new Date();
String hours = ( now.getHours() < 10 )
? "0" + String.valueOf( now.getHours() )
: String.valueOf( now.getHours() );
String minutes = ( now.getMinutes() < 10 )
? "0" + String.valueOf( now.getMinutes() )
: String.valueOf( now.getMinutes() );
String seconds = ( now.getSeconds() < 10 )
? "0" + String.valueOf( now.getSeconds() )
: String.valueOf( now.getSeconds() );
String time = hours + ":" + minutes + ":" + seconds;
return ( time );
}
public String getSuffix() {
return SUFFIX;
}
public void setSuffix(String s) {
SUFFIX = s;
}
/**
* Temporary stop this thread for 5 seconds.
*
*/
public boolean sleep(int ms) {
try {
THREAD.sleep( 5000 );
} catch ( Exception e ) {
p( "sleep failed: " + e );
return false;
}
return true;
}
/**
* Implementations need to override this method, which should call
* its own constructor, passing the args object as an argument.
*/
/**
* Process options should parse the ARGS object.
*
* return true if the driver should continue. return false if the driver
* should not continue.
*
*/
public boolean processOptions() {
return false;
}
public static void main ( String[] args ) {
TestDriver d = new TestDriver( args );
d.start();
}
public static final String SUMMARY_LOG_NAME = "summ.html";
public static final String CASE_LOG_NAME = "case.html";
public static final String FILE_LOG_NAME = "file.html";
public static final String SUITE_LOG_NAME = "suite.html";
public static final String DEBUG_LOG_NAME = "debug.html";
public static final String TERMINATOR = "<BR>\n";
}

Просмотреть файл

@ -0,0 +1,62 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
/**
* TestEnvironment creates the JavaScript environment in which the program in
* the TestFile is evaluated. It expects the test result to be a JavaScript
* array of JavaScript TestCase objects. TestEnvironment creates a
* com.netscape.javascript.qa.drivers.TestCase object for each TestCase it
* finds, and populates the TestCase, TestFile, and TestSuite object
* properties.
*
* @see com.netscape.javascript.qa.drivers.TestDriver
* @author christine@netscape.com
*
*/
public interface TestEnvironment {
/**
* Pass the JavaScript program to the JavaScript environment.
*/
public void runTest();
/**
* Create a new JavaScript context in which to evaluate a JavaScript
* program.
*
* @return the JavaScript context
*
*/
public Object createContext();
/**
* Given a filename, evaluate the file's contents as a JavaScript
* program.
*
* @return the return value of the JavaScript program. If the test throws
* a Java exception or JavaScript runtime or compilation error, return the
* string value of the error message.
*/
public Object executeTestFile();
/**
* Evaluate the result of the JavaScript program. Attempt to get the
* JavaScript Array of TestCase objects. For each TestCase object
* found, create a com.netscape.javascript.qa.drivers.TestCase object
* and populate its fields.
*
* @return true if the the result could be parsed successfully; false
* otherwise.
*/
public boolean parseResult();
/**
* Close the context. Destroy the JavaScript environment.
*/
public void close();
}

Просмотреть файл

@ -0,0 +1,65 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
import java.io.*;
import java.util.*;
/**
* For each file found in a test suite directory, the TestDriver creates a
* TestFile object. This object has no methods; it only stores information
* about the program in the file it represents. TestFile fields are populated
* by the TestEnvironment when the program in the TestFile is executed.
*
* @see com.netscape.javascript.qa.drivers.TestDriver
* @see com.netscape.javascript.qa.drivers.TestEnvironment
*
* @author christine@netscape.com
*/
public class TestFile extends File {
public String description;
public String name;
public String filePath;
public boolean passed;
public boolean completed;
public String startTime;
public String endTime;
public String reason;
public String program;
public int totalCases;
public int casesPassed;
public int casesFailed;
public Vector caseVector;
public String exception;
public String bugnumber;
/**
* Create a new TestFile.
*
* @param name name of this test file
* @param filePath full path to this file
*/
public TestFile( String name, String filePath ) {
super( filePath );
this.name = name;
this.filePath = filePath;
this.passed = true;
this.completed = false;
this.startTime = "00:00:00";
this.endTime = "00:00:00";
this.reason = "";
this.program = "";
this.totalCases = 0;
this.casesPassed = 0;
this.casesFailed = 0;
this.caseVector = new Vector();
this.exception = "";
this.bugnumber = "";
}
}

Просмотреть файл

@ -0,0 +1,84 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
//import netscape.security.PrivilegeManager;
import java.io.*;
/**
* Class that writes and appends test result information to a file.
*
* @author christine@netscape.com
*
*/
public class TestLog {
private String name;
private ByteArrayOutputStream outputStream;
private PrintStream printStream;
private String terminator;
/**
* Create a new TestLog and open associated streams.
*
* @param name name of the log file
* @param terminator string that will be appended to the end of each line
*
*
*/
public TestLog ( String name, String terminator ) {
this.name = name;
this.terminator = terminator;
openLog();
}
/**
* Write a string to the end TestLog file.
*/
public void writeLine( String string ) {
if ( printStream != null ) {
printStream.println( string + terminator );
try {
RandomAccessFile raf = new RandomAccessFile( name, "rw" );
raf.seek( raf.length() );
raf.write( outputStream.toByteArray() );
raf.close();
outputStream.reset();
} catch ( Exception e ) {
System.out.println( "Exception writing to "+ name +".writeLine():"+ e );
}
}
}
/**
* Override if privileges are required to write to file system.
* The default implemenation does nothing.
*/
public void enablePrivileges() {
return;
}
/**
* Close print stream associated with the TestLog file.
*/
public void closeLog() {
if ( printStream != null ) {
printStream.close();
}
}
/**
* Create streams associated with this TestLog file.
*/
public void openLog() {
enablePrivileges();
this.outputStream = new ByteArrayOutputStream();
this.printStream = new PrintStream( this.outputStream );
}
public String toString() {
return this.name;
}
}

Просмотреть файл

@ -0,0 +1,47 @@
/* -*- Mode: java; tab-width: 8 -*-
* Copyright © 1997, 1998 Netscape Communications Corporation,
* All Rights Reserved.
*/
package com.netscape.javascript.qa.drivers;
import java.io.*;
import java.util.*;
/**
* For each directory that the TestDriver finds, the TestDriver creates a
* TestSuite object. The TestDriver executes the JavaScript tests it finds
* in that directory, and updates the TestSuite object properties, maintaing
* the total number of test cases, and the number of test cases that have
* failed.
*
* @see com.netscape.javascript.qa.drivers.TestDriver
* @see com.netscape.javascript.qa.drivers.TestEnvironment
*
* @author christine@netscape.com
*/
public class TestSuite extends Vector {
public String name;
public String filePath;
public boolean passed;
public int totalCases;
public int casesPassed;
public int casesFailed;
/**
* Create a new TestSuite object.
*
* @param name name of the TestSuite
* @param filePath full path to TestSuite directory
*/
public TestSuite( String name, String filePath ) {
this.name = name;
this.filePath = filePath;
this.passed = true;
this.totalCases = 0;
this.casesPassed = 0;
this.casesFailed = 0;
}
}