Author: johnh
Date: Thu Jul 22 01:19:37 2010
New Revision: 966473

URL: http://svn.apache.org/viewvc?rev=966473&view=rev
Log:
shindig.uri: Pure-JS library for Uri manipulation.


Added:
    shindig/trunk/features/src/main/javascript/features/shindig.uri/
    shindig/trunk/features/src/main/javascript/features/shindig.uri/feature.xml
    shindig/trunk/features/src/main/javascript/features/shindig.uri/uri.js
    shindig/trunk/features/src/main/javascript/features/shindig.uri/util.js
    shindig/trunk/features/src/test/javascript/features/shindig.uri/
    shindig/trunk/features/src/test/javascript/features/shindig.uri/uritest.js
Modified:
    shindig/trunk/features/pom.xml
    shindig/trunk/features/src/main/javascript/features/features.txt
    shindig/trunk/features/src/test/javascript/features/alltests.js

Modified: shindig/trunk/features/pom.xml
URL: 
http://svn.apache.org/viewvc/shindig/trunk/features/pom.xml?rev=966473&r1=966472&r2=966473&view=diff
==============================================================================
--- shindig/trunk/features/pom.xml (original)
+++ shindig/trunk/features/pom.xml Thu Jul 22 01:19:37 2010
@@ -123,6 +123,7 @@
                 <source>i18n/numberformat.js</source>
                 <source>setprefs/setprefs.js</source>
                 <source>views/views.js</source>
+                <source>shindig.uri/uri.js</source>
                 <source>shindig.xhrwrapper/xhrwrapper.js</source>
                 <source>xmlutil/xmlutil.js</source>
                 <source>opensocial-data-context/datacontext.js</source>

Modified: shindig/trunk/features/src/main/javascript/features/features.txt
URL: 
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/features.txt?rev=966473&r1=966472&r2=966473&view=diff
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/features.txt (original)
+++ shindig/trunk/features/src/main/javascript/features/features.txt Thu Jul 22 
01:19:37 2010
@@ -64,6 +64,7 @@ features/shindig.auth/feature.xml
 features/shindig.container/feature.xml
 features/shindig.container-1.0/feature.xml
 features/shindig.random/feature.xml
+features/shindig.uri/feature.xml
 features/shindig.xhrwrapper/feature.xml
 features/skins/feature.xml
 features/swfobject/feature.xml

Added: 
shindig/trunk/features/src/main/javascript/features/shindig.uri/feature.xml
URL: 
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/shindig.uri/feature.xml?rev=966473&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/shindig.uri/feature.xml 
(added)
+++ shindig/trunk/features/src/main/javascript/features/shindig.uri/feature.xml 
Thu Jul 22 01:19:37 2010
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you 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.
+-->
+<feature>
+  <!--
+  A Pure-JS Uri implementation.
+  -->
+  <name>shindig.uri</name>
+  <dependency>globals</dependency>
+  <gadget>
+    <script src="uri.js"/>
+  </gadget>
+  <container>
+    <script src="uri.js"/>
+  </container>
+</feature>

Added: shindig/trunk/features/src/main/javascript/features/shindig.uri/uri.js
URL: 
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/shindig.uri/uri.js?rev=966473&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/shindig.uri/uri.js 
(added)
+++ shindig/trunk/features/src/main/javascript/features/shindig.uri/uri.js Thu 
Jul 22 01:19:37 2010
@@ -0,0 +1,227 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * @fileoverview Pure JS code for processing Uris.
+ *
+ * Unlike Java Shindig and other code, these Uris are mutable. While
+ * this introduces some challenges, ultimately the confusion introduced
+ * by passing around a Uri versus a UriBuilder in an untyped language
+ * is too great.
+ *
+ * The class only implements core methods associated with Uris -
+ * essentially the minimum required for various helper routines. Lazy evalution
+ * of query and fragment params is chosen to avoid undue performance hit.
+ * Further, only set operations are provided for query/fragment params,
+ * in order to keep the API relatively small, yet sufficiently flexible. 
Values set to
+ * null are equivalent to being removed, for instance.
+ * 
+ * Limitations include, but are not limited to:
+ * + Multiple params with the same key not supported via set APIs.
+ * + Full RPC-compliant parsing not supported. A "highly useful" subset is 
impl'd.
+ * + Helper methods are all provided in the shindig.uri.full feature.
+ * + Query and fragment do not contain their preceding ? and # chars.
+ *
+ * Example usage:
+ * var uri = shindig.uri("http://www.apache.org";);
+ * uri.setPath("random.xml");
+ * alert(uri.toString());  // Emits "http://www.apache.org/random.xml";
+ * var other =  // resolve() provided in shindig.uri.full
+ *     shindig.uri("http://www.other.com/foo";).resolve("/bar").setQP({ hi: 
"bye" });
+ * alert(other);  // Emits "http://other.com/bar?hi=bye";
+ */
+shindig.uri = (function() {
+  var PARSE_REGEX = new 
RegExp("^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?");
+
+  return function(opt_in) {
+    var schema_ = "";
+    var authority_ = "";
+    var path_ = "";
+    var query_ = "";
+    var qparms_ = null;
+    var fragment_ = "";
+    var fparms_ = null;
+    var unesc = window.decodeURIComponent ? decodeURIComponent : unescape;
+    var esc = window.encodeURIComponent ? encodeURIComponent : escape;
+    var bundle = null;
+
+    function parseFrom(url) {
+      if (url.match(PARSE_REGEX) === null) {
+        throw "Malformed URL: " + url;
+      }
+      schema_ = RegExp.$1;
+      authority_ = RegExp.$2;
+      path_ = RegExp.$3;
+      query_ = RegExp.$4;
+      fragment_ = RegExp.$5;
+    }
+
+    function serializeParams(params) {
+      var str = [];
+      for (var i = 0, j = params.length; i < j; ++i) {
+        var key = params[i][0];
+        var val = params[i][1];
+        if (val === undefined) {
+          continue;
+        }
+        str.push(esc(key) + (val !== null ? '=' + esc(val) : ""));
+      }
+      return str.join('&');
+    }
+
+    function getQuery() {
+      if (qparms_) {
+        query_ = serializeParams(qparms_);
+        qparms_ = null;
+      }
+      return query_;
+    }
+
+    function getFragment() {
+      if (fparms_) {
+        fragment_ = serializeParams(fparms_);
+        fparms_ = null;
+      }
+      return fragment_;
+    }
+
+    /**
+     * Returns a readable representation of the URL.
+     * 
+     * @return {string} A readable URL.
+     */
+    function toString() {
+      var query = getQuery();
+      var fragment = getFragment();
+      return [
+        schema_,
+        schema_ !== "" ? ":" : "",
+        authority_ !== "" ? "//" : "",
+        authority_,
+        path_,
+        query !== "" ? "?" : "",
+        query,
+        fragment !== "" ? "#" : "",
+        fragment
+      ].join("");
+    }
+
+    function parseParams(str) {
+      var params = [];
+      var pairs = str.split("&");
+      for (var i = 0, j = pairs.length; i < j; ++i) {
+        var kv = pairs[i].split('=');
+        var key = kv.shift();
+        var value = null;
+        if (kv.length > 0) {
+          value = kv.join('').replace(/\+/g, " ");
+        }
+        params.push([ key, value != null ? unesc(value) : null ]);
+      }
+      return params;
+    }
+
+    function getParam(pmap, key) {
+      for (var i = 0, j = pmap.length; i < j; ++i) {
+        if (pmap[i][0] == key) {
+          return pmap[i][1];
+        }
+      }
+      // undefined = no key set
+      // vs. null = no value set and "" = value is empty
+      return undefined;
+    }
+
+    function setParams(pset, argOne, argTwo) {
+      // Assume by default that we're setting by map (full replace).
+      var newParams = argOne;
+      if (typeof argOne === 'string') {
+        // N/V set (single param override)
+        newParams = {};
+        newParams[argOne] = argTwo;
+      }
+      for (var key in newParams) {
+        var found = false;
+        for (var i = 0, j = pset.length; !found && i < j; ++i) {
+          if (pset[i][0] == key) {
+            pset[i][1] = newParams[key];
+            found = true;
+          }
+        }
+        if (!found) {
+          pset.push([ key, newParams[key] ]);
+        }
+      }
+      return pset;
+    }
+
+    function stripPrefix(str, pfx) {
+      str = str || "";
+      if (str[0] === pfx) {
+        str = str.substr(pfx.length);
+      }
+      return str;
+    }
+
+    // CONSTRUCTOR
+    if (typeof opt_in === "object" &&
+        typeof opt_in.toString === "function") {
+      // Assume it's another shindig.uri, or something that can be parsed from 
one.
+      parseFrom(opt_in.toString());
+    } else if (opt_in) {
+      parseFrom(opt_in);
+    }
+
+    bundle = {
+      // Getters
+      getSchema: function() { return schema_; },
+      getAuthority: function() { return authority_; },
+      getPath: function() { return path_; },
+      getQuery: getQuery,
+      getFragment: getFragment,
+      getQP: function(key) {
+        qparms_ = qparms_ || parseParams(query_);
+        return getParam(qparms_, key);
+      },
+      getFP: function(key) {
+        fparms_ = fparms_ || parseParams(fragment_);
+        return getParam(fparms_, key);
+      },
+
+      // Setters
+      setSchema: function(schema) { schema_ = schema; return bundle; },
+      setAuthority: function(authority) { authority_ = authority; return 
bundle; },
+      setPath: function(path) { path_ = (path[0] === "/" ? "" : "/") + path; 
return bundle; },
+      setQuery: function(query) { qparms_ = null; query_ = stripPrefix(query, 
'?'); return bundle; },
+      setFragment: function(fragment) { fparms_ = null; fragment_ = 
stripPrefix(fragment, '#'); return bundle; },
+      setQP: function(argOne, argTwo) {
+        qparms_ = setParams(qparms_ || parseParams(query_), argOne, argTwo);
+        return bundle;
+      },
+      setFP: function(argOne, argTwo) {
+        fparms_ = setParams(fparms_ || parseParams(fragment_), argOne, argTwo);
+        return bundle;
+      },
+
+      // Core utility methods.
+      toString: toString
+    };
+
+    return bundle;
+  }
+})();

