Author: [email protected]
Date: Mon Jul  6 06:13:32 2009
New Revision: 5666

Modified:
     
trunk/user/src/com/google/gwt/user/client/rpc/impl/ClientSerializationStreamWriter.java
    trunk/user/test/com/google/gwt/user/client/rpc/UnicodeEscapingTest.java

Log:
Improve correctness of UnicodeEscapingTest.
Splits testClientToServerBMP() into two methods to correctly report  
failures.
Removes support for Safari2.
Extends WebKit regex to support Safari4.

Patch by: bobv
Review by: jat, jgw

Modified:  
trunk/user/src/com/google/gwt/user/client/rpc/impl/ClientSerializationStreamWriter.java
==============================================================================
---  
trunk/user/src/com/google/gwt/user/client/rpc/impl/ClientSerializationStreamWriter.java
  
(original)
+++  
trunk/user/src/com/google/gwt/user/client/rpc/impl/ClientSerializationStreamWriter.java
  
Mon Jul  6 06:13:32 2009
@@ -56,26 +56,18 @@
    private static native JavaScriptObject getQuotingRegex() /*-{
      // "|" = AbstractSerializationStream.RPC_SEPARATOR_CHAR
      var ua = navigator.userAgent.toLowerCase();
-    var webkitregex = /webkit\/([\d]+)/;
-    var webkit = 0;
-    var result = webkitregex.exec(ua);
-    if (result) {
-      webkit = parseInt(result[1]);
-    }
      if (ua.indexOf("android") != -1) {
        // initial version of Android WebKit has a double-encoding bug for  
UTF8,
        // so we have to encode every non-ASCII character.
        // TODO(jat): revisit when this bug is fixed in Android
        return /[\u0000\|\\\u0080-\uFFFF]/g;
-    } else if (webkit < 522) {
-      // Safari 2 doesn't handle \\uXXXX in regexes
-    // TODO(jat): should iPhone be treated specially?
-    return /[\x00\|\\]/g;
-    } else if (webkit > 0) {
-    // other WebKit-based browsers need some additional quoting
-    return /[\u0000\|\\\u0300-\u036F\u0590-\u05FF\uD800-\uFFFF]/g;
+    } else if (ua.indexOf("webkit") != -1) {
+      // other WebKit-based browsers need some additional quoting due to  
combining
+      // forms and normalization (one codepoint being replaced with  
another).
+      // Verified with Safari 4.0.1 (5530.18)
+      return /[\u0000\| 
\\\u0300-\u03ff\u0590-\u05FF\u0600-\u06ff\u0730-\u074A\u07eb-\u07f3\u0940-\u0963\u0980-\u09ff\u0a00-\u0a7f\u0b00-\u0b7f\u0e00-\u0e7f\u0f00-\u0fff\u1900-\u194f\u1a00-\u1a1f\u1b00-\u1b7f\u1dc0-\u1dff\u1f00-\u1fff\u2000-\u206f\u20d0-\u20ff\u2100-\u214f\u2300-\u23ff\u2a00-\u2aff\u3000-\u303f\uD800-\uFFFF]/g;
      } else {
-    return /[\u0000\|\\\uD800-\uFFFF]/g;
+      return /[\u0000\|\\\uD800-\uFFFF]/g;
      }
    }-*/;


Modified:  
trunk/user/test/com/google/gwt/user/client/rpc/UnicodeEscapingTest.java
==============================================================================
--- trunk/user/test/com/google/gwt/user/client/rpc/UnicodeEscapingTest.java     
 
(original)
+++ trunk/user/test/com/google/gwt/user/client/rpc/UnicodeEscapingTest.java     
 
Mon Jul  6 06:13:32 2009
@@ -19,11 +19,14 @@
  import com.google.gwt.junit.client.GWTTestCase;
  import  
com.google.gwt.user.client.rpc.UnicodeEscapingService.InvalidCharacterException;

+import java.util.ArrayList;
+import java.util.List;
+
  /**
   * Test that any valid string can be sent via RPC in both directions.
   *
- * TODO(jat): make unpaired surrogates work properly if it is possible to  
do
- * so on all browsers, then add them to this test.
+ * TODO(jat): make unpaired surrogates work properly if it is possible to  
do so
+ * on all browsers, then add them to this test.
   */
  public class UnicodeEscapingTest extends GWTTestCase {

@@ -32,8 +35,8 @@

    /**
     * When doing the non-BMP test, we don't test every block of characters
-   * because it takes too long - this is the increment to use.  It is not a
-   * power of two so we alter the alignment of the block of characters we  
skip.
+   * because it takes too long - this is the increment to use. It is not a  
power
+   * of two so we alter the alignment of the block of characters we skip.
     */
    private static final int NON_BMP_TEST_INCREMENT = 8192 + 64;

@@ -60,28 +63,6 @@
      return buf.toString();
    }

-  /*
-   * Copied from HistoryTest.
-   */
-  private static native boolean isSafari2() /*-{
-    var exp = / AppleWebKit\/([\d]+)/;
-    var result = exp.exec(navigator.userAgent);
-    if (result) {
-      // The standard history implementation works fine on WebKit >= 522
-      // (Safari 3 beta).
-      if (parseInt(result[1]) >= 522) {
-        return false;
-      }
-    }
-
-    // The standard history implementation works just fine on the iPhone,  
which
-    // unfortunately reports itself as WebKit/420+.
-    if (navigator.userAgent.indexOf('iPhone') != -1) {
-      return false;
-    }
-
-    return true;
-  }-*/;
    /**
     * Verifies that the supplied string includes the requested code points.
     *
@@ -98,8 +79,8 @@
      }
      int expectedLen = end - start;
      int strLen = str.codePointCount(0, str.length());
-    for (int i = 0, codePoint = start; i < strLen;
-        i = Character.offsetByCodePoints(str, i, 1)) {
+    for (int i = 0, codePoint = start; i < strLen; i =  
Character.offsetByCodePoints(
+        str, i, 1)) {
        int strCodePoint = str.codePointAt(i);
        if (strCodePoint != codePoint) {
          throw new InvalidCharacterException(i, codePoint, strCodePoint);
@@ -109,14 +90,16 @@
      if (strLen < expectedLen) {
        throw new InvalidCharacterException(strLen, start + strLen, -1);
      } else if (expectedLen != strLen) {
-      throw new RuntimeException("Too many characters returned on block  
from U+"
-          + Integer.toHexString(start) + " to U+" +  
Integer.toHexString(end)
-          + ": expected=" + expectedLen + ", actual=" + strLen);
+      throw new RuntimeException(
+          "Too many characters returned on block from U+"
+              + Integer.toHexString(start) + " to U+"
+              + Integer.toHexString(end) + ": expected=" + expectedLen
+              + ", actual=" + strLen);
      }
    }
+
    private static UnicodeEscapingServiceAsync getService() {
-    UnicodeEscapingServiceAsync service = GWT.create(
-        UnicodeEscapingService.class);
+    UnicodeEscapingServiceAsync service =  
GWT.create(UnicodeEscapingService.class);
      ServiceDefTarget target = (ServiceDefTarget) service;
      target.setServiceEntryPoint(GWT.getModuleBaseURL() + "unicodeEscape");
      return service;
@@ -136,30 +119,41 @@
     * properly handles all BMP characters.
     *
     * Unpaired or improperly paired surrogates are not tested here, as some
-   * browsers refuse to accept them.  Properly paired surrogates are tested
-   * in the non-BMP test.
-   *
+   * browsers refuse to accept them. Properly paired surrogates are tested  
in
+   * the non-BMP test.
+   *
     * Note that this does not test all possible combinations, which might  
be an
     * issue, particularly with combining marks, though they should be  
logically
     * equivalent in that case.
     *
     * @throws InvalidCharacterException
     */
