jaroslav@260: /** jaroslav@358: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. jaroslav@260: * jaroslav@551: * Copyright 2013-2014 Oracle and/or its affiliates. All rights reserved. jaroslav@260: * jaroslav@358: * Oracle and Java are registered trademarks of Oracle and/or its affiliates. jaroslav@358: * Other names may be trademarks of their respective owners. jaroslav@260: * jaroslav@358: * The contents of this file are subject to the terms of either the GNU jaroslav@358: * General Public License Version 2 only ("GPL") or the Common jaroslav@358: * Development and Distribution License("CDDL") (collectively, the jaroslav@358: * "License"). You may not use this file except in compliance with the jaroslav@358: * License. You can obtain a copy of the License at jaroslav@358: * http://www.netbeans.org/cddl-gplv2.html jaroslav@358: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the jaroslav@358: * specific language governing permissions and limitations under the jaroslav@358: * License. When distributing the software, include this License Header jaroslav@358: * Notice in each file and include the License file at jaroslav@358: * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this jaroslav@358: * particular file as subject to the "Classpath" exception as provided jaroslav@358: * by Oracle in the GPL Version 2 section of the License file that jaroslav@358: * accompanied this code. If applicable, add the following below the jaroslav@358: * License Header, with the fields enclosed by brackets [] replaced by jaroslav@358: * your own identifying information: jaroslav@358: * "Portions Copyrighted [year] [name of copyright owner]" jaroslav@358: * jaroslav@358: * Contributor(s): jaroslav@358: * jaroslav@358: * The Original Software is NetBeans. The Initial Developer of the Original jaroslav@551: * Software is Oracle. Portions Copyright 2013-2014 Oracle. All Rights Reserved. jaroslav@358: * jaroslav@358: * If you wish your version of this file to be governed by only the CDDL jaroslav@358: * or only the GPL Version 2, indicate your decision by adding jaroslav@358: * "[Contributor] elects to include this software in this distribution jaroslav@358: * under the [CDDL or GPL Version 2] license." If you do not indicate a jaroslav@358: * single choice of license, a recipient has the option to distribute jaroslav@358: * your version of this file under either the CDDL, the GPL Version 2 or jaroslav@358: * to extend the choice of license to its licensees as provided above. jaroslav@358: * However, if you add GPL Version 2 code and therefore, elected the GPL jaroslav@358: * Version 2 license, then the option applies only if the new code is jaroslav@358: * made subject to such option by the copyright holder. jaroslav@260: */ jtulach@1057: package org.netbeans.html.xhr4j; jaroslav@260: jaroslav@260: import java.io.BufferedReader; jaroslav@260: import java.io.IOException; jaroslav@260: import java.io.InputStreamReader; jaroslav@260: import java.lang.annotation.Annotation; jaroslav@260: import java.lang.reflect.Method; jaroslav@260: import java.net.URI; jaroslav@260: import java.net.URISyntaxException; jaroslav@260: import java.net.URL; jaroslav@260: import java.net.URLConnection; jaroslav@260: import java.util.ArrayList; jaroslav@260: import java.util.List; jaroslav@260: import java.util.Map; jaroslav@574: import java.util.concurrent.Executor; jaroslav@260: import java.util.concurrent.Executors; jaroslav@260: import net.java.html.BrwsrCtx; jaroslav@260: import net.java.html.boot.BrowserBuilder; jaroslav@260: import net.java.html.js.JavaScriptBody; jtulach@838: import org.netbeans.html.boot.spi.Fn; jtulach@838: import org.netbeans.html.context.spi.Contexts; jtulach@838: import org.netbeans.html.json.spi.Technology; jtulach@838: import org.netbeans.html.json.tck.KOTest; jtulach@838: import org.netbeans.html.json.tck.KnockoutTCK; jaroslav@444: import org.netbeans.html.ko4j.KO4J; jaroslav@260: import org.openide.util.lookup.ServiceProvider; jaroslav@488: import org.testng.Assert; jaroslav@444: import static org.testng.Assert.*; jaroslav@260: import org.testng.annotations.Factory; jaroslav@260: jaroslav@260: /** jaroslav@260: * jtulach@790: * @author Jaroslav Tulach jaroslav@260: */ jaroslav@260: @ServiceProvider(service = KnockoutTCK.class) jtulach@1057: public final class JsonKnockoutTest extends KnockoutTCK { jaroslav@260: private static Class browserClass; jaroslav@288: private static Fn.Presenter browserContext; jaroslav@260: jtulach@1057: public JsonKnockoutTest() { jaroslav@260: } jaroslav@260: jaroslav@260: @Factory public static Object[] compatibilityTests() throws Exception { jaroslav@260: Class[] arr = testClasses(); jaroslav@260: for (int i = 0; i < arr.length; i++) { jtulach@1057: assertEquals(arr[i].getClassLoader(), jtulach@1057: JsonKnockoutTest.class.getClassLoader(), jaroslav@260: "All classes loaded by the same classloader" jaroslav@260: ); jaroslav@260: } jaroslav@260: jtulach@1057: URI uri = JsonDynamicHTTP.initServer(); jaroslav@260: jtulach@1057: final BrowserBuilder bb = BrowserBuilder.newBrowser().loadClass(JsonKnockoutTest.class). jaroslav@260: loadPage(uri.toString()). jaroslav@260: invoke("initialized"); jaroslav@260: jaroslav@260: Executors.newSingleThreadExecutor().submit(new Runnable() { jaroslav@260: @Override jaroslav@260: public void run() { jaroslav@260: bb.showAndWait(); jaroslav@260: } jaroslav@260: }); jaroslav@260: jaroslav@260: ClassLoader l = getClassLoader(); jaroslav@260: List res = new ArrayList(); jaroslav@260: for (int i = 0; i < arr.length; i++) { jaroslav@260: Class c = Class.forName(arr[i].getName(), true, l); jaroslav@260: Class koTest = jaroslav@260: c.getClassLoader().loadClass(KOTest.class.getName()). jaroslav@260: asSubclass(Annotation.class); jaroslav@260: for (Method m : c.getMethods()) { jaroslav@260: if (m.getAnnotation(koTest) != null) { jtulach@1057: res.add(new JsonFX(browserContext, m)); jaroslav@260: } jaroslav@260: } jaroslav@260: } jaroslav@260: return res.toArray(); jaroslav@260: } jaroslav@260: jaroslav@260: static synchronized ClassLoader getClassLoader() throws InterruptedException { jaroslav@260: while (browserClass == null) { jtulach@1057: JsonKnockoutTest.class.wait(); jaroslav@260: } jaroslav@260: return browserClass.getClassLoader(); jaroslav@260: } jaroslav@260: jaroslav@260: public static synchronized void initialized(Class browserCls) throws Exception { jaroslav@260: browserClass = browserCls; jaroslav@339: browserContext = Fn.activePresenter(); jtulach@1057: JsonKnockoutTest.class.notifyAll(); jaroslav@260: } jaroslav@260: jaroslav@260: public static void initialized() throws Exception { jtulach@1057: Assert.assertSame(JsonKnockoutTest.class.getClassLoader(), jaroslav@488: ClassLoader.getSystemClassLoader(), jaroslav@488: "No special classloaders" jaroslav@488: ); jtulach@1057: JsonKnockoutTest.initialized(JsonKnockoutTest.class); jtulach@1057: } jtulach@1057: jtulach@1057: @Override jtulach@1057: public boolean canFailWebSocketTest() { jtulach@1057: return true; jaroslav@260: } jaroslav@260: jaroslav@260: @Override jaroslav@260: public BrwsrCtx createContext() { jaroslav@444: KO4J ko = new KO4J(browserContext); jtulach@1057: XmlHttpResourceContext tc = new XmlHttpResourceContext(); jaroslav@260: Contexts.Builder cb = Contexts.newBuilder(). jaroslav@444: register(Technology.class, ko.knockout(), 10). jaroslav@574: register(Executor.class, (Executor)browserContext, 10). jaroslav@574: register(Fn.Presenter.class, (Fn.Presenter)browserContext, 10); jtulach@1057: tc.fillContext(cb, browserClass); jaroslav@260: return cb.build(); jaroslav@260: } jaroslav@260: jaroslav@260: @Override jaroslav@260: public Object createJSON(Map values) { jtulach@1057: Object json = createJSON(); jaroslav@260: for (Map.Entry entry : values.entrySet()) { jtulach@1057: setProperty(json, entry.getKey(), entry.getValue()); jaroslav@260: } jaroslav@260: return json; jaroslav@260: } jaroslav@260: jtulach@1057: @JavaScriptBody(args = {}, body = "return new Object();") jtulach@1057: private static native Object createJSON(); jtulach@1057: jtulach@1057: @JavaScriptBody(args = {"json", "key", "value"}, body = "json[key] = value;") jtulach@1057: private static native void setProperty(Object json, String key, Object value); jtulach@1057: jaroslav@260: @Override jaroslav@260: @JavaScriptBody(args = { "s", "args" }, body = "" jaroslav@260: + "var f = new Function(s); " jaroslav@260: + "return f.apply(null, args);" jaroslav@260: ) jaroslav@260: public native Object executeScript(String script, Object[] arguments); jaroslav@260: jaroslav@260: @JavaScriptBody(args = { }, body = jaroslav@260: "var h;" jaroslav@260: + "if (!!window && !!window.location && !!window.location.href)\n" jaroslav@260: + " h = window.location.href;\n" jaroslav@260: + "else " jaroslav@260: + " h = null;" jaroslav@260: + "return h;\n" jaroslav@260: ) jaroslav@260: private static native String findBaseURL(); jaroslav@260: jaroslav@260: @Override jaroslav@260: public URI prepareURL(String content, String mimeType, String[] parameters) { jaroslav@260: try { jaroslav@260: final URL baseURL = new URL(findBaseURL()); jaroslav@260: StringBuilder sb = new StringBuilder(); jaroslav@260: sb.append("/dynamic?mimeType=").append(mimeType); jaroslav@260: for (int i = 0; i < parameters.length; i++) { jaroslav@260: sb.append("¶m" + i).append("=").append(parameters[i]); jaroslav@260: } jaroslav@260: String mangle = content.replace("\n", "%0a") jaroslav@260: .replace("\"", "\\\"").replace(" ", "%20"); jaroslav@260: sb.append("&content=").append(mangle); jaroslav@260: jaroslav@260: URL query = new URL(baseURL, sb.toString()); jaroslav@260: URLConnection c = query.openConnection(); jaroslav@260: BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream())); jaroslav@260: URI connectTo = new URI(br.readLine()); jaroslav@260: return connectTo; jaroslav@260: } catch (IOException ex) { jaroslav@260: throw new IllegalStateException(ex); jaroslav@260: } catch (URISyntaxException ex) { jaroslav@260: throw new IllegalStateException(ex); jaroslav@260: } jaroslav@260: } jaroslav@260: }