[rfc][icedtea-web] a new reproducer LiveConnect "function parameters" tests

Adam Domurad adomurad at redhat.com
Wed Feb 6 08:21:11 PST 2013


On 01/15/2013 07:59 AM, Jana Fabrikova wrote:
 > Hello,
 >
 > I have rewritten the JSToJFuncParam reproducer according to Adam's 
comments, please see the attached patch.

Thanks for revisiting the patch, sorry for the long process.

 > adding 19 testcases - 18 based on the interactive Liveconnect 
JS->Java function parameter tests, 1 additional testcase for passing 
parameters of type JSObject (from JS to Java)
 >
 > * /tests/reproducers/simple/JSToJFuncParam/srcs/JSToJFuncParam.java:
 > the applet whose methods are invoked from JS during the tests
 >
 > * 
/tests/reproducers/simple/JSToJFuncParam/resources/JSToJava_FuncParam.js:
 > the JavaScript code for calling the applet methods from JS
 >
 > * 
/tests/reproducers/simple/JSToJFuncParam/resources/jstoj-funcparam.jnlp:
 > java network launch protocol file for displaying applet in the html page

'java network launch protocol' --> we can call this simply JNLP, anyone 
dealing with icedtea-web will understand :-)

[.. long snip .. ]

New patch:

 >
 > 2013-01-15  Jana Fabrikova  <jfabriko at redhat.com>
 >
 > * 
/tests/reproducers/simple/JSToJFuncParam/testcases/JSToJFuncParamTest.jav
 > diff --git 
a/tests/reproducers/simple/JSToJFuncParam/resources/JSToJFuncParam.html 
b/tests/reproducers/simple/JSToJFuncParam/resources/JSToJFuncParam.html
 > new file mode 100644
 > --- /dev/null
 > +++ 
b/tests/reproducers/simple/JSToJFuncParam/resources/JSToJFuncParam.html
 > @@ -0,0 +1,25 @@
 > +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 > +<html lang="en-US">
 > +  <head>
 > +    <title>JavaScript to Java LiveConnect -  function parameter 
conversion</title>
 > +    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 > +
 > +    <script language="JavaScript" src="JSToJava_FuncParam.js"></script>
 > +
 > +  </head>
 > +  <body>
 > +
 > + <h2> The JSToJFuncParam html page</h2>
 > +
 > +    <applet code="JSToJFuncParam" width="1000" height="100" 
name="JSToJFuncParam" id="jstojFuncParamApplet" MAYSCRIPT>
 > +      <param name="jnlp_href" value="jstoj-funcparam.jnlp">
 > +    </applet>
 > +
 > +   <div id="messageDiv"></div>
 > +
 > +    <script language="javascript">
 > +        doFuncParamTests();
 > +    </script>
 > +
 > +  </body>
 > +</html>
 > diff --git 
a/tests/reproducers/simple/JSToJFuncParam/resources/JSToJava_FuncParam.js b/tests/reproducers/simple/JSToJFuncParam/resources/JSToJava_FuncParam.js
 > new file mode 100644
 > --- /dev/null
 > +++ 
b/tests/reproducers/simple/JSToJFuncParam/resources/JSToJava_FuncParam.js
 > @@ -0,0 +1,55 @@
 > +//dummy javascript class whose instance is passed as JSObject parameter:
 > +function JSCar(mph,color){
 > +    this.mph = mph;
 > +    this.color = color;
 > +}
 > +
 > +//the main routine used for all tests:
 > +function doFuncParamTests( ){
 > +
 > +    var urlArgs = document.URL.split("?");
 > +    var testParams = urlArgs[1].split(";");
 > +    var applet = document.getElementById('jstojFuncParamApplet');
 > +    var func = testParams[0];
 > +    var value = testParams[1];
 > +
 > +    if( value === "JavaScript"){
 > +
 > +        if( func === "charParam"){
 > +            value = 97; // 'a'
 > +        }
 > +
 > +        if( func === "charArrayParam"){
 > +            value = [97,98,99]; //[a, b, c]
 > +        }
 > +
 > +        if( func === "StringParam"){
 > +            value = "test";
 > +        }
 > +
 > +        if( func === "CharacterParam"){
 > +            value = new (applet.Packages).java.lang.Character(65); 
// 'A'
 > +        }

Hm, I understand the reasoning here but I think actually we can get away 
without any special values after all. There is a handy function in 
javascript that works across all browsers:

var testParams = decodeURIComponent( urlArgs[1].split(";") );
You will be then free to pass any of the characters you need! I was a 
bit skeptical but I have tested it on multiple browsers and it really 
seems to work fine.
You can pass even this long string ('new 
(applet.Packages).java.lang.Character(65)') from the test driver. This 
will improve the test as the input data and the expectation will be kept 
in one location, the test-driver.

 > +
 > +        if( func === "StringIntMixedParam"){
 > +            value = new Array();
 > +            value[0] = "test"; //string
 > +            value[1] = 123;    //number

With the decodeURIComponent improvement, this can be passed as ["test", 
123] safely :-)).

 > +        }
 > +
 > +        if( func === "DummyObjectArrayParam"){
 > +            value = new Array();
 > +            value[0] = applet.getNewDummyObject("Dummy1");
 > +            value[1] = applet.getNewDummyObject("Dummy2");

Even this can be passed, eg [applet.getNewDummyObject("Dummy1"), 
applet.getNewDummyObject("Dummy2")]. Testing this string on firefox and 
google-chrome works fine.

 > +        }
 > +
 > +        if( func === "JSObjectParam"){
 > +            value = new JSCar(100,"red");
 > +        }
 > +     }
 > +
 > +    eval('applet.' + func + '(value)');

