You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by bi...@apache.org on 2007/11/18 18:19:39 UTC

svn commit: r596101 - in /incubator/cxf/trunk/rt/javascript/src/test: java/org/apache/cxf/javascript/ resources/org/apache/cxf/javascript/

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();
 }