ko-ws-tyrus/src/test/java/org/apidesign/html/wstyrus/TyrusKnockoutTest.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 12 Sep 2013 09:33:50 +0200
changeset 288 8c5b40231d26
parent 260 23e2ad7e6d23
child 300 aee69a14a859
child 309 7025177bd67e
permissions -rw-r--r--
Support for multiple FX WebViews running at once in isolation
jaroslav@260
     1
/**
jaroslav@260
     2
 * HTML via Java(tm) Language Bindings
jaroslav@260
     3
 * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
jaroslav@260
     4
 *
jaroslav@260
     5
 * This program is free software: you can redistribute it and/or modify
jaroslav@260
     6
 * it under the terms of the GNU General Public License as published by
jaroslav@260
     7
 * the Free Software Foundation, version 2 of the License.
jaroslav@260
     8
 *
jaroslav@260
     9
 * This program is distributed in the hope that it will be useful,
jaroslav@260
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
jaroslav@260
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
jaroslav@260
    12
 * GNU General Public License for more details. apidesign.org
jaroslav@260
    13
 * designates this particular file as subject to the
jaroslav@260
    14
 * "Classpath" exception as provided by apidesign.org
jaroslav@260
    15
 * in the License file that accompanied this code.
jaroslav@260
    16
 *
jaroslav@260
    17
 * You should have received a copy of the GNU General Public License
jaroslav@260
    18
 * along with this program. Look for COPYING file in the top folder.
jaroslav@260
    19
 * If not, see http://wiki.apidesign.org/wiki/GPLwithClassPathException
jaroslav@260
    20
 */
jaroslav@260
    21
package org.apidesign.html.wstyrus;
jaroslav@260
    22
jaroslav@260
    23
import java.io.BufferedReader;
jaroslav@260
    24
import java.io.IOException;
jaroslav@260
    25
import java.io.InputStreamReader;
jaroslav@260
    26
import java.lang.annotation.Annotation;
jaroslav@260
    27
import java.lang.reflect.Method;
jaroslav@260
    28
import java.net.URI;
jaroslav@260
    29
import java.net.URISyntaxException;
jaroslav@260
    30
import java.net.URL;
jaroslav@260
    31
import java.net.URLConnection;
jaroslav@260
    32
import java.util.ArrayList;
jaroslav@260
    33
import java.util.List;
jaroslav@260
    34
import java.util.Map;
jaroslav@260
    35
import java.util.concurrent.Executors;
jaroslav@260
    36
import net.java.html.BrwsrCtx;
jaroslav@260
    37
import net.java.html.boot.BrowserBuilder;
jaroslav@260
    38
import net.java.html.js.JavaScriptBody;
jaroslav@288
    39
import org.apidesign.html.boot.impl.FnUtils;
jaroslav@288
    40
import org.apidesign.html.boot.spi.Fn;
jaroslav@260
    41
import org.apidesign.html.context.spi.Contexts;
jaroslav@260
    42
import org.apidesign.html.json.spi.Technology;
jaroslav@260
    43
import org.apidesign.html.json.spi.Transfer;
jaroslav@260
    44
import org.apidesign.html.json.spi.WSTransfer;
jaroslav@260
    45
import org.apidesign.html.json.tck.KOTest;
jaroslav@260
    46
import org.apidesign.html.json.tck.KnockoutTCK;
jaroslav@260
    47
import org.apidesign.html.kofx.FXContext;
jaroslav@260
    48
import org.json.JSONException;
jaroslav@260
    49
import org.json.JSONObject;
jaroslav@260
    50
import org.openide.util.lookup.ServiceProvider;
jaroslav@260
    51
import org.testng.annotations.Factory;
jaroslav@260
    52
import static org.testng.Assert.*;
jaroslav@260
    53
jaroslav@260
    54
/**
jaroslav@260
    55
 *
jaroslav@260
    56
 * @author Jaroslav Tulach <jtulach@netbeans.org>
jaroslav@260
    57
 */
jaroslav@260
    58
