# HG changeset patch # User Jaroslav Tulach # Date 1359650387 -3600 # Node ID 4af0d3dedb9dd210d74474ec802208e532daf2c4 # Parent a07253cf2ca4da85eb873865dedccd355fd862a6 @HttpResource allows a test to connect back to the server and read static resource diff -r a07253cf2ca4 -r 4af0d3dedb9d launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Thu Jan 31 16:58:27 2013 +0100 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/Bck2BrwsrLauncher.java Thu Jan 31 17:39:47 2013 +0100 @@ -147,13 +147,40 @@ private void executeInBrowser() throws InterruptedException, URISyntaxException, IOException { wait = new CountDownLatch(1); server = initServer(".", true); - ServerConfiguration conf = server.getServerConfiguration(); + final ServerConfiguration conf = server.getServerConfiguration(); + + class DynamicResourceHandler extends HttpHandler { + private final InvocationContext ic; + public DynamicResourceHandler(InvocationContext ic) { + if (ic == null || ic.httpPath == null) { + throw new NullPointerException(); + } + this.ic = ic; + conf.addHttpHandler(this, ic.httpPath); + } + + public void close() { + conf.removeHttpHandler(this); + } + + @Override + public void service(Request request, Response response) throws Exception { + if (ic.httpPath.equals(request.getRequestURI())) { + LOG.log(Level.INFO, "Serving HttpResource for {0}", request.getRequestURI()); + response.setContentType(ic.httpType); + response.getWriter().write(ic.httpContent); + } + } + } + conf.addHttpHandler(new Page(resources, "org/apidesign/bck2brwsr/launcher/harness.xhtml" ), "/execute"); + conf.addHttpHandler(new HttpHandler() { int cnt; List cases = new ArrayList<>(); + DynamicResourceHandler prev; @Override public void service(Request request, Response response) throws Exception { String id = request.getParameter("request"); @@ -165,6 +192,11 @@ cases.get(Integer.parseInt(id)).result(value, null); } + if (prev != null) { + prev.close(); + prev = null; + } + InvocationContext mi = methods.take(); if (mi == END) { response.getWriter().write(""); @@ -174,6 +206,10 @@ return; } + if (mi.httpPath != null) { + prev = new DynamicResourceHandler(mi); + } + cases.add(mi); final String cn = mi.clazz.getName(); final String mn = mi.methodName; diff -r a07253cf2ca4 -r 4af0d3dedb9d launcher/src/main/java/org/apidesign/bck2brwsr/launcher/InvocationContext.java --- a/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/InvocationContext.java Thu Jan 31 16:58:27 2013 +0100 +++ b/launcher/src/main/java/org/apidesign/bck2brwsr/launcher/InvocationContext.java Thu Jan 31 17:39:47 2013 +0100 @@ -55,6 +55,9 @@ * perform an HTTP query and obtain a resource relative to the page. */ public void setHttpResource(String relativePath, String mimeType, String content) { + if (relativePath == null || mimeType == null || content == null) { + throw new NullPointerException(); + } this.httpPath = relativePath; this.httpType = mimeType; this.httpContent = content; diff -r a07253cf2ca4 -r 4af0d3dedb9d vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/HttpResource.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/HttpResource.java Thu Jan 31 17:39:47 2013 +0100 @@ -0,0 +1,39 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.vmtest; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** Exposes an HTTP page to the running {@link BrwsrTest}, so it can access + * under the relative path. + * + * @author Jaroslav Tulach + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD, ElementType.TYPE}) +public @interface HttpResource { + /** path on the server that the test can use to access the exposed resource */ + String path(); + /** the content of the HttpResource */ + String content(); + /** mime type of the resource */ + String mimeType(); +} diff -r a07253cf2ca4 -r 4af0d3dedb9d vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java --- a/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java Thu Jan 31 16:58:27 2013 +0100 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/Bck2BrwsrCase.java Thu Jan 31 17:39:47 2013 +0100 @@ -25,6 +25,8 @@ import java.lang.reflect.Method; import org.apidesign.bck2brwsr.launcher.Launcher; import org.apidesign.bck2brwsr.launcher.InvocationContext; +import org.apidesign.bck2brwsr.vmtest.HtmlFragment; +import org.apidesign.bck2brwsr.vmtest.HttpResource; import org.testng.ITest; import org.testng.annotations.Test; @@ -37,15 +39,17 @@ private final Launcher l; private final String type; private final boolean fail; + private final HtmlFragment html; + private final HttpResource http; Object value; - private final String html; - Bck2BrwsrCase(Method m, String type, Launcher l, boolean fail, String html) { + Bck2BrwsrCase(Method m, String type, Launcher l, boolean fail, HtmlFragment html, HttpResource http) { this.l = l; this.m = m; this.type = type; this.fail = fail; this.html = html; + this.http = http; } @Test(groups = "run") @@ -53,7 +57,10 @@ if (l != null) { InvocationContext c = l.createInvocation(m.getDeclaringClass(), m.getName()); if (html != null) { - c.setHtmlFragment(html); + c.setHtmlFragment(html.value()); + } + if (http != null) { + c.setHttpResource(http.path(), http.mimeType(), http.content()); } String res = c.invoke(); value = res; diff -r a07253cf2ca4 -r 4af0d3dedb9d vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java --- a/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java Thu Jan 31 16:58:27 2013 +0100 +++ b/vmtest/src/main/java/org/apidesign/bck2brwsr/vmtest/impl/CompareCase.java Thu Jan 31 17:39:47 2013 +0100 @@ -111,17 +111,17 @@ if (c == null) { return; } - final Bck2BrwsrCase real = new Bck2BrwsrCase(m, "Java", null, false, null); + final Bck2BrwsrCase real = new Bck2BrwsrCase(m, "Java", null, false, null, null); ret.add(real); if (c.scripting()) { - final Bck2BrwsrCase js = new Bck2BrwsrCase(m, "JavaScript", l.javaScript(), false, null); + final Bck2BrwsrCase js = new Bck2BrwsrCase(m, "JavaScript", l.javaScript(), false, null, null); ret.add(js); ret.add(new CompareCase(m, real, js)); } for (String b : brwsr) { final Launcher s = l.brwsr(b); ret.add(s); - final Bck2BrwsrCase cse = new Bck2BrwsrCase(m, b, s, false, null); + final Bck2BrwsrCase cse = new Bck2BrwsrCase(m, b, s, false, null, null); ret.add(cse); ret.add(new CompareCase(m, real, cse)); } @@ -135,16 +135,19 @@ if (f == null) { f = m.getDeclaringClass().getAnnotation(HtmlFragment.class); } - String html = f == null ? null : f.value(); + HttpResource r = m.getAnnotation(HttpResource.class); + if (r == null) { + r = m.getDeclaringClass().getAnnotation(HttpResource.class); + } if (brwsr.length == 0) { final Launcher s = l.brwsr(null); ret.add(s); - ret.add(new Bck2BrwsrCase(m, "Brwsr", s, true, html)); + ret.add(new Bck2BrwsrCase(m, "Brwsr", s, true, f, r)); } else { for (String b : brwsr) { final Launcher s = l.brwsr(b); ret.add(s); - ret.add(new Bck2BrwsrCase(m, b, s, true, html)); + ret.add(new Bck2BrwsrCase(m, b, s, true, f, r)); } } } diff -r a07253cf2ca4 -r 4af0d3dedb9d vmtest/src/test/java/org/apidesign/bck2brwsr/tck/HttpResourceTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vmtest/src/test/java/org/apidesign/bck2brwsr/tck/HttpResourceTest.java Thu Jan 31 17:39:47 2013 +0100 @@ -0,0 +1,53 @@ +/** + * Back 2 Browser Bytecode Translator + * Copyright (C) 2012 Jaroslav Tulach + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. Look for COPYING file in the top folder. + * If not, see http://opensource.org/licenses/GPL-2.0. + */ +package org.apidesign.bck2brwsr.tck; + +import org.apidesign.bck2brwsr.core.JavaScriptBody; +import org.apidesign.bck2brwsr.vmtest.BrwsrTest; +import org.apidesign.bck2brwsr.vmtest.HttpResource; +import org.apidesign.bck2brwsr.vmtest.VMTest; +import org.testng.annotations.Factory; + +/** + * + * @author Jaroslav Tulach + */ +public class HttpResourceTest { + + @HttpResource(path = "/xhr", content = "Hello Brwsr!", mimeType = "text/plain") + @BrwsrTest + public String testReadContentViaXHR() throws Exception { + String msg = read("/xhr"); + assert "Hello Brwsr!".equals(msg) : "The message was " + msg; + return msg; + } + + @JavaScriptBody(args = { "url" }, body = + "var req = new XMLHttpRequest();\n" + + "req.open('GET', url, false);\n" + + "req.send();\n" + + "return req.responseText;" + ) + private static native String read(String url); + + + @Factory + public static Object[] create() { + return VMTest.create(HttpResourceTest.class); + } +}