boot/src/test/java/org/netbeans/html/boot/impl/FnTest.java
author Jaroslav Tulach <jtulach@netbeans.org>
Fri, 15 Jan 2016 11:40:28 +0100
changeset 1041 36165f49f598
parent 838 bdc3d696dd4a
permissions -rw-r--r--
Use fully qualified names when referencing java.lang.Object
     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.io.Flushable;
    47 import java.io.IOException;
    48 import java.io.Reader;
    49 import java.net.URL;
    50 import java.net.URLClassLoader;
    51 import java.util.ArrayList;
    52 import java.util.Arrays;
    53 import java.util.Collection;
    54 import java.util.List;
    55 import javax.script.Invocable;
    56 import javax.script.ScriptEngine;
    57 import javax.script.ScriptEngineManager;
    58 import javax.script.ScriptException;
    59 import org.netbeans.html.boot.spi.Fn;
    60 import static org.testng.Assert.assertEquals;
    61 import org.testng.annotations.BeforeClass;
    62 import org.testng.annotations.BeforeMethod;
    63 import org.testng.annotations.Test;
    64 
    65 /**
    66  *
    67  * @author Jaroslav Tulach
    68  */
    69 public class FnTest extends JsClassLoaderBase {
    70     private static Fn.Presenter presenter;
    71     
    72     public FnTest() {
    73     }
    74 
    75     @BeforeClass
    76     public static void createClassLoader() throws Exception {
    77         ScriptEngineManager sem = new ScriptEngineManager();
    78         final ScriptEngine eng = sem.getEngineByMimeType("text/javascript");
    79         
    80         final URL my = FnTest.class.getProtectionDomain().getCodeSource().getLocation();
    81         ClassLoader parent = JsClassLoaderTest.class.getClassLoader().getParent();
    82         final URLClassLoader ul = new URLClassLoader(new URL[] { my }, parent);
    83         
    84         class Impl implements FindResources, Fn.Presenter {
    85             @Override
    86             public void findResources(String path, Collection<? super URL> results, boolean oneIsEnough) {
    87                 URL u = ul.findResource(path);
    88                 if (u != null) {
    89                     results.add(u);
    90                 }
    91             }
    92 
    93             @Override
    94             public Fn defineFn(String code, String... names) {
    95                 StringBuilder sb = new StringBuilder();
    96                 sb.append("(function() {");
    97                 sb.append("return function(");
    98                 String sep = "";
    99                 for (String n : names) {
   100                     sb.append(sep);
   101                     sb.append(n);
   102                     sep = ", ";
   103                 }
   104                 sb.append(") {");
   105                 sb.append(code);
   106                 sb.append("};");
   107                 sb.append("})()");
   108                 try {
   109                     final java.lang.Object val = eng.eval(sb.toString());
   110                     return new Fn(this) {
   111                         @Override
   112                         public java.lang.Object invoke(java.lang.Object thiz, java.lang.Object... args) throws Exception {
   113                             List<java.lang.Object> all = new ArrayList<java.lang.Object>(args.length + 1);
   114                             all.add(thiz == null ? val : thiz);
   115                             all.addAll(Arrays.asList(args));
   116                             Invocable inv = (Invocable)eng;
   117                             try {
   118                                 java.lang.Object ret = inv.invokeMethod(val, "call", all.toArray());
   119                                 return val.equals(ret) ? null : ret;
   120                             } catch (ScriptException ex) {
   121                                 throw ex;
   122                             }
   123                         }
   124                     };
   125                 } catch (ScriptException ex) {
   126                     throw new LinkageError("Can't parse: " + sb, ex);
   127                 }
   128             }
   129 
   130             @Override
   131             public void displayPage(URL resource, Runnable r) {
   132                 throw new UnsupportedOperationException();
   133             }
   134 
   135             @Override
   136             public void loadScript(Reader code) throws Exception {
   137                 eng.eval(code);
   138             }
   139         }
   140         Impl impl = new Impl();
   141         ClassLoader loader = FnUtils.newLoader(impl, impl, parent);
   142         presenter = impl;
   143         
   144         Closeable close = FnContext.activate(impl);
   145         methodClass = loader.loadClass(JsMethods.class.getName());
   146         close.close();
   147     }
   148     
   149     @Test public void flushingPresenter() throws IOException {
   150         class FP implements Fn.Presenter, Flushable {
   151             int flush;
   152 
   153             @Override
   154             public Fn defineFn(String code, String... names) {
   155                 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   156             }
   157 
   158             @Override
   159             public void displayPage(URL page, Runnable onPageLoad) {
   160                 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   161             }
   162 
   163             @Override
   164             public void loadScript(Reader code) throws Exception {
   165                 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   166             }
   167 
   168             @Override
   169             public void flush() throws IOException {
   170                 flush++;
   171             }
   172         }
   173         
   174         FP p = new FP();
   175         Closeable c1 = Fn.activate(p);
   176         Closeable c2 = Fn.activate(p);
   177         c2.close();
   178         assertEquals(p.flush, 0, "No flush yet");
   179         c1.close();
   180         assertEquals(p.flush, 1, "Now flushed");
   181     }
   182 
   183     @BeforeMethod public void initPresenter() {
   184         FnContext.currentPresenter(presenter);
   185     }
   186 }