http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXJavaScriptTest.java ---------------------------------------------------------------------- diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXJavaScriptTest.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXJavaScriptTest.java new file mode 100644 index 0000000..f531d4c --- /dev/null +++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXJavaScriptTest.java @@ -0,0 +1,124 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.html.boot.fx; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import net.java.html.BrwsrCtx; +import net.java.html.boot.BrowserBuilder; +import org.netbeans.html.boot.spi.Fn; +import org.netbeans.html.json.tck.KOTest; +import org.testng.Assert; +import static org.testng.Assert.assertNotSame; +import static org.testng.Assert.assertSame; +import org.testng.annotations.Factory; + +/** + * + * @author Jaroslav Tulach + */ +public class FXJavaScriptTest { + private static Class<?> browserClass; + private static Fn.Presenter browserPresenter; + + public FXJavaScriptTest() { + } + + @Factory public static Object[] compatibilityTests() throws Exception { + final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(FXJavaScriptTest.class). + loadPage("empty.html"). + invoke("initialized"); + + Executors.newSingleThreadExecutor().submit(new Runnable() { + @Override + public void run() { + bb.showAndWait(); + } + }); + + List<Object> res = new ArrayList<Object>(); + Class<? extends Annotation> test = + loadClass().getClassLoader().loadClass(KOTest.class.getName()). + asSubclass(Annotation.class); + + Class[] arr = (Class[]) loadClass().getDeclaredMethod("tests").invoke(null); + for (Class c : arr) { + for (Method m : c.getMethods()) { + if (m.getAnnotation(test) != null) { + res.add(new KOFx(browserPresenter, m)); + } + } + } + return res.toArray(); + } + + static synchronized Class<?> loadClass() throws InterruptedException { + while (browserClass == null) { + FXJavaScriptTest.class.wait(); + } + return browserClass; + } + + public static synchronized void ready(Class<?> browserCls) throws Exception { + browserClass = browserCls; + browserPresenter = Fn.activePresenter(); + FXJavaScriptTest.class.notifyAll(); + } + + public static void initialized() throws Exception { + BrwsrCtx b1 = BrwsrCtx.findDefault(FXJavaScriptTest.class); + TestingProvider.assertCalled("Our context created"); + assertNotSame(b1, BrwsrCtx.EMPTY, "Browser context is not empty"); + BrwsrCtx b2 = BrwsrCtx.findDefault(FXJavaScriptTest.class); + assertSame(b1, b2, "Browser context remains stable"); + Assert.assertSame( + FXJavaScriptTest.class.getClassLoader(), + ClassLoader.getSystemClassLoader(), + "No special classloaders" + ); + FXJavaScriptTest.ready(FxJavaScriptTst.class); + } +}
http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXPresenterTst.java ---------------------------------------------------------------------- diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXPresenterTst.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXPresenterTst.java new file mode 100644 index 0000000..8a93ad3 --- /dev/null +++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/FXPresenterTst.java @@ -0,0 +1,103 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.html.boot.fx; + +import java.util.logging.Handler; +import java.util.logging.LogRecord; +import net.java.html.js.JavaScriptBody; +import static org.testng.Assert.*; +import org.testng.annotations.Test; + +/** + * + * @author Jaroslav Tulach + */ +public class FXPresenterTst { + @Test public void showClassLoader() { + R run = new R(); + callback(run); + assertEquals(run.cnt, 1, "Can call even private implementation classes"); + } + + @Test public void checkConsoleLogging() { + class H extends Handler { + LogRecord record; + + @Override + public void publish(LogRecord record) { + assert this.record == null; + this.record = record; + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + } + H h = new H(); + FXConsole.LOG.addHandler(h); + + log("Ahoj"); + + assert h.record != null : "Some log record obtained"; + assert "Ahoj".equals(h.record.getMessage()) : "It is our Ahoj: " + h.record.getMessage(); + } + + @JavaScriptBody(args = { "r" }, javacall = true, body = "[email protected]::run()();") + private static native void callback(Runnable r); + + @JavaScriptBody(args = { "msg" }, body = "console.log(msg);") + private static native void log(String msg); + + private static class R implements Runnable { + int cnt; + + @Override + public void run() { + cnt++; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/FxJavaScriptTst.java ---------------------------------------------------------------------- diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/FxJavaScriptTst.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/FxJavaScriptTst.java new file mode 100644 index 0000000..5a1a042 --- /dev/null +++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/FxJavaScriptTst.java @@ -0,0 +1,55 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.html.boot.fx; + +import org.netbeans.html.json.tck.JavaScriptTCK; + +/** + * + * @author Jaroslav Tulach + */ +public final class FxJavaScriptTst extends JavaScriptTCK { + public static Class[] tests() { + return testClasses(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/KOFx.java ---------------------------------------------------------------------- diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/KOFx.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/KOFx.java new file mode 100644 index 0000000..6d12324 --- /dev/null +++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/KOFx.java @@ -0,0 +1,125 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.html.boot.fx; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import javafx.application.Platform; +import org.netbeans.html.boot.impl.FnContext; +import org.netbeans.html.boot.spi.Fn; +import org.testng.IHookCallBack; +import org.testng.IHookable; +import org.testng.ITest; +import org.testng.ITestResult; +import org.testng.annotations.Test; + +/** + * + * @author Jaroslav Tulach + */ +public final class KOFx implements ITest, IHookable, Runnable { + private final Fn.Presenter p; + private final Method m; + private Object result; + private Object inst; + + KOFx(Fn.Presenter p, Method m) { + this.p = p; + this.m = m; + } + + @Override + public String getTestName() { + return m.getName(); + } + + @Test + public synchronized void executeTest() throws Exception { + if (result == null) { + Platform.runLater(this); + wait(); + } + if (result instanceof Exception) { + throw (Exception)result; + } + if (result instanceof Error) { + throw (Error)result; + } + } + + @Override + public synchronized void run() { + boolean notify = true; + try { + FnContext.currentPresenter(p); + if (inst == null) { + inst = m.getDeclaringClass().newInstance(); + } + result = m.invoke(inst); + if (result == null) { + result = this; + } + } catch (InvocationTargetException ex) { + Throwable r = ex.getTargetException(); + if (r instanceof InterruptedException) { + notify = false; + Platform.runLater(this); + return; + } + result = r; + } catch (Exception ex) { + result = ex; + } finally { + if (notify) { + notifyAll(); + } + FnContext.currentPresenter(null); + } + } + + @Override + public void run(IHookCallBack ihcb, ITestResult itr) { + ihcb.runTestMethod(itr); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/ReloadTest.java ---------------------------------------------------------------------- diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/ReloadTest.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/ReloadTest.java new file mode 100644 index 0000000..5a704f5 --- /dev/null +++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/ReloadTest.java @@ -0,0 +1,157 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.html.boot.fx; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import javafx.application.Platform; +import net.java.html.BrwsrCtx; +import net.java.html.boot.BrowserBuilder; +import net.java.html.js.JavaScriptBody; +import org.netbeans.html.boot.spi.Fn; +import static org.testng.Assert.*; +import org.testng.annotations.Test; + +/** + * + * @author Jaroslav Tulach + */ +public class ReloadTest { + private static Runnable whenInitialized; + + public ReloadTest() { + } + + @JavaScriptBody(args = { "a", "b" }, body = "return a + b;") + private static native int plus(int a, int b); + + @Test public void checkReload() throws Throwable { + final Throwable[] arr = { null }; + + final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(ReloadTest.class). + loadPage("empty.html"). + invoke("initialized"); + + class ShowBrowser implements Runnable { + @Override + public void run() { + bb.showAndWait(); + } + } + + class WhenInitialized implements Runnable { + CountDownLatch cdl = new CountDownLatch(1); + AbstractFXPresenter p; + BrwsrCtx ctx; + + @Override + public void run() { + try { + whenInitialized = null; + doCheckReload(); + p = (AbstractFXPresenter) Fn.activePresenter(); + assertNotNull(p, "Presenter is defined"); + ctx = BrwsrCtx.findDefault(WhenInitialized.class); + } catch (Throwable ex) { + arr[0] = ex; + } finally { + cdl.countDown(); + } + } + } + WhenInitialized when = new WhenInitialized(); + whenInitialized = when; + Executors.newSingleThreadExecutor().submit(new ShowBrowser()); + when.cdl.await(); + if (arr[0] != null) throw arr[0]; + + class ReloadPage implements Runnable { + final CountDownLatch cdl = new CountDownLatch(1); + private final AbstractFXPresenter p; + + public ReloadPage(AbstractFXPresenter p) { + this.p = p; + } + + @Override + public void run() { + p.engine.reload(); + cdl.countDown(); + } + } + ReloadPage relPage = new ReloadPage(when.p); + + class SecondInit implements Runnable { + CountDownLatch cdl = new CountDownLatch(1); + + @Override + public void run() { + try { + whenInitialized = null; + doCheckReload(); + } catch (Throwable ex) { + arr[0] = ex; + } finally { + cdl.countDown(); + } + + } + } + SecondInit second = new SecondInit(); + whenInitialized = second; + + Platform.runLater(relPage); + + second.cdl.await(); + if (arr[0] != null) throw arr[0]; + } + + final void doCheckReload() throws Exception { + int res = plus(30, 12); + assertEquals(res, 42, "Meaning of world computed"); + } + + public static synchronized void initialized() throws Exception { + whenInitialized.run(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/TestingProvider.java ---------------------------------------------------------------------- diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/TestingProvider.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/TestingProvider.java new file mode 100644 index 0000000..a79baef --- /dev/null +++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/TestingProvider.java @@ -0,0 +1,65 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.html.boot.fx; + +import org.netbeans.html.context.spi.Contexts; +import org.openide.util.lookup.ServiceProvider; +import static org.testng.Assert.assertTrue; + +/** + * + * @author Jaroslav Tulach + */ +@ServiceProvider(service = Contexts.Provider.class) +public final class TestingProvider implements Contexts.Provider { + + static void assertCalled(String msg) { + assertTrue(Boolean.getBoolean(TestingProvider.class.getName()), msg); + } + + @Override + public void fillContext(Contexts.Builder context, Class<?> requestor) { + System.setProperty(TestingProvider.class.getName(), "true"); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/netbeans/html/boot/fx/TitleTest.java ---------------------------------------------------------------------- diff --git a/boot-fx/src/test/java/org/netbeans/html/boot/fx/TitleTest.java b/boot-fx/src/test/java/org/netbeans/html/boot/fx/TitleTest.java new file mode 100644 index 0000000..8b09be3 --- /dev/null +++ b/boot-fx/src/test/java/org/netbeans/html/boot/fx/TitleTest.java @@ -0,0 +1,146 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.netbeans.html.boot.fx; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import javafx.beans.value.ChangeListener; +import javafx.beans.value.ObservableValue; +import javafx.stage.Stage; +import net.java.html.BrwsrCtx; +import net.java.html.boot.BrowserBuilder; +import net.java.html.js.JavaScriptBody; +import org.netbeans.html.boot.spi.Fn; +import static org.testng.Assert.*; +import org.testng.annotations.Test; + +/** + * + * @author Jaroslav Tulach + */ +public class TitleTest { + private static Runnable whenInitialized; + + public TitleTest() { + } + + @JavaScriptBody(args = { "a", "b" }, body = "return a + b;") + private static native int plus(int a, int b); + + @Test public void checkReload() throws Throwable { + final Throwable[] arr = { null }; + + final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(TitleTest.class). + loadPage("empty.html"). + invoke("initialized"); + + class ShowBrowser implements Runnable { + @Override + public void run() { + bb.showAndWait(); + } + } + + class WhenInitialized implements Runnable { + CountDownLatch cdl = new CountDownLatch(1); + AbstractFXPresenter p; + BrwsrCtx ctx; + + @Override + public void run() { + try { + whenInitialized = null; + doCheckReload(); + p = (AbstractFXPresenter) Fn.activePresenter(); + assertNotNull(p, "Presenter is defined"); + ctx = BrwsrCtx.findDefault(WhenInitialized.class); + } catch (Throwable ex) { + arr[0] = ex; + } finally { + cdl.countDown(); + } + } + } + WhenInitialized when = new WhenInitialized(); + whenInitialized = when; + Executors.newSingleThreadExecutor().submit(new ShowBrowser()); + when.cdl.await(); + if (arr[0] != null) throw arr[0]; + + Stage s = FXBrwsr.findStage(); + assertEquals(s.getTitle(), "FX Presenter Harness"); + + final CountDownLatch propChange = new CountDownLatch(1); + s.titleProperty().addListener(new ChangeListener<String>() { + @Override + public void changed(ObservableValue<? extends String> ov, String t, String t1) { + propChange.countDown(); + } + }); + + when.ctx.execute(new Runnable() { + @Override + public void run() { + changeTitle("New title"); + } + }); + + propChange.await(5, TimeUnit.SECONDS); + assertEquals(s.getTitle(), "New title"); + } + + final void doCheckReload() throws Exception { + int res = plus(30, 12); + assertEquals(res, 42, "Meaning of world computed"); + } + + public static synchronized void initialized() throws Exception { + whenInitialized.run(); + } + + @JavaScriptBody(args = { "s" }, body = + "document.getElementsByTagName('title')[0].innerHTML = s;" + ) + static native void changeTitle(String s); +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/java/org/sample/app/pkg/SampleApp.java ---------------------------------------------------------------------- diff --git a/boot-fx/src/test/java/org/sample/app/pkg/SampleApp.java b/boot-fx/src/test/java/org/sample/app/pkg/SampleApp.java new file mode 100644 index 0000000..ab83113 --- /dev/null +++ b/boot-fx/src/test/java/org/sample/app/pkg/SampleApp.java @@ -0,0 +1,62 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package org.sample.app.pkg; + +import net.java.html.boot.BrowserBuilder; +import org.netbeans.html.boot.fx.FXBrwsrTest; + +public class SampleApp implements Runnable { + + public static void main() { + BrowserBuilder.newBrowser() + .loadPage("org/netbeans/html/boot/fx/empty.html") // NOI18N + .loadFinished(new SampleApp()) + .showAndWait(); + } + + @Override + public void run() { + FXBrwsrTest.computeCalleeClassName(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/resources/net/java/html/boot/fx/wnd.js ---------------------------------------------------------------------- diff --git a/boot-fx/src/test/resources/net/java/html/boot/fx/wnd.js b/boot-fx/src/test/resources/net/java/html/boot/fx/wnd.js new file mode 100644 index 0000000..acd0f9e --- /dev/null +++ b/boot-fx/src/test/resources/net/java/html/boot/fx/wnd.js @@ -0,0 +1,49 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +if (typeof wnd !== 'undefined') { + throw 'Window should not be defined yet: ' + wnd; +} + +wnd = { +}; + http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-fx/src/test/resources/org/netbeans/html/boot/fx/empty.html ---------------------------------------------------------------------- diff --git a/boot-fx/src/test/resources/org/netbeans/html/boot/fx/empty.html b/boot-fx/src/test/resources/org/netbeans/html/boot/fx/empty.html new file mode 100644 index 0000000..c292ab3 --- /dev/null +++ b/boot-fx/src/test/resources/org/netbeans/html/boot/fx/empty.html @@ -0,0 +1,55 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + + Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + + Oracle and Java are registered trademarks of Oracle and/or its affiliates. + Other names may be trademarks of their respective owners. + + The contents of this file are subject to the terms of either the GNU + General Public License Version 2 only ("GPL") or the Common + Development and Distribution License("CDDL") (collectively, the + "License"). You may not use this file except in compliance with the + License. You can obtain a copy of the License at + http://www.netbeans.org/cddl-gplv2.html + or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + specific language governing permissions and limitations under the + License. When distributing the software, include this License Header + Notice in each file and include the License file at + nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + particular file as subject to the "Classpath" exception as provided + by Oracle in the GPL Version 2 section of the License file that + accompanied this code. If applicable, add the following below the + License Header, with the fields enclosed by brackets [] replaced by + your own identifying information: + "Portions Copyrighted [year] [name of copyright owner]" + + Contributor(s): + + The Original Software is NetBeans. The Initial Developer of the Original + Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + + If you wish your version of this file to be governed by only the CDDL + or only the GPL Version 2, indicate your decision by adding + "[Contributor] elects to include this software in this distribution + under the [CDDL or GPL Version 2] license." If you do not indicate a + single choice of license, a recipient has the option to distribute + your version of this file under either the CDDL, the GPL Version 2 or + to extend the choice of license to its licensees as provided above. + However, if you add GPL Version 2 code and therefore, elected the GPL + Version 2 license, then the option applies only if the new code is + made subject to such option by the copyright holder. + +--> +<!DOCTYPE html> +<html> + <head> + <title>FX Presenter Harness</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <meta name="viewport" content="width=device-width"> + </head> + <body> + <div>FX Presenter Harness</div> + </body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/pom.xml ---------------------------------------------------------------------- diff --git a/boot-script/pom.xml b/boot-script/pom.xml new file mode 100644 index 0000000..55073fd --- /dev/null +++ b/boot-script/pom.xml @@ -0,0 +1,152 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + + Copyright 2013-2016 Oracle and/or its affiliates. All rights reserved. + + Oracle and Java are registered trademarks of Oracle and/or its affiliates. + Other names may be trademarks of their respective owners. + + The contents of this file are subject to the terms of either the GNU + General Public License Version 2 only ("GPL") or the Common + Development and Distribution License("CDDL") (collectively, the + "License"). You may not use this file except in compliance with the + License. You can obtain a copy of the License at + http://www.netbeans.org/cddl-gplv2.html + or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + specific language governing permissions and limitations under the + License. When distributing the software, include this License Header + Notice in each file and include the License file at + nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + particular file as subject to the "Classpath" exception as provided + by Oracle in the GPL Version 2 section of the License file that + accompanied this code. If applicable, add the following below the + License Header, with the fields enclosed by brackets [] replaced by + your own identifying information: + "Portions Copyrighted [year] [name of copyright owner]" + + Contributor(s): + + The Original Software is NetBeans. The Initial Developer of the Original + Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + + If you wish your version of this file to be governed by only the CDDL + or only the GPL Version 2, indicate your decision by adding + "[Contributor] elects to include this software in this distribution + under the [CDDL or GPL Version 2] license." If you do not indicate a + single choice of license, a recipient has the option to distribute + your version of this file under either the CDDL, the GPL Version 2 or + to extend the choice of license to its licensees as provided above. + However, if you add GPL Version 2 code and therefore, elected the GPL + Version 2 license, then the option applies only if the new code is + made subject to such option by the copyright holder. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.netbeans.html</groupId> + <artifactId>pom</artifactId> + <version>2.0-SNAPSHOT</version> + </parent> + <name>Presenter via javax.script</name> + <artifactId>net.java.html.boot.script</artifactId> + <version>2.0-SNAPSHOT</version> + <packaging>bundle</packaging> + <properties> + <netbeans.compile.on.save>NONE</netbeans.compile.on.save> + <publicPackages>net.java.html.boot.script</publicPackages> + </properties> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <Export-Package>${publicPackages}</Export-Package> + <Bundle-SymbolicName>net.java.html.boot.script</Bundle-SymbolicName> + </instructions> + </configuration> + </plugin> + <plugin> + <groupId>org.netbeans.html</groupId> + <artifactId>html4j-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>2.3.2</version> + <configuration> + <source>1.7</source> + <target>1.7</target> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>org.netbeans.api</groupId> + <artifactId>org-openide-util-lookup</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.netbeans.html</groupId> + <artifactId>net.java.html.boot</artifactId> + <version>${project.version}</version> + <type>jar</type> + </dependency> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>net.java.html.json.tck</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.glassfish.grizzly</groupId> + <artifactId>grizzly-http-server</artifactId> + <version>${grizzly.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.glassfish.grizzly</groupId> + <artifactId>grizzly-websockets-server</artifactId> + <version>${grizzly.version}</version> + <scope>test</scope> + <type>jar</type> + </dependency> + <dependency> + <groupId>org.glassfish.grizzly</groupId> + <artifactId>grizzly-http-servlet</artifactId> + <version>${grizzly.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + <scope>test</scope> + <version>3.1.0</version> + </dependency> + <dependency> + <groupId>org.netbeans.html</groupId> + <artifactId>ko4j</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <type>jar</type> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>ko-ws-tyrus</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <type>jar</type> + </dependency> + </dependencies> +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/src/main/java/net/java/html/boot/script/ScriptPresenter.java ---------------------------------------------------------------------- diff --git a/boot-script/src/main/java/net/java/html/boot/script/ScriptPresenter.java b/boot-script/src/main/java/net/java/html/boot/script/ScriptPresenter.java new file mode 100644 index 0000000..82dabff --- /dev/null +++ b/boot-script/src/main/java/net/java/html/boot/script/ScriptPresenter.java @@ -0,0 +1,443 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.script; + +import java.io.Closeable; +import java.io.IOException; +import java.io.ObjectOutput; +import java.io.Reader; +import java.lang.ref.WeakReference; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executor; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.script.Invocable; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.netbeans.html.boot.spi.Fn; +import org.netbeans.html.boot.spi.Fn.Presenter; + +/** Implementation of {@link Presenter} that delegates + * to Java {@link ScriptEngine scripting} API. The presenter runs headless + * without appropriate simulation of browser APIs. Its primary usefulness + * is inside testing environments. + * <p> + * One can load in browser simulation for example from + * <a href="http://www.envjs.com/">env.js</a>. The best way to achieve so, + * is to wait until JDK-8046013 gets fixed.... + * + * + * @author Jaroslav Tulach + */ +final class ScriptPresenter implements Fn.KeepAlive, +Presenter, Fn.FromJavaScript, Fn.ToJavaScript, Executor { + private static final Logger LOG = Logger.getLogger(ScriptPresenter.class.getName()); + private static final boolean JDK7; + static { + boolean jdk7; + try { + Class.forName("java.lang.FunctionalInterface"); + jdk7 = false; + } catch (ClassNotFoundException ex) { + jdk7 = true; + } + JDK7 = jdk7; + } + private final ScriptEngine eng; + private final Executor exc; + private final Object undefined; + + public ScriptPresenter(Executor exc) { + this.exc = exc; + try { + eng = new ScriptEngineManager().getEngineByName("javascript"); + eng.eval("function alert(msg) { Packages.java.lang.System.out.println(msg); };"); + eng.eval("function confirm(msg) { Packages.java.lang.System.out.println(msg); return true; };"); + eng.eval("function prompt(msg, txt) { Packages.java.lang.System.out.println(msg + ':' + txt); return txt; };"); + Object undef; + if (JDK7) { + undef = new JDK7Callback().undefined(eng); + } else { + undef = ((Object[])eng.eval("Java.to([undefined])"))[0]; + } + this.undefined = undef; + } catch (ScriptException ex) { + throw new IllegalStateException(ex); + } + } + + @Override + public Fn defineFn(String code, String... names) { + return defineImpl(code, names, null); + } + + @Override + public Fn defineFn(String code, String[] names, boolean[] keepAlive) { + return defineImpl(code, names, keepAlive); + } + private FnImpl defineImpl(String code, String[] names, boolean[] keepAlive) { + StringBuilder sb = new StringBuilder(); + sb.append("(function() {\n"); + sb.append(" return function("); + String sep = ""; + if (names != null) for (String n : names) { + sb.append(sep).append(n); + sep = ","; + } + sb.append(") {\n"); + sb.append(code); + sb.append("\n };\n"); + sb.append("})()\n"); + + final Object fn; + try { + fn = eng.eval(sb.toString()); + } catch (ScriptException ex) { + throw new IllegalStateException(ex); + } + return new FnImpl(this, fn, keepAlive); + } + + @Override + public void displayPage(URL page, Runnable onPageLoad) { + try { + eng.eval("if (typeof window !== 'undefined') window.location = '" + page + "'"); + } catch (ScriptException ex) { + LOG.log(Level.SEVERE, "Cannot load " + page, ex); + } + if (onPageLoad != null) { + onPageLoad.run(); + } + } + + @Override + public void loadScript(Reader code) throws Exception { + eng.eval(code); + } + + // + // array conversions + // + + final Object convertArrays(Object[] arr) throws Exception { + for (int i = 0; i < arr.length; i++) { + if (arr[i] instanceof Object[]) { + arr[i] = convertArrays((Object[]) arr[i]); + } + } + final Object wrapArr = wrapArrFn().invokeImpl(null, false, arr); // NOI18N + return wrapArr; + } + + private FnImpl wrapArrImpl; + private FnImpl wrapArrFn() { + if (wrapArrImpl == null) { + try { + wrapArrImpl = defineImpl("return Array.prototype.slice.call(arguments);", null, null); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + return wrapArrImpl; + } + + final Object checkArray(Object val) throws Exception { + final FnImpl fn = arraySizeFn(); + final Object fnRes = fn.invokeImpl(null, false, val, null); + int length = ((Number) fnRes).intValue(); + if (length == -1) { + return val; + } + Object[] arr = new Object[length]; + fn.invokeImpl(null, false, val, arr); + return arr; + } + + private FnImpl arraySize; + private FnImpl arraySizeFn() { + if (arraySize == null) { + try { + arraySize = defineImpl("\n" + + "if (to === null) {\n" + + " if (Object.prototype.toString.call(arr) === '[object Array]') return arr.length;\n" + + " else return -1;\n" + + "} else {\n" + + " var l = arr.length;\n" + + " for (var i = 0; i < l; i++) {\n" + + " to[i] = arr[i] === undefined ? null : arr[i];\n" + + " }\n" + + " return l;\n" + + "}", new String[] { "arr", "to" }, null + ); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + return arraySize; + } + + @Override + public Object toJava(Object toJS) { + if (toJS instanceof Weak) { + toJS = ((Weak)toJS).get(); + } + if (toJS == undefined) { + return null; + } + try { + return checkArray(toJS); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + + @Override + public Object toJavaScript(Object toReturn) { + if (toReturn instanceof Object[]) { + try { + return convertArrays((Object[])toReturn); + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } else { + if (JDK7) { + if (toReturn instanceof Boolean) { + return ((Boolean)toReturn) ? true : null; + } + } + return toReturn; + } + } + + @Override + public void execute(final Runnable command) { + if (Fn.activePresenter() == this) { + command.run(); + return; + } + + class Wrap implements Runnable { + public void run() { + try (Closeable c = Fn.activate(ScriptPresenter.this)) { + command.run(); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + } + } + final Runnable wrap = new Wrap(); + if (exc == null) { + wrap.run(); + } else { + exc.execute(wrap); + } + } + + private class FnImpl extends Fn { + + private final Object fn; + private final boolean[] keepAlive; + + public FnImpl(Presenter presenter, Object fn, boolean[] keepAlive) { + super(presenter); + this.fn = fn; + this.keepAlive = keepAlive; + } + + @Override + public Object invoke(Object thiz, Object... args) throws Exception { + return invokeImpl(thiz, true, args); + } + + final Object invokeImpl(Object thiz, boolean arrayChecks, Object... args) throws Exception { + List<Object> all = new ArrayList<>(args.length + 1); + all.add(thiz == null ? fn : thiz); + for (int i = 0; i < args.length; i++) { + Object conv = args[i]; + if (arrayChecks) { + if (args[i] instanceof Object[]) { + Object[] arr = (Object[]) args[i]; + conv = ((ScriptPresenter) presenter()).convertArrays(arr); + } + if (conv != null && keepAlive != null + && !keepAlive[i] && !isJSReady(conv) + && !conv.getClass().getSimpleName().equals("$JsCallbacks$") // NOI18N + ) { + conv = new Weak(conv); + } + if (conv instanceof Character) { + conv = (int)(Character)conv; + } + } + all.add(conv); + } + Object ret = ((Invocable)eng).invokeMethod(fn, "call", all.toArray()); // NOI18N + if (ret instanceof Weak) { + ret = ((Weak)ret).get(); + } + if (ret == fn) { + return null; + } + if (!arrayChecks) { + return ret; + } + return ((ScriptPresenter)presenter()).checkArray(ret); + } + } + + private static boolean isJSReady(Object obj) { + if (obj == null) { + return true; + } + if (obj instanceof String) { + return true; + } + if (obj instanceof Number) { + return true; + } + final String cn = obj.getClass().getName(); + if (cn.startsWith("jdk.nashorn") || ( // NOI18N + cn.contains(".mozilla.") && cn.contains(".Native") // NOI18N + )) { + return true; + } + if (obj instanceof Character) { + return true; + } + return false; + } + + private static final class Weak extends WeakReference<Object> { + public Weak(Object referent) { + super(referent); + } + } + + private static final class JDK7Callback implements ObjectOutput { + private Object undefined; + + @Override + public void writeObject(Object obj) throws IOException { + undefined = obj; + } + + @Override + public void write(int b) throws IOException { + } + + @Override + public void write(byte[] b) throws IOException { + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + } + + @Override + public void flush() throws IOException { + } + + @Override + public void close() throws IOException { + } + + @Override + public void writeBoolean(boolean v) throws IOException { + } + + @Override + public void writeByte(int v) throws IOException { + } + + @Override + public void writeShort(int v) throws IOException { + } + + @Override + public void writeChar(int v) throws IOException { + } + + @Override + public void writeInt(int v) throws IOException { + } + + @Override + public void writeLong(long v) throws IOException { + } + + @Override + public void writeFloat(float v) throws IOException { + } + + @Override + public void writeDouble(double v) throws IOException { + } + + @Override + public void writeBytes(String s) throws IOException { + } + + @Override + public void writeChars(String s) throws IOException { + } + + @Override + public void writeUTF(String s) throws IOException { + } + + public Object undefined(ScriptEngine eng) { + try { + eng.eval("function isJDK7Undefined(js) { js.writeObject(undefined); }"); + Invocable inv = (Invocable) eng; + inv.invokeFunction("isJDK7Undefined", this); + } catch (NoSuchMethodException | ScriptException ex) { + throw new IllegalStateException(ex); + } + return undefined; + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/src/main/java/net/java/html/boot/script/Scripts.java ---------------------------------------------------------------------- diff --git a/boot-script/src/main/java/net/java/html/boot/script/Scripts.java b/boot-script/src/main/java/net/java/html/boot/script/Scripts.java new file mode 100644 index 0000000..d5ff411 --- /dev/null +++ b/boot-script/src/main/java/net/java/html/boot/script/Scripts.java @@ -0,0 +1,119 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.script; + +import java.io.Closeable; +import java.util.concurrent.Executor; +import javax.script.ScriptEngine; +import net.java.html.boot.BrowserBuilder; +import net.java.html.js.JavaScriptBody; +import org.netbeans.html.boot.spi.Fn; +import org.netbeans.html.boot.spi.Fn.Presenter; + +/** Implementations of {@link Presenter}s that delegate + * to Java {@link ScriptEngine scripting} API. Initialize your presenter + * like this: + * + * <pre> + * + * {@link Runnable} <em>run</em> = ...; // your own init code + * {@link Presenter Fn.Presenter} <b>p</b> = Scripts.{@link Scripts#createPresenter()}; + * BrowserBuilder.{@link BrowserBuilder#newBrowser(java.lang.Object...) newBrowser(<b>p</b>)}. + * {@link BrowserBuilder#loadFinished(java.lang.Runnable) loadFinished(run)}. + * {@link BrowserBuilder#showAndWait()}; + * </pre> + * + * and your runnable can make extensive use of {@link JavaScriptBody} directly or + * indirectly via APIs using {@link JavaScriptBody such annotation} themselves. + * <p> + * Alternatively one can manipulate the presenter manually, which is + * especially useful when writing tests: + * <pre> + * {@code @Test} public void runInASimulatedBrowser() throws Exception { + * {@link Presenter Fn.Presenter} <b>p</b> = Scripts.{@link Scripts#createPresenter()}; + * try ({@link Closeable} c = {@link Fn#activate(org.netbeans.html.boot.spi.Fn.Presenter) Fn.activate}(<b>p</b>)) { + * // your code operating in context of <b>p</b> + * } + * } + * </pre> + * The previous code snippet requires Java 7 language syntax, as it relies + * on try-with-resources language syntactic sugar feature. The same block + * of code can be used on older versions of Java, but it is slightly more + * verbose. + * + * @author Jaroslav Tulach + */ +public final class Scripts { + private Scripts() { + } + + /** Simple implementation of {@link Presenter} that delegates + * to Java {@link ScriptEngine scripting} API. The presenter runs headless + * without appropriate simulation of browser APIs. Its primary usefulness + * is inside testing environments. The presenter implements {@link Executor} + * interface, but invokes all runnables passed to {@link Executor#execute(java.lang.Runnable)} + * immediately. + * + * @return new instance of a presenter that is using its own + * {@link ScriptEngine} for <code>text/javascript</code> mimetype + */ + public static Presenter createPresenter() { + return new ScriptPresenter(null); + } + + /** Implementation of {@link Presenter} that delegates + * to Java {@link ScriptEngine scripting} API and can control execution + * thread. The presenter runs headless + * without appropriate simulation of browser APIs. Its primary usefulness + * is inside testing environments. The presenter implements {@link Executor} + * interface, and passes all runnables from {@link Executor#execute(java.lang.Runnable)} + * to here in provided <code>exc</code> instance. + * + * @param exc the executor to re-schedule all asynchronous requests to + * @return new instance of a presenter that is using its own + * {@link ScriptEngine} for <code>text/javascript</code> mimetype + */ + public static Presenter createPresenter(Executor exc) { + return new ScriptPresenter(exc); + } +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/src/main/java/net/java/html/boot/script/package.html ---------------------------------------------------------------------- diff --git a/boot-script/src/main/java/net/java/html/boot/script/package.html b/boot-script/src/main/java/net/java/html/boot/script/package.html new file mode 100644 index 0000000..f700a76 --- /dev/null +++ b/boot-script/src/main/java/net/java/html/boot/script/package.html @@ -0,0 +1,51 @@ +<!-- + + DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + + Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + + Oracle and Java are registered trademarks of Oracle and/or its affiliates. + Other names may be trademarks of their respective owners. + + The contents of this file are subject to the terms of either the GNU + General Public License Version 2 only ("GPL") or the Common + Development and Distribution License("CDDL") (collectively, the + "License"). You may not use this file except in compliance with the + License. You can obtain a copy of the License at + http://www.netbeans.org/cddl-gplv2.html + or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + specific language governing permissions and limitations under the + License. When distributing the software, include this License Header + Notice in each file and include the License file at + nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + particular file as subject to the "Classpath" exception as provided + by Oracle in the GPL Version 2 section of the License file that + accompanied this code. If applicable, add the following below the + License Header, with the fields enclosed by brackets [] replaced by + your own identifying information: + "Portions Copyrighted [year] [name of copyright owner]" + + Contributor(s): + + The Original Software is NetBeans. The Initial Developer of the Original + Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + + If you wish your version of this file to be governed by only the CDDL + or only the GPL Version 2, indicate your decision by adding + "[Contributor] elects to include this software in this distribution + under the [CDDL or GPL Version 2] license." If you do not indicate a + single choice of license, a recipient has the option to distribute + your version of this file under either the CDDL, the GPL Version 2 or + to extend the choice of license to its licensees as provided above. + However, if you add GPL Version 2 code and therefore, elected the GPL + Version 2 license, then the option applies only if the new code is + made subject to such option by the copyright holder. + +--> +<body> + <p> + {@link net.java.html.boot.script.Scripts Factories} to create headless + {@link net.java.html.boot.BrowserBuilder browser environment} which is + useful for testing. + </p> +</body> http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTest.java ---------------------------------------------------------------------- diff --git a/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTest.java b/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTest.java new file mode 100644 index 0000000..8868d62 --- /dev/null +++ b/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTest.java @@ -0,0 +1,117 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.script; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import net.java.html.boot.BrowserBuilder; +import org.netbeans.html.boot.spi.Fn; +import org.netbeans.html.json.tck.KOTest; +import org.testng.Assert; +import org.testng.annotations.Factory; + +/** + * + * @author Jaroslav Tulach + */ +public class Jsr223JavaScriptTest { + private static Class<?> browserClass; + private static Fn.Presenter browserPresenter; + + public Jsr223JavaScriptTest() { + } + + @Factory public static Object[] compatibilityTests() throws Exception { + final BrowserBuilder bb = BrowserBuilder.newBrowser(new ScriptPresenter(SingleCase.JS)). + loadClass(Jsr223JavaScriptTest.class). + loadPage("empty.html"). + invoke("initialized"); + + Executors.newSingleThreadExecutor().submit(new Runnable() { + @Override + public void run() { + bb.showAndWait(); + } + }); + + List<Object> res = new ArrayList<Object>(); + Class<? extends Annotation> test = + loadClass().getClassLoader().loadClass(KOTest.class.getName()). + asSubclass(Annotation.class); + + Class[] arr = (Class[]) loadClass().getDeclaredMethod("tests").invoke(null); + for (Class c : arr) { + for (Method m : c.getMethods()) { + if (m.getAnnotation(test) != null) { + res.add(new SingleCase(browserPresenter, m)); + } + } + } + return res.toArray(); + } + + static synchronized Class<?> loadClass() throws InterruptedException { + while (browserClass == null) { + Jsr223JavaScriptTest.class.wait(); + } + return browserClass; + } + + public static synchronized void ready(Class<?> browserCls) throws Exception { + browserClass = browserCls; + browserPresenter = Fn.activePresenter(); + Jsr223JavaScriptTest.class.notifyAll(); + } + + public static void initialized() throws Exception { + Assert.assertSame( + Jsr223JavaScriptTest.class.getClassLoader(), + ClassLoader.getSystemClassLoader(), + "No special classloaders" + ); + Jsr223JavaScriptTest.ready(Jsr223JavaScriptTst.class); + } +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTst.java ---------------------------------------------------------------------- diff --git a/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTst.java b/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTst.java new file mode 100644 index 0000000..56fde22 --- /dev/null +++ b/boot-script/src/test/java/net/java/html/boot/script/Jsr223JavaScriptTst.java @@ -0,0 +1,55 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.script; + +import org.netbeans.html.json.tck.JavaScriptTCK; + +/** + * + * @author Jaroslav Tulach + */ +public final class Jsr223JavaScriptTst extends JavaScriptTCK { + public static Class[] tests() { + return testClasses(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-netbeans-html4j/blob/226089a5/boot-script/src/test/java/net/java/html/boot/script/SingleCase.java ---------------------------------------------------------------------- diff --git a/boot-script/src/test/java/net/java/html/boot/script/SingleCase.java b/boot-script/src/test/java/net/java/html/boot/script/SingleCase.java new file mode 100644 index 0000000..5ffa79c --- /dev/null +++ b/boot-script/src/test/java/net/java/html/boot/script/SingleCase.java @@ -0,0 +1,127 @@ +/** + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Oracle. Portions Copyright 2013-2016 Oracle. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + */ +package net.java.html.boot.script; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import org.netbeans.html.boot.spi.Fn; +import org.netbeans.html.boot.impl.FnContext; +import org.testng.IHookCallBack; +import org.testng.IHookable; +import org.testng.ITest; +import org.testng.ITestResult; +import org.testng.annotations.Test; + +/** + * + * @author Jaroslav Tulach + */ +public final class SingleCase implements ITest, IHookable, Runnable { + static final Executor JS = Executors.newSingleThreadExecutor(); + private final Fn.Presenter p; + private final Method m; + private Object result; + private Object inst; + + SingleCase(Fn.Presenter p, Method m) { + this.p = p; + this.m = m; + } + + @Override + public String getTestName() { + return m.getName(); + } + + @Test + public synchronized void executeTest() throws Exception { + if (result == null) { + JS.execute(this); + wait(); + } + if (result instanceof Exception) { + throw (Exception)result; + } + if (result instanceof Error) { + throw (Error)result; + } + } + + @Override + public synchronized void run() { + boolean notify = true; + try { + FnContext.currentPresenter(p); + if (inst == null) { + inst = m.getDeclaringClass().newInstance(); + } + result = m.invoke(inst); + if (result == null) { + result = this; + } + } catch (InvocationTargetException ex) { + Throwable r = ex.getTargetException(); + if (r instanceof InterruptedException) { + notify = false; + JS.execute(this); + return; + } + result = r; + } catch (Exception ex) { + result = ex; + } finally { + if (notify) { + notifyAll(); + } + FnContext.currentPresenter(null); + } + } + + @Override + public void run(IHookCallBack ihcb, ITestResult itr) { + ihcb.runTestMethod(itr); + } + +}
