зеркало из https://github.com/mozilla/pjs.git
Fix for #353501: Add Java port of jsDriver.pl; catch some additional failure cases in JUnit test driver
This commit is contained in:
Родитель
79721b17ea
Коммит
db0cc5fc09
|
@ -204,7 +204,39 @@ Requires Ant version 1.2 or later
|
|||
<delete quiet="true" file="${dist.file}"/>
|
||||
<delete quiet="true" file="${dist.source-only-zip}"/>
|
||||
</target>
|
||||
|
||||
|
||||
<!--
|
||||
The next two targets run the JavaScript Test Library tests. Note that these tests are quite extensive and take a long time
|
||||
to run. They are not documented in the 'help' target for now.
|
||||
-->
|
||||
|
||||
<!--
|
||||
Run the tests using JUnit. Beware that if you are using Ant from the command-line, there are some difficulties you may
|
||||
encounter setting this up correctly; see http://ant.apache.org/faq.html#delegating-classloader
|
||||
|
||||
IDEs that use Ant as the build system probably handle this fine.
|
||||
-->
|
||||
<target name="junit-all" depends="compile">
|
||||
<ant antfile="testsrc/build.xml" target="junit"/>
|
||||
</target>
|
||||
|
||||
<!--
|
||||
Run the tests using the Java port of jsdriver.pl. Note that running this port from the command-line
|
||||
may be superior, as it allows configuration options, such as running with a non-default optimization level or running only
|
||||
a subset of the tests.
|
||||
-->
|
||||
<target name="jsdriver-all" depends="compile">
|
||||
<ant antfile="testsrc/build.xml" target="jsdriver" />
|
||||
</target>
|
||||
|
||||
<!--
|
||||
Target just for development of the test code.
|
||||
-->
|
||||
<target name="_test-recompile" depends="compile">
|
||||
<ant antfile="testsrc/build.xml" target="clean" />
|
||||
<ant antfile="testsrc/build.xml" target="compile" />
|
||||
</target>
|
||||
|
||||
<target name="help" depends="properties">
|
||||
<echo>The following targets are available with this build file:
|
||||
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="testsrc" basedir="..">
|
||||
<!--
|
||||
Location of mozilla/js/tests directory
|
||||
-->
|
||||
<property name="test.library.dir" location="../tests" />
|
||||
|
||||
<!--
|
||||
Destination to which testing classes should be built
|
||||
-->
|
||||
<property name="test.classes" value="${build.dir}/test/classes" />
|
||||
|
||||
<!--
|
||||
Output directory for HTML files generated by jsdriver
|
||||
-->
|
||||
<property name="test.output" value="${build.dir}/test/output" />
|
||||
|
||||
<!--
|
||||
Timeout in milliseconds for tests
|
||||
-->
|
||||
<property name="test.timeout" value="60000" />
|
||||
|
||||
<!--
|
||||
Maximum heap size for VM executing test cases.
|
||||
-->
|
||||
<property name="test.vm.mx" value="256m" />
|
||||
|
||||
<!--
|
||||
TODO Currently JUnit is required in order to compile the test code, which ought not be necessary
|
||||
-->
|
||||
<target name="compile">
|
||||
<mkdir dir="${test.classes}" />
|
||||
<javac destdir="${test.classes}" debug="true"
|
||||
target="${target-jvm}"
|
||||
source="${source-level}"
|
||||
>
|
||||
<classpath>
|
||||
<pathelement path="${classes}" />
|
||||
</classpath>
|
||||
<src path="testsrc" />
|
||||
</javac>
|
||||
<copy todir="${test.classes}/org/mozilla/javascript">
|
||||
<fileset dir="testsrc/org/mozilla/javascript">
|
||||
<include name="*.html"/>
|
||||
</fileset>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="clean">
|
||||
<delete dir="${test.classes}" />
|
||||
</target>
|
||||
|
||||
<target name="junit" depends="compile">
|
||||
<junit printsummary="on" fork="true" forkmode="once" maxmemory="${test.vm.mx}" showoutput="true">
|
||||
<sysproperty key="mozilla.js.tests" value="${test.library.dir}" />
|
||||
<sysproperty key="mozilla.js.tests.timeout" value="${test.timeout}" />
|
||||
<classpath>
|
||||
<pathelement location="${xbean.jar}"/>
|
||||
<pathelement location="${jsr173.jar}"/>
|
||||
<pathelement path="${classes}" />
|
||||
<pathelement path="${test.classes}" />
|
||||
</classpath>
|
||||
<test name="org.mozilla.javascript.StandardTests" />
|
||||
<formatter type="plain" usefile="false" />
|
||||
</junit>
|
||||
</target>
|
||||
|
||||
<target name="jsdriver" depends="compile">
|
||||
<tstamp>
|
||||
<format property="test.timestamp" pattern="yyyy.MM.dd.HH.mm.ss" />
|
||||
</tstamp>
|
||||
<mkdir dir="${test.output}" />
|
||||
<java
|
||||
fork="true"
|
||||
classname="org.mozilla.javascript.JsDriver"
|
||||
maxmemory="${test.vm.mx}"
|
||||
>
|
||||
<classpath>
|
||||
<pathelement location="${xbean.jar}"/>
|
||||
<pathelement location="${jsr173.jar}"/>
|
||||
<pathelement path="${classes}" />
|
||||
<pathelement path="${test.classes}" />
|
||||
</classpath>
|
||||
<arg value="-p" />
|
||||
<arg file="${test.library.dir}" />
|
||||
<arg value="-f" />
|
||||
<arg value="${test.output}/rhino-test-results.${test.timestamp}.html" />
|
||||
<arg value="--timeout" />
|
||||
<arg value="${test.timeout}" />
|
||||
</java>
|
||||
</target>
|
||||
</project>
|
|
@ -0,0 +1,770 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Java port of jsDriver.pl.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* David P. Caldwell.
|
||||
* Portions created by David P. Caldwell are Copyright (C) 2007 David P. Caldwell
|
||||
*
|
||||
* Contributor(s):
|
||||
* David P. Caldwell <inonit@inonit.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.*;
|
||||
|
||||
import org.w3c.dom.*;
|
||||
|
||||
import org.mozilla.javascript.tools.shell.*;
|
||||
|
||||
public class JsDriver {
|
||||
private JsDriver() {
|
||||
}
|
||||
|
||||
private static String join(String[] list) {
|
||||
String rv = "";
|
||||
for (int i=0; i<list.length; i++) {
|
||||
rv += list[i];
|
||||
if (i+1 != list.length) {
|
||||
rv += ",";
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
private static class Tests {
|
||||
private File testDirectory;
|
||||
private String[] list;
|
||||
private String[] skip;
|
||||
|
||||
Tests(File testDirectory, String[] list, String[] skip, boolean skipRhinoN) {
|
||||
this.testDirectory = testDirectory;
|
||||
this.list = list;
|
||||
ArrayList skips = new ArrayList();
|
||||
skips.addAll(Arrays.asList(skip));
|
||||
if (skipRhinoN) {
|
||||
try {
|
||||
Properties rhinoN = new Properties();
|
||||
rhinoN.load( new FileInputStream( new File(testDirectory, "rhino-n.tests") ) );
|
||||
skips.addAll( rhinoN.keySet() );
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Could not read rhino-n.tests", e);
|
||||
}
|
||||
}
|
||||
this.skip = (String[])skips.toArray(new String[0]);
|
||||
}
|
||||
|
||||
private boolean matches(String[] patterns, String path) {
|
||||
for (int i=0; i<patterns.length; i++) {
|
||||
if (path.startsWith(patterns[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean matches(String path) {
|
||||
if (list.length == 0) return true;
|
||||
return matches(list, path);
|
||||
}
|
||||
|
||||
private boolean excluded(String path) {
|
||||
if (skip.length == 0) return false;
|
||||
return matches(skip, path);
|
||||
}
|
||||
|
||||
private void addFiles(List rv, String prefix, File directory) {
|
||||
File[] files = directory.listFiles();
|
||||
if (files == null) throw new RuntimeException("files null for " + directory);
|
||||
for (int i=0; i<files.length; i++) {
|
||||
String path = prefix + files[i].getName();
|
||||
if (ShellTest.DIRECTORY_FILTER.accept(files[i])) {
|
||||
addFiles(rv, path + "/", files[i]);
|
||||
} else {
|
||||
boolean isTopLevel = prefix.length() == 0;
|
||||
if (ShellTest.TEST_FILTER.accept(files[i]) && matches(path) && !excluded(path) && !isTopLevel) {
|
||||
rv.add(new Script(path, files[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class Script {
|
||||
private String path;
|
||||
private File file;
|
||||
|
||||
Script(String path, File file) {
|
||||
this.path = path;
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
File getFile() {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
|
||||
Script[] getFiles() {
|
||||
ArrayList rv = new ArrayList();
|
||||
addFiles(rv, "", testDirectory);
|
||||
return (Script[])rv.toArray(new Script[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConsoleStatus extends ShellTest.Status {
|
||||
private File jsFile;
|
||||
|
||||
private Arguments.Console console;
|
||||
private boolean trace;
|
||||
|
||||
private boolean failed;
|
||||
|
||||
ConsoleStatus(Arguments.Console console, boolean trace) {
|
||||
this.console = console;
|
||||
this.trace = trace;
|
||||
}
|
||||
|
||||
void running(File jsFile) {
|
||||
try {
|
||||
console.println("Running: " + jsFile.getCanonicalPath());
|
||||
this.jsFile = jsFile;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
void failed(String s) {
|
||||
console.println("Failed: " + jsFile + ": " + s);
|
||||
failed = true;
|
||||
}
|
||||
|
||||
void threw(Throwable t) {
|
||||
console.println("Failed: " + jsFile + " with exception.");
|
||||
console.println(ShellTest.getStackTrace(t));
|
||||
failed = true;
|
||||
}
|
||||
|
||||
void timedOut() {
|
||||
console.println("Failed: " + jsFile + ": timed out.");
|
||||
failed = true;
|
||||
}
|
||||
|
||||
void exitCodesWere(int expected, int actual) {
|
||||
if (expected != actual) {
|
||||
console.println("Failed: " + jsFile + " expected " + expected + " actual " + actual);
|
||||
failed = true;
|
||||
}
|
||||
}
|
||||
|
||||
void outputWas(String s) {
|
||||
if (!failed) {
|
||||
console.println("Passed: " + jsFile);
|
||||
if (trace) {
|
||||
console.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if node was found, false otherwise
|
||||
private static boolean setContent(Element node, String id, String content) {
|
||||
if (node.getAttribute("id").equals(id)) {
|
||||
node.setTextContent(node.getTextContent() + "\n" + content);
|
||||
return true;
|
||||
} else {
|
||||
NodeList children = node.getChildNodes();
|
||||
for (int i=0; i<children.getLength(); i++) {
|
||||
if (children.item(i) instanceof Element) {
|
||||
Element e = (Element)children.item(i);
|
||||
boolean rv = setContent( e, id, content );
|
||||
if (rv) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Element getElementById(Element node, String id) {
|
||||
if (node.getAttribute("id").equals(id)) {
|
||||
return node;
|
||||
} else {
|
||||
NodeList children = node.getChildNodes();
|
||||
for (int i=0; i<children.getLength(); i++) {
|
||||
if (children.item(i) instanceof Element) {
|
||||
Element rv = getElementById( (Element)children.item(i), id );
|
||||
if (rv != null) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class HtmlStatus extends ShellTest.Status {
|
||||
private String testPath;
|
||||
private String bugUrl;
|
||||
private String lxrUrl;
|
||||
private Document html;
|
||||
private Element failureHtml;
|
||||
|
||||
private File file;
|
||||
private boolean failed;
|
||||
|
||||
private String output;
|
||||
|
||||
HtmlStatus(String lxrUrl, String bugUrl, String testPath, Document html, Element failureHtml) {
|
||||
this.testPath = testPath;
|
||||
this.bugUrl = bugUrl;
|
||||
this.lxrUrl = lxrUrl;
|
||||
this.html = html;
|
||||
this.failureHtml = failureHtml;
|
||||
}
|
||||
|
||||
void running(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
void failed(String s) {
|
||||
failed = true;
|
||||
setContent(failureHtml, "failureDetails.reason", "Failure reason: \n" + s);
|
||||
}
|
||||
|
||||
void exitCodesWere(int expected, int actual) {
|
||||
if (expected != actual) {
|
||||
failed = true;
|
||||
setContent(failureHtml, "failureDetails.reason", "expected exit code " + expected + " but got " + actual);
|
||||
}
|
||||
}
|
||||
|
||||
private String newlineLineEndings(String s) {
|
||||
StringBuffer rv = new StringBuffer();
|
||||
for (int i=0; i<s.length(); i++) {
|
||||
if (s.charAt(i) == '\r') {
|
||||
if (i+1<s.length() && s.charAt(i+1) == '\n') {
|
||||
// just skip \r
|
||||
} else {
|
||||
// Macintosh, substitute \n
|
||||
rv.append('\n');
|
||||
}
|
||||
} else {
|
||||
rv.append(s.charAt(i));
|
||||
}
|
||||
}
|
||||
return rv.toString();
|
||||
}
|
||||
|
||||
void threw(Throwable e) {
|
||||
failed = true;
|
||||
setContent(failureHtml, "failureDetails.reason", "Threw Java exception:\n" + newlineLineEndings(ShellTest.getStackTrace(e)));
|
||||
}
|
||||
|
||||
void timedOut() {
|
||||
failed = true;
|
||||
setContent(failureHtml, "failureDetails.reason", "Timed out.");
|
||||
}
|
||||
|
||||
void outputWas(String s) {
|
||||
this.output = s;
|
||||
}
|
||||
|
||||
private String getLinesStartingWith(String prefix) {
|
||||
BufferedReader r = new BufferedReader(new StringReader(output));
|
||||
String line = null;
|
||||
String rv = "";
|
||||
try {
|
||||
while( (line = r.readLine()) != null ) {
|
||||
if (line.startsWith(prefix)) {
|
||||
if (rv.length() > 0) {
|
||||
rv += "\n";
|
||||
}
|
||||
rv += line;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Can't happen.");
|
||||
}
|
||||
}
|
||||
|
||||
boolean failed() {
|
||||
return failed;
|
||||
}
|
||||
|
||||
void finish() {
|
||||
if (failed) {
|
||||
getElementById(failureHtml, "failureDetails.status").setTextContent(getLinesStartingWith("STATUS:"));
|
||||
|
||||
String bn = getLinesStartingWith("BUGNUMBER:");
|
||||
Element bnlink = getElementById(failureHtml, "failureDetails.bug.href");
|
||||
if (bn.length() > 0) {
|
||||
String number = bn.substring("BUGNUMBER: ".length());
|
||||
if (!number.equals("none")) {
|
||||
bnlink.setAttribute("href", bugUrl + number);
|
||||
getElementById(bnlink, "failureDetails.bug.number").setTextContent(number);
|
||||
} else {
|
||||
bnlink.getParentNode().removeChild(bnlink);
|
||||
}
|
||||
} else {
|
||||
bnlink.getParentNode().removeChild(bnlink);
|
||||
}
|
||||
|
||||
getElementById(failureHtml, "failureDetails.lxr").setAttribute("href", lxrUrl + testPath);
|
||||
getElementById(failureHtml, "failureDetails.lxr.text").setTextContent(testPath);
|
||||
|
||||
getElementById(html.getDocumentElement(), "retestList.text").setTextContent(
|
||||
getElementById(html.getDocumentElement(), "retestList.text").getTextContent()
|
||||
+ testPath
|
||||
+ "\n"
|
||||
);
|
||||
|
||||
getElementById(html.getDocumentElement(), "failureDetails").appendChild(failureHtml);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Results {
|
||||
private ShellContextFactory factory;
|
||||
private Arguments arguments;
|
||||
private File output;
|
||||
private boolean trace;
|
||||
|
||||
private Document html;
|
||||
private Element failureHtml;
|
||||
|
||||
private int tests;
|
||||
private int failures;
|
||||
|
||||
private Document parse(InputStream in) {
|
||||
try {
|
||||
javax.xml.parsers.DocumentBuilderFactory factory = javax.xml.parsers.DocumentBuilderFactory.newInstance();
|
||||
factory.setValidating(false);
|
||||
javax.xml.parsers.DocumentBuilder dom = factory.newDocumentBuilder();
|
||||
return dom.parse(in);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException("Parser failure", t);
|
||||
}
|
||||
}
|
||||
|
||||
private Document getTemplate() {
|
||||
return parse(getClass().getResourceAsStream("results.html"));
|
||||
}
|
||||
|
||||
Results(ShellContextFactory factory, Arguments arguments, File output, boolean trace) {
|
||||
this.factory = factory;
|
||||
this.arguments = arguments;
|
||||
this.output = output;
|
||||
this.trace = trace;
|
||||
|
||||
this.html = getTemplate();
|
||||
this.failureHtml = getElementById(html.getDocumentElement(), "failureDetails.prototype");
|
||||
if (this.failureHtml == null) {
|
||||
try {
|
||||
javax.xml.transform.TransformerFactory.newInstance().newTransformer().transform(
|
||||
new javax.xml.transform.dom.DOMSource(html),
|
||||
new javax.xml.transform.stream.StreamResult(System.err)
|
||||
);
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
throw new RuntimeException("No");
|
||||
}
|
||||
this.failureHtml.getParentNode().removeChild(this.failureHtml);
|
||||
}
|
||||
|
||||
private void write(Document template) {
|
||||
try {
|
||||
javax.xml.transform.TransformerFactory.newInstance().newTransformer().transform(
|
||||
new javax.xml.transform.dom.DOMSource(template),
|
||||
new javax.xml.transform.stream.StreamResult( new FileOutputStream(output) )
|
||||
);
|
||||
} catch (IOException e) {
|
||||
arguments.getConsole().println("Could not write results file to " + output + ": ");
|
||||
e.printStackTrace(System.err);
|
||||
} catch (javax.xml.transform.TransformerConfigurationException e) {
|
||||
throw new RuntimeException("Parser failure", e);
|
||||
} catch (javax.xml.transform.TransformerException e) {
|
||||
throw new RuntimeException("Parser failure", e);
|
||||
}
|
||||
}
|
||||
|
||||
void run(String path, File test, ShellTest.Parameters parameters) {
|
||||
ConsoleStatus cStatus = new ConsoleStatus(arguments.getConsole(), trace);
|
||||
HtmlStatus hStatus = new HtmlStatus(arguments.getLxrUrl(), arguments.getBugUrl(), path, html, (Element)failureHtml.cloneNode(true));
|
||||
ShellTest.Status status = ShellTest.Status.compose(cStatus, hStatus);
|
||||
try {
|
||||
ShellTest.run(factory, test, parameters, status);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
tests++;
|
||||
if (hStatus.failed()) {
|
||||
failures++;
|
||||
}
|
||||
hStatus.finish();
|
||||
}
|
||||
|
||||
private void set(Document document, String id, String value) {
|
||||
getElementById(document.getDocumentElement(), id).setTextContent(value);
|
||||
}
|
||||
|
||||
void finish(Date start, Date end) {
|
||||
long elapsedMs = end.getTime() - start.getTime();
|
||||
set(html, "results.testlist", join(arguments.getTestList()));
|
||||
set(html, "results.skiplist", join(arguments.getSkipList()));
|
||||
String pct = new java.text.DecimalFormat("##0.00").format( (double)failures / (double)tests * 100.0 );
|
||||
set(html, "results.results", "Tests attempted: " + tests + " Failures: " + failures + " (" + pct + "%)");
|
||||
set(html, "results.platform", "java.home=" + System.getProperty("java.home")
|
||||
+ "\n" + "java.version=" + System.getProperty("java.version")
|
||||
+ "\n" + "os.name=" + System.getProperty("os.name")
|
||||
);
|
||||
set(html, "results.classpath", System.getProperty("java.class.path").replace(File.pathSeparatorChar, ' '));
|
||||
int elapsedSeconds = (int)(elapsedMs / 1000);
|
||||
int elapsedMinutes = elapsedSeconds / 60;
|
||||
elapsedSeconds = elapsedSeconds % 60;
|
||||
String elapsed = "" + elapsedMinutes + " minutes, " + elapsedSeconds + " seconds";
|
||||
set(html, "results.elapsed", elapsed);
|
||||
set(html, "results.time", new java.text.SimpleDateFormat("MMMM d yyyy h:mm:ss aa").format(new java.util.Date()));
|
||||
write(html);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ShellTestParameters extends ShellTest.Parameters {
|
||||
private int timeout;
|
||||
|
||||
ShellTestParameters(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
int getTimeoutMilliseconds() {
|
||||
return timeout;
|
||||
}
|
||||
}
|
||||
|
||||
void run(Arguments arguments) throws Throwable {
|
||||
// TODO Allow rhino-n tests to be skipped
|
||||
|
||||
if (arguments.help()) {
|
||||
System.out.println("See mozilla/js/tests/README-jsDriver.html; note that some options are not supported.");
|
||||
System.out.println("Consult the Java source code at testsrc/org/mozilla/javascript/JsDriver.java for details.");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
ShellContextFactory factory = new ShellContextFactory();
|
||||
factory.setOptimizationLevel(arguments.getOptimizationLevel());
|
||||
|
||||
File path = arguments.getTestsPath();
|
||||
if (path == null) {
|
||||
path = new File("../tests");
|
||||
}
|
||||
if (!path.exists()) {
|
||||
throw new RuntimeException("JavaScript tests not found at " + path.getCanonicalPath());
|
||||
}
|
||||
Tests tests = new Tests(path, arguments.getTestList(), arguments.getSkipList(), !arguments.ignoreRhinoSkipList());
|
||||
Tests.Script[] all = tests.getFiles();
|
||||
arguments.getConsole().println("Running " + all.length + " tests.");
|
||||
|
||||
File output = new File("rhino-test-results." + new java.text.SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date()) + ".html");
|
||||
if (arguments.getOutputFile() != null) {
|
||||
output = arguments.getOutputFile();
|
||||
}
|
||||
|
||||
Results results = new Results(factory, arguments, output, arguments.trace());
|
||||
Date start = new Date();
|
||||
for (int i=0; i<all.length; i++) {
|
||||
results.run(all[i].getPath(), all[i].getFile(), new ShellTestParameters(arguments.getTimeout()));
|
||||
}
|
||||
Date end = new Date();
|
||||
results.finish(start, end);
|
||||
}
|
||||
|
||||
public static void main(Arguments arguments) throws Throwable {
|
||||
JsDriver driver = new JsDriver();
|
||||
driver.run(arguments);
|
||||
}
|
||||
|
||||
public static abstract class Arguments {
|
||||
// List of jsDriver.pl arguments
|
||||
|
||||
// -b URL, --bugurl=URL
|
||||
public abstract String getBugUrl();
|
||||
|
||||
// -c PATH, --classpath=PATH
|
||||
// Does not apply; we will use the VM's classpath
|
||||
|
||||
// -e TYPE ..., --engine=TYPE ...
|
||||
// Does not apply, but we should provide the ability to test various optimization levels
|
||||
public abstract int getOptimizationLevel();
|
||||
|
||||
// -f FILE, --file=FILE
|
||||
public abstract File getOutputFile();
|
||||
|
||||
// -h, --help
|
||||
public abstract boolean help();
|
||||
|
||||
// -j PATH, --javapath=PATH
|
||||
// Does not apply; we will use this JVM
|
||||
|
||||
// -k, --confail
|
||||
// TODO Currently this is ignored; not clear precisely what it means (perhaps we should not be logging ordinary
|
||||
// pass/fail to the console currently?
|
||||
public abstract boolean logFailuresToConsole();
|
||||
|
||||
// -l FILE ..., --list=FILE ...
|
||||
public abstract String[] getTestList();
|
||||
|
||||
// -L FILE ..., --neglist=FILE ...
|
||||
public abstract String[] getSkipList();
|
||||
|
||||
// -p PATH, --testpath=PATH
|
||||
public abstract File getTestsPath();
|
||||
|
||||
// -s PATH, --shellpath=PATH
|
||||
// Does not apply; we will use the Rhino shell with any classes given on the classpath
|
||||
|
||||
// -t, --trace
|
||||
public abstract boolean trace();
|
||||
|
||||
// -u URL, --lxrurl=URL
|
||||
public abstract String getLxrUrl();
|
||||
|
||||
//
|
||||
// New arguments
|
||||
//
|
||||
|
||||
// --ignore-rhino-n
|
||||
public abstract boolean ignoreRhinoSkipList();
|
||||
|
||||
// --timeoutms
|
||||
public abstract int getTimeout();
|
||||
|
||||
public static abstract class Console {
|
||||
public abstract void print(String message);
|
||||
public abstract void println(String message);
|
||||
}
|
||||
|
||||
public abstract Console getConsole();
|
||||
}
|
||||
|
||||
private static class CommandLineArguments extends Arguments {
|
||||
private ArrayList options = new ArrayList();
|
||||
|
||||
private Option bugUrl = new Option("b", "bugurl", false, false, "http://bugzilla.mozilla.org/show_bug.cgi?id=");
|
||||
private Option optimizationLevel = new Option("o", "optimization", false, false, "-1");
|
||||
private Option outputFile = new Option("f", "file", false, false, null);
|
||||
private Option help = new Option("h", "help", false, true, null);
|
||||
private Option logFailuresToConsole = new Option("k", "confail", false, true, null);
|
||||
private Option testList = new Option("l", "list", true, false, null);
|
||||
private Option skipList = new Option("L", "neglist", true, false, null);
|
||||
private Option testsPath = new Option("p", "testpath", false, false, null);
|
||||
private Option trace = new Option("t", "trace", false, true, null);
|
||||
private Option lxrUrl = new Option("u", "lxrurl", false, false, "http://lxr.mozilla.org/mozilla/source/js/tests/");
|
||||
|
||||
private Option ignoreRhinoN = new Option(null, "ignore-rhino-n", false, true, null);
|
||||
private Option timeout = new Option(null, "timeout", false, false, "60000");
|
||||
|
||||
private Option classpath = new Option("c", "classpath", false, false, null).ignored();
|
||||
private Option engine = new Option("e", "engine", false, false, null).ignored();
|
||||
private Option javapath = new Option("j", "javapath", false, false, null).ignored();
|
||||
private Option shellpath = new Option("s", "shellpath", false, false, null).ignored();
|
||||
|
||||
private Console console = new Console() {
|
||||
public void print(String s) {
|
||||
System.out.print(s);
|
||||
}
|
||||
|
||||
public void println(String s) {
|
||||
System.out.println(s);
|
||||
}
|
||||
};
|
||||
|
||||
private class Option {
|
||||
private String letterOption;
|
||||
private String wordOption;
|
||||
private boolean array;
|
||||
private boolean flag;
|
||||
private boolean ignored;
|
||||
|
||||
private ArrayList values = new ArrayList();
|
||||
|
||||
// array: can this option have multiple values?
|
||||
// flag: is this option a simple true/false switch?
|
||||
Option(String letterOption, String wordOption, boolean array, boolean flag, String unspecified) {
|
||||
this.letterOption = letterOption;
|
||||
this.wordOption = wordOption;
|
||||
this.flag = flag;
|
||||
this.array = array;
|
||||
if (!flag && !array) {
|
||||
this.values.add(unspecified);
|
||||
}
|
||||
options.add(this);
|
||||
}
|
||||
|
||||
Option ignored() {
|
||||
this.ignored = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
int getInt() {
|
||||
return Integer.parseInt( getValue() );
|
||||
}
|
||||
|
||||
String getValue() {
|
||||
return (String)values.get(0);
|
||||
}
|
||||
|
||||
boolean getSwitch() {
|
||||
return values.size() > 0;
|
||||
}
|
||||
|
||||
File getFile() {
|
||||
if (getValue() == null) return null;
|
||||
return new File(getValue());
|
||||
}
|
||||
|
||||
String[] getValues() {
|
||||
return (String[])values.toArray(new String[0]);
|
||||
}
|
||||
|
||||
void process(List arguments) {
|
||||
String option = (String)arguments.get(0);
|
||||
String dashLetter = (letterOption == null) ? (String)null : "-" + letterOption;
|
||||
if (option.equals(dashLetter) || option.equals("--" + wordOption)) {
|
||||
arguments.remove(0);
|
||||
if (flag) {
|
||||
values.add(0, (String)null );
|
||||
} else if (array) {
|
||||
while( arguments.size() > 0 && !( (String)arguments.get(0) ).startsWith("-") ) {
|
||||
values.add( (String)arguments.remove(0) );
|
||||
}
|
||||
} else {
|
||||
values.set(0, arguments.remove(0));
|
||||
}
|
||||
if (ignored) {
|
||||
System.err.println("WARNING: " + option + " is ignored in the Java version of the test driver.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getBugUrl() {
|
||||
return bugUrl.getValue();
|
||||
}
|
||||
|
||||
public int getOptimizationLevel() {
|
||||
return optimizationLevel.getInt();
|
||||
}
|
||||
|
||||
public File getOutputFile() {
|
||||
return outputFile.getFile();
|
||||
}
|
||||
|
||||
public boolean help() {
|
||||
return help.getSwitch();
|
||||
}
|
||||
|
||||
public boolean logFailuresToConsole() {
|
||||
return logFailuresToConsole.getSwitch();
|
||||
}
|
||||
|
||||
public String[] getTestList() {
|
||||
return testList.getValues();
|
||||
}
|
||||
|
||||
public String[] getSkipList() {
|
||||
return skipList.getValues();
|
||||
}
|
||||
|
||||
public File getTestsPath() {
|
||||
return testsPath.getFile();
|
||||
}
|
||||
|
||||
public boolean trace() {
|
||||
return trace.getSwitch();
|
||||
}
|
||||
|
||||
public String getLxrUrl() {
|
||||
return lxrUrl.getValue();
|
||||
}
|
||||
|
||||
public boolean ignoreRhinoSkipList() {
|
||||
return ignoreRhinoN.getSwitch();
|
||||
}
|
||||
|
||||
public int getTimeout() {
|
||||
return timeout.getInt();
|
||||
}
|
||||
|
||||
public Console getConsole() {
|
||||
return console;
|
||||
}
|
||||
|
||||
void process(List arguments) {
|
||||
while(arguments.size() > 0) {
|
||||
String option = (String)arguments.get(0);
|
||||
if (option.startsWith("--")) {
|
||||
// preprocess --name=value options into --name value
|
||||
if (option.indexOf("=") != -1) {
|
||||
arguments.set(0, option.substring(option.indexOf("=")));
|
||||
arguments.add(1, option.substring(option.indexOf("=") + 1));
|
||||
}
|
||||
} else if (option.startsWith("-")) {
|
||||
// could be multiple single-letter options, e.g. -kht, so preprocess them into -k -h -t
|
||||
if (option.length() > 2) {
|
||||
for (int i=2; i<option.length(); i++) {
|
||||
arguments.add(1, "-" + option.substring(i,i+1));
|
||||
}
|
||||
arguments.set(0, option.substring(0,2));
|
||||
}
|
||||
}
|
||||
int lengthBefore = arguments.size();
|
||||
for (int i=0; i<options.size(); i++) {
|
||||
if (arguments.size() > 0) {
|
||||
((Option)options.get(i)).process(arguments);
|
||||
}
|
||||
}
|
||||
if (arguments.size() == lengthBefore) {
|
||||
System.err.println("WARNING: Ignoring unrecognized option: " + arguments.remove(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
ArrayList arguments = new ArrayList();
|
||||
arguments.addAll(Arrays.asList(args));
|
||||
CommandLineArguments clArguments = new CommandLineArguments();
|
||||
clArguments.process(arguments);
|
||||
main(clArguments);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,324 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the Java port of jsDriver.pl.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* David P. Caldwell.
|
||||
* Portions created by David P. Caldwell are Copyright (C) 2007 David P. Caldwell
|
||||
*
|
||||
* Contributor(s):
|
||||
* David P. Caldwell <inonit@inonit.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
* case the provisions of the GPL are applicable instead of those above. If
|
||||
* you wish to allow use of your version of this file only under the terms of
|
||||
* the GPL and not to allow others to use your version of this file under the
|
||||
* MPL, indicate your decision by deleting the provisions above and replacing
|
||||
* them with the notice and other provisions required by the GPL. If you do
|
||||
* not delete the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.mozilla.javascript.tools.shell.*;
|
||||
|
||||
class ShellTest {
|
||||
static final FileFilter DIRECTORY_FILTER = new FileFilter() {
|
||||
public boolean accept(File pathname)
|
||||
{
|
||||
return pathname.isDirectory() && !pathname.getName().equals("CVS");
|
||||
}
|
||||
};
|
||||
|
||||
static final FileFilter TEST_FILTER = new FileFilter() {
|
||||
public boolean accept(File pathname)
|
||||
{
|
||||
return pathname.getName().endsWith(".js") && !pathname.getName().equals("shell.js") && !pathname.getName().equals("browser.js");
|
||||
}
|
||||
};
|
||||
|
||||
static String getStackTrace(Throwable t) {
|
||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||
t.printStackTrace(new PrintStream(bytes));
|
||||
return new String(bytes.toByteArray());
|
||||
}
|
||||
|
||||
private static void runFileIfExists(Context cx, Scriptable global, File f)
|
||||
{
|
||||
if(f.isFile())
|
||||
{
|
||||
Main.processFile(cx, global, f.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestState
|
||||
{
|
||||
boolean finished;
|
||||
ErrorReporterWrapper errors;
|
||||
}
|
||||
|
||||
static abstract class Status {
|
||||
private boolean negative;
|
||||
|
||||
final void setNegative() {
|
||||
this.negative = true;
|
||||
}
|
||||
|
||||
final boolean isNegative() {
|
||||
return this.negative;
|
||||
}
|
||||
|
||||
final void hadErrors(JsError[] errors) {
|
||||
if (!negative && errors.length > 0) {
|
||||
failed("JavaScript errors:\n" + JsError.toString(errors));
|
||||
} else if (negative && errors.length == 0) {
|
||||
failed("Should have produced runtime error.");
|
||||
}
|
||||
}
|
||||
|
||||
abstract void running(File jsFile);
|
||||
|
||||
|
||||
abstract void failed(String s);
|
||||
abstract void threw(Throwable t);
|
||||
abstract void timedOut();
|
||||
abstract void exitCodesWere(int expected, int actual);
|
||||
abstract void outputWas(String s);
|
||||
|
||||
static Status compose(final Status one, final Status two) {
|
||||
return new Status() {
|
||||
void running(File file) {
|
||||
one.running(file);
|
||||
two.running(file);
|
||||
}
|
||||
void threw(Throwable t) {
|
||||
one.threw(t);
|
||||
two.threw(t);
|
||||
}
|
||||
void failed(String s) {
|
||||
one.failed(s);
|
||||
two.failed(s);
|
||||
}
|
||||
void exitCodesWere(int expected, int actual) {
|
||||
one.exitCodesWere(expected, actual);
|
||||
two.exitCodesWere(expected, actual);
|
||||
}
|
||||
void outputWas(String s) {
|
||||
one.outputWas(s);
|
||||
two.outputWas(s);
|
||||
}
|
||||
void timedOut() {
|
||||
one.timedOut();
|
||||
two.timedOut();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static class JsError {
|
||||
static String toString(JsError[] e) {
|
||||
String rv = "";
|
||||
for (int i=0; i<e.length; i++) {
|
||||
rv += e[i].toString();
|
||||
if (i+1 != e.length) {
|
||||
rv += "\n";
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
private String message;
|
||||
private String sourceName;
|
||||
private int line;
|
||||
private String lineSource;
|
||||
private int lineOffset;
|
||||
|
||||
JsError(String message, String sourceName, int line, String lineSource, int lineOffset) {
|
||||
this.message = message;
|
||||
this.sourceName = sourceName;
|
||||
this.line = line;
|
||||
this.lineSource = lineSource;
|
||||
this.lineOffset = lineOffset;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String locationLine = sourceName + ":" + line + ": " + message;
|
||||
String sourceLine = this.lineSource;
|
||||
String errCaret = null;
|
||||
if (lineSource != null) {
|
||||
errCaret = "";
|
||||
for (int i=0; i<lineSource.length(); i++) {
|
||||
char c = lineSource.charAt(i);
|
||||
if (i < lineOffset-1) {
|
||||
if (c == '\t') {
|
||||
errCaret += "\t";
|
||||
} else {
|
||||
errCaret += " ";
|
||||
}
|
||||
} else if (i == lineOffset-1) {
|
||||
errCaret += "^";
|
||||
}
|
||||
}
|
||||
}
|
||||
String rv = locationLine;
|
||||
if (sourceLine != null) {
|
||||
rv += "\n" + sourceLine;
|
||||
}
|
||||
if (errCaret != null) {
|
||||
rv += "\n" + errCaret;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
String getSourceName() {
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
int getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
String getLineSource() {
|
||||
return lineSource;
|
||||
}
|
||||
|
||||
int getLineOffset() {
|
||||
return lineOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class ErrorReporterWrapper implements ErrorReporter {
|
||||
private ErrorReporter original;
|
||||
private ArrayList errors = new ArrayList();
|
||||
|
||||
ErrorReporterWrapper(ErrorReporter original) {
|
||||
this.original = original;
|
||||
}
|
||||
|
||||
private void addError(String string, String string0, int i, String string1, int i0) {
|
||||
errors.add( new Status.JsError(string, string0, i, string1, i0) );
|
||||
}
|
||||
|
||||
public void warning(String string, String string0, int i, String string1, int i0) {
|
||||
original.warning(string, string0, i, string1, i0);
|
||||
}
|
||||
|
||||
public EvaluatorException runtimeError(String string, String string0, int i, String string1, int i0) {
|
||||
return original.runtimeError(string, string0, i, string1, i0);
|
||||
}
|
||||
|
||||
public void error(String string, String string0, int i, String string1, int i0) {
|
||||
addError(string, string0, i, string1, i0);
|
||||
}
|
||||
}
|
||||
|
||||
static abstract class Parameters {
|
||||
abstract int getTimeoutMilliseconds();
|
||||
}
|
||||
|
||||
static void run(final ShellContextFactory shellContextFactory, final File jsFile, final Parameters parameters, final Status status) throws Exception {
|
||||
final Global global = new Global();
|
||||
final ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
final PrintStream p = new PrintStream(out);
|
||||
global.setOut(p);
|
||||
global.setErr(p);
|
||||
final TestState testState = new TestState();
|
||||
if (jsFile.getName().endsWith("-n.js")) {
|
||||
status.setNegative();
|
||||
}
|
||||
Thread t = new Thread(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
shellContextFactory.call(new ContextAction()
|
||||
{
|
||||
public Object run(Context cx)
|
||||
{
|
||||
status.running(jsFile);
|
||||
testState.errors = new ErrorReporterWrapper(cx.getErrorReporter());
|
||||
cx.setErrorReporter( testState.errors );
|
||||
global.init(cx);
|
||||
try {
|
||||
runFileIfExists(cx, global, new File(jsFile.getParentFile().getParentFile(), "shell.js"));
|
||||
runFileIfExists(cx, global, new File(jsFile.getParentFile(), "shell.js"));
|
||||
runFileIfExists(cx, global, jsFile);
|
||||
status.hadErrors( (Status.JsError[])testState.errors.errors.toArray(new Status.JsError[0]) );
|
||||
} catch (ThreadDeath e) {
|
||||
} catch (Throwable t) {
|
||||
status.threw(t);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
synchronized(testState)
|
||||
{
|
||||
testState.finished = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
t.join(parameters.getTimeoutMilliseconds());
|
||||
synchronized(testState)
|
||||
{
|
||||
if(!testState.finished)
|
||||
{
|
||||
status.timedOut();
|
||||
t.stop();
|
||||
}
|
||||
}
|
||||
int exitCode = 0;
|
||||
int expectedExitCode = 0;
|
||||
p.flush();
|
||||
status.outputWas(new String(out.toByteArray()));
|
||||
BufferedReader r = new BufferedReader(new InputStreamReader(
|
||||
new ByteArrayInputStream(out.toByteArray())));
|
||||
String failures = "";
|
||||
for(;;)
|
||||
{
|
||||
String s = r.readLine();
|
||||
if(s == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(s.indexOf("FAILED!") != -1)
|
||||
{
|
||||
failures += s + '\n';
|
||||
}
|
||||
int expex = s.indexOf("EXPECT EXIT ");
|
||||
if(expex != -1)
|
||||
{
|
||||
expectedExitCode = s.charAt(expex + "EXPECT EXIT ".length()) - '0';
|
||||
}
|
||||
}
|
||||
status.exitCodesWere(expectedExitCode, exitCode);
|
||||
if(failures != "")
|
||||
{
|
||||
status.failed(failures);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,6 +19,8 @@
|
|||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Attila Szegedi
|
||||
* David P. Caldwell <inonit@inonit.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* the GNU General Public License Version 2 or later (the "GPL"), in which
|
||||
|
@ -60,22 +62,28 @@ import org.mozilla.javascript.tools.shell.ShellContextFactory;
|
|||
* Executes the tests in the js/tests directory, much like jsDriver.pl does.
|
||||
* Excludes tests found in the js/tests/rhino-n.tests file.
|
||||
* @author Attila Szegedi
|
||||
* @version $Id: StandardTests.java,v 1.4 2006-11-10 15:27:38 gerv%gerv.net Exp $
|
||||
* @version $Id: StandardTests.java,v 1.5 2007-01-24 22:14:59 inonit%inonit.com Exp $
|
||||
*/
|
||||
public class StandardTests extends TestSuite
|
||||
{
|
||||
public static TestSuite suite() throws Exception
|
||||
{
|
||||
TestSuite suite = new TestSuite("Standard JavaScript tests");
|
||||
URL url = StandardTests.class.getResource(".");
|
||||
String path = url.getFile();
|
||||
int jsIndex = path.lastIndexOf("/js");
|
||||
if(jsIndex == -1)
|
||||
{
|
||||
throw new IllegalStateException("You aren't running the tests from within the standard mozilla/js directory structure");
|
||||
}
|
||||
path = path.substring(0, jsIndex + 3).replace('/', File.separatorChar);
|
||||
File testDir = new File(path, "tests");
|
||||
|
||||
File testDir = null;
|
||||
if (System.getProperty("mozilla.js.tests") != null) {
|
||||
testDir = new File(System.getProperty("mozilla.js.tests"));
|
||||
} else {
|
||||
URL url = StandardTests.class.getResource(".");
|
||||
String path = url.getFile();
|
||||
int jsIndex = path.lastIndexOf("/js");
|
||||
if(jsIndex == -1)
|
||||
{
|
||||
throw new IllegalStateException("You aren't running the tests from within the standard mozilla/js directory structure");
|
||||
}
|
||||
path = path.substring(0, jsIndex + 3).replace('/', File.separatorChar);
|
||||
testDir = new File(path, "tests");
|
||||
}
|
||||
if(!testDir.isDirectory())
|
||||
{
|
||||
throw new FileNotFoundException(testDir + " is not a directory");
|
||||
|
@ -101,16 +109,12 @@ public class StandardTests extends TestSuite
|
|||
|
||||
private static void addSuites(TestSuite topLevel, File testDir, Properties excludes, int optimizationLevel)
|
||||
{
|
||||
File[] subdirs = testDir.listFiles(new DirectoryFilter());
|
||||
File[] subdirs = testDir.listFiles(ShellTest.DIRECTORY_FILTER);
|
||||
Arrays.sort(subdirs);
|
||||
for (int i = 0; i < subdirs.length; i++)
|
||||
{
|
||||
File subdir = subdirs[i];
|
||||
String name = subdir.getName();
|
||||
if(name.equals("CVS"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
TestSuite testSuite = new TestSuite(name);
|
||||
addCategories(testSuite, subdir, name + "/", excludes, optimizationLevel);
|
||||
topLevel.addTest(testSuite);
|
||||
|
@ -119,16 +123,12 @@ public class StandardTests extends TestSuite
|
|||
|
||||
private static void addCategories(TestSuite suite, File suiteDir, String prefix, Properties excludes, int optimizationLevel)
|
||||
{
|
||||
File[] subdirs = suiteDir.listFiles(new DirectoryFilter());
|
||||
File[] subdirs = suiteDir.listFiles(ShellTest.DIRECTORY_FILTER);
|
||||
Arrays.sort(subdirs);
|
||||
for (int i = 0; i < subdirs.length; i++)
|
||||
{
|
||||
File subdir = subdirs[i];
|
||||
String name = subdir.getName();
|
||||
if(name.equals("CVS"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
TestSuite testCategory = new TestSuite(name);
|
||||
addTests(testCategory, subdir, prefix + name + "/", excludes, optimizationLevel);
|
||||
suite.addTest(testCategory);
|
||||
|
@ -137,20 +137,46 @@ public class StandardTests extends TestSuite
|
|||
|
||||
private static void addTests(TestSuite suite, File suiteDir, String prefix, Properties excludes, int optimizationLevel)
|
||||
{
|
||||
File[] jsFiles = suiteDir.listFiles(new JsFilter());
|
||||
File[] jsFiles = suiteDir.listFiles(ShellTest.TEST_FILTER);
|
||||
Arrays.sort(jsFiles);
|
||||
for (int i = 0; i < jsFiles.length; i++)
|
||||
{
|
||||
File jsFile = jsFiles[i];
|
||||
String name = jsFile.getName();
|
||||
if(name.equals("shell.js") || name.equals("browser.js") || excludes.containsKey(prefix + name))
|
||||
if(excludes.containsKey(prefix + name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
suite.addTest(new JsTestCase(jsFile, optimizationLevel));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class JunitStatus extends ShellTest.Status {
|
||||
final void running(File jsFile) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
final void failed(String s) {
|
||||
Assert.fail(s);
|
||||
}
|
||||
|
||||
final void exitCodesWere(int expected, int actual) {
|
||||
Assert.assertEquals("Unexpected exit code", expected, actual);
|
||||
}
|
||||
|
||||
final void outputWas(String s) {
|
||||
System.out.print(s);
|
||||
}
|
||||
|
||||
final void threw(Throwable t) {
|
||||
Assert.fail(ShellTest.getStackTrace(t));
|
||||
}
|
||||
|
||||
final void timedOut() {
|
||||
failed("Timed out.");
|
||||
}
|
||||
}
|
||||
|
||||
private static final class JsTestCase extends TestCase
|
||||
{
|
||||
private final File jsFile;
|
||||
|
@ -168,133 +194,20 @@ public class StandardTests extends TestSuite
|
|||
return 1;
|
||||
}
|
||||
|
||||
private static class TestState
|
||||
{
|
||||
boolean finished;
|
||||
Exception e;
|
||||
}
|
||||
|
||||
private static class ShellTestParameters extends ShellTest.Parameters {
|
||||
int getTimeoutMilliseconds() {
|
||||
if (System.getProperty("mozilla.js.tests.timeout") != null) {
|
||||
return Integer.parseInt(System.getProperty("mozilla.js.tests.timeout"));
|
||||
}
|
||||
return 60000;
|
||||
}
|
||||
}
|
||||
|
||||
public void runBare() throws Exception
|
||||
{
|
||||
final Global global = new Global();
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
PrintStream p = new PrintStream(out);
|
||||
global.setOut(p);
|
||||
global.setErr(p);
|
||||
final ShellContextFactory shellContextFactory = new ShellContextFactory();
|
||||
shellContextFactory.setOptimizationLevel(optimizationLevel);
|
||||
final TestState testState = new TestState();
|
||||
Thread t = new Thread(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
shellContextFactory.call(new ContextAction()
|
||||
{
|
||||
public Object run(Context cx)
|
||||
{
|
||||
global.init(cx);
|
||||
runFileIfExists(cx, global, new File(jsFile.getParentFile().getParentFile(), "shell.js"));
|
||||
runFileIfExists(cx, global, new File(jsFile.getParentFile(), "shell.js"));
|
||||
runFileIfExists(cx, global, jsFile);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
synchronized(testState)
|
||||
{
|
||||
testState.e = e;
|
||||
}
|
||||
}
|
||||
synchronized(testState)
|
||||
{
|
||||
testState.finished = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
t.join(60000);
|
||||
boolean isNegativeTest = jsFile.getName().endsWith("-n.js");
|
||||
synchronized(testState)
|
||||
{
|
||||
if(!testState.finished)
|
||||
{
|
||||
t.stop();
|
||||
Assert.fail("Timed out");
|
||||
}
|
||||
if(testState.e != null)
|
||||
{
|
||||
if(isNegativeTest)
|
||||
{
|
||||
if(testState.e instanceof EvaluatorException)
|
||||
{
|
||||
// Expected to bomb
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw testState.e;
|
||||
}
|
||||
}
|
||||
if(isNegativeTest)
|
||||
{
|
||||
Assert.fail("Test was expected to produce a runtime error");
|
||||
}
|
||||
int exitCode = 0;
|
||||
int expectedExitCode = 0;
|
||||
p.flush();
|
||||
System.out.print(new String(out.toByteArray()));
|
||||
BufferedReader r = new BufferedReader(new InputStreamReader(
|
||||
new ByteArrayInputStream(out.toByteArray())));
|
||||
String failures = "";
|
||||
for(;;)
|
||||
{
|
||||
String s = r.readLine();
|
||||
if(s == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if(s.indexOf("FAILED!") != -1)
|
||||
{
|
||||
failures += s + '\n';
|
||||
}
|
||||
int expex = s.indexOf("EXPECT EXIT ");
|
||||
if(expex != -1)
|
||||
{
|
||||
expectedExitCode = s.charAt(expex + "EXPECT EXIT ".length()) - '0';
|
||||
}
|
||||
}
|
||||
Assert.assertEquals("Unexpected exit code", expectedExitCode, exitCode);
|
||||
if(failures != "")
|
||||
{
|
||||
Assert.fail(failures);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void runFileIfExists(Context cx, Scriptable global, File f)
|
||||
{
|
||||
if(f.isFile())
|
||||
{
|
||||
Main.processFile(cx, global, f.getPath());
|
||||
}
|
||||
}
|
||||
|
||||
private static class DirectoryFilter implements FileFilter
|
||||
{
|
||||
public boolean accept(File pathname)
|
||||
{
|
||||
return pathname.isDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
private static class JsFilter implements FileFilter
|
||||
{
|
||||
public boolean accept(File pathname)
|
||||
{
|
||||
return pathname.getName().endsWith(".js");
|
||||
final ShellContextFactory shellContextFactory = new ShellContextFactory();
|
||||
shellContextFactory.setOptimizationLevel(optimizationLevel);
|
||||
ShellTest.run(shellContextFactory, jsFile, new ShellTestParameters(), new JunitStatus());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче