jaroslav@1433: package ${package}; jaroslav@1433: jaroslav@1433: import java.io.Closeable; jaroslav@1433: import java.io.Reader; jaroslav@1433: import java.net.URL; jaroslav@1433: import java.util.ArrayList; jaroslav@1433: import java.util.List; jaroslav@1433: import javax.script.Invocable; jaroslav@1433: import javax.script.ScriptEngine; jaroslav@1433: import javax.script.ScriptEngineManager; jaroslav@1433: import javax.script.ScriptException; jaroslav@1433: import org.apidesign.html.boot.spi.Fn; jaroslav@1433: import static org.testng.Assert.assertEquals; jaroslav@1433: import org.testng.annotations.AfterMethod; jaroslav@1433: import org.testng.annotations.BeforeMethod; jaroslav@1433: import org.testng.annotations.Test; jaroslav@1433: jaroslav@1433: /** Tests for behavior of @JavaScriptBody methods. Set your JavaScript jaroslav@1433: * environment up (for example define alert or use some jaroslav@1433: * emulation library like env.js), register script presenter jaroslav@1433: * and then you can call methods that deal with JavaScript in your tests. jaroslav@1433: */ jaroslav@1433: public class JsInteractionTest { jaroslav@1433: private Closeable jsEngine; jaroslav@1433: @BeforeMethod public void initializeJSEngine() throws Exception { jaroslav@1433: jsEngine = Fn.activate(new ScriptPresenter()); jaroslav@1433: } jaroslav@1433: jaroslav@1433: @AfterMethod public void shutdownJSEngine() throws Exception { jaroslav@1433: jsEngine.close(); jaroslav@1433: } jaroslav@1433: jaroslav@1433: @Test public void testCallbackFromJavaScript() throws Exception { jaroslav@1433: class R implements Runnable { jaroslav@1433: int called; jaroslav@1433: jaroslav@1433: @Override jaroslav@1433: public void run() { jaroslav@1433: called++; jaroslav@1433: } jaroslav@1433: } jaroslav@1433: R callback = new R(); jaroslav@1433: jaroslav@1433: DataModel.confirmByUser("Hello", callback); jaroslav@1433: jaroslav@1433: assertEquals(callback.called, 1, "One immediate callback"); jaroslav@1433: } jaroslav@1433: jaroslav@1433: private static class ScriptPresenter implements Fn.Presenter { jaroslav@1433: private final ScriptEngine eng; jaroslav@1433: jaroslav@1433: public ScriptPresenter() throws ScriptException { jaroslav@1433: eng = new ScriptEngineManager().getEngineByName("javascript"); jaroslav@1433: eng.eval("function alert(msg) { Packages.java.lang.System.out.println(msg); };"); jaroslav@1433: } jaroslav@1433: jaroslav@1433: @Override jaroslav@1433: public Fn defineFn(String code, String... names) { jaroslav@1433: StringBuilder sb = new StringBuilder(); jaroslav@1433: sb.append("(function() {"); jaroslav@1433: sb.append(" return function("); jaroslav@1433: String sep = ""; jaroslav@1433: for (String n : names) { jaroslav@1433: sb.append(sep).append(n); jaroslav@1433: sep = ","; jaroslav@1433: } jaroslav@1433: sb.append(") {\n"); jaroslav@1433: sb.append(code); jaroslav@1433: sb.append("};"); jaroslav@1433: sb.append("})()"); jaroslav@1433: jaroslav@1433: final Object fn; jaroslav@1433: try { jaroslav@1433: fn = eng.eval(sb.toString()); jaroslav@1433: } catch (ScriptException ex) { jaroslav@1433: throw new IllegalStateException(ex); jaroslav@1433: } jaroslav@1433: return new Fn(this) { jaroslav@1433: @Override jaroslav@1433: public Object invoke(Object thiz, Object... args) throws Exception { jaroslav@1433: List all = new ArrayList(args.length + 1); jaroslav@1433: all.add(thiz == null ? fn : thiz); jaroslav@1433: for (int i = 0; i < args.length; i++) { jaroslav@1433: all.add(args[i]); jaroslav@1433: } jaroslav@1433: Object ret = ((Invocable)eng).invokeMethod(fn, "call", all.toArray()); // NOI18N jaroslav@1433: return fn.equals(ret) ? null : thiz; jaroslav@1433: } jaroslav@1433: }; jaroslav@1433: } jaroslav@1433: jaroslav@1433: @Override jaroslav@1433: public void displayPage(URL page, Runnable onPageLoad) { jaroslav@1433: // not really displaying anything jaroslav@1433: onPageLoad.run(); jaroslav@1433: } jaroslav@1433: jaroslav@1433: @Override jaroslav@1433: public void loadScript(Reader code) throws Exception { jaroslav@1433: eng.eval(code); jaroslav@1433: } jaroslav@1433: } jaroslav@1433: }