Revision: 6329 Author: jlaba...@google.com Date: Thu Oct 8 13:06:28 2009 Log: Adding UrlBuilder and using it in Showcase and GwtTestCase so we don't remove gwt.hosted parameter in URLs.
Patch by: jlabanca Review by: jat http://code.google.com/p/google-web-toolkit/source/detail?r=6329 Added: /trunk/user/src/com/google/gwt/http/client/UrlBuilder.java /trunk/user/test/com/google/gwt/http/client/UrlBuilderTest.java Modified: /trunk/samples/showcase/src/com/google/gwt/sample/showcase/client/Showcase.java /trunk/user/src/com/google/gwt/user/client/Window.java /trunk/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java /trunk/user/test/com/google/gwt/http/HTTPSuite.java /trunk/user/test/com/google/gwt/user/client/WindowTest.java ======================================= --- /dev/null +++ /trunk/user/src/com/google/gwt/http/client/UrlBuilder.java Thu Oct 8 13:06:28 2009 @@ -0,0 +1,243 @@ +/* + * Copyright 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.http.client; + +import java.util.HashMap; +import java.util.Map; + +/** + * Utility class to build a URL from components. + * + * TODO(jlabanca): Add a constructor that parses an existing URL + */ +public class UrlBuilder { + + /** + * The port to use when no port should be specified. + */ + public static final int PORT_UNSPECIFIED = Integer.MIN_VALUE; + + /** + * A mapping of query parameters to their values. + */ + private Map<String, String[]> listParamMap = new HashMap<String, String[]>(); + + private String protocol = "http"; + private String host = null; + private int port = PORT_UNSPECIFIED; + private String path = null; + private String hash = null; + + /** + * Build the URL and return it as an encoded string. + * + * @return the encoded URL string + */ + public String buildString() { + StringBuilder url = new StringBuilder(); + + // http:// + url.append(protocol).append("://"); + + // http://www.google.com + if (host != null) { + url.append(host); + } + + // http://www.google.com:80 + if (port != PORT_UNSPECIFIED) { + url.append(":").append(port); + } + + // http://www.google.com:80/path/to/file.html + if (path != null && !"".equals(path)) { + url.append("/").append(path); + } + + // Generate the query string. + // http://www.google.com:80/path/to/file.html?k0=v0&k1=v1 + char prefix = '?'; + for (Map.Entry<String, String[]> entry : listParamMap.entrySet()) { + for (String val : entry.getValue()) { + url.append(prefix).append(entry.getKey()).append('='); + if (val != null) { + url.append(val); + } + prefix = '&'; + } + } + + // http://www.google.com:80/path/to/file.html?k0=v0&k1=v1#token + if (hash != null) { + url.append("#").append(hash); + } + + return URL.encode(url.toString()); + } + + /** + * Remove a query parameter from the map. + * + * @param name the parameter name + */ + public UrlBuilder removeParameter(String name) { + listParamMap.remove(name); + return this; + } + + /** + * Set the hash portion of the location (ex. myAnchor or #myAnchor). + * + * @param hash the hash + */ + public UrlBuilder setHash(String hash) { + if (hash != null && hash.startsWith("#")) { + hash = hash.substring(1); + } + this.hash = hash; + return this; + } + + /** + * Set the host portion of the location (ex. google.com). You can also specify + * the port in this method (ex. localhost:8888). + * + * @param host the host + */ + public UrlBuilder setHost(String host) { + // Extract the port from the host. + if (host != null && host.contains(":")) { + String[] parts = host.split(":"); + if (parts.length > 2) { + throw new IllegalArgumentException( + "Host contains more than one colon: " + host); + } + try { + setPort(Integer.parseInt(parts[1])); + } catch (NumberFormatException e) { + throw new IllegalArgumentException("Could not parse port out of host: " + + host); + } + host = parts[0]; + } + this.host = host; + return this; + } + + /** + * <p> + * Set a query parameter to a list of values. Each value in the list will be + * added as its own key/value pair. + * + * <p> + * <h3>Example Output</h3> + * <code>?mykey=value0&mykey=value1&mykey=value2</code> + * </p> + * + * @param key the key + * @param values the list of values + */ + public UrlBuilder setParameter(String key, String... values) { + assertNotNullOrEmpty(key, "Key cannot be null or empty", false); + assertNotNull(values, + "Values cannot null. Try using removeParameter instead."); + if (values.length == 0) { + throw new IllegalArgumentException( + "Values cannot be empty. Try using removeParameter instead."); + } + listParamMap.put(key, values); + return this; + } + + /** + * Set the path portion of the location (ex. path/to/file.html). + * + * @param path the path + */ + public UrlBuilder setPath(String path) { + if (path != null && path.startsWith("/")) { + path = path.substring(1); + } + this.path = path; + return this; + } + + /** + * Set the port to connect to. + * + * @param port the port, or {...@link #PORT_UNSPECIFIED} + */ + public UrlBuilder setPort(int port) { + this.port = port; + return this; + } + + /** + * Set the protocol portion of the location (ex. http). + * + * @param protocol the protocol + */ + public UrlBuilder setProtocol(String protocol) { + assertNotNull(protocol, "Protocol cannot be null"); + if (protocol.endsWith("://")) { + protocol = protocol.substring(0, protocol.length() - 3); + } else if (protocol.endsWith(":/")) { + protocol = protocol.substring(0, protocol.length() - 2); + } else if (protocol.endsWith(":")) { + protocol = protocol.substring(0, protocol.length() - 1); + } + if (protocol.contains(":")) { + throw new IllegalArgumentException("Invalid protocol: " + protocol); + } + assertNotNullOrEmpty(protocol, "Protocol cannot be empty", false); + this.protocol = protocol; + return this; + } + + /** + * Assert that the value is not null. + * + * @param value the value + * @param message the message to include with any exceptions + * @throws IllegalArgumentException if value is null + */ + private void assertNotNull(Object value, String message) + throws IllegalArgumentException { + if (value == null) { + throw new IllegalArgumentException(message); + } + } + + /** + * Assert that the value is not null or empty. + * + * @param value the value + * @param message the message to include with any exceptions + * @param isState if true, throw a state exception instead + * @throws IllegalArgumentException if value is null + * @throws IllegalStateException if value is null and isState is true + */ + private void assertNotNullOrEmpty(String value, String message, + boolean isState) throws IllegalArgumentException { + if (value == null || value.length() == 0) { + if (isState) { + throw new IllegalStateException(message); + } else { + throw new IllegalArgumentException(message); + } + } + } +} ======================================= --- /dev/null +++ /trunk/user/test/com/google/gwt/http/client/UrlBuilderTest.java Thu Oct 8 13:06:28 2009 @@ -0,0 +1,335 @@ +/* + * Copyright 2009 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.google.gwt.http.client; + +import com.google.gwt.junit.client.GWTTestCase; + +import java.util.ArrayList; +import java.util.List; + +/** + * Test Case for {...@link UrlBuilder}. + */ +public class UrlBuilderTest extends GWTTestCase { + + @Override + public String getModuleName() { + return "com.google.gwt.http.HttpSuite"; + } + + /** + * Test that the URL is encoded correctly. + */ + public void testBuildStringEncode() { + UrlBuilder builder = new UrlBuilder(); + builder.setHost("google.com"); + builder.setPath("path to file"); + builder.setParameter("the key", "the value"); + assertEquals("http://google.com/path%20to%20file?the%20key=the%20value", + builder.buildString()); + } + + public void testBuildStringEntireUrl() { + UrlBuilder builder = new UrlBuilder(); + builder.setHost("google.com"); + + // Host only. + assertEquals("http://google.com", builder.buildString()); + + // Host:Port + builder.setPort(100); + assertEquals("http://google.com:100", builder.buildString()); + + // Host:Port/Path + builder.setPath("path/to/file"); + assertEquals("http://google.com:100/path/to/file", builder.buildString()); + + // Host:Port/Path?Param + builder.setParameter("key", "value"); + assertEquals("http://google.com:100/path/to/file?key=value", + builder.buildString()); + + // Host:Port/Path?Param#Hash + builder.setHash("token"); + assertEquals("http://google.com:100/path/to/file?key=value#token", + builder.buildString()); + } + + public void testBuildStringEntireUrlWithReturns() { + UrlBuilder builder = new UrlBuilder(); + builder.setHost("google.com").setPort(100).setPath("path/to/file").setParameter( + "key", "value").setHash("token"); + assertEquals("http://google.com:100/path/to/file?key=value#token", + builder.buildString()); + } + + public void testBuildStringParts() { + UrlBuilder builder = new UrlBuilder(); + builder.setHost("google.com"); + + // Host only. + assertEquals("http://google.com", builder.buildString()); + + // Host:Port + builder.setPort(100); + assertEquals("http://google.com:100", builder.buildString()); + builder.setPort(UrlBuilder.PORT_UNSPECIFIED); + + // Host/Path + builder.setPath("path/to/file"); + assertEquals("http://google.com/path/to/file", builder.buildString()); + builder.setPath(null); + + // Host?Param + builder.setParameter("key", "value"); + assertEquals("http://google.com?key=value", builder.buildString()); + builder.removeParameter("key"); + + // Host#Hash + builder.setHash("token"); + assertEquals("http://google.com#token", builder.buildString()); + builder.setHash(null); + } + + public void testSetHash() { + UrlBuilder builder = new UrlBuilder(); + builder.setHost("google.com"); + + // Hash not specified + assertEquals("http://google.com", builder.buildString()); + + // # added if not present + builder.setHash("myHash"); + assertEquals("http://google.com#myHash", builder.buildString()); + + // Null hash + builder.setHash(null); + assertEquals("http://google.com", builder.buildString()); + + // # not added if present + builder.setHash("#myHash2"); + assertEquals("http://google.com#myHash2", builder.buildString()); + } + + public void testSetHost() { + UrlBuilder builder = new UrlBuilder(); + + // Host not specified. + assertEquals("http://", builder.buildString()); + + // Null host. + builder.setHost(null); + assertEquals("http://", builder.buildString()); + + // Empty host. + builder.setHost(""); + assertEquals("http://", builder.buildString()); + + // google.com + builder.setHost("google.com"); + assertEquals("http://google.com", builder.buildString()); + + // google.com:80 + builder.setHost("google.com:80"); + assertEquals("http://google.com:80", builder.buildString()); + + // google.com:80 with overridden port. + builder.setHost("google.com:80"); + builder.setPort(1000); + assertEquals("http://google.com:1000", builder.buildString()); + + // google.com:80 with overridden port in host. + builder.setPort(1000); + builder.setHost("google.com:80"); + assertEquals("http://google.com:80", builder.buildString()); + + // Specify to many ports. + // google.com:80:90 + try { + builder.setHost("google.com:80:90"); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // Expected. + } + + // Specify invalid port. + // google.com:test + try { + builder.setHost("google.com:test"); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // Expected. + } + } + + public void testSetParameter() { + UrlBuilder builder = new UrlBuilder(); + builder.setHost("google.com"); + + // Parameters not specified. + assertEquals("http://google.com", builder.buildString()); + + // Simple parameter. + builder.setParameter("key", "value"); + assertEquals("http://google.com?key=value", builder.buildString()); + + // Remove simple parameter. + builder.removeParameter("key"); + assertEquals("http://google.com", builder.buildString()); + + // List parameter. + List<String> values = new ArrayList<String>(); + builder.setParameter("key", "value0", "value1", "value2"); + assertEquals("http://google.com?key=value0&key=value1&key=value2", + builder.buildString()); + + // Remove list parameter. + builder.removeParameter("key"); + assertEquals("http://google.com", builder.buildString()); + + // Multiple parameters. + builder.setParameter("key0", "value0", "value1", "value2"); + builder.setParameter("key1", "simpleValue"); + + // The order of query params is not defined, so either URL is acceptable. + String url = builder.buildString(); + assertTrue(url.equals("http://google.com?key0=value0&key0=value1&key0=value2&key1=simpleValue") + || url.equals("http://google.com?key1=simpleValue&key0=value0&key0=value1&key0=value2")); + + // Empty list of multiple parameters. + builder.setParameter("key0", "value0", "value1", "value2"); + builder.setParameter("key1", "simpleValue"); + assertTrue(url.equals("http://google.com?key0=value0&key0=value1&key0=value2&key1=simpleValue") + || url.equals("http://google.com?key1=simpleValue&key0=value0&key0=value1&key0=value2")); + } + + public void testSetParameterToNull() { + UrlBuilder builder = new UrlBuilder(); + builder.setHost("google.com"); + + try { + builder.setParameter(null, "value"); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // Expected. + } + + try { + builder.setParameter(null); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // Expected. + } + + try { + builder.setParameter("key", new String[0]); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // Expected. + } + + try { + builder.setParameter("key", (String[]) null); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // Expected. + } + + // Null values are okay. + builder.setParameter("key", (String) null); + assertEquals("http://google.com?key=", builder.buildString()); + } + + public void testSetPath() { + UrlBuilder builder = new UrlBuilder(); + builder.setHost("google.com"); + + // Path not specified. + assertEquals("http://google.com", builder.buildString()); + + // Null path. + builder.setPath(null); + assertEquals("http://google.com", builder.buildString()); + + // Empty path. + builder.setPath(""); + assertEquals("http://google.com", builder.buildString()); + + // path/to/file.html + builder.setPath("path/to/file.html"); + assertEquals("http://google.com/path/to/file.html", builder.buildString()); + + // /path/to/file.html + builder.setPath("/path/to/file.html"); + assertEquals("http://google.com/path/to/file.html", builder.buildString()); + } + + public void testSetPort() { + UrlBuilder builder = new UrlBuilder(); + builder.setHost("google.com"); + + // Port not specified. + assertEquals("http://google.com", builder.buildString()); + + // Port 1000. + builder.setPort(1000); + assertEquals("http://google.com:1000", builder.buildString()); + + // PORT_UNSPECIFIED. + builder.setPort(UrlBuilder.PORT_UNSPECIFIED); + assertEquals("http://google.com", builder.buildString()); + } + + public void testSetProtocol() { + UrlBuilder builder = new UrlBuilder(); + builder.setHost("google.com"); + + // Protocol not specified. + assertEquals("http://google.com", builder.buildString()); + + // Null host. + try { + builder.setProtocol(null); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // Expected. + } + + // Empty host. + try { + builder.setProtocol(""); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException e) { + // Expected. + } + + // ftp + builder.setProtocol("ftp"); + assertEquals("ftp://google.com", builder.buildString()); + + // tcp: + builder.setProtocol("tcp:"); + assertEquals("tcp://google.com", builder.buildString()); + + // http:/ + builder.setProtocol("http:/"); + assertEquals("http://google.com", builder.buildString()); + + // http:// + builder.setProtocol("http://"); + assertEquals("http://google.com", builder.buildString()); + } +} ======================================= --- /trunk/samples/showcase/src/com/google/gwt/sample/showcase/client/Showcase.java Mon May 18 11:47:32 2009 +++ /trunk/samples/showcase/src/com/google/gwt/sample/showcase/client/Showcase.java Thu Oct 8 13:06:28 2009 @@ -29,6 +29,7 @@ import com.google.gwt.event.logical.shared.SelectionHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; +import com.google.gwt.http.client.UrlBuilder; import com.google.gwt.i18n.client.LocaleInfo; import com.google.gwt.sample.showcase.client.content.i18n.CwConstantsExample; import com.google.gwt.sample.showcase.client.content.i18n.CwConstantsWithLookupExample; @@ -69,6 +70,7 @@ import com.google.gwt.user.client.Command; import com.google.gwt.user.client.History; import com.google.gwt.user.client.Window; +import com.google.gwt.user.client.Window.Location; import com.google.gwt.user.client.ui.AbstractImagePrototype; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HasHorizontalAlignment; @@ -150,29 +152,6 @@ */ static String CUR_THEME = ShowcaseConstants.STYLE_THEMES[0]; - /** - * Get the URL of the page, without an hash of query string. - * - * @return the location of the page - */ - private static native String getHostPageLocation() - /*-{ - var s = $doc.location.href; - - // Pull off any hash. - var i = s.indexOf('#'); - if (i != -1) - s = s.substring(0, i); - - // Pull off any query string. - i = s.indexOf('?'); - if (i != -1) - s = s.substring(0, i); - - // Ensure a final slash if non-empty. - return s; - }-*/; - /** * The {...@link Application}. */ @@ -449,8 +428,9 @@ localeBox.addChangeHandler(new ChangeHandler() { public void onChange(ChangeEvent event) { String localeName = localeBox.getValue(localeBox.getSelectedIndex()); - Window.open(getHostPageLocation() + "?locale=" + localeName, "_self", - ""); + UrlBuilder builder = Location.createUrlBuilder().setParameter("locale", + localeName); + Window.Location.replace(builder.buildString()); } }); HorizontalPanel localeWrapper = new HorizontalPanel(); ======================================= --- /trunk/user/src/com/google/gwt/user/client/Window.java Wed May 6 15:19:45 2009 +++ /trunk/user/src/com/google/gwt/user/client/Window.java Thu Oct 8 13:06:28 2009 @@ -30,6 +30,7 @@ import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.event.shared.HasHandlers; import com.google.gwt.http.client.URL; +import com.google.gwt.http.client.UrlBuilder; import com.google.gwt.user.client.impl.WindowImpl; import java.util.ArrayList; @@ -130,6 +131,39 @@ public static native void assign(String newURL) /*-{ $wnd.location.assign(newURL); }-*/; + + /** + * Create a {...@link UrlBuilder} based on this {...@link Location}. + * + * @return the new builder + */ + public static UrlBuilder createUrlBuilder() { + UrlBuilder builder = new UrlBuilder(); + builder.setProtocol(getProtocol()); + builder.setHost(getHost()); + String path = getPath(); + if (path != null && path.length() > 0) { + builder.setPath(path); + } + String hash = getHash(); + if (hash != null && hash.length() > 0) { + builder.setHash(hash); + } + String port = getPort(); + if (port != null && port.length() > 0) { + builder.setPort(Integer.parseInt(port)); + } + + // Add query parameters. + Map<String, List<String>> params = getParameterMap(); + for (Map.Entry<String, List<String>> entry : params.entrySet()) { + List<String> values = new ArrayList<String>(entry.getValue()); + builder.setParameter(entry.getKey(), + values.toArray(new String[values.size()])); + } + + return builder; + } /** * Gets the string to the right of the URL's hash. @@ -400,7 +434,7 @@ private static boolean resizeHandlersInitialized; private static int lastResizeWidth; private static int lastResizeHeight; - + private static final WindowImpl impl = GWT.create(WindowImpl.class); /** @@ -478,7 +512,8 @@ * Adds a listener to receive window scroll events. * * @param listener the listener to be informed when the window is scrolled - * @deprecated use {...@link Window#addWindowScrollHandler(ScrollHandler)} instead + * @deprecated use {...@link Window#addWindowScrollHandler(ScrollHandler)} + * instead */ @Deprecated public static void addWindowScrollListener(WindowScrollListener listener) { ======================================= --- /trunk/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java Tue Sep 15 11:52:45 2009 +++ /trunk/user/super/com/google/gwt/junit/translatable/com/google/gwt/junit/client/impl/GWTRunner.java Thu Oct 8 13:06:28 2009 @@ -17,6 +17,7 @@ import com.google.gwt.core.client.EntryPoint; import com.google.gwt.core.client.GWT; +import com.google.gwt.http.client.UrlBuilder; import com.google.gwt.junit.client.GWTTestCase; import com.google.gwt.junit.client.impl.JUnitHost.TestBlock; import com.google.gwt.junit.client.impl.JUnitHost.TestInfo; @@ -257,18 +258,11 @@ * We're being asked to run a test in a different module. We must navigate * the browser to a new URL which will run that other module. */ - String href = Window.Location.getHref(); - if (href.contains("?")) { - href = href.substring(0, href.indexOf("?")); - } else if (href.contains("#")) { - href = href.substring(0, href.indexOf("#")); - } - String newHref = href.replace(currentModule, newModule); - newHref += "?" + BLOCKINDEX_QUERY_PARAM + "=" + currentBlock.getIndex(); - if (maxRetryCount >= 0) { - newHref += "&" + RETRYCOUNT_QUERY_PARAM + "=" + maxRetryCount; - } - Window.Location.replace(newHref); + UrlBuilder builder = Window.Location.createUrlBuilder(); + builder.setParameter(BLOCKINDEX_QUERY_PARAM, + Integer.toString(currentBlock.getIndex())).setPath( + newModule + "/junit.html"); + Window.Location.replace(builder.buildString()); currentBlock = null; currentTestIndex = 0; } ======================================= --- /trunk/user/test/com/google/gwt/http/HTTPSuite.java Mon Mar 2 23:51:53 2009 +++ /trunk/user/test/com/google/gwt/http/HTTPSuite.java Thu Oct 8 13:06:28 2009 @@ -20,6 +20,7 @@ import com.google.gwt.http.client.RequestTest; import com.google.gwt.http.client.ResponseTest; import com.google.gwt.http.client.URLTest; +import com.google.gwt.http.client.UrlBuilderTest; import com.google.gwt.junit.tools.GWTTestSuite; import junit.framework.Test; @@ -38,6 +39,7 @@ suite.addTestSuite(RequestBuilderTest.class); suite.addTestSuite(RequestTest.class); suite.addTestSuite(ResponseTest.class); + suite.addTestSuite(UrlBuilderTest.class); return suite; } ======================================= --- /trunk/user/test/com/google/gwt/user/client/WindowTest.java Wed Sep 30 16:46:38 2009 +++ /trunk/user/test/com/google/gwt/user/client/WindowTest.java Thu Oct 8 13:06:28 2009 @@ -16,9 +16,11 @@ package com.google.gwt.user.client; import com.google.gwt.event.logical.shared.ResizeEvent; +import com.google.gwt.http.client.UrlBuilder; import com.google.gwt.junit.DoNotRunWith; import com.google.gwt.junit.Platform; import com.google.gwt.junit.client.GWTTestCase; +import com.google.gwt.user.client.Window.Location; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RootPanel; @@ -32,8 +34,8 @@ public class WindowTest extends GWTTestCase { private static native String getNodeName(Element elem) /*-{ - return (elem.nodeName || "").toLowerCase(); - }-*/; + return (elem.nodeName || "").toLowerCase(); + }-*/; /** * Removes all elements in the body, except scripts and iframes. @@ -84,6 +86,46 @@ assertEquals(host, hostName + ":" + port); assertEquals(href, protocol + "//" + host + path + query + hash); } + + public void testLocationCreateUrlBuilder() { + History.newItem("theHash"); + String expected = Location.getHref(); + + // Build the string with the builder. + UrlBuilder builder = Location.createUrlBuilder(); + String actual = builder.buildString(); + + // Check the hash. + { + String[] expectedParts = expected.split("#"); + String[] actualParts = actual.split("#"); + assertEquals(2, actualParts.length); + assertEquals(expectedParts[1], actualParts[1]); + expected = expectedParts[0]; + actual = actualParts[0]; + } + + // Check the query parameters. + { + String[] expectedParts = expected.split("[?]"); + String[] actualParts = actual.split("[?]"); + if (expectedParts.length > 1) { + assertEquals(2, actualParts.length); + String[] expectedPairs = expectedParts[1].split("&"); + String[] actualPairs = actualParts[1].split("&"); + assertEquals(expectedPairs.length, actualPairs.length); + for (String actualPair : actualPairs) { + String[] kv = actualPair.split("="); + assertEquals(Location.getParameter(kv[0]), kv[1]); + } + } + expected = expectedParts[0]; + actual = actualParts[0]; + } + + // Check everything but the query params and hash/ + assertEquals(expected, actual); + } public void testLocationParsing() { Map<String, List<String>> map; @@ -93,23 +135,22 @@ assertEquals(map.size(), 3); assertEquals(map.get("foo").get(0), "bar"); assertEquals(map.get("fuzzy").get(0), "bunnies"); - + // multiple values for the same parameter map = Window.Location.buildListParamMap( "?fuzzy=bunnies&foo=bar&num=42&foo=baz"); assertEquals(map.size(), 3); assertEquals(map.get("foo").get(0), "bar"); assertEquals(map.get("foo").get(1), "baz"); - + // no query parameters. map = Window.Location.buildListParamMap(""); assertEquals(map.size(), 0); - + // blank keys should be ignored, but blank values are OK. Also, // keys can contain whitespace. (but the browser may give whitespace // back as escaped). - map = Window.Location.buildListParamMap( - "?&& &a&b=&c=c&d=d=d&=e&f=2&f=1&"); + map = Window.Location.buildListParamMap("?&& &a&b=&c=c&d=d=d&=e&f=2&f=1&"); assertEquals(map.size(), 6); assertEquals(map.get(" ").get(0), ""); assertEquals(map.get("a").get(0), ""); @@ -120,8 +161,7 @@ assertEquals(map.get("f").get(1), "1"); // Values escaped with hex codes should work too. - map = Window.Location.buildListParamMap( - "?foo=bar%20baz%3aqux"); + map = Window.Location.buildListParamMap("?foo=bar%20baz%3aqux"); assertEquals(map.get("foo").get(0), "bar baz:qux"); } @@ -190,7 +230,7 @@ @SuppressWarnings("deprecation") static class ListenerTester implements WindowResizeListener { static int resize = 0; - + public void onWindowResized(int width, int height) { ++resize; } @@ -216,7 +256,7 @@ Window.removeWindowResizeListener(r1); ListenerTester.fire(); assertEquals(ListenerTester.resize, 1); - + Window.removeWindowResizeListener(r2); ListenerTester.fire(); assertEquals(ListenerTester.resize, 0); --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---