-  public void testClientToServerBMP() throws InvalidCharacterException {
+  public void testClientToServerBMPHigh() throws InvalidCharacterException  
{
      delayTestFinish(TEST_FINISH_DELAY_MS);
-    if (isSafari2()) {
-      // Safari2 can't be fixed for many characters, including null
-      // We only guarantee that basic ISO-Latin characters are unmolested.
-      clientToServerVerifyRange(0x0001, 0x0300, CHARACTER_BLOCK_SIZE,
-          CHARACTER_BLOCK_SIZE);
-    } else {
-      clientToServerVerifyRange(Character.MIN_CODE_POINT,
-          Character.MIN_SURROGATE, CHARACTER_BLOCK_SIZE,
-          CHARACTER_BLOCK_SIZE);
-      clientToServerVerifyRange(Character.MAX_SURROGATE + 1,
-          Character.MIN_SUPPLEMENTARY_CODE_POINT, CHARACTER_BLOCK_SIZE,
-          CHARACTER_BLOCK_SIZE);
-    }
+    clientToServerVerifyRange(Character.MAX_SURROGATE + 1,
+        Character.MIN_SUPPLEMENTARY_CODE_POINT, CHARACTER_BLOCK_SIZE,
+        CHARACTER_BLOCK_SIZE);
+  }
+
+  /**
+   * Generate strings containing ranges of characters and sends them to the
+   * server for verification. This ensures that client->server string  
escaping
+   * properly handles all BMP characters.
+   *
+   * Unpaired or improperly paired surrogates are not tested here, as some
+   * browsers refuse to accept them. Properly paired surrogates are tested  
in
+   * the non-BMP test.
+   *
+   * Note that this does not test all possible combinations, which might  
be an
+   * issue, particularly with combining marks, though they should be  
logically
+   * equivalent in that case.
+   *
+   * @throws InvalidCharacterException
+   */
+  public void testClientToServerBMPLow() throws InvalidCharacterException {
+    delayTestFinish(TEST_FINISH_DELAY_MS);
+    clientToServerVerifyRange(Character.MIN_CODE_POINT,
+        Character.MIN_SURROGATE, CHARACTER_BLOCK_SIZE,  
CHARACTER_BLOCK_SIZE);
    }

    /**
@@ -181,9 +175,9 @@
    }

    /**
-   * Requests strings of CHARACTER_RANGE_SIZE from the server and validates
-   * that the returned string length matches CHARACTER_RANGE_SIZE and that  
all
-   * of the characters remain intact.
+   * Requests strings of CHARACTER_RANGE_SIZE from the server and  
validates that
+   * the returned string length matches CHARACTER_RANGE_SIZE and that all  
of the
+   * characters remain intact.
     *
     * Note that this does not test all possible combinations, which might  
be an
     * issue, particularly with combining marks, though they should be  
logically
@@ -199,7 +193,7 @@
    /**
     * Requests strings of CHARACTER_RANGE_SIZE from the server and  
validates that
     * the returned string length matches CHARACTER_RANGE_SIZE and that all  
of the
-   * characters remain intact.  Note that this test verifies non-BMP  
characters
+   * characters remain intact. Note that this test verifies non-BMP  
characters
     * (ie, those which are represented as pairs of surrogates).
     *
     * Note that this does not test all possible combinations, which might  
be an
@@ -220,53 +214,78 @@
      getService().verifyStringContainingCharacterRange(current, blockEnd,
          getStringContainingCharacterRange(start, blockEnd),
          new AsyncCallback<Boolean>() {
-      public void onFailure(Throwable caught) {
-        TestSetValidator.rethrowException(caught);
-      }
+          List<Throwable> fails = new ArrayList<Throwable>();

-      public void onSuccess(Boolean ignored) {
-        current += step;
-        if (current < end) {
-          delayTestFinish(TEST_FINISH_DELAY_MS);
-          int blockEnd = Math.min(end, current + size);
-          try {
-            getService().verifyStringContainingCharacterRange(current,  
blockEnd,
-                getStringContainingCharacterRange(current, blockEnd),  
this);
-          } catch (InvalidCharacterException e) {
-            TestSetValidator.rethrowException(e);
+          public void onFailure(Throwable caught) {
+            fails.add(caught);
+            onSuccess(false);
            }
-        } else {
-          finishTest();
-        }
-      }
-    });
+
+          public void onSuccess(Boolean ignored) {
+            current += step;
+            if (current < end) {
+              delayTestFinish(TEST_FINISH_DELAY_MS);
+              int blockEnd = Math.min(end, current + size);
+              try {
+                getService().verifyStringContainingCharacterRange(current,
+                    blockEnd,
+                    getStringContainingCharacterRange(current, blockEnd),  
this);
+              } catch (InvalidCharacterException e) {
+                fails.add(e);
+              }
+            } else if (!fails.isEmpty()) {
+              StringBuilder msg = new StringBuilder();
+              for (Throwable t : fails) {
+                msg.append(t.getMessage()).append("\n");
+              }
+              TestSetValidator.rethrowException(new RuntimeException(
+                  msg.toString()));
+            } else {
+              finishTest();
+            }
+          }
+        });
    }

    private void serverToClientVerify(final int start, final int end,
        final int size, final int step) {
      current = start;
-    getService().getStringContainingCharacterRange(start, Math.min(end,
-        current + size), new AsyncCallback<String>() {
-      public void onFailure(Throwable caught) {
-        TestSetValidator.rethrowException(caught);
-      }
+    getService().getStringContainingCharacterRange(start,
+        Math.min(end, current + size), new AsyncCallback<String>() {
+          List<Throwable> fails = new ArrayList<Throwable>();
+
+          public void onFailure(Throwable caught) {
+            fails.add(caught);
+            nextBatch();
+          }

-      public void onSuccess(String str) {
-        try {
-          verifyStringContainingCharacterRange(current, Math.min(end,
-              current + size), str);
-        } catch (InvalidCharacterException e) {
-          TestSetValidator.rethrowException(e);
-        }
-        current += step;
-        if (current < end) {
-          delayTestFinish(TEST_FINISH_DELAY_MS);
-          getService().getStringContainingCharacterRange(current,
-              Math.min(end, current + size), this);
-        } else {
-          finishTest();
-        }
-      }
-    });
+          public void onSuccess(String str) {
+            try {
+              verifyStringContainingCharacterRange(current, Math.min(end,
+                  current + size), str);
+            } catch (InvalidCharacterException e) {
+              fails.add(e);
+            }
+            nextBatch();
+          }
+
+          private void nextBatch() {
+            current += step;
+            if (current < end) {
+              delayTestFinish(TEST_FINISH_DELAY_MS);
+              getService().getStringContainingCharacterRange(current,
+                  Math.min(end, current + size), this);
+            } else if (!fails.isEmpty()) {
+              StringBuilder msg = new StringBuilder();
+              for (Throwable t : fails) {
+                msg.append(t.getMessage()).append("\n");
+              }
+              TestSetValidator.rethrowException(new RuntimeException(
+                  msg.toString()));
+            } else {
+              finishTest();
+            }
+          }
+        });
    }
  }

--~--~---------~--~----~------------~-------~--~----~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~----------~----~----~----~------~----~------~--~---

Reply via email to