Author: bimargulies
Date: Sun Nov 18 09:19:38 2007
New Revision: 596101
URL: http://svn.apache.org/viewvc?rev=596101&view=rev
Log:
Add tests for asynchronous processing of HTTP.
Modified:
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JavascriptTestUtilities.java
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JsHttpRequestTest.java
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JsXMLHttpRequest.java
incubator/cxf/trunk/rt/javascript/src/test/resources/org/apache/cxf/javascript/XMLHttpRequestTests.js
Modified:
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JavascriptTestUtilities.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JavascriptTestUtilities.java?rev=596101&r1=596100&r2=596101&view=diff
==============================================================================
---
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JavascriptTestUtilities.java
(original)
+++
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JavascriptTestUtilities.java
Sun Nov 18 09:19:38 2007
@@ -79,7 +79,38 @@
LOG.fine(message);
}
//CHECKSTYLE:ON
+ }
+
+ public static class Notifier extends ScriptableObject {
+
+ private boolean notified;
+
+ public Notifier() {
+ }
+
+ @Override
+ public String getClassName() {
+ return "org_apache_cxf_notifier";
+ }
+
+ public synchronized boolean waitForJavascript(long timeout) {
+ while (!notified) {
+ try {
+ wait(timeout);
+ return notified;
+ } catch (InterruptedException e) {
+ // do nothing.
+ }
+ }
+ return true; // only here if true on entry.
+ }
+ //CHECKSTYLE:OFF
+ public synchronized void jsFunction_notify() {
+ notified = true;
+ notifyAll();
+ }
+ //CHECKSTYLE:ON
}
public JavascriptTestUtilities(Class<?> classpathReference) {
@@ -97,6 +128,7 @@
try {
ScriptableObject.defineClass(rhinoScope, JsAssert.class);
ScriptableObject.defineClass(rhinoScope, Trace.class);
+ ScriptableObject.defineClass(rhinoScope, Notifier.class);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
@@ -134,11 +166,27 @@
return rhinoContext.newObject(rhinoScope, constructorName);
}
+ /**
+ * Evaluate a javascript expression, returning the raw Rhino object.
+ * @param jsExpression the javascript expression.
+ * @return return value.
+ */
public Object rhinoEvaluate(String jsExpression) {
return rhinoContext.evaluateString(rhinoScope, jsExpression,
"<testcase>", 1, null);
}
/**
+ * Evaluate a Javascript expression, converting the return value to a
convenient Java type.
+ * @param <T> The desired type
+ * @param jsExpression the javascript expression.
+ * @param clazz the Class object for the desired type.
+ * @return the result.
+ */
+ public <T> T rhinoEvaluateConvert(String jsExpression, Class<T> clazz) {
+ return clazz.cast(Context.jsToJava(rhinoEvaluate(jsExpression),
clazz));
+ }
+
+ /**
* Call a JavaScript function. Optionally, require it to throw an
exception equal to
* a supplied object. If the exception is called for, this function will
either return null
* or Assert.
@@ -173,5 +221,9 @@
public Object rhinoCall(String functionName, Object ... args) {
return rhinoCallExpectingException(null, functionName, args);
+ }
+
+ public <T> T rhinoCallConvert(String functionName, Class<T> clazz, Object
... args) {
+ return clazz.cast(Context.jsToJava(rhinoCall(functionName, args),
clazz));
}
}
Modified:
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JsHttpRequestTest.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JsHttpRequestTest.java?rev=596101&r1=596100&r2=596101&view=diff
==============================================================================
---
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JsHttpRequestTest.java
(original)
+++
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JsHttpRequestTest.java
Sun Nov 18 09:19:38 2007
@@ -24,6 +24,7 @@
import java.util.Properties;
import org.apache.cxf.Bus;
+import org.apache.cxf.javascript.JavascriptTestUtilities.Notifier;
import org.apache.cxf.test.AbstractCXFSpringTest;
import org.junit.Before;
import org.junit.Test;
@@ -79,6 +80,28 @@
@Test
public void testSequencing() throws Exception {
testUtilities.rhinoCallExpectingException("INVALID_STATE_ERR",
"testSendNotOpenError");
+ testUtilities.rhinoCall("testStateNotificationSync");
+ }
+
+ @Test public void testAsync() throws Exception {
+ Notifier notifier =
testUtilities.rhinoCallConvert("testAsyncHttpFetch1", Notifier.class);
+ testUtilities.rhinoCall("testAsyncHttpFetch2");
+ boolean notified = notifier.waitForJavascript(10);
+ assertTrue(notified);
+ assertEquals("HEADERS_RECEIVED", Boolean.TRUE,
+
testUtilities.rhinoEvaluateConvert("asyncGotHeadersReceived", Boolean.class));
+ assertEquals("LOADING", Boolean.TRUE,
+ testUtilities.rhinoEvaluateConvert("asyncGotLoading",
Boolean.class));
+ assertEquals("DONE", Boolean.TRUE,
+ testUtilities.rhinoEvaluateConvert("asyncGotDone",
Boolean.class));
+ String outOfOrder =
testUtilities.rhinoEvaluateConvert("outOfOrderError", String.class);
+ assertEquals("OutOfOrder", null, outOfOrder);
+ assertEquals("status 200", Integer.valueOf(200),
+ testUtilities.rhinoEvaluateConvert("asyncStatus",
Integer.class));
+ assertEquals("status text", "OK",
+ testUtilities.rhinoEvaluateConvert("asyncStatusText",
String.class));
+ assertTrue("headers",
testUtilities.rhinoEvaluateConvert("asyncResponseHeaders", String.class)
+ .contains("Content-Type: text/html"));
}
@Test
@@ -88,6 +111,7 @@
assertNotNull(httpObj);
assertTrue(httpObj instanceof String);
String httpResponse = (String) httpObj;
+ // check for 'Shalom' in Hebrew as a charset check.
assertTrue(httpResponse.contains("\u05e9\u05dc\u05d5\u05dd"));
}
Modified:
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JsXMLHttpRequest.java
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JsXMLHttpRequest.java?rev=596101&r1=596100&r2=596101&view=diff
==============================================================================
---
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JsXMLHttpRequest.java
(original)
+++
incubator/cxf/trunk/rt/javascript/src/test/java/org/apache/cxf/javascript/JsXMLHttpRequest.java
Sun Nov 18 09:19:38 2007
@@ -456,6 +456,10 @@
// 3 pile up the headers.
StringBuilder builder = new StringBuilder();
for (Map.Entry<String, List<String>> headersEntry :
responseHeaders.entrySet()) {
+ if (headersEntry.getKey() == null) {
+ // why does the HTTP connection return a null key with the
response code and text?
+ continue;
+ }
builder.append(headersEntry.getKey());
builder.append(": ");
for (String value : headersEntry.getValue()) {
@@ -501,7 +505,7 @@
public String doGetResponseText() {
// 1 check state.
if (readyState == jsGet_UNSENT() || readyState == jsGet_OPENED()) {
- LOG.severe("invalid state");
+ LOG.severe("invalid state " + readyState);
throwError("INVALID_STATE_ERR");
}
Modified:
incubator/cxf/trunk/rt/javascript/src/test/resources/org/apache/cxf/javascript/XMLHttpRequestTests.js
URL:
http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/javascript/src/test/resources/org/apache/cxf/javascript/XMLHttpRequestTests.js?rev=596101&r1=596100&r2=596101&view=diff
==============================================================================
---
incubator/cxf/trunk/rt/javascript/src/test/resources/org/apache/cxf/javascript/XMLHttpRequestTests.js
(original)
+++
incubator/cxf/trunk/rt/javascript/src/test/resources/org/apache/cxf/javascript/XMLHttpRequestTests.js
Sun Nov 18 09:19:38 2007
@@ -58,5 +58,95 @@
assertionFailed("state not DONE after sync send.")
}
return r.responseText;
+}
+
+// global variable used for state checking.
+
+var globalState = null;
+
+function testStateNotificationSync() {
+ globalState = null;
+ var r = new XMLHttpRequest();
+ // create closure.
+ r.onreadystatechange = function() {
+ globalState = r.readyState;
+ }
+ r.open("GET", "http://localhost:8808/test.html", false);
+ if (r.readyState != r.OPENED) {
+ assertionFailed("state not OPENED after OPEN");
+ }
+ if(globalState != r.OPENED) {
+ assertionFailed("global state not OPENED after OPEN (event
handler didn't run?)");
+ }
+ r.send();
+ if (r.readyState != r.DONE) {
+ assertionFailed("state not DONE after sync send.")
+ }
+ if(globalState != r.DONE) {
+ assertionFailed("global state not DONE after sync send (event
handler didn't run?)");
+ }
+}
+
+var asyncGotHeadersReceived = false;
+var asyncGotLoading = false;
+var outOfOrderError = null;
+var asyncGotDone = false;
+var asyncStatus = -1;
+var asyncStatusText = null;
+var asyncResponseHeaders = null;
+var globalAsyncRequest = null;
+
+// to ensure everyone stays in sync, this does NOT call send.
+function testAsyncHttpFetch1() {
+ globalState = null;
+ asyncGotHeadersReceived = false;
+ asyncGotLoading = false;
+ outOfOrderError = null;
+ asyncGotDone = false;
+ asyncStatus = -1;
+ asyncStatusText = null;
+ asyncResponseHeaders = null;
+ var notifier = new org_apache_cxf_notifier();
+
+ var r = new XMLHttpRequest();
+ globalAsyncRequest = r;
+ // create closure.
+ r.onreadystatechange = function() {
+ globalState = r.readyState;
+ if(globalState == r.OPENED) {
+ // no need to do anything will be checked below.
+ } else if(globalState == r.HEADERS_RECEIVED) {
+ asyncGotHeadersReceived = true;
+ } else if(globalState == r.LOADING) {
+ if(!asyncGotHeadersReceived) {
+ outOfOrderError = "LOADING before
HEADERS_RECEIVED";
+ }
+ asyncGotLoading = true;
+ } else if(globalState = r.DONE) {
+ if(!asyncGotLoading) {
+ outOfOrderError = "DONE before LOADING";
+ }
+ asyncGotDone = true;
+ asyncResponseText = r.responseText;
+ asyncStatus = r.status;
+ asyncStatusText = r.statusText;
+ asyncResponseHeaders = r.getAllResponseHeaders();
+ notifier.notify();
+ globalAsyncRequest = null;
+ }
+ }
+
+ r.open("GET", "http://localhost:8808/test.html", true);
+ if (r.readyState != r.OPENED) {
+ assertionFailed("state not OPENED after OPEN");
+ }
+ if(globalState != r.OPENED) {
+ assertionFailed("global state not OPENED after OPEN (event
handler didn't run?)");
+ }
+ return notifier;
+}
+
+function testAsyncHttpFetch2() {
+ globalAsyncRequest.send();
}