зеркало из https://github.com/mozilla/pjs.git
initial add
This commit is contained in:
Родитель
7065652faa
Коммит
a1985df10f
|
@ -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>"
|
||||
) +
|
||||
" " +
|
||||
"<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 += ( " " +
|
||||
"<a href='case.html#"+ suite.name +"-"+ file.name + "'>" +
|
||||
file.name + "</a>" );
|
||||
|
||||
if ( ! file.bugnumber.equals("") ) {
|
||||
buffer += ( " "+
|
||||
"(<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> "
|
||||
: "#dd0000>FAILED</font> " ) +
|
||||
"<a href='case.html#" + suitename +"-"+ file.name + "'>" +
|
||||
suitename+" "+file.name + "</a > " +
|
||||
file.exception + "\n" );
|
||||
|
||||
if ( ! file.bugnumber.equals("") ) {
|
||||
buffer += ( " "+
|
||||
"(<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;
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче