This is an automated email from the ASF dual-hosted git repository.

jtulach pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans-html4j.git

commit b7bbe85ec63333990ff50d0a59912ea18b562e28
Author: Jaroslav Tulach <jaroslav.tul...@apidesign.org>
AuthorDate: Mon Dec 21 20:17:30 2020 +0100

    Trigger asynchronous action in JavaScript in middle of a computation
---
 .../java/html/boot/script/ScriptEngineTest.java    |  1 +
 generic/pom.xml                                    |  2 +-
 .../html/presenters/spi/test/CallbackTest.java     |  7 +-
 .../netbeans/html/presenters/spi/test/Case.java    |  6 +-
 .../html/presenters/spi/test/GenericTest.java      | 30 ++++++--
 .../netbeans/html/presenters/spi/test/Testing.java | 17 ++++-
 .../java/html/js/tests/AsyncJavaScriptAction.java  | 79 ++++++++++++++++++++++
 .../net/java/html/js/tests/JavaScriptBodyTest.java | 75 ++++++++++----------
 .../main/java/net/java/html/js/tests/JsUtils.java  | 46 +++++++++++++
 .../main/java/net/java/html/json/tests/Utils.java  | 32 ++++-----
 .../org/netbeans/html/json/tck/JavaScriptTCK.java  | 20 ++++++
 11 files changed, 249 insertions(+), 66 deletions(-)

diff --git 
a/boot-script/src/test/java/net/java/html/boot/script/ScriptEngineTest.java 
b/boot-script/src/test/java/net/java/html/boot/script/ScriptEngineTest.java
index 94eec03..9c2912d 100644
--- a/boot-script/src/test/java/net/java/html/boot/script/ScriptEngineTest.java
+++ b/boot-script/src/test/java/net/java/html/boot/script/ScriptEngineTest.java
@@ -89,6 +89,7 @@ public class ScriptEngineTest {
                 if (n === 'Number') continue;
                 if (n === 'Boolean') continue;
                 if (n === 'Array') continue;
+                if (n === 'eval') continue;
                 delete this[n];
               }
               return Object.getOwnPropertyNames(this).toString();
diff --git a/generic/pom.xml b/generic/pom.xml
index 0008110..78b52d2 100644
--- a/generic/pom.xml
+++ b/generic/pom.xml
@@ -75,7 +75,7 @@
                     <compilerArguments>
                         <Aversion>${project.version}</Aversion>
                     </compilerArguments>
-                    <testSource>1.8</testSource>
+                    <testSource>15</testSource>
                     <testTarget>1.8</testTarget>
                 </configuration>
             </plugin>
diff --git 
a/generic/src/test/java/org/netbeans/html/presenters/spi/test/CallbackTest.java 
b/generic/src/test/java/org/netbeans/html/presenters/spi/test/CallbackTest.java
index cdf0341..9aa2aeb 100644
--- 
a/generic/src/test/java/org/netbeans/html/presenters/spi/test/CallbackTest.java
+++ 
b/generic/src/test/java/org/netbeans/html/presenters/spi/test/CallbackTest.java
@@ -19,6 +19,7 @@
 package org.netbeans.html.presenters.spi.test;
 
 import java.lang.reflect.Method;
+import java.util.concurrent.CountDownLatch;
 import java.util.logging.Level;
 import javax.script.ScriptException;
 import static org.testng.Assert.assertEquals;
@@ -38,7 +39,7 @@ public class CallbackTest {
     private static final class CBP extends Testing {
 
         @Override
-        protected void loadJS(String js) {
+        protected void loadJS(String js, CountDownLatch notify) {
             dispatch(new Runnable () {
                 @Override
                 public void run() {
@@ -47,10 +48,12 @@ public class CallbackTest {
                         LOG.log(Level.FINE, "counter res: {0}", res);
                     } catch (ScriptException ex) {
                         LOG.log(Level.SEVERE, null, ex);
+                    } finally {
+                        notify.countDown();
                     }
                 }
             });
-            super.loadJS(js);
+            super.loadJS(js, notify);
         }
 
         @Override void beforeTest(Class<?> testClass) throws Exception {
diff --git 
a/generic/src/test/java/org/netbeans/html/presenters/spi/test/Case.java 
b/generic/src/test/java/org/netbeans/html/presenters/spi/test/Case.java
index c3bc60d..8f4b94f 100644
--- a/generic/src/test/java/org/netbeans/html/presenters/spi/test/Case.java
+++ b/generic/src/test/java/org/netbeans/html/presenters/spi/test/Case.java
@@ -33,14 +33,16 @@ import org.testng.annotations.Test;
 
 public final class Case implements ITest, IHookable, Runnable {
     private final Fn.Presenter p;
+    private final Testing t;
     private CountDownLatch finished;
     private final Method m;
     private Object result;
     private Object inst;
     private int cnt;
 
-    Case(Fn.Presenter p, Method m) {
-        this.p = p;
+    Case(Testing t, Method m) {
+        this.t = t;
+        this.p = t.presenter;
         this.m = m;
     }
 
diff --git 
a/generic/src/test/java/org/netbeans/html/presenters/spi/test/GenericTest.java 
b/generic/src/test/java/org/netbeans/html/presenters/spi/test/GenericTest.java
index 9df6444..9999365 100644
--- 
a/generic/src/test/java/org/netbeans/html/presenters/spi/test/GenericTest.java
+++ 
b/generic/src/test/java/org/netbeans/html/presenters/spi/test/GenericTest.java
@@ -22,11 +22,14 @@ import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
 import net.java.html.boot.BrowserBuilder;
 import org.netbeans.html.boot.spi.Fn;
 import org.netbeans.html.json.tck.JavaScriptTCK;
 import org.netbeans.html.json.tck.KOTest;
+import static org.testng.Assert.assertNotNull;
 import org.testng.annotations.Factory;
 
 public class GenericTest extends JavaScriptTCK {
@@ -39,8 +42,8 @@ public class GenericTest extends JavaScriptTCK {
         return createTests(new Testing());
     }
     
-    static Object[] createTests(Testing p) throws Exception {
-        Fn.Presenter presenter = p.presenter;
+    static Object[] createTests(Testing t) throws Exception {
+        Fn.Presenter presenter = t.presenter;
 
         final BrowserBuilder bb = 
BrowserBuilder.newBrowser(presenter).loadClass(GenericTest.class).
             loadPage("empty.html").
@@ -60,14 +63,27 @@ public class GenericTest extends JavaScriptTCK {
 
         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 Case(presenter, m));
-                }
-            }
+            addTestMethods(c, test, res, t);
         }
         return res.toArray();
     }
+
+    private static void addTestMethods(Class c, Class<? extends Annotation> 
test, List<Object> res, Testing t) throws SecurityException {
+        for (Method m : c.getMethods()) {
+            if (m.getAnnotation(test) != null) {
+                res.add(new Case(t, m));
+            }
+        }
+    }
+
+    @Override
+    public void executeNow(String script) throws Exception {
+        Testing t = Testing.MAP.get(Fn.activePresenter());
+        assertNotNull(t, "Testing framework found");
+        CountDownLatch cdl = new CountDownLatch(1);
+        t.loadJS(script, cdl);
+        cdl.await(5, TimeUnit.SECONDS);
+    }
     
     public static Class[] tests() {
         return testClasses();
diff --git 
a/generic/src/test/java/org/netbeans/html/presenters/spi/test/Testing.java 
b/generic/src/test/java/org/netbeans/html/presenters/spi/test/Testing.java
index 4adc485..ccab68a 100644
--- a/generic/src/test/java/org/netbeans/html/presenters/spi/test/Testing.java
+++ b/generic/src/test/java/org/netbeans/html/presenters/spi/test/Testing.java
@@ -19,6 +19,9 @@
 package org.netbeans.html.presenters.spi.test;
 
 import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.logging.Level;
@@ -36,6 +39,7 @@ class Testing {
     final ScriptEngine eng;
     final boolean sync;
     final ProtoPresenter presenter;
+    static final Map<ProtoPresenter, Testing> MAP = new HashMap<>();
 
     public Testing() {
         this(false);
@@ -51,11 +55,14 @@ class Testing {
             .app("Testing")
             .type("test")
             .dispatcher(QUEUE, false)
-            .loadJavaScript(this::loadJS, sync)
+            .loadJavaScript((s) -> {
+                loadJS(s, new java.util.concurrent.CountDownLatch(1));
+            }, sync)
             .displayer(this::displayPage)
             .preparator(this::callbackFn, true)
             .logger(this::log)
             .build();
+        MAP.put(this.presenter, this);
 
         ScriptEngineManager sem = new ScriptEngineManager();
         eng = sem.getEngineByMimeType("text/javascript");
@@ -120,7 +127,7 @@ class Testing {
         ready.callbackIsPrepared("testingCB");
     }
 
-    protected void loadJS(final String js) {
+    protected void loadJS(final String js, CountDownLatch notify) {
         QUEUE.execute(new Runnable() {
             public void run() {
                 try {
@@ -128,6 +135,8 @@ class Testing {
                     LOG.log(Level.FINE, "Result: {0}", res);
                 } catch (Throwable ex) {
                     LOG.log(Level.SEVERE, "Can't process " + js, ex);
+                } finally {
+                    notify.countDown();
                 }
             }
         });
@@ -150,12 +159,14 @@ class Testing {
         }
 
         @Override
-        protected void loadJS(final String js) {
+        protected void loadJS(final String js, CountDownLatch notify) {
             try {
                 Object res = eng.eval(js);
                 LOG.log(Level.FINE, "Result: {0}", res);
             } catch (Throwable ex) {
                 LOG.log(Level.SEVERE, "Can't process " + js, ex);
+            } finally {
+                notify.countDown();
             }
         }
 
diff --git 
a/json-tck/src/main/java/net/java/html/js/tests/AsyncJavaScriptAction.java 
b/json-tck/src/main/java/net/java/html/js/tests/AsyncJavaScriptAction.java
new file mode 100644
index 0000000..a9f20af
--- /dev/null
+++ b/json-tck/src/main/java/net/java/html/js/tests/AsyncJavaScriptAction.java
@@ -0,0 +1,79 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package net.java.html.js.tests;
+
+import java.util.List;
+import net.java.html.js.JavaScriptBody;
+import static net.java.html.js.tests.JavaScriptBodyTest.assertEquals;
+
+final class AsyncJavaScriptAction {
+    List<Integer> collected = new java.util.ArrayList<>();
+
+    @JavaScriptBody(args = { "n" }, javacall = true, body = """
+        return 
th...@net.java.html.js.tests.AsyncJavaScriptAction::performTheTest(I)(n);
+    """)
+    private native int r(int n);
+
+    @JavaScriptBody(args = {}, javacall = true, body = """
+        var self = this;
+        var global = (0 || eval)("this");
+        global.storeLater = function(s) {
+            
se...@net.java.html.js.tests.AsyncJavaScriptAction::storeLater(I)(s);
+        };
+    """)
+    private native void defineStore();
+
+    @JavaScriptBody(args = { "store" }, javacall = true, wait4js = false, body 
= """
+        storeLater(store);
+    """)
+    private static native void jsStore(int store);
+
+    void storeLater(int value) {
+        collected.add(value);
+    }
+
+    int performTheTest(int from) throws Exception {
+        for (int i = 0; i < 5; i++) {
+            jsStore(from++);
+        }
+        final String n = "" + from++;
+        JsUtils.executeNow(AsyncJavaScriptAction.class, """
+            storeLater({n});
+        """.replace("{n}", n));
+        for (int i = 6; i < 11; i++) {
+            jsStore(from++);
+        }
+        return from;
+    }
+
+    public void runTheWholeTest() {
+        defineStore();
+        assertEquals(r(0), 11);
+        assertEquals(collected.size(), 11, "11 items: " + collected);
+        for (int i = 0; i < 11; i++) {
+            assertEquals(collected.get(i).intValue(), i, i + "th out of order: 
" + collected);
+        }
+        assertEquals(r(11), 22);
+
+        assertEquals(collected.size(), 22, "22 items: " + collected);
+        for (int i = 0; i < 22; i++) {
+            assertEquals(collected.get(i).intValue(), i, i + "th out of order: 
" + collected);
+        }
+    }
+}
diff --git 
a/json-tck/src/main/java/net/java/html/js/tests/JavaScriptBodyTest.java 
b/json-tck/src/main/java/net/java/html/js/tests/JavaScriptBodyTest.java
index b3c3f21..3a0e8cf 100644
--- a/json-tck/src/main/java/net/java/html/js/tests/JavaScriptBodyTest.java
+++ b/json-tck/src/main/java/net/java/html/js/tests/JavaScriptBodyTest.java
@@ -18,7 +18,6 @@
  */
 package net.java.html.js.tests;
 
-import java.io.StringReader;
 import java.util.concurrent.Callable;
 import net.java.html.json.Models;
 import org.netbeans.html.boot.spi.Fn;
@@ -38,7 +37,7 @@ public class JavaScriptBodyTest {
         int res = Bodies.sumJS(5, 3);
         assertEquals(res, 8, "Expecting 8: " + res);
     }
-    
+
     @KOTest public void accessJsObject() {
         Object o = Bodies.instance(10);
         int ten = Bodies.readIntX(o);
@@ -51,13 +50,13 @@ public class JavaScriptBodyTest {
         int ten = Bodies.readIntX(o);
         assertEquals(ten, 11, "Expecting eleven: " + ten);
     }
-    
+
     @KOTest public void callbackToRunnable() {
         R run = new R();
         Bodies.callback(run);
         assertEquals(run.cnt, 1, "Can call even private implementation 
classes: " + run.cnt);
     }
-    
+
     private R asyncRun;
     @KOTest public void asyncCallbackToRunnable() throws InterruptedException {
         if (asyncRun == null) {
@@ -79,7 +78,7 @@ public class JavaScriptBodyTest {
         assertEquals(r.cnt, 10, "Ten calls: " + r.cnt);
         assertEquals(fourtyTwo, 42, "Meaning of the world expected: " + 
fourtyTwo);
     }
-    
+
     @KOTest public void typeOfCharacter() {
         String charType = Bodies.typeof('a', false);
         assertEquals("number", charType, "Expecting number type: " + charType);
@@ -91,7 +90,7 @@ public class JavaScriptBodyTest {
 
     @KOTest public void typeOfPrimitiveBoolean() {
         String booleanType = Bodies.typeof(true);
-        assertTrue("boolean".equals(booleanType) || 
"number".equals(booleanType), 
+        assertTrue("boolean".equals(booleanType) || 
"number".equals(booleanType),
             "Expecting boolean or at least number type: " + booleanType);
     }
 
@@ -109,7 +108,7 @@ public class JavaScriptBodyTest {
         String doubleType = Bodies.typeof(0.33, false);
         assertEquals("number", doubleType, "Expecting number type: " + 
doubleType);
     }
-    
+
     @KOTest public void typeOfBooleanValueOf() {
         String booleanType = Bodies.typeof(true, true);
         assertEquals("boolean", booleanType, "Expecting boolean type: " + 
booleanType);
@@ -151,7 +150,7 @@ public class JavaScriptBodyTest {
         assertEquals(sum[0], 42, "Computed OK " + sum[0]);
         assertEquals(sum[1], 42, "Computed OK too: " + sum[1]);
     }
-    
+
     @KOTest public void doubleCallbackToRunnable() {
         final R run = new R();
         final R r2 = new R();
@@ -165,7 +164,7 @@ public class JavaScriptBodyTest {
         assertEquals(run.cnt, 1, "Can call even private implementation 
classes: " + run.cnt);
         assertEquals(r2.cnt, 1, "Can call even private implementation classes: 
" + r2.cnt);
     }
-    
+
     @KOTest public void identity() {
         Object p = new Object();
         Object r = Bodies.id(p);
@@ -189,7 +188,7 @@ public class JavaScriptBodyTest {
         Object r = Bodies.id(p);
         assertEquals(r, p, "The null is the same");
     }
-    
+
     @KOTest public void callbackWithTrueResult() {
         Callable<Boolean> c = new C(true);
         String b = Bodies.yesNo(c);
@@ -201,13 +200,13 @@ public class JavaScriptBodyTest {
         String b = Bodies.yesNo(c);
         assertEquals(b, "no", "Should return false");
     }
-    
+
     @KOTest public void callbackWithParameters() throws InterruptedException {
         Sum s = new Sum();
         int res = Bodies.sumIndirect(s, 40, 2);
         assertEquals(res, 42, "Expecting 42");
     }
-    
+
     @KOTest public void selectFromStringJavaArray() {
         String[] arr = { "Ahoj", "Wo\nrld" };
         Object res = Bodies.select(arr, 1);
@@ -238,7 +237,7 @@ public class JavaScriptBodyTest {
         assertNotNull(res, "Non-null is returned");
         assertTrue(res instanceof Object[], "Returned an array: " + res);
         assertFalse(res instanceof String[], "Not returned a string array: " + 
res);
-        
+
         Object[] ret = (Object[]) res;
         assertEquals(arr.length, ret.length, "Same length: " + ret.length);
         assertEquals(arr[0], ret[0], "Same first elem");
@@ -269,7 +268,7 @@ public class JavaScriptBodyTest {
         assertEquals("He\nllo", arr[0], "Hello expected: " + arr[0]);
         assertEquals("Worl\nd!", arr[1], "World! expected: " + arr[1]);
     }
-    
+
     @KOTest public void sumVector() {
         double[] arr = { 1.0, 2.0, 3.0 };
         double res = Bodies.sumVector(arr);
@@ -285,32 +284,32 @@ public class JavaScriptBodyTest {
     @KOTest public void truth() {
         assertTrue(Bodies.truth(), "True is true");
     }
-    
+
     @KOTest public void factorial2() {
         assertEquals(new Factorial().factorial(2), 2);
     }
-    
+
     @KOTest public void factorial3() {
         assertEquals(new Factorial().factorial(3), 6);
     }
-    
+
     @KOTest public void factorial4() {
         assertEquals(new Factorial().factorial(4), 24);
     }
-    
+
     @KOTest public void factorial5() {
         assertEquals(new Factorial().factorial(5), 120);
     }
-    
+
     @KOTest public void factorial6() {
         assertEquals(new Factorial().factorial(6), 720);
     }
-    
+
     @KOTest public void sumArray() {
         int r = Bodies.sumArr(new Sum());
         assertEquals(r, 6, "Sum is six: " + r);
     }
-    
+
     @KOTest public void staticCallback() {
         int r = Bodies.staticCallback();
         assertEquals(r, 42, "Expecting 42: " + r);
@@ -323,12 +322,12 @@ public class JavaScriptBodyTest {
         assertTrue(r instanceof Number, "Is number " + r);
         assertEquals(((Number)r).intValue(), 42, "Expecting 42: " + r);
     }
-    
+
     @KOTest public void asyncCallFromAJSCallbackNeedToFinishBeforeReturnToJS() 
{
         int r = Bodies.incAsync();
         assertEquals(r, 42, "Expecting 42: " + r);
     }
-    
+
     @KOTest public void iterateArray() {
         String[] arr = { "Ahoj", "Hi", "Ciao" };
         Object[] ret = Bodies.forIn(arr);
@@ -338,7 +337,7 @@ public class JavaScriptBodyTest {
         assertEquals(ret[3], "Hi", "Expecting Hi: " + ret[1]);
         assertEquals(ret[5], "Ciao", "Expecting Ciao: " + ret[2]);
     }
-    
+
     @KOTest public void primitiveTypes() {
         String all = Bodies.primitiveTypes(new Sum());
         assertEquals("Ahojfalse12356.07.0 TheEND", all, "Valid return type: " 
+ all);
@@ -366,7 +365,7 @@ public class JavaScriptBodyTest {
         boolean nonNull = Bodies.nonNull(s, "x");
         assertTrue(nonNull, "x property exists");
     }
-    
+
     @KOTest public void callbackUnknown() {
         Sum s = new Sum();
         boolean nonNull = Bodies.nonNull(s, "y");
@@ -388,7 +387,7 @@ public class JavaScriptBodyTest {
         int len = Math.min(orig.length(), js.length());
         for (int i = 0; i < len; i++) {
             if (orig.charAt(i) != js.charAt(i)) {
-                fail("Difference at position " + i + 
+                fail("Difference at position " + i +
                     "\norig: " +
                     orig.substring(i - 5, Math.min(i + 10, orig.length())) +
                     "\n  js: " +
@@ -404,7 +403,7 @@ public class JavaScriptBodyTest {
         boolean res = Bodies.isInArray(new Object[] { val }, val);
         assertTrue(res, "Should be in the array");
     }
-    
+
     Later l;
     @KOTest public void callLater() throws Exception{
         final Fn.Presenter p = Fn.activePresenter();
@@ -412,14 +411,14 @@ public class JavaScriptBodyTest {
             return;
         }
         if (l == null) {
-            p.loadScript(new StringReader(
+            JsUtils.executeNow(JavaScriptBodyTest.class,
                 "if (typeof window === 'undefined') window = {};"
-            ));
+            );
             l = new Later();
             l.register();
-            p.loadScript(new StringReader(
+            JsUtils.executeNow(JavaScriptBodyTest.class,
                 "window.later();"
-            ));
+            );
         }
         if (l.call != 42) {
             throw new InterruptedException();
@@ -428,6 +427,12 @@ public class JavaScriptBodyTest {
     }
 
     @KOTest
+    public void asynchCallFromJavaScriptInMiddleOfDefferedProcessing() {
+        AsyncJavaScriptAction t = new AsyncJavaScriptAction();
+        t.runTheWholeTest();
+    }
+
+    @KOTest
     public void globalStringAvailable() throws Exception {
         assertEquals("HTML/Java", GlobalString.init());
         assertEquals("HTML/Java", Bodies.readGlobalString());
@@ -451,11 +456,11 @@ public class JavaScriptBodyTest {
         assertEquals(value[0], "NetBeans", "As a returned value from defining 
method");
         assertEquals(value[1], "NetBeans", "As read later by different 
method");
     }
-    
+
     private static class R implements Runnable {
         int cnt;
         private final Thread initThread;
-        
+
         public R() {
             initThread = Thread.currentThread();
         }
@@ -466,14 +471,14 @@ public class JavaScriptBodyTest {
             cnt++;
         }
     }
-    
+
     private static class C implements Callable<Boolean> {
         private final boolean ret;
 
         public C(boolean ret) {
             this.ret = ret;
         }
-        
+
         @Override
         public Boolean call() throws Exception {
             return ret;
diff --git a/json-tck/src/main/java/net/java/html/js/tests/JsUtils.java 
b/json-tck/src/main/java/net/java/html/js/tests/JsUtils.java
new file mode 100644
index 0000000..de99cca
--- /dev/null
+++ b/json-tck/src/main/java/net/java/html/js/tests/JsUtils.java
@@ -0,0 +1,46 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package net.java.html.js.tests;
+
+import java.io.StringReader;
+import org.netbeans.html.boot.spi.Fn;
+import org.netbeans.html.json.tck.JavaScriptTCK;
+
+public class JsUtils {
+    private JsUtils() {
+    }
+
+    private static JavaScriptTCK instantiatedJsTCK;
+
+    public static void registerTCK(JavaScriptTCK tck) {
+        instantiatedJsTCK = tck;
+    }
+
+    static void executeNow(Class<?> clazz, String script) throws Exception {
+        if (instantiatedJsTCK != null) {
+            instantiatedJsTCK.executeNow(script);
+        } else {
+            Fn.Presenter p = Fn.activePresenter();
+            if (p != null) {
+                p.loadScript(new StringReader(script));
+            }
+        }
+    }
+
+}
diff --git a/json-tck/src/main/java/net/java/html/json/tests/Utils.java 
b/json-tck/src/main/java/net/java/html/json/tests/Utils.java
index 3a7aca6..afcf9fe 100644
--- a/json-tck/src/main/java/net/java/html/json/tests/Utils.java
+++ b/json-tck/src/main/java/net/java/html/json/tests/Utils.java
@@ -66,7 +66,7 @@ public final class Utils {
 
     private Utils() {
     }
-    
+
     public static void registerTCK(KnockoutTCK tck) {
         instantiatedTCK = tck;
     }
@@ -89,7 +89,7 @@ public final class Utils {
         }
         throw new AssertionError("Can't find appropriate Context in 
ServiceLoader!");
     }
-    static Object executeScript(Class<?> clazz, 
+    static Object executeScript(Class<?> clazz,
         String script, Object... arguments
     ) throws Exception {
         for (KnockoutTCK tck : tcks(clazz)) {
@@ -116,17 +116,17 @@ public final class Utils {
           """;
         executeScript(clazz, s);
     }
-    
+
     static Object exposeHTML(Class<?> clazz, String html) throws Exception {
         String s = """
-          var n = window.document.getElementById('ko.test.div'); 
-           if (!n) { 
-            n = window.document.createElement('div'); 
-             n.id = 'ko.test.div'; 
+          var n = window.document.getElementById('ko.test.div');
+           if (!n) {
+            n = window.document.createElement('div');
+             n.id = 'ko.test.div';
              var body = window.document.getElementsByTagName('body')[0];
             body.appendChild(n);
           }
-          n.innerHTML = arguments[0]; 
+          n.innerHTML = arguments[0];
            """;
         return executeScript(clazz, s, html);
     }
@@ -160,7 +160,7 @@ public final class Utils {
             """, id, field, value
         );
     }
-    
+
     static void scheduleClick(Class<?> clazz, String id, int delay) throws 
Exception {
         String s = """
             var id = arguments[0];
@@ -175,8 +175,8 @@ public final class Utils {
             """;
         Utils.executeScript(clazz, s, id, delay);
     }
-    
-    
+
+
     static String prepareURL(
         Class<?> clazz, String content, String mimeType, String... parameters) 
{
         for (KnockoutTCK tck : tcks(clazz)) {
@@ -197,7 +197,7 @@ public final class Utils {
         }
         return false;
     }
-    
+
     private static ClassLoader cl(Class<?> c) {
         try {
             return c.getClassLoader();
@@ -205,11 +205,11 @@ public final class Utils {
             return null;
         }
     }
-    
+
     static void fail(String msg) {
         throw new AssertionError(msg);
     }
-    
+
     static void assertTrue(boolean c, String msg) {
         if (!c) {
             throw new AssertionError(msg);
@@ -221,7 +221,7 @@ public final class Utils {
             throw new AssertionError(msg);
         }
     }
-    
+
     static void assertNull(Object o, String msg) {
         if (o != null) {
             throw new AssertionError(msg + " but was: " + o);
@@ -233,7 +233,7 @@ public final class Utils {
             throw new AssertionError(msg);
         }
     }
-    
+
     static void assertEquals(Object a, Object b, String msg) {
         if (a == b) {
             return;
diff --git 
a/json-tck/src/main/java/org/netbeans/html/json/tck/JavaScriptTCK.java 
b/json-tck/src/main/java/org/netbeans/html/json/tck/JavaScriptTCK.java
index 5d39f9a..13c5350 100644
--- a/json-tck/src/main/java/org/netbeans/html/json/tck/JavaScriptTCK.java
+++ b/json-tck/src/main/java/org/netbeans/html/json/tck/JavaScriptTCK.java
@@ -18,9 +18,11 @@
  */
 package org.netbeans.html.json.tck;
 
+import java.io.StringReader;
 import net.java.html.js.tests.GCBodyTest;
 import net.java.html.js.tests.JavaScriptBodyTest;
 import net.java.html.js.tests.ExposedPropertiesTest;
+import net.java.html.js.tests.JsUtils;
 import org.netbeans.html.boot.spi.Fn;
 import org.netbeans.html.boot.spi.Fn.Presenter;
 
@@ -63,6 +65,11 @@ import org.netbeans.html.boot.spi.Fn.Presenter;
  * @since 0.7
  */
 public abstract class JavaScriptTCK {
+    /** Creates and registers instance of the TCK. */
+    public JavaScriptTCK() {
+        JsUtils.registerTCK(this);
+    }
+
     /** Gives you list of classes included in the TCK. Their test methods
      * are annotated by {@link KOTest} annotation. The methods are public
      * instance methods that take no arguments. The method should be
@@ -75,4 +82,17 @@ public abstract class JavaScriptTCK {
             JavaScriptBodyTest.class, GCBodyTest.class, 
ExposedPropertiesTest.class
         };
     }
+
+    /** Executes JavaScript now. Simulates that something suddenly happens
+     * in the JavaScript while Java code may already be doing something
+     * different.
+     *
+     * @param script the script to execute in the JavaScript
+     * @throws Exception if something goes wrong
+     * @since 1.7.1
+     */
+    public void executeNow(String script) throws Exception {
+        Presenter p = Fn.activePresenter();
+        p.loadScript(new StringReader(script));
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@netbeans.apache.org
For additional commands, e-mail: commits-h...@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists

Reply via email to