boot/src/test/java/org/netbeans/html/boot/impl/JsClassLoaderBase.java
author Jaroslav Tulach <jtulach@netbeans.org>
Mon, 15 Feb 2016 05:23:17 +0100
changeset 1051 d0e6c8f97dc3
parent 1049 3f4a172c6d8b
child 1052 aca779a0fcec
permissions -rw-r--r--
Returning primitive array should yield ClassCastException during runtime
     1 /**
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved.
     5  *
     6  * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
     7  * Other names may be trademarks of their respective owners.
     8  *
     9  * The contents of this file are subject to the terms of either the GNU
    10  * General Public License Version 2 only ("GPL") or the Common
    11  * Development and Distribution License("CDDL") (collectively, the
    12  * "License"). You may not use this file except in compliance with the
    13  * License. You can obtain a copy of the License at
    14  * http://www.netbeans.org/cddl-gplv2.html
    15  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    16  * specific language governing permissions and limitations under the
    17  * License.  When distributing the software, include this License Header
    18  * Notice in each file and include the License file at
    19  * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
    20  * particular file as subject to the "Classpath" exception as provided
    21  * by Oracle in the GPL Version 2 section of the License file that
    22  * accompanied this code. If applicable, add the following below the
    23  * License Header, with the fields enclosed by brackets [] replaced by
    24  * your own identifying information:
    25  * "Portions Copyrighted [year] [name of copyright owner]"
    26  *
    27  * Contributor(s):
    28  *
    29  * The Original Software is NetBeans. The Initial Developer of the Original
    30  * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved.
    31  *
    32  * If you wish your version of this file to be governed by only the CDDL
    33  * or only the GPL Version 2, indicate your decision by adding
    34  * "[Contributor] elects to include this software in this distribution
    35  * under the [CDDL or GPL Version 2] license." If you do not indicate a
    36  * single choice of license, a recipient has the option to distribute
    37  * your version of this file under either the CDDL, the GPL Version 2 or
    38  * to extend the choice of license to its licensees as provided above.
    39  * However, if you add GPL Version 2 code and therefore, elected the GPL
    40  * Version 2 license, then the option applies only if the new code is
    41  * made subject to such option by the copyright holder.
    42  */
    43 package org.netbeans.html.boot.impl;
    44 
    45 import java.io.Closeable;
    46 import java.lang.reflect.InvocationTargetException;
    47 import java.lang.reflect.Method;
    48 import java.lang.reflect.Modifier;
    49 import java.util.HashMap;
    50 import java.util.Map;
    51 import org.netbeans.html.boot.spi.Fn;
    52 import org.testng.Assert;
    53 import static org.testng.Assert.*;
    54 import org.testng.annotations.BeforeMethod;
    55 import org.testng.annotations.Test;
    56 
    57 /**
    58  *
    59  * @author Jaroslav Tulach
    60  */
    61 public class JsClassLoaderBase {
    62     protected static Class<?> methodClass;
    63     
    64     public JsClassLoaderBase() {
    65     }
    66     
    67     @BeforeMethod
    68     public void assertClassDefined() {
    69         assertNotNull(methodClass, "BeforeClass set up code should provide methodClass");
    70     }
    71 
    72     @Test public void noParamMethod() throws Throwable {
    73         Method plus = methodClass.getMethod("fortyTwo");
    74         try {
    75             final java.lang.Object val = plus.invoke(null);
    76             assertTrue(val instanceof Number, "A number returned " + val);
    77             assertEquals(((Number)val).intValue(), 42);
    78         } catch (InvocationTargetException ex) {
    79             throw ex.getTargetException();
    80         }
    81     }
    82     
    83     @Test public void testExecuteScript() throws Throwable {
    84         Method plus = methodClass.getMethod("plus", int.class, int.class);
    85         try {
    86             assertEquals(plus.invoke(null, 10, 20), 30);
    87         } catch (InvocationTargetException ex) {
    88             throw ex.getTargetException();
    89         }
    90     }
    91 
    92     @Test public void overloadedMethod() throws Throwable {
    93         Method plus = methodClass.getMethod("plus", int.class);
    94         try {
    95             assertEquals(plus.invoke(null, 10), 10);
    96         } catch (InvocationTargetException ex) {
    97             throw ex.getTargetException();
    98         }
    99     }
   100     
   101     @Test public void instanceMethod() throws Throwable {
   102         Method plus = methodClass.getMethod("plusInst", int.class);
   103         java.lang.Object inst = methodClass.newInstance();
   104         try {
   105             assertEquals(plus.invoke(inst, 10), 10);
   106         } catch (InvocationTargetException ex) {
   107             throw ex.getTargetException();
   108         }
   109     }
   110     
   111     @Test public void staticThis() throws Throwable {
   112         Method st = methodClass.getMethod("staticThis");
   113         try {
   114             assertNull(st.invoke(null));
   115         } catch (InvocationTargetException ex) {
   116             throw ex.getTargetException();
   117         }
   118     }
   119 
   120     @Test public void getThis() throws Throwable {
   121         java.lang.Object th = methodClass.newInstance();
   122         Method st = methodClass.getMethod("getThis");
   123         try {
   124             assertEquals(st.invoke(th), th);
   125         } catch (InvocationTargetException ex) {
   126             throw ex.getTargetException();
   127         }
   128     }
   129 
   130     @Test public void primitiveArrayReturn() throws Throwable {
   131         Method st = methodClass.getMethod("both", double.class, double.class);
   132         Throwable ex;
   133         try {
   134             Object arr = st.invoke(null, 2, 5);
   135             ex = null;
   136         } catch (InvocationTargetException invoke) {
   137             ex = invoke.getTargetException();
   138         }
   139         assertTrue(ex instanceof ClassCastException, "Primitive arrays aren't returned from JavaScript: " + ex);
   140     }
   141     
   142     @Test public void truth() throws Throwable {
   143         Method st = methodClass.getMethod("truth");
   144         assertTrue((st.getModifiers() & Modifier.STATIC) != 0, "Is static");
   145         assertEquals(st.invoke(null), Boolean.TRUE, "Can return boolean");
   146     }
   147     
   148     @Test public void callback() throws Throwable {
   149         class R implements Runnable {
   150             int cnt;
   151             
   152             @Override
   153             public void run() {
   154                 cnt++;
   155             }
   156         }
   157         R r = new R();
   158         
   159         Method inc = methodClass.getMethod("callback", Runnable.class);
   160         inc.invoke(null, r);
   161         
   162         assertEquals(r.cnt, 1, "Callback happened");
   163     }
   164     
   165     @Test public void sumArray() throws Throwable {
   166         Method st = methodClass.getMethod("sumArr", int[].class);
   167         assertEquals(st.invoke(null, new int[] { 1, 2, 3 }), 6, "1+2+3 is six");
   168     }
   169     
   170     @Test public void javaScriptResource() throws Throwable {
   171         try {
   172             Method st = methodClass.getMethod("useExternalMul", int.class, int.class);
   173             assertEquals(st.invoke(null, 6, 7), 42, "Meaning of JavaScript?");
   174         } catch (InvocationTargetException ex) {
   175             throw ex.getTargetException();
   176         }
   177     }
   178     
   179     @Test public void callJavaScriptMethodOnOwnClass() throws Throwable {
   180         try {
   181             java.lang.Object thiz = methodClass.newInstance();
   182             Method st = methodClass.getMethod("returnYourSelf", methodClass);
   183             assertEquals(st.invoke(null, thiz), thiz, "Returns this");
   184         } catch (InvocationTargetException ex) {
   185             throw ex.getTargetException();
   186         }
   187     }
   188     
   189     @Test public void callStaticJavaMethod() throws Throwable {
   190         Method st = methodClass.getMethod("staticCallback", int.class, int.class);
   191         assertEquals(st.invoke(null, 6, 7), 42, "Meaning of JavaScript?");
   192     }
   193 
   194     @Test public void callStaticStringParamMethod() throws Throwable {
   195         Method st = methodClass.getMethod("parseInt", String.class);
   196         assertEquals(st.invoke(null, "42"), 42, "Meaning of JavaScript?");
   197     }
   198 
   199     @Test public void passEnum() throws Throwable {
   200         Class<?> enmClazz = methodClass.getDeclaredClasses()[0];
   201         assertTrue(Enum.class.isAssignableFrom(enmClazz), "It is an enum: " + enmClazz);
   202         Class<? extends Enum> enmClazz2 = enmClazz.asSubclass(Enum.class);
   203         Method st = methodClass.getMethod("fromEnum", enmClazz);
   204         
   205         java.lang.Object valueB = Enum.valueOf(enmClazz2, "B");
   206         assertEquals(st.invoke(null, valueB), "B", "Converts to string");
   207     }
   208     
   209     @Test public void firstLong() throws Throwable {
   210         Method st = methodClass.getMethod("chooseLong", boolean.class, boolean.class, long.class, long.class);
   211         assertEquals(st.invoke(null, true, false, 10, 20), 10L, "Take first value");
   212     }
   213 
   214     @Test public void secondLong() throws Throwable {
   215         Method st = methodClass.getMethod("chooseLong", boolean.class, boolean.class, long.class, long.class);
   216         assertEquals(st.invoke(null, false, true, 10, 20), 20L, "Take 2nd value");
   217     }
   218 
   219     @Test public void bothLong() throws Throwable {
   220         Method st = methodClass.getMethod("chooseLong", boolean.class, boolean.class, long.class, long.class);
   221         assertEquals(st.invoke(null, true, true, 10, 20), 30L, "Take both values");
   222     }
   223     
   224     @Test public void recordError() throws Throwable {
   225         Method st = methodClass.getMethod("recordError", java.lang.Object.class);
   226         assertEquals(st.invoke(methodClass.newInstance(), "Hello"), "Hello", "The same parameter returned");
   227     }
   228     
   229     @Test public void plusOrMul() throws Throwable {
   230         Method st = methodClass.getMethod("plusOrMul", int.class, int.class);
   231         assertNotNull(Fn.activePresenter(), "Is there a presenter?");
   232         Closeable c = Fn.activate(null);
   233         try {
   234             assertNull(Fn.activePresenter(), "No presenter now");
   235             assertEquals(st.invoke(null, 6, 7), 42, "Mul in Java");
   236         } finally {
   237             c.close();
   238         }
   239         assertNotNull(Fn.activePresenter(), "Is there a presenter again");
   240         assertEquals(st.invoke(null, 6, 7), 13, "Plus in JavaScript");
   241         c = Fn.activate(null);
   242         try {
   243             assertNull(Fn.activePresenter(), "No presenter again");
   244             assertEquals(st.invoke(null, 6, 7), 42, "Mul in Java");
   245         } finally {
   246             c.close();
   247         }
   248         assertNotNull(Fn.activePresenter(), "Is there a presenter again");
   249         assertEquals(st.invoke(null, 6, 7), 13, "Plus in JavaScript again");
   250     }
   251     
   252     @Test public void arrayInOut() throws Throwable {
   253         String[] arr = { "Ahoj" };
   254         Method st = methodClass.getMethod("arr", java.lang.Object[].class);
   255         java.lang.Object ret = st.invoke(null, (java.lang.Object) arr);
   256         assertTrue(ret instanceof java.lang.Object[], "Expecting array: " + ret);
   257         java.lang.Object[] res = (java.lang.Object[]) ret;
   258         assertEquals(res.length, 1, "One element");
   259         assertEquals(res[0], "Ahoj", "The right string");
   260     }
   261 
   262     @Test public void parametricCallback() throws Throwable {
   263         Map<String,Number> map = new HashMap<String, Number>();
   264         Method st = methodClass.getMethod("callParamTypes", Map.class, int.class);
   265         st.invoke(null, map, 42);
   266         assertEquals(map.get("key").intValue(), 42, "The right value");
   267     }
   268     
   269    @Test public void checkTheTypeOfThrownException() throws Throwable {
   270         FnContext.currentPresenter(null);
   271         assertNull(Fn.activePresenter(), "No presenter is activer right now");
   272         java.lang.Object res = null;
   273         try {
   274             Method st = methodClass.getMethod("plus", int.class, int.class);
   275             try {
   276                 res = st.invoke(null, 40, 2);
   277                 Assert.fail("Native method should throw IllegalStateException. Was: " + res);
   278             } catch (InvocationTargetException ex) {
   279                 throw ex.getTargetException();
   280             }
   281         } catch (IllegalStateException ex) {
   282             assertEquals(ex.getMessage(), "No presenter active. Use BrwsrCtx.execute!");
   283         }
   284     }    
   285 }