Added: shindig/trunk/features/src/main/javascript/features/shindig.uri/util.js
URL: 
http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/shindig.uri/util.js?rev=966473&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/shindig.uri/util.js 
(added)
+++ shindig/trunk/features/src/main/javascript/features/shindig.uri/util.js Thu 
Jul 22 01:19:37 2010
@@ -0,0 +1,76 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * @fileoverview Augments shindig.uri class with various useful helper methods.
+ */
+
+shindig._uri = shindig.uri;
+shindig.uri = (function() {
+  var oldCtor = shindig._uri;
+  shindig._uri = null;
+
+  /**
+   * Checks that a Uri has the same origin as this Uri.
+   *
+   * Two Uris have the same origin if they point to the same schema, server
+   * and port.
+   *
+   * @param {Url} other The Uri to compare to this Uri.
+   * @return {boolean} Whether the Uris have the same origin.
+   */
+  function hasSameOrigin(self, other) {
+    return self.getSchema() == other.getSchema() &&
+           self.getAuthority() == self.getAuthority();
+  }
+
+  /**
+   * Fully qualifies this Uri if it is relative, using a given base Uri.
+   * 
+   * @param {Uri} self The base Uri.
+   * @param {Uri} base The Uri to resolve.
+   */
+  function fullyQualify(self, base) {
+    if (self.getSchema() == '') {
+      self.setSchema(base.getSchema());
+    }
+    if (self.getAuthority() == '') {
+      self.setAuthority(base.getAuthority());
+    }
+    var selfPath = self.getPath();
+    if (selfPath == '' || selfPath[0] != '/') {
+      var basePath = base.getPath();
+      var lastSlash = basePath.lastIndexOf('/');
+      if (lastSlash != -1) {
+        basePath = basePath(0, lastSlash + 1);
+      }
+      self.setPath(base.getPath() + selfPath);
+    }
+  }
+
+  return function(opt_in) {
+    var self = oldCtor(opt_in);
+    self.hasSameOrigin = function(other) {
+      return hasSameOrigin(self, other);
+    };
+    self.fullyQualify = function(other) {
+      return fullyQualify(self, other);
+    };
+    return self;
+  };
+});