Under the new mechanism, this will instead be 'applet.' + func + '(' + 
value +')'.

 > +    applet.writeAfterTest();
 > +}
 > +
 > +
 > diff --git 
a/tests/reproducers/simple/JSToJFuncParam/resources/jstoj-funcparam.jnlp 
b/tests/reproducers/simple/JSToJFuncParam/resources/jstoj-funcparam.jnlp
 > new file mode 100644
 > --- /dev/null
 > +++ 
b/tests/reproducers/simple/JSToJFuncParam/resources/jstoj-funcparam.jnlp
 > @@ -0,0 +1,23 @@
 > +
 > +<?xml version="1.0" encoding="UTF-8"?>
 > +<jnlp spec="1.0+" codebase="" href="jstoj-funcparam.jnlp">
 > +    <information>
 > +        <title>JavaScript to Java LiveConnect - FuncParam</title>
 > +        <vendor>RedHat</vendor>

Vendor is typically IcedTea I think, representing the open source project

 > +        <homepage 
href="http://icedtea.classpath.org/wiki/IcedTea-Web#Testing_IcedTea-Web"/>
 > +        <description>LiveConnect - tests for function parameter 
conversion when calling Java from JS.</description>
 > +    </information>
 > +    <resources>
 > +        <!-- Application Resources -->
 > +        <j2se version="1.6+"
 > + href="http://java.sun.com/products/autodl/j2se"/>
 > +        <jar href="JSToJFuncParam.jar" main="true" />
 > +
 > +    </resources>
 > +    <applet-desc
 > +         name="JS to J FuncParam"
 > +         main-class="JSToJFuncParam"
 > +         width="1000"
 > +         height="100">
 > +     </applet-desc>
 > +</jnlp>
 > diff --git 
a/tests/reproducers/simple/JSToJFuncParam/srcs/JSToJFuncParam.java 
b/tests/reproducers/simple/JSToJFuncParam/srcs/JSToJFuncParam.java
 > new file mode 100644
 > --- /dev/null
 > +++ b/tests/reproducers/simple/JSToJFuncParam/srcs/JSToJFuncParam.java
 > @@ -0,0 +1,124 @@
 > +import java.applet.Applet;
 > +import java.awt.Label;
 > +import java.awt.BorderLayout;
 > +import java.util.Arrays;
 > +import netscape.javascript.JSObject;
 > +
 > +public class JSToJFuncParam extends Applet {
 > +
 > +    private Label statusLabel;
 > +
 > +    public void init() {
 > +        setLayout(new BorderLayout());
 > +        statusLabel = new Label();
 > +        add(statusLabel);

I'd prefer not to have the statusLabel.

 > +        String initStr = "JSToJFuncParam applet initialized.";
 > +        System.out.println(initStr);
 > +        statusLabel.setText(initStr);
 > +    }
 > +
 > +    public void intParam(int i) {
 > +        System.out.println("intParam "+i);
 > +    }
 > +
 > +    public void doubleParam(double d) {
 > +        System.out.println("doubleParam "+d);
 > +    }
 > +
 > +    public void floatParam(float f) {
 > +        System.out.println("floatParam "+f);
 > +    }
 > +
 > +    public void longParam(long l) {
 > +        System.out.println("longParam "+l);
 > +    }
 > +
 > +    public void booleanParam(boolean b) {
 > +        System.out.println("booleanParam "+b);
 > +    }
 > +
 > +    public void charParam(char c) {
 > +        System.out.println("charParam "+c);
 > +    }
 > +
 > +    public void byteParam(byte b) {
 > +        System.out.println("byteParam "+b);
 > +    }
 > +
 > +    public void charArrayParam(char[] ca) {
 > +        System.out.println("charArrayParam "+Arrays.toString(ca));
 > +    }
 > +
 > +    public void StringParam(String s) {
 > +        System.out.println("StringParam "+s);
 > +    }
 > +
 > +    public void IntegerParam(Integer p) {
 > +        System.out.println("IntegerParam "+p);
 > +    }
 > +
 > +    public void DoubleParam(Double p) {
 > +        System.out.println("DoubleParam "+p);
 > +    }
 > +
 > +    public void FloatParam(Float p) {
 > +        System.out.println("FloatParam "+p);
 > +    }
 > +
 > +    public void LongParam(Long p) {
 > +        System.out.println("LongParam "+p);
 > +    }
 > +
 > +    public void BooleanParam(Boolean p) {
 > +        System.out.println("BooleanParam "+p);
 > +    }
 > +
 > +    public void CharacterParam(Character p) {
 > +        System.out.println("CharacterParam "+p);
 > +    }
 > +
 > +    public void ByteParam(Byte p) {
 > +        System.out.println("ByteParam "+p);
 > +    }
 > +
 > +    public void StringIntMixedParam(String[] s) {
 > +        System.out.println("StringIntMixedParam "+Arrays.toString(s));
 > +    }
 > +
 > +    public void DummyObjectArrayParam(DummyObject[] ca) {
 > +        System.out.println("DummyObjectArrayParam 
"+Arrays.toString(ca));
 > +    }
 > +
 > +    public void JSObjectParam(JSObject car){
 > +        Integer mph = (Integer)car.getMember("mph");
 > +        String color = (String)car.getMember("color");
 > +
 > +        System.out.println("JSObjectParam "+mph+", "+color);
 > +    }
 > +
 > +    public void writeAfterTest(){
 > +        System.out.println("afterTests");
 > +    }
 > +
 > +    public class DummyObject {
 > +        private String str;
 > +
 > +        public DummyObject(String s) {
 > +            this.str = s;
 > +        }
 > +
 > +        public void setStr(String s) {
 > +            this.str = s;
 > +        }
 > +
 > +        public String toString() {
 > +           return str;
 > +        }
 > +    }
 > +
 > +    public DummyObject getNewDummyObject(String str){
 > +        return new DummyObject(str);
 > +    }
 > +}

Looks nice and clean otherwise!

 > +
 > +
 > diff --git 
a/tests/reproducers/simple/JSToJFuncParam/testcases/JSToJFuncParamTest.java 
b/tests/reproducers/simple/JSToJFuncParam/testcases/JSToJFuncParamTest.java
 > new file mode 100644
 > --- /dev/null
 > +++ 
b/tests/reproducers/simple/JSToJFuncParam/testcases/JSToJFuncParamTest.java
 > @@ -0,0 +1,226 @@
 > +/* JSToJFuncParamTest.java
 > +Copyright (C) 2012 Red Hat, Inc.
 > +
 > +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, version 2.
 > +
 > +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.
 > + */
 > +
 > +import net.sourceforge.jnlp.ProcessResult;
 > +import net.sourceforge.jnlp.ServerAccess;
 > +import net.sourceforge.jnlp.browsertesting.BrowserTest;
 > +import net.sourceforge.jnlp.browsertesting.Browsers;
 > +import net.sourceforge.jnlp.closinglisteners.CountingClosingListener;
 > +import net.sourceforge.jnlp.annotations.NeedsDisplay;
 > +import net.sourceforge.jnlp.annotations.TestInBrowsers;
 > +import org.junit.Assert;
 > +
 > +import org.junit.Test;
 > +
 > +public class JSToJFuncParamTest extends BrowserTest {
 > +
 > +    private final String initStr = "JSToJFuncParam applet initialized.";
 > +    private final String afterStr = "afterTests";
 > +
 > +    private class CountingClosingListenerImpl extends 
CountingClosingListener {
 > +
 > +            @Override
 > +            protected boolean isAlowedToFinish(String s) {
 > +                return (s.contains(initStr) && s.contains(afterStr));
 > +            }
 > +        }
 > +
 > +    private void evaluateStdoutContents(String expectedStdout, 
ProcessResult pr) {
 > +        // Assert that the applet was initialized.
 > +        Assert.assertTrue("JSToJFuncParam: the stdout should contain 
" + initStr
 > +                + ", but it didnt.", pr.stdout.contains(initStr));
 > +
 > +        // Assert that the values set by JavaScript are ok
 > +        Assert.assertTrue("JSToJFuncParam: the output should 
include: "+expectedStdout+", but it didnt.", 
pr.stdout.contains(expectedStdout));
 > +
 > +    }
 > +
 > +    private void jsToJavaFuncParamNormalTest(String funcStr, String 
paramStr) throws Exception {
 > +        String strURL = "/JSToJFuncParam.html?" + funcStr + ";" + 
paramStr;
 > +        ProcessResult pr = server.executeBrowser(strURL, new 
CountingClosingListenerImpl(), new CountingClosingListenerImpl());
 > +        String expectedStdout = funcStr+" "+ paramStr;
 > +        evaluateStdoutContents(expectedStdout, pr);
 > +    }
 > +
 > +    private void jsToJavaFuncParamSpecialTest(String funcStr, String 
paramStr) throws Exception {

With any luck this won't be needed. Of course let me know if you run 
into problems with the URI decoding function, but it should be fairly 
robust, and not require any change in how data is passed on the Java end.

 > +        String strURL = "/JSToJFuncParam.html?";
 > +        String expectedStdout = "";
 > +
 > +        //special parameters - char, char[], Character, mixed array 
of int and String, DummyObject[]

Just a question on this comment, is there a mixed array of int and 
String in this patch ? I can't seem to see one.

 > +        // - to be set at JS side
 > +        strURL += funcStr + ";JavaScript";
 > +        expectedStdout = funcStr+" "+paramStr;
 > +
 > +        ProcessResult pr = server.executeBrowser(strURL, new 
CountingClosingListenerImpl(), new CountingClosingListenerImpl());
 > +        evaluateStdoutContents(expectedStdout, pr);
 > +    }
 > +
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_int_Test() throws Exception {
 > +        jsToJavaFuncParamNormalTest("intParam", "1");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_double_Test() throws Exception {
 > +        jsToJavaFuncParamNormalTest("doubleParam", "1.1");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_float_Test() throws Exception {
 > +        jsToJavaFuncParamNormalTest("floatParam", "1.1");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_long_Test() throws Exception {
 > +        jsToJavaFuncParamNormalTest("longParam", "10000");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_boolean_Test() throws Exception {
 > +        jsToJavaFuncParamNormalTest("booleanParam", "true");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_char_Test() throws Exception {
 > +        jsToJavaFuncParamSpecialTest("charParam", "a");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_byte_Test() throws Exception {
 > +        jsToJavaFuncParamNormalTest("byteParam", "10");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_charArray_Test() throws Exception {
 > +        jsToJavaFuncParamSpecialTest("charArrayParam", "[a, b, c]");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_String_Test() throws Exception {
 > +        jsToJavaFuncParamSpecialTest("StringParam", "test");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_Integer_Test() throws Exception {
 > +        jsToJavaFuncParamNormalTest("IntegerParam", "1");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_Double_Test() throws Exception {
 > +        jsToJavaFuncParamNormalTest("DoubleParam", "1.1");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_Float_Test() throws Exception {
 > +        jsToJavaFuncParamNormalTest("FloatParam", "1.1");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_Long_Test() throws Exception {
 > +        jsToJavaFuncParamNormalTest("LongParam", "10000");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_Boolean_Test() throws Exception {
 > +        jsToJavaFuncParamNormalTest("BooleanParam", "true");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_Character_Test() throws Exception {
 > +        jsToJavaFuncParamSpecialTest("CharacterParam", "A");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_Byte_Test() throws Exception {
 > +        jsToJavaFuncParamNormalTest("ByteParam", "10");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_StringIntMixed_Test() throws 
Exception {
 > +        jsToJavaFuncParamSpecialTest("StringIntMixedParam", "[test, 
123]");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_DummyObjectArray_Test() throws 
Exception {
 > +        jsToJavaFuncParamSpecialTest("DummyObjectArrayParam", 
"[Dummy1, Dummy2]");
 > +    }
 > +
 > +    @Test
 > +    @TestInBrowsers(testIn = { Browsers.all })
 > +    @NeedsDisplay
 > +    public void AppletJSToJFuncParam_JSObject_Test() throws Exception {
 > +        jsToJavaFuncParamSpecialTest("JSObjectParam", "100, red");
 > +    }
 > +
 > +}

Otherwise it's a great improvement. Try and see if you can get rid of 
the special arguments with the URI decoding tip, if not it isn't a huge 
deal and can probably go in as-is.

Happy hacking,
-Adam



More information about the distro-pkg-dev mailing list