blob: 87b9cdaffc394adeb87768c1282c7a247894b9ec [file] [log] [blame]
package com.netscape.javascript.qa.drivers;
import java.io.*;
import com.netscape.javascript.*;
import org.mozilla.javascript.*;
import org.mozilla.javascript.tools.shell.*;
/**
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 Global 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 Global();
((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 = shouldBeWithErrorCheck(
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 ));
}
}