ko/archetype/src/main/resources/archetype-resources/src/test/java/JsInteractionTest.java
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/ko/archetype/src/main/resources/archetype-resources/src/test/java/JsInteractionTest.java Tue Feb 04 09:32:27 2014 +0100
1.3 @@ -0,0 +1,103 @@
1.4 +package ${package};
1.5 +
1.6 +import java.io.Closeable;
1.7 +import java.io.Reader;
1.8 +import java.net.URL;
1.9 +import java.util.ArrayList;
1.10 +import java.util.List;
1.11 +import javax.script.Invocable;
1.12 +import javax.script.ScriptEngine;
1.13 +import javax.script.ScriptEngineManager;
1.14 +import javax.script.ScriptException;
1.15 +import org.apidesign.html.boot.spi.Fn;
1.16 +import static org.testng.Assert.assertEquals;
1.17 +import org.testng.annotations.AfterMethod;
1.18 +import org.testng.annotations.BeforeMethod;
1.19 +import org.testng.annotations.Test;
1.20 +
1.21 +/** Tests for behavior of @JavaScriptBody methods. Set your JavaScript
1.22 + * environment up (for example define <code>alert</code> or use some
1.23 + * emulation library like <em>env.js</em>), register script presenter
1.24 + * and then you can call methods that deal with JavaScript in your tests.
1.25 + */
1.26 +public class JsInteractionTest {
1.27 + private Closeable jsEngine;
1.28 + @BeforeMethod public void initializeJSEngine() throws Exception {
1.29 + jsEngine = Fn.activate(new ScriptPresenter());
1.30 + }
1.31 +
1.32 + @AfterMethod public void shutdownJSEngine() throws Exception {
1.33 + jsEngine.close();
1.34 + }
1.35 +
1.36 + @Test public void testCallbackFromJavaScript() throws Exception {
1.37 + class R implements Runnable {
1.38 + int called;
1.39 +
1.40 + @Override
1.41 + public void run() {
1.42 + called++;
1.43 + }
1.44 + }
1.45 + R callback = new R();
1.46 +
1.47 + DataModel.confirmByUser("Hello", callback);
1.48 +
1.49 + assertEquals(callback.called, 1, "One immediate callback");
1.50 + }
1.51 +
1.52 + private static class ScriptPresenter implements Fn.Presenter {
1.53 + private final ScriptEngine eng;
1.54 +
1.55 + public ScriptPresenter() throws ScriptException {
1.56 + eng = new ScriptEngineManager().getEngineByName("javascript");
1.57 + eng.eval("function alert(msg) { Packages.java.lang.System.out.println(msg); };");
1.58 + }
1.59 +
1.60 + @Override
1.61 + public Fn defineFn(String code, String... names) {
1.62 + StringBuilder sb = new StringBuilder();
1.63 + sb.append("(function() {");
1.64 + sb.append(" return function(");
1.65 + String sep = "";
1.66 + for (String n : names) {
1.67 + sb.append(sep).append(n);
1.68 + sep = ",";
1.69 + }
1.70 + sb.append(") {\n");
1.71 + sb.append(code);
1.72 + sb.append("};");
1.73 + sb.append("})()");
1.74 +
1.75 + final Object fn;
1.76 + try {
1.77 + fn = eng.eval(sb.toString());
1.78 + } catch (ScriptException ex) {
1.79 + throw new IllegalStateException(ex);
1.80 + }
1.81 + return new Fn(this) {
1.82 + @Override
1.83 + public Object invoke(Object thiz, Object... args) throws Exception {
1.84 + List<Object> all = new ArrayList<Object>(args.length + 1);
1.85 + all.add(thiz == null ? fn : thiz);
1.86 + for (int i = 0; i < args.length; i++) {
1.87 + all.add(args[i]);
1.88 + }
1.89 + Object ret = ((Invocable)eng).invokeMethod(fn, "call", all.toArray()); // NOI18N
1.90 + return fn.equals(ret) ? null : thiz;
1.91 + }
1.92 + };
1.93 + }
1.94 +
1.95 + @Override
1.96 + public void displayPage(URL page, Runnable onPageLoad) {
1.97 + // not really displaying anything
1.98 + onPageLoad.run();
1.99 + }
1.100 +
1.101 + @Override
1.102 + public void loadScript(Reader code) throws Exception {
1.103 + eng.eval(code);
1.104 + }
1.105 + }
1.106 +}