@ServiceProvider(service = KnockoutTCK.class)
jaroslav@260
    59
public final class TyrusKnockoutTest extends KnockoutTCK {
jaroslav@260
    60
    private static Class<?> browserClass;
jaroslav@288
    61
    private static Fn.Presenter browserContext;
jaroslav@260
    62
    
jaroslav@260
    63
    public TyrusKnockoutTest() {
jaroslav@260
    64
    }
jaroslav@260
    65
    
jaroslav@260
    66
    @Factory public static Object[] compatibilityTests() throws Exception {
jaroslav@260
    67
        Class[] arr = testClasses();
jaroslav@260
    68
        for (int i = 0; i < arr.length; i++) {
jaroslav@260
    69
            assertEquals(
jaroslav@260
    70
                arr[i].getClassLoader(),
jaroslav@260
    71
                TyrusKnockoutTest.class.getClassLoader(),
jaroslav@260
    72
                "All classes loaded by the same classloader"
jaroslav@260
    73
            );
jaroslav@260
    74
        }
jaroslav@260
    75
        
jaroslav@260
    76
        URI uri = TyrusDynamicHTTP.initServer();
jaroslav@260
    77
    
jaroslav@260
    78
        final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(TyrusKnockoutTest.class).
jaroslav@260
    79
            loadPage(uri.toString()).
jaroslav@260
    80
            invoke("initialized");
jaroslav@260
    81
        
jaroslav@260
    82
        Executors.newSingleThreadExecutor().submit(new Runnable() {
jaroslav@260
    83
            @Override
jaroslav@260
    84
            public void run() {
jaroslav@260
    85
                bb.showAndWait();
jaroslav@260
    86
            }
jaroslav@260
    87
        });
jaroslav@260
    88
        
jaroslav@260
    89
        ClassLoader l = getClassLoader();
jaroslav@260
    90
        List<Object> res = new ArrayList<Object>();
jaroslav@260
    91
        for (int i = 0; i < arr.length; i++) {
jaroslav@260
    92
            Class<?> c = Class.forName(arr[i].getName(), true, l);
jaroslav@260
    93
            Class<? extends Annotation> koTest = 
jaroslav@260
    94
                c.getClassLoader().loadClass(KOTest.class.getName()).
jaroslav@260
    95
                asSubclass(Annotation.class);
jaroslav@260
    96
            for (Method m : c.getMethods()) {
jaroslav@260
    97
                if (m.getAnnotation(koTest) != null) {
jaroslav@288
    98
                    res.add(new TyrusFX(browserContext, m));
jaroslav@260
    99
                }
jaroslav@260
   100
            }
jaroslav@260
   101
        }
jaroslav@260
   102
        return res.toArray();
jaroslav@260
   103
    }
jaroslav@260
   104
jaroslav@260
   105
    static synchronized ClassLoader getClassLoader() throws InterruptedException {
jaroslav@260
   106
        while (browserClass == null) {
jaroslav@260
   107
            TyrusKnockoutTest.class.wait();
jaroslav@260
   108
        }
jaroslav@260
   109
        return browserClass.getClassLoader();
jaroslav@260
   110
    }
jaroslav@260
   111
    
jaroslav@260
   112
    public static synchronized void initialized(Class<?> browserCls) throws Exception {
jaroslav@260
   113
        browserClass = browserCls;
jaroslav@288
   114
        browserContext = FnUtils.currentPresenter();
jaroslav@260
   115
        TyrusKnockoutTest.class.notifyAll();
jaroslav@260
   116
    }
jaroslav@260
   117
    
jaroslav@260
   118
    public static void initialized() throws Exception {
jaroslav@260
   119
        Class<?> classpathClass = ClassLoader.getSystemClassLoader().loadClass(TyrusKnockoutTest.class.getName());
jaroslav@260
   120
        Method m = classpathClass.getMethod("initialized", Class.class);
jaroslav@260
   121
        m.invoke(null, TyrusKnockoutTest.class);
jaroslav@288
   122
        browserContext = FnUtils.currentPresenter();
jaroslav@260
   123
    }
jaroslav@260
   124
    
jaroslav@260
   125
    @Override
jaroslav@260
   126
    public BrwsrCtx createContext() {
jaroslav@288
   127
        FXContext fx = new FXContext(browserContext);
jaroslav@260
   128
        TyrusContext tc = new TyrusContext();
jaroslav@260
   129
        Contexts.Builder cb = Contexts.newBuilder().
jaroslav@260
   130
            register(Technology.class, fx, 10).
jaroslav@260
   131
            register(Transfer.class, fx, 10).
jaroslav@260
   132
            register(WSTransfer.class, tc, 10);
jaroslav@260
   133
        return cb.build();
jaroslav@260
   134
    }
jaroslav@260
   135
jaroslav@260
   136
    @Override
jaroslav@260
   137
    public Object createJSON(Map<String, Object> values) {
jaroslav@260
   138
        JSONObject json = new JSONObject();
jaroslav@260
   139
        for (Map.Entry<String, Object> entry : values.entrySet()) {
jaroslav@260
   140
            try {
jaroslav@260
   141
                json.put(entry.getKey(), entry.getValue());
jaroslav@260
   142
            } catch (JSONException ex) {
jaroslav@260
   143
                throw new IllegalStateException(ex);
jaroslav@260
   144
            }
jaroslav@260
   145
        }
jaroslav@260
   146
        return json;
jaroslav@260
   147
    }
jaroslav@260
   148
jaroslav@260
   149
    @Override
jaroslav@260
   150
    @JavaScriptBody(args = { "s", "args" }, body = ""
jaroslav@260
   151
        + "var f = new Function(s); "
jaroslav@260
   152
        + "return f.apply(null, args);"
jaroslav@260
   153
    )
jaroslav@260
   154
    public native Object executeScript(String script, Object[] arguments);
jaroslav@260
   155
jaroslav@260
   156
    @JavaScriptBody(args = {  }, body = 
jaroslav@260
   157
          "var h;"
jaroslav@260
   158
        + "if (!!window && !!window.location && !!window.location.href)\n"
jaroslav@260
   159
        + "  h = window.location.href;\n"
jaroslav@260
   160
        + "else "
jaroslav@260
   161
        + "  h = null;"
jaroslav@260
   162
        + "return h;\n"
jaroslav@260
   163
    )
jaroslav@260
   164
    private static native String findBaseURL();
jaroslav@260
   165
    
jaroslav@260
   166
    @Override
jaroslav@260
   167
    public URI prepareURL(String content, String mimeType, String[] parameters) {
jaroslav@260
   168
        try {
jaroslav@260
   169
            final URL baseURL = new URL(findBaseURL());
jaroslav@260
   170
            StringBuilder sb = new StringBuilder();
jaroslav@260
   171
            sb.append("/dynamic?mimeType=").append(mimeType);
jaroslav@260
   172
            for (int i = 0; i < parameters.length; i++) {
jaroslav@260
   173
                sb.append("&param" + i).append("=").append(parameters[i]);
jaroslav@260
   174
            }
jaroslav@260
   175
            String mangle = content.replace("\n", "%0a")
jaroslav@260
   176
                .replace("\"", "\\\"").replace(" ", "%20");
jaroslav@260
   177
            sb.append("&content=").append(mangle);
jaroslav@260
   178
jaroslav@260
   179
            URL query = new URL(baseURL, sb.toString());
jaroslav@260
   180
            URLConnection c = query.openConnection();
jaroslav@260
   181
            BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
jaroslav@260
   182
            URI connectTo = new URI(br.readLine());
jaroslav@260
   183
            return connectTo;
jaroslav@260
   184
        } catch (IOException ex) {
jaroslav@260
   185
            throw new IllegalStateException(ex);
jaroslav@260
   186
        } catch (URISyntaxException ex) {
jaroslav@260
   187
            throw new IllegalStateException(ex);
jaroslav@260
   188
        }
jaroslav@260
   189
    }
jaroslav@260
   190
}