Modified: shindig/trunk/features/src/test/javascript/features/alltests.js
URL: 
http://svn.apache.org/viewvc/shindig/trunk/features/src/test/javascript/features/alltests.js?rev=966473&r1=966472&r2=966473&view=diff
==============================================================================
--- shindig/trunk/features/src/test/javascript/features/alltests.js (original)
+++ shindig/trunk/features/src/test/javascript/features/alltests.js Thu Jul 22 
01:19:37 2010
@@ -73,11 +73,11 @@ if (!this.JsUtil) {
   eval(JsUtil.prototype.include(srcDir + '/osapi/jsonrpctransport.js'));
   eval(JsUtil.prototype.include(srcDir + '/osapi/gadgetsrpctransport.js'));
   eval(JsUtil.prototype.include(srcDir + '/osapi/peoplehelpers.js'));
+  eval(JsUtil.prototype.include(srcDir + '/shindig.uri/uri.js'));
   eval(JsUtil.prototype.include(testToolsDir + "/JsUnit.js"));
   eval(JsUtil.prototype.include(testSrcDir + "/core/authtest.js"));
   eval(JsUtil.prototype.include(testSrcDir + "/core/config-test.js"));
   eval(JsUtil.prototype.include(testSrcDir + "/core/prefstest.js"));
-  eval(JsUtil.prototype.include(testSrcDir + "/core/utiltest.js"));
   eval(JsUtil.prototype.include(testSrcDir + "/core.io/iotest.js"));
   eval(JsUtil.prototype.include(testSrcDir + 
"/opensocial-base/jsonactivitytest.js"));
   eval(JsUtil.prototype.include(testSrcDir + 
"/opensocial-reference/activitytest.js"));
@@ -93,6 +93,7 @@ if (!this.JsUtil) {
   eval(JsUtil.prototype.include(testSrcDir + 
"/osapi/jsonrpctransporttest.js"));
   eval(JsUtil.prototype.include(testSrcDir + "/views/urltemplatetest.js"));
   eval(JsUtil.prototype.include(testSrcDir + "/xhrwrapper/xhrwrappertest.js"));
+  eval(JsUtil.prototype.include(testSrcDir + '/shindig.uri/uritest.js'));
 }
 
 function AllTests() {

Added: 
shindig/trunk/features/src/test/javascript/features/shindig.uri/uritest.js
URL: 
http://svn.apache.org/viewvc/shindig/trunk/features/src/test/javascript/features/shindig.uri/uritest.js?rev=966473&view=auto
==============================================================================
--- shindig/trunk/features/src/test/javascript/features/shindig.uri/uritest.js 
(added)
+++ shindig/trunk/features/src/test/javascript/features/shindig.uri/uritest.js 
Thu Jul 22 01:19:37 2010
@@ -0,0 +1,327 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+ * @fileoverview
+ *
+ * Unittests for the shindig.uri library.
+ */
+
+function ShindigUriTest(name) {
+  TestCase.call(this, name);
+}
+
+ShindigUriTest.inherits(TestCase);
+
+ShindigUriTest.prototype.testParseFullUri = function() {
+  var str = "http://www.example.com/my/path?qk1=qv1&qk2=qv2#fk1=fv1&fk2=fv2";;
+  var uri = shindig.uri(str);
+
+  this.assertEquals("http", uri.getSchema());
+  this.assertEquals("www.example.com", uri.getAuthority());
+  this.assertEquals("/my/path", uri.getPath());
+  this.assertEquals("qk1=qv1&qk2=qv2", uri.getQuery());
+  this.assertEquals("fk1=fv1&fk2=fv2", uri.getFragment());
+  this.assertEquals("qv1", uri.getQP("qk1"));
+  this.assertEquals("qv2", uri.getQP("qk2"));
+  this.assertEquals("fv1", uri.getFP("fk1"));
+  this.assertEquals("fv2", uri.getFP("fk2"));
+
+  // Check query and fragment again to ensure ordering doesn't matter.
+  this.assertEquals("qk1=qv1&qk2=qv2", uri.getQuery());
+  this.assertEquals("fk1=fv1&fk2=fv2", uri.getFragment());
+
+  // Re-serialize all.
+  this.assertEquals(str, uri.toString());
+};
+
+ShindigUriTest.prototype.testParseQuerylessUri = function() {
+  var str = "http://www.example.com/my/path#fk1=fv1&fk2=fv2";;
+  var uri = shindig.uri(str);
+
+  this.assertEquals("http", uri.getSchema());
+  this.assertEquals("www.example.com", uri.getAuthority());
+  this.assertEquals("/my/path", uri.getPath());
+  this.assertEquals("fk1=fv1&fk2=fv2", uri.getFragment());
+  this.assertEquals("fv1", uri.getFP("fk1"));
+  this.assertEquals("fv2", uri.getFP("fk2"));
+
+  // Check query and fragment again to ensure ordering doesn't matter.
+  this.assertEquals("fk1=fv1&fk2=fv2", uri.getFragment());
+
+  // Re-serialize all.
+  this.assertEquals(str, uri.toString());
+};
+
+ShindigUriTest.prototype.testParseFragmentlessUri = function() {
+  var str = "http://www.example.com/my/path?qk1=qv1&qk2=qv2";;
+  var uri = shindig.uri(str);
+
+  this.assertEquals("http", uri.getSchema());
+  this.assertEquals("www.example.com", uri.getAuthority());
+  this.assertEquals("/my/path", uri.getPath());
+  this.assertEquals("qk1=qv1&qk2=qv2", uri.getQuery());
+  this.assertEquals("qv1", uri.getQP("qk1"));
+  this.assertEquals("qv2", uri.getQP("qk2"));
+
+  // Check query and fragment again to ensure ordering doesn't matter.
+  this.assertEquals("qk1=qv1&qk2=qv2", uri.getQuery());
+
+  // Re-serialize all.
+  this.assertEquals(str, uri.toString());
+};
+
+ShindigUriTest.prototype.testParseSchemalessUri = function() {
+  var str = "//www.example.com/my/path?qk1=qv1&qk2=qv2#fk1=fv1&fk2=fv2";
+  var uri = shindig.uri(str);
+
+  this.assertEquals("", uri.getSchema());
+  this.assertEquals("www.example.com", uri.getAuthority());
+  this.assertEquals("/my/path", uri.getPath());
+  this.assertEquals("qk1=qv1&qk2=qv2", uri.getQuery());
+  this.assertEquals("fk1=fv1&fk2=fv2", uri.getFragment());
+  this.assertEquals("qv1", uri.getQP("qk1"));
+  this.assertEquals("qv2", uri.getQP("qk2"));
+  this.assertEquals("fv1", uri.getFP("fk1"));
+  this.assertEquals("fv2", uri.getFP("fk2"));
+
+  // Check query and fragment again to ensure ordering doesn't matter.
+  this.assertEquals("qk1=qv1&qk2=qv2", uri.getQuery());
+  this.assertEquals("fk1=fv1&fk2=fv2", uri.getFragment());
+
+  // Re-serialize all.
+  this.assertEquals(str, uri.toString());
+};
+
+ShindigUriTest.prototype.testParseAuthoritylessUri = function() {
+  var str = "/my/path?qk1=qv1&qk2=qv2#fk1=fv1&fk2=fv2";
+  var uri = shindig.uri(str);
+
+  this.assertEquals("", uri.getSchema());
+  this.assertEquals("", uri.getAuthority());
+  this.assertEquals("/my/path", uri.getPath());
+  this.assertEquals("qk1=qv1&qk2=qv2", uri.getQuery());
+  this.assertEquals("fk1=fv1&fk2=fv2", uri.getFragment());
+  this.assertEquals("qv1", uri.getQP("qk1"));
+  this.assertEquals("qv2", uri.getQP("qk2"));
+  this.assertEquals("fv1", uri.getFP("fk1"));
+  this.assertEquals("fv2", uri.getFP("fk2"));
+
+  // Check query and fragment again to ensure ordering doesn't matter.
+  this.assertEquals("qk1=qv1&qk2=qv2", uri.getQuery());
+  this.assertEquals("fk1=fv1&fk2=fv2", uri.getFragment());
+
+  // Re-serialize all.
+  this.assertEquals(str, uri.toString());
+};
+
+ShindigUriTest.prototype.testParsePathlessUri = function() {
+  var str = "http://www.example.com?qk1=qv1&qk2=qv2#fk1=fv1&fk2=fv2";;
+  var uri = shindig.uri(str);
+
+  this.assertEquals("http", uri.getSchema());
+  this.assertEquals("www.example.com", uri.getAuthority());
+  this.assertEquals("qk1=qv1&qk2=qv2", uri.getQuery());
+  this.assertEquals("fk1=fv1&fk2=fv2", uri.getFragment());
+  this.assertEquals("qv1", uri.getQP("qk1"));
+  this.assertEquals("qv2", uri.getQP("qk2"));
+  this.assertEquals("fv1", uri.getFP("fk1"));
+  this.assertEquals("fv2", uri.getFP("fk2"));
+
+  // Check query and fragment again to ensure ordering doesn't matter.
+  this.assertEquals("qk1=qv1&qk2=qv2", uri.getQuery());
+  this.assertEquals("fk1=fv1&fk2=fv2", uri.getFragment());
+
+  // Re-serialize all.
+  this.assertEquals(str, uri.toString());
+};
+
+ShindigUriTest.prototype.testParsePathOnly = function() {
+  var str = "/my/path";
+  var uri = shindig.uri(str);
+
+  this.assertEquals("", uri.getSchema());
+  this.assertEquals("", uri.getAuthority());
+  this.assertEquals("/my/path", uri.getPath());
+
+  this.assertEquals(str, uri.toString());
+};
+
+ShindigUriTest.prototype.testParseQueryOnly = function() {
+  var str = "?foo=bar&baz=bak&boo=hiss";
+  var uri = shindig.uri(str);
+
+  this.assertEquals("bar", uri.getQP("foo"));
+  this.assertEquals("bak", uri.getQP("baz"));
+  this.assertEquals("hiss", uri.getQP("boo"));
+
+  this.assertEquals(str, uri.toString());
+};
+
+ShindigUriTest.prototype.testParseFragmentOnly = function() {
+  var str = "#foo=bar&baz=bak";
+  var uri = shindig.uri(str);
+
+  this.assertEquals("bar", uri.getFP("foo"));
+  this.assertEquals("bak", uri.getFP("baz"));
+
+  this.assertEquals(str, uri.toString());
+};
+
+ShindigUriTest.prototype.testParseWithContextualOddities = function() {
+  var uri = shindig.uri("//www.example.com/my//path?#");
+
+  this.assertEquals("", uri.getSchema());
+  this.assertEquals("www.example.com", uri.getAuthority());
+  this.assertEquals("/my//path", uri.getPath());
+  this.assertEquals("", uri.getQuery());
+  this.assertEquals("", uri.getFragment());
+
+  this.assertEquals("//www.example.com/my//path", uri.toString());
+};
+
+ShindigUriTest.prototype.testParseQueryNullAndMissing = function() {
+  var uri = shindig.uri("?&one=two&three&&four=five");
+  this.assertEquals("two", uri.getQP("one"));
+  this.assertTrue(null === uri.getQP("three"));
+  this.assertTrue(undefined === uri.getQP("nonexistent"));
+  this.assertEquals("five", uri.getQP("four"));
+};
+
+ShindigUriTest.prototype.testParseFragmentNullAndMissing = function() {
+  var uri = shindig.uri("#&one=two&three&&four=five");
+  this.assertEquals("two", uri.getFP("one"));
+  this.assertTrue(null === uri.getFP("three"));
+  this.assertTrue(undefined === uri.getQP("nonexistent"));
+  this.assertEquals("five", uri.getFP("four"));
+};
+
+ShindigUriTest.prototype.testBuildFullUri = function() {
+  var uri = shindig.uri().setSchema("http")
+                         .setAuthority("www.example.com")
+                         .setPath("/my/path")
+                         .setQuery("?one=two&three=four")
+                         .setFragment("#five=six");
+  
this.assertEquals("http://www.example.com/my/path?one=two&three=four#five=six";, 
uri.toString());
+};
+
+ShindigUriTest.prototype.testBuildSchemalessUri = function() {
+  var uri = shindig.uri().setAuthority("www.example.com")
+                         .setPath("/my/path")
+                         .setQuery("?one=two&three=four")
+                         .setFragment("#five=six");
+  this.assertEquals("//www.example.com/my/path?one=two&three=four#five=six", 
uri.toString());
+};
+
+ShindigUriTest.prototype.testBuildAuthoritylessUri = function() {
+  var uri = shindig.uri().setPath("/my/path")
+                         .setQuery("?one=two&three=four")
+                         .setFragment("#five=six");
+  this.assertEquals("/my/path?one=two&three=four#five=six", uri.toString());
+};
+
+ShindigUriTest.prototype.testBuildPathlessUri = function() {
+  var uri = shindig.uri().setSchema("http")
+                         .setAuthority("www.example.com")
+                         .setQuery("?one=two&three=four")
+                         .setFragment("#five=six");
+  this.assertEquals("http://www.example.com?one=two&three=four#five=six";, 
uri.toString());
+};
+
+ShindigUriTest.prototype.testBuildQuerylessUri = function() {
+  var uri = shindig.uri().setSchema("http")
+                         .setAuthority("www.example.com")
+                         .setPath("/my/path")
+                         .setFragment("#five=six");
+  this.assertEquals("http://www.example.com/my/path#five=six";, uri.toString());
+};
+
+ShindigUriTest.prototype.testBuildFragmentlessUri = function() {
+  var uri = shindig.uri().setSchema("http")
+                         .setAuthority("www.example.com")
+                         .setPath("/my/path")
+                         .setQuery("?one=two&three=four");
+  this.assertEquals("http://www.example.com/my/path?one=two&three=four";, 
uri.toString());
+};
+
+ShindigUriTest.prototype.testBuildPath = function() {
+  var uri = shindig.uri().setPath("/my/path");
+  this.assertEquals("/my/path", uri.toString());
+};
+
+ShindigUriTest.prototype.testBuildAuthority = function() {
+  var uri = shindig.uri().setAuthority("www.example.com");
+  this.assertEquals("//www.example.com", uri.toString());
+};
+
+ShindigUriTest.prototype.testBuildDirectQuery = function() {
+  var uri = shindig.uri().setQuery("one=two&three&&four=five");
+  this.assertEquals("two", uri.getQP("one"));
+  this.assertTrue(null === uri.getQP("three"));
+  this.assertTrue(undefined === uri.getQP("nonexistent"));
+  this.assertEquals("five", uri.getQP("four"));
+};
+
+ShindigUriTest.prototype.testBuildDirectFragment = function() {
+  var uri = shindig.uri().setFragment("one=two&three&&four=five");
+  this.assertEquals("two", uri.getFP("one"));
+  this.assertTrue(null === uri.getFP("three"));
+  this.assertTrue(undefined === uri.getQP("nonexistent"));
+  this.assertEquals("five", uri.getFP("four"));
+};
+
+ShindigUriTest.prototype.testBuildQuery = function() {
+  var uri = shindig.uri().setQuery("one=two&three=four");
+  this.assertEquals("two", uri.getQP("one"));
+  this.assertEquals("four", uri.getQP("three"));
+  uri.setQP("three", "five");
+  this.assertEquals("two", uri.getQP("one"));
+  this.assertEquals("five", uri.getQP("three"));
+  uri.setQP({ one: "one", two: "two", three: "three" });
+  this.assertEquals("one", uri.getQP("one"));
+  this.assertEquals("two", uri.getQP("two"));
+  this.assertEquals("three", uri.getQP("three"));
+  uri.setQP("two", null);
+  this.assertEquals("?one=one&three=three&two", uri.toString());
+};
+
+ShindigUriTest.prototype.testBuildFragment = function() {
+  var uri = shindig.uri().setFragment("one=two&three=four");
+  this.assertEquals("two", uri.getFP("one"));
+  this.assertEquals("four", uri.getFP("three"));
+  uri.setFP("three", "five");
+  this.assertEquals("two", uri.getFP("one"));
+  this.assertEquals("five", uri.getFP("three"));
+  uri.setFP({ one: "one", two: "two", three: "three" });
+  this.assertEquals("one", uri.getFP("one"));
+  this.assertEquals("two", uri.getFP("two"));
+  this.assertEquals("three", uri.getFP("three"));
+  uri.setFP("two", null);
+  this.assertEquals("#one=one&three=three&two", uri.toString());
+};
+
+ShindigUriTest.prototype.testBuildWithOverrides = function() {
+  var uri =
+      shindig.uri("http://www.example.com/my/path?one=two&baz#three=four";)
+        .setAuthority("www.foo.com")
+        .setQP("one", "five")
+        .setFragment("foo=bar");
+  this.assertEquals(null, uri.getQP("baz"));
+  this.assertEquals(uri.toString(), 
"http://www.foo.com/my/path?one=five&baz#foo=bar";, uri.toString());
+};


Reply via email to