All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rhino1.7.6.testsrc.org.mozilla.javascript.drivers.ShellTest Maven / Gradle / Ivy

Go to download

Rhino is an open-source implementation of JavaScript written entirely in Java. It is typically embedded into Java applications to provide scripting to end users.

There is a newer version: 1.7.15
Show newest version
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.javascript.drivers;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;

import org.mozilla.javascript.*;
import org.mozilla.javascript.tools.shell.Global;
import org.mozilla.javascript.tools.shell.Main;
import org.mozilla.javascript.tools.shell.ShellContextFactory;

/**
 * @version $Id: ShellTest.java,v 1.14 2011/03/29 15:17:49 hannes%helma.at Exp $
 */
public class ShellTest {
    public static final FileFilter DIRECTORY_FILTER = new FileFilter() {
        public boolean accept(File pathname)
        {
            return pathname.isDirectory() && !pathname.getName().equals("CVS");
        }
    };

    public 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");
        }
    };

    public 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.processFileNoThrow(cx, global, f.getPath());
        }
    }

    private static class TestState {
        boolean finished;
        ErrorReporterWrapper errors;
        int exitCode = 0;
    }

    public static abstract class Status {
        private boolean negative;

        public final void setNegative() {
            this.negative = true;
        }

        public final boolean isNegative() {
            return this.negative;
        }

        public 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.");
            }
        }

        public final void hadErrors(File jsFile, JsError[] errors) {
            if (!negative && errors.length > 0) {
                failed("JavaScript errors in " + jsFile + ":\n" + JsError.toString(errors));
            } else if (negative && errors.length == 0) {
                failed("Should have produced runtime error in " + jsFile + ".");
            }
        }

        public abstract void running(File jsFile);

        public abstract void failed(String s);
        public abstract void threw(Throwable t);
        public abstract void timedOut();
        public abstract void exitCodesWere(int expected, int actual);
        public abstract void outputWas(String s);

        static Status compose(final Status[] array) {
            return new Status() {
                @Override
                public void running(File file) {
					for (int i=0; i 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);
        }
    }

    public static abstract class Parameters {
        public abstract int getTimeoutMilliseconds();
    }

    @SuppressWarnings(value={"deprecation"})
    private static void callStop(Thread t) {
        t.stop();
    }

    public 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);
        global.defineFunctionProperties(
                new String[] { "options" }, ShellTest.class,
                ScriptableObject.DONTENUM | ScriptableObject.PERMANENT |
                  ScriptableObject.READONLY);
        // test suite expects keywords to be disallowed as identifiers
        shellContextFactory.setAllowReservedKeywords(false);
        final TestState testState = new TestState();
        if (jsFile.getName().endsWith("-n.js")) {
            status.setNegative();
        }
        final Throwable thrown[] = {null};

        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().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);
                                status.hadErrors(jsFile, testState.errors.errors.toArray(new Status.JsError[0]));
                            } catch (ThreadDeath e) {
                            } catch (Throwable t) {
                                status.threw(t);
                            }
                            return null;
                        }
                    });
                }
                catch (Error t)
                {
                    thrown[0] = t;
                }
                catch (RuntimeException t)
                {
                    thrown[0] = t;
                }
                finally {
                    synchronized(testState)
                    {
                        testState.finished = true;
                    }
                }
            }
        }, jsFile.getPath());
        t.setDaemon(true);
        t.start();
        t.join(parameters.getTimeoutMilliseconds());
        synchronized(testState)
        {
            if(!testState.finished)
            {
                callStop(t);
                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';
            }
        }
        if (thrown[0] != null)
        {
        	status.threw(thrown[0]);
        }
        status.exitCodesWere(expectedExitCode, testState.exitCode);
        if(failures != "")
        {
            status.failed(failures);
        }
    }

    // Global function to mimic options() function in spidermonkey.
    // It looks like this toggles jit compiler mode in spidermonkey
    // when called with "jit" as argument. Our version is a no-op
    // and returns an empty string.
    public static String options() {
        return "";
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy