view src/org/RhinoTests/InvocableTest.java @ 354:6fcf6a73fde4 draft

Several new tests added into InvocableTest.
author Pavel Tisnovsky <ptisnovs@redhat.com>
date Thu, 24 Apr 2014 10:01:24 +0200
parents d649db1c7d07
children
line wrap: on
line source

/*
  Rhino test framework

   Copyright (C) 2011, 2012, 2013, 2014  Red Hat

This file is part of IcedTea.

IcedTea is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

IcedTea is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with IcedTea; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version.
*/

package org.RhinoTests;

import java.util.Date;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import org.RhinoTests.TestClasses.TestClass;



/**
 * Basic Invocable interface test suite.
 * 
 * @author Pavel Tisnovsky
 */
public class InvocableTest extends BaseRhinoTest {
    ScriptEngineManager engineManager;
    ScriptEngine scriptEngine;
    Invocable invocableEngine;

    @Override
    protected void setUp(String[] args) {
        this.engineManager = new ScriptEngineManager();
        this.scriptEngine = this.engineManager.getEngineByName("JavaScript");
        this.invocableEngine = (Invocable)this.scriptEngine;
    }

    @Override
    protected void tearDown() {
        // this block could be empty
        return;
    }

    /**
     * Test the JavaScript method invocation.
     * 
     * @throws ScriptException in case there's something wrong in JS engine.
     * @throws NoSuchMethodException if wrong method is called.
     */
    protected void testInvokeFunction() throws ScriptException, NoSuchMethodException {
        final String script =
            "function foo() {" +
            "}";
        this.scriptEngine.eval(script);
        this.invocableEngine.invokeFunction("foo");
    }

    /**
     * Test the JavaScript method invocation.
     * 
     * @throws ScriptException in case there's something wrong in JS engine.
     * @throws NoSuchMethodException if wrong method is called.
     */
    protected void testInvokeFunction2() throws ScriptException, NoSuchMethodException {
        final String script =
            "function foo() {" +
            "    println('\tHello, world!');" +
            "}";
        this.scriptEngine.eval(script);
        this.invocableEngine.invokeFunction("foo");
    }

    /**
     * Test the JavaScript method invocation.
     * 
     * @throws ScriptException in case there's something wrong in JS engine.
     * @throws NoSuchMethodException if wrong method is called.
     */
    protected void testInvokeFunction3() throws ScriptException, NoSuchMethodException {
        final String script =
            "function foo() {" +
            "    println('\tHello, world!');" +
            "    println('\tHello, world!');" +
            "}";
        this.scriptEngine.eval(script);
        this.invocableEngine.invokeFunction("foo");
    }

    /**
     * Test the invocation of wrong JavaScript method.
     * 
     * @throws Exception when NoSuchMethodException is not thrown.
     */
    protected void testInvokeFunctionNegative() throws Exception {
        final String script =
            "function foo() {" +
            "    println('\tHello, world!');" +
            "}";
        this.scriptEngine.eval(script);
        try {
            this.invocableEngine.invokeFunction("bar");
        }
        catch (NoSuchMethodException e) {
        	System.out.println("\tException thrown as expected " + e.getMessage());
            return;
        }
        throw new Exception("NoSuchMethodException not thrown as expected!");
    }

    /**
     * Test invocation of method containing parameters.
     *
     * @throws ScriptException in case there's something wrong in JS engine.
     * @throws NoSuchMethodException if wrong method is called.
     */
    protected void testInvokeFunctionWithParameters() throws ScriptException, NoSuchMethodException {
        final String script =
            "function printHello(str1, str2) {" +
            "    println('\t' + str1 + ' ' + str2);" +
            "}";
        this.scriptEngine.eval(script);
        this.invocableEngine.invokeFunction("printHello", "hello", "world");
    }

    /**
     * Test invocation of method containing parameters.
     *
     * @throws ScriptException in case there's something wrong in JS engine.
     * @throws NoSuchMethodException if wrong method is called.
     */
    protected void testInvokeFunctionWithParameters2() throws ScriptException, NoSuchMethodException {
        final String script =
            "function printHello(str1, val2) {" +
            "    println('\t' + str1 + ' ' + val2);" +
            "}";
        this.scriptEngine.eval(script);
        this.invocableEngine.invokeFunction("printHello", "hello", 42);
    }

    /**
     * Test invocation of method containing parameters.
     *
     * @throws ScriptException in case there's something wrong in JS engine.
     * @throws NoSuchMethodException if wrong method is called.
     */
    protected void testInvokeFunctionWithParameters3() throws ScriptException, NoSuchMethodException {
        final String script =
            "function printHello(val1, str2) {" +
            "    println('\t' + val1 + ' ' + str2);" +
            "}";
        this.scriptEngine.eval(script);
        this.invocableEngine.invokeFunction("printHello", 42, "world!");
    }

    /**
     * Prints all properties of Java object.
     * 
     * @throws ScriptException in case there's something wrong in JS engine.
     * @throws NoSuchMethodException if wrong method is called.
     */
    protected void testPrintAllObjectProperties() throws ScriptException, NoSuchMethodException {
        final String script =
            "function printAllObjectProperties(object) {" +
            "    println('\tobject.toString(): ' + object);" +
            "    for (var prop in object) {" +
            "        println('\tproperty: ' + prop);" +
            "    }" +
            "}";
        this.scriptEngine.eval(script);
        this.invocableEngine.invokeFunction("printAllObjectProperties", new Object());
        this.invocableEngine.invokeFunction("printAllObjectProperties", new StringBuffer());
        this.invocableEngine.invokeFunction("printAllObjectProperties", new Date());
        this.invocableEngine.invokeFunction("printAllObjectProperties", new TestClass());
    }

    /**
     * Test if property of common class is presented in JS engine.
     * 
     * @throws ScriptException in case there's something wrong in JS engine.
     * @throws NoSuchMethodException if wrong method is called.
     */
    protected void testCheckObjectPropertyCommonClass() throws ScriptException, NoSuchMethodException {
        final String script =
            "function checkObjectProperty(object, property) {" +
            "    println('\tobject.toString(): ' + object);" +
            "    for (var prop in object) {" +
            "        if (prop == property) return true;" +
            "    }" +
            "    return false;" +
            "}";
        this.scriptEngine.eval(script);
        String[] methods = new String[] { "getRed", "getBlue", "getGreen", "getAlpha" };
        for (String method : methods) {
            System.out.println("\ttesting property " + method);
            Boolean result = (Boolean) this.invocableEngine.invokeFunction(
                    "checkObjectProperty", new java.awt.Color(0), method);
            assertTrue(result.booleanValue(), "invalid result: " + result);
        }
    }

    /**
     * Test if property of custom class is presented in JS engine.
     * 
     * @throws ScriptException in case there's something wrong in JS engine.
     * @throws NoSuchMethodException if wrong method is called.
     */
    protected void testCheckObjectPropertyUserClass() throws ScriptException, NoSuchMethodException {
        final String script =
            "function checkObjectProperty(object, property) {" +
            "    println('\tobject.toString(): ' + object);" +
            "    for (var prop in object) {" +
            "        if (prop == property) return true;" +
            "    }" +
            "    return false;" +
            "}";
        this.scriptEngine.eval(script);
        Boolean result = (Boolean)this.invocableEngine.invokeFunction("checkObjectProperty", new TestClass(), "getValue");
        assertTrue(result.booleanValue(), "invalid result: " + result);
    }

    /**
     * Check if JavaScript function returns proper boolean value.
     * 
     * @throws Exception thrown if this test case fails.
     */
    @SuppressWarnings("boxing")
    protected void testInvokeFunctionWhichReturnsBoolean() throws Exception {
        final String script =
            "function booleanTest(x, y) {" +
            "    var result = x && y;" +
            "    println('\tresult=' + result);" +
            "    return result;" +
            "}";
        this.scriptEngine.eval(script);
        Boolean result;
        result = (Boolean)this.invocableEngine.invokeFunction("booleanTest", true, true);
        assertTrue(result, "function returns incorrect value " + result);
        result = (Boolean)this.invocableEngine.invokeFunction("booleanTest", false, true);
        assertFalse(result, "function returns incorrect value " + result);
        result = (Boolean)this.invocableEngine.invokeFunction("booleanTest", true, false);
        assertFalse(result, "function returns incorrect value " + result);
        result = (Boolean)this.invocableEngine.invokeFunction("booleanTest", false, false);
        assertFalse(result, "function returns incorrect value " + result);
    }

    /**
     * Check if JavaScript function returns proper double value.
     * 
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeFunctionWhichReturnsDouble() throws Exception {
        final String script =
            "function plus(x, y) {" +
            "    var result = x + y;" +
            "    println('\tresult=' + result);" +
            "    return result;" +
            "}";
        this.scriptEngine.eval(script);
        Double result;
        result = (Double)this.invocableEngine.invokeFunction("plus", Double.valueOf(1.2), Double.valueOf(3.4));
        assertTrue(result.doubleValue() == 4.6, "function returns incorrect value " + result);
        result = (Double)this.invocableEngine.invokeFunction("plus", Double.valueOf(0), Double.valueOf(1.1));
        assertTrue(result.doubleValue() == 1.1, "function returns incorrect value " + result);
        result = (Double)this.invocableEngine.invokeFunction("plus", Double.valueOf(1.1), Double.valueOf(0));
        assertTrue(result.doubleValue() == 1.1, "function returns incorrect value " + result);
        result = (Double)this.invocableEngine.invokeFunction("plus", Double.valueOf(-1.234), Double.valueOf(1.234));
        assertTrue(result.doubleValue() == 0, "function returns incorrect value " + result);
    }

    /**
     * Check if JavaScript function returns proper double value.
     * 
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeFunctionWhichReturnsString() throws Exception {
        final String script =
            "function concatenateWords(str1, str2) {" +
            "    return str1 + ' ' + str2;" +
            "}";
        this.scriptEngine.eval(script);
        String result = (String)this.invocableEngine.invokeFunction("concatenateWords", "Hello", "world");
        assertTrue("Hello world".equals(result), "function returns incorrect value " + result);
    }

    /**
     * Check if JavaScript function returns proper Java class instance.
     * 
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeFunctionWhichReturnsJavaObject() throws Exception {
        final String script =
            "function getDate(str1, str2) {" +
            "    return new java.util.Date();" +
            "}";
        this.scriptEngine.eval(script);
        Date result = (Date)this.invocableEngine.invokeFunction("getDate");
        assertType(result, Date.class, "function returns incorrect type " + result.getClass());
    }

    /**
     * Check the behaviour of method call.
     *
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeFunctionWhichAccessJavaObject() throws Exception {
        final String script =
            "function accessJavaObject(object) {" +
            "    object.setValue('123');" +
            "    return object.getValue();" +
            "}";
        this.scriptEngine.eval(script);
        String result = (String)this.invocableEngine.invokeFunction("accessJavaObject", new TestClass());
        assertTrue("123".equals(result), "function returns incorrect value " + result);
    }

    /**
     * Check the behaviour of method overloading.
     *
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeMethodOverloading() throws Exception {
        final String script =
            "function accessJavaObject(object) {" +
            "    object.overloaded(true);" +
            "    object.overloaded(false);" +
            "    object.overloaded(object == null);" +
            "    object.overloaded(new java.util.Date());" +
            "    object.overloaded(new Date());" +
            "    object.overloaded(new java.awt.Color(0));" +
            "    object.overloaded('Hello world');" +
            "    object.overloaded(42);" +
            "    object.overloaded(1/3.0);" +
            "    object.overloaded(new java.awt.Frame());" +
            "}";
        this.scriptEngine.eval(script);
        this.invocableEngine.invokeFunction("accessJavaObject", new TestClass());
    }

    /**
     * Test if JavaScript function returns the correct result.
     *
     * @param function JavaScript function to be called.
     * @param expectedResult result which should be returned by JavaScript function.
     *
     * @throws ScriptException thrown if any JS exception occured
     * @throws NoSuchMethodException thrown if wrong javascript method is called.
     * @throws AssertionError thrown if wrong result is returned.
     */
    private void checkReturnedString(String function, String expectedResult) throws ScriptException, NoSuchMethodException, AssertionError {
        String result = (String)this.invocableEngine.invokeFunction(function, new TestClass());
        assertEquals(result, expectedResult, "called wrong overloaded method, expected=" + expectedResult + ", returned=" + result);
    }

    /**
     * Test if proper overloaded method is called from JavaScript function and
     * if this function returns correct result.
     * 
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeMethodOverloadingBoolean1() throws Exception {
        final String script =
            "function accessJavaObject(object) {" +
            "    return object.overloaded(true);" +
            "}";
        this.scriptEngine.eval(script);
        checkReturnedString("accessJavaObject", "boolean");
    }

    /**
     * Test if proper overloaded method is called from JavaScript function and
     * if this function returns correct result.
     * 
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeMethodOverloadingBoolean2() throws Exception {
        final String script =
            "function accessJavaObject(object) {" +
            "    return object.overloaded(false);" +
            "}";
        this.scriptEngine.eval(script);
        checkReturnedString("accessJavaObject", "boolean");
    }

    /**
     * Test if proper overloaded method is called from JavaScript function and
     * if this function returns correct result.
     * 
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeMethodOverloadingBoolean3() throws Exception {
        final String script =
            "function accessJavaObject(object) {" +
            "    return object.overloaded(object != null);" +
            "}";
        this.scriptEngine.eval(script);
        checkReturnedString("accessJavaObject", "boolean");
    }

    /**
     * Test if proper overloaded method is called from JavaScript function and
     * if this function returns correct result.
     * 
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeMethodOverloadingBoolean4() throws Exception {
        final String script =
            "function accessJavaObject(object) {" +
            "    return object.overloaded(new java.lang.Boolean(true));" +
            "}";
        this.scriptEngine.eval(script);
        checkReturnedString("accessJavaObject", "Boolean");
    }

    /**
     * Test if proper overloaded method is called from JavaScript function and
     * if this function returns correct result.
     * 
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeMethodOverloadingBoolean5() throws Exception {
        final String script =
            "function accessJavaObject(object) {" +
            "    return object.overloaded(new java.lang.Boolean(object != null));" +
            "}";
        this.scriptEngine.eval(script);
        checkReturnedString("accessJavaObject", "Boolean");
    }

    /**
     * Test if proper overloaded method is called from JavaScript function and
     * if this function returns correct result.
     * 
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeMethodOverloadingDate1() throws Exception {
        final String script =
            "function accessJavaObject(object) {" +
            "    return object.overloaded(new java.util.Date());" +
            "}";
        this.scriptEngine.eval(script);
        checkReturnedString("accessJavaObject", "Date");
    }

    /**
     * Test if proper overloaded method is called from JavaScript function and
     * if this function returns correct result.
     * 
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeMethodOverloadingDate2() throws Exception {
        final String script =
            "function accessJavaObject(object) {" +
            "    return object.overloaded(new Date());" +
            "}";
        this.scriptEngine.eval(script);
        checkReturnedString("accessJavaObject", "Date");
    }

    /**
     * Test if proper overloaded method is called from JavaScript function and
     * if this function returns correct result.
     * 
     * @throws Exception thrown if this test case fails.
     */
    protected void testInvokeMethodOverloadingDouble() throws Exception {
        final String script =
            "function accessJavaObject(object) {" +
            "    return object.overloaded(4/3);" +
            "}";
        this.scriptEngine.eval(script);
        checkReturnedString("accessJavaObject", "Double");
    }

    /**
     * Entry point to this test case.
     *
     * @param args parameters passed from command line
     */
    public static void main(String[] args) {
        new InvocableTest().doTests(args);
    }

}