diff options
Diffstat (limited to 'infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/ShellTest.java')
-rw-r--r-- | infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/ShellTest.java | 346 |
1 files changed, 346 insertions, 0 deletions
diff --git a/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/ShellTest.java b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/ShellTest.java new file mode 100644 index 0000000..9acf64e --- /dev/null +++ b/infrastructure/rhino1_7R1/testsrc/org/mozilla/javascript/drivers/ShellTest.java @@ -0,0 +1,346 @@ +/* ***** 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. All Rights Reserved. + * + * + * 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.drivers; + +import org.mozilla.javascript.*; +import java.io.*; +import java.util.*; + +import org.mozilla.javascript.tools.shell.*; + +/** + * @version $Id: ShellTest.java,v 1.5 2007/10/11 19:44:10 szegedia%freemail.hu Exp $ + */ +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") && !pathname.getName().equals("template.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; + int exitCode = 0; + } + + 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[] array) { + return new Status() { + void running(File file) { + for (int i=0; i<array.length; i++) { + array[i].running(file); + } + } + void threw(Throwable t) { + for (int i=0; i<array.length; i++) { + array[i].threw(t); + } + } + void failed(String s) { + for (int i=0; i<array.length; i++) { + array[i].failed(s); + } + } + void exitCodesWere(int expected, int actual) { + for (int i=0; i<array.length; i++) { + array[i].exitCodesWere(expected, actual); + } + } + void outputWas(String s) { + for (int i=0; i<array.length; i++) { + array[i].outputWas(s); + } + } + void timedOut() { + for (int i=0; i<array.length; i++) { + array[i].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) + { + System.out.println("Running " + jsFile); + 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().getParentFile(), "shell.js")); + runFileIfExists(cx, global, new File(jsFile.getParentFile().getParentFile(), "shell.js")); + runFileIfExists(cx, global, new File(jsFile.getParentFile(), "shell.js")); + runFileIfExists(cx, global, jsFile); + // Emulate SpiderMonkey enum value from mozilla/js/src/js.c + for (int i=0; i<testState.errors.errors.size(); i++) { + Status.JsError thisOne = (Status.JsError)testState.errors.errors.get(i); + if (thisOne.getMessage().indexOf("java.lang.OutOfMemoryError") != -1) { + testState.exitCode = 5; + testState.errors.errors.remove(thisOne); + } + } + 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; + } + } + } + }, jsFile.getPath()); + t.setDaemon(true); + t.start(); + t.join(parameters.getTimeoutMilliseconds()); + synchronized(testState) + { + if(!testState.finished) + { + t.stop(); + status.timedOut(); + } + } + 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 CODE "); + if(expex != -1) + { + expectedExitCode = s.charAt(expex + "EXPECT EXIT CODE ".length()) - '0'; + } + } + status.exitCodesWere(expectedExitCode, testState.exitCode); + if(failures != "") + { + status.failed(failures); + } + } +} |