From 2b3d9e4ad077393ea2af0f4d45d4c00c00071dcd Mon Sep 17 00:00:00 2001 From: isaacs Date: Mon, 4 Jan 2010 21:07:50 -0800 Subject: [PATCH] Use "url" module instead of "uri" module in http.js. Deprecate the URI module and remove tests for it. - Rename "uri" to "url". - Use the "url" module instead of the "uri" module. - Remove the url parsing from http.js - Update http.cat with the changed field names. - Update tests for changes to http.js - Update documentation for changes in http.js --- doc/api.txt | 41 +++- lib/http.js | 68 ++---- lib/uri.js | 244 +------------------- test/mjsunit/test-http-client-race.js | 3 +- test/mjsunit/test-http-malformed-request.js | 3 +- test/mjsunit/test-http-proxy.js | 3 +- test/mjsunit/test-http-server.js | 12 +- test/mjsunit/test-http-tls.js | 7 +- test/mjsunit/test-http.js | 7 +- test/mjsunit/test-remote-module-loading.js | 3 +- test/mjsunit/test-uri.js | 193 ---------------- 11 files changed, 76 insertions(+), 508 deletions(-) delete mode 100644 test/mjsunit/test-uri.js diff --git a/doc/api.txt b/doc/api.txt index 4e125bf8f7..698accb91a 100644 --- a/doc/api.txt +++ b/doc/api.txt @@ -818,8 +818,8 @@ The request method as a string. Read only. Example: +"GET"+, +"DELETE"+. -+request.uri+ :: -Request URI Object. This contains only the parameters that are ++request.url+ :: +Request URL string. This contains only the URL that is present in the actual HTTP request. If the request is + ---------------------------------------- @@ -828,16 +828,41 @@ Accept: text/plain\r\n \r\n ---------------------------------------- + -Then +request.uri+ will be +Then +request.url+ will be + ---------------------------------------- -{ full: "/status?name=ryan", - path: "/status", - queryString: "name=ryan", - params: { "name": "ryan" }, - fragment: "" +"/status?name=ryan" +---------------------------------------- ++ +If you would like to parse the URL into its parts, you can use ++require("url").parse(request.url)+. Example: ++ +---------------------------------------- +node> require("url").parse("/status?name=ryan") +{ + "href": "/status?name=ryan", + "search": "?name=ryan", + "query": "name=ryan", + "pathname": "/status" +} +---------------------------------------- ++ +If you would like to extract the params from the query string, +you can use the +require("querystring").parse+ function, or pass ++true+ as the second argument to +require("url").parse+. Example: ++ +---------------------------------------- +node> require("url").parse("/status?name=ryan", true) +{ + "href": "/status?name=ryan", + "search": "?name=ryan", + "query": { + "name": "ryan" + }, + "pathname": "/status" } ---------------------------------------- ++ +request.headers+ :: diff --git a/lib/http.js b/lib/http.js index abb472e7e7..80762b4232 100644 --- a/lib/http.js +++ b/lib/http.js @@ -57,13 +57,7 @@ function IncomingMessage (connection) { this.headers = {}; // request (server) only - this.uri = { - full: "", - queryString: "", - fragment: "", - path: "", - params: {} - }; + this.url = ""; this.method = null; @@ -74,20 +68,8 @@ function IncomingMessage (connection) { sys.inherits(IncomingMessage, process.EventEmitter); exports.IncomingMessage = IncomingMessage; -var decode = require("uri").decode; IncomingMessage.prototype._parseQueryString = function () { - var parts = this.uri.queryString.split('&'); - for (var j = 0; j < parts.length; j++) { - var i = parts[j].indexOf('='); - if (i < 0) continue; - try { - var key = decode(parts[j].slice(0,i)) - var value = decode(parts[j].slice(i+1)); - this.uri.params[key] = value; - } catch (e) { - continue; - } - } + throw new Error("_parseQueryString is deprecated. Use require(\"querystring\") to parse query strings.\n"); }; IncomingMessage.prototype.setBodyEncoding = function (enc) { @@ -267,7 +249,7 @@ ServerResponse.prototype.sendHeader = function (statusCode, headers) { }; -function ClientRequest (method, uri, headers) { +function ClientRequest (method, url, headers) { OutgoingMessage.call(this); this.should_keep_alive = false; @@ -278,7 +260,7 @@ function ClientRequest (method, uri, headers) { } this.closeOnFinish = true; - this.sendHeaderLines(method + " " + uri + " HTTP/1.1\r\n", headers); + this.sendHeaderLines(method + " " + url + " HTTP/1.1\r\n", headers); } sys.inherits(ClientRequest, OutgoingMessage); exports.ClientRequest = ClientRequest; @@ -301,22 +283,10 @@ function createIncomingMessageStream (connection, incoming_listener) { field = null; value = null; }); - - // Only servers will get URI events. + + // Only servers will get URL events. connection.addListener("url", function (data) { - incoming.uri.full += data; - }); - - connection.addListener("path", function (data) { - incoming.uri.path += data; - }); - - connection.addListener("fragment", function (data) { - incoming.uri.fragment += data; - }); - - connection.addListener("queryString", function (data) { - incoming.uri.queryString += data; + incoming.url += data; }); connection.addListener("headerField", function (data) { @@ -352,10 +322,6 @@ function createIncomingMessageStream (connection, incoming_listener) { if (info.method) { // server only incoming.method = info.method; - - if (incoming.uri.queryString.length > 0) { - incoming._parseQueryString(); - } } else { // client only incoming.statusCode = info.statusCode; @@ -548,13 +514,13 @@ process.http.Client.prototype.put = function () { throw new Error("client.put(...) is now client.request('PUT', ...)"); }; -process.http.Client.prototype.request = function (method, uri, headers) { - if (typeof(uri) != "string") { // assume method was omitted, shift arguments - headers = uri; - uri = method; +process.http.Client.prototype.request = function (method, url, headers) { + if (typeof(url) != "string") { // assume method was omitted, shift arguments + headers = url; + url = method; method = null; } - var req = new ClientRequest(method || "GET", uri, headers); + var req = new ClientRequest(method || "GET", url, headers); this._pushRequest(req); return req; }; @@ -565,7 +531,7 @@ exports.cat = function (url, encoding, headers) { encoding = encoding || "utf8"; - var uri = require("uri").parse(url); + var url = require("url").parse(url); headers = headers || {}; var hasHost = false; @@ -574,11 +540,11 @@ exports.cat = function (url, encoding, headers) { break; } if (!hasHost) { - headers["Host"] = uri.domain; + headers["Host"] = url.hostname; } - - var client = exports.createClient(uri.port || 80, uri.domain); - var req = client.request(uri.path || "/", headers); + + var client = exports.createClient(url.port || 80, url.hostname); + var req = client.request((url.pathname || "/")+(url.search || "")+(url.hash || ""), headers); client.addListener("error", function () { promise.emitError(); diff --git a/lib/uri.js b/lib/uri.js index e44dd40a46..ddf483651b 100644 --- a/lib/uri.js +++ b/lib/uri.js @@ -1,243 +1,5 @@ -/** - * uri.js - * A URI parser, compliant with assorted RFCs, providing parsing and resolution utilities. - **/ +process.stdio.writeError("\nWARNING: uri module is deprecated. Please use require(\"url\") instead.\n"); -/* -Blatantly stolen with permission from Narwhal, which did the same from Chiron, -and bits taken from parseUri 1.2.1 (c) 2007 Steven Levithan MIT License, -and probably also plagiarizing http://code.google.com/p/js-uri/ in some ways. -Most lines have been changed, please don't blame any of the above persons for -any errors in this file. - -*/ - -exports.parse = uri_parse; -exports.format = uri_format; -exports.resolve = uri_resolve; -exports.resolveObject = uri_resolveObject; -exports.decode = uri_decode; - -/**** -Decode a URI, replacing + with space -*/ -function uri_decode (s) { - return decodeURIComponent(s.replace(/\+/g, ' ')); -} - -/**** expressionKeys - members of a parsed URI object that you get - from evaluting the strict regular expression. -*/ -var expressionKeys = [ - "url", - "protocol", - "authorityRoot", - "authority", - "userInfo", - "user", - "password", - "domain", - "port", - "path", - "root", - "directory", - "file", - "query", - "anchor" - ], - strictExpression = new RegExp( /* url */ - "^" + - "(?:" + - "([^:/?#]+):" + /* protocol */ - ")?" + - "(?:" + - "(//)" + /* authorityRoot */ - "(" + /* authority */ - "(?:" + - "(" + /* userInfo */ - "([^:@/]*)" + /* user */ - ":?" + - "([^@/]*)" + /* password */ - ")?" + - "@" + - ")?" + - "([^:/?#]*)" + /* domain */ - "(?::(\\d*))?" + /* port */ - ")" + - ")?" + - "(" + /* path */ - "(/?)" + /* root */ - "((?:[^?#/]*/)*)" + - "([^?#]*)" + /* file */ - ")" + - "(?:\\?([^#]*))?" + /* query */ - "(?:#(.*))?" /*anchor */ - ); - -/**** parse - a URI parser function that uses the `strictExpression` - and `expressionKeys` and returns an `Object` - mapping all `keys` to values. -*/ -function uri_parse (url) { - var items = {}, - parts = strictExpression.exec(url); - - for (var i = 0; i < parts.length; i++) { - items[expressionKeys[i]] = parts[i] ? parts[i] : ""; - } - - items.root = (items.root || items.authorityRoot) ? '/' : ''; - - items.directories = items.directory.split("/"); - if (items.directories[items.directories.length - 1] == "") { - items.directories.pop(); - } - - /* normalize */ - items.directories = require("path").normalizeArray(items.directories); - - items.domains = items.domain.split("."); - - return items; +exports.decode = exports.parse = exports.format = exports.resolveObject = exports.resolve = function () { + throw new Error("uri module is deprecated. Please use require(\"url\") instead."); }; - - -/**** format - accepts a parsed URI object and returns - the corresponding string. -*/ -function uri_format (object) { - if (typeof(object) == 'undefined') - throw new Error("UrlError: URL undefined for urls#format"); - if (object instanceof String || typeof(object) === 'string') - return object; - - var domain = - object.domains ? - object.domains.join(".") : - object.domain; - var userInfo = ( - object.user || - object.password - ) ? ( - (object.user || "") + - (object.password ? ":" + object.password : "") - ) : - object.userInfo; - var authority = object.authority || (( - userInfo || - domain || - object.port - ) ? ( - (userInfo ? userInfo + "@" : "") + - (domain || "") + - (object.port ? ":" + object.port : "") - ) : ""); - - var directory = - object.directories ? - object.directories.join("/") : - object.directory; - var path = - object.path ? object.path.substr(1) : ( - (directory || object.file) ? ( - (directory ? directory + "/" : "") + - (object.file || "") - ) : ""); - var authorityRoot = - object.authorityRoot - || authority ? "//" : ""; - - return object.url = (( - (object.protocol ? object.protocol + ":" : "") + - (authorityRoot) + - (authority) + - (object.root || (authority && path) ? "/" : "") + - (path ? path : "") + - (object.query ? "?" + object.query : "") + - (object.anchor ? "#" + object.anchor : "") - ) || object.url || ""); -}; - -function uri_resolveObject (source, relative) { - if (!source) return relative; - - // parse a string, or get new objects - source = uri_parse(uri_format(source)); - relative = uri_parse(uri_format(relative)); - - if (relative.url === "") return source; - - // links to xyz:... from abc:... are always absolute. - if (relative.protocol && source.protocol && relative.protocol !== source.protocol) { - return relative; - } - - // if there's an authority root, but no protocol, then keep the current protocol - if (relative.authorityRoot && !relative.protocol) { - relative.protocol = source.protocol; - } - // if we have an authority root, then it's absolute - if (relative.authorityRoot) return relative; - - - // at this point, we start doing the tricky stuff - // we know that relative doesn't have an authority, but might have root, - // path, file, query, etc. - // also, the directory segments might contain .. or . - // start mutating "source", and then return that. - - // relative urls that start with / are absolute to the authority/protocol - if (relative.root) { - [ - "path", "root", "directory", "directories", "file", "query", "anchor" - ].forEach(function (part) { source[part] = relative[part] }); - } else { - // if you have /a/b/c and you're going to x/y/z, then that's /a/b/x/y/z - // if you have /a/b/c/ and you're going ot x/y/z, then that's /a/b/c/x/y/z - // if you have /a/b/c and you're going to ?foo, then that's /a/b/c?foo - if (relative.file || relative.directory) { - source.file = relative.file; - source.query = relative.query; - source.anchor = relative.anchor; - } - if (relative.query) source.query = relative.query; - if (relative.query || relative.anchor) source.anchor = relative.anchor; - - // just append the dirs. we'll sort out .. and . later - source.directories = source.directories.concat(relative.directories); - } - - // back up "file" to the first non-dot - // one step for ., two for .. - var file = source.file; - while (file === ".." || file === ".") { - if (file === "..") source.directories.pop(); - file = source.directories.pop(); - } - source.file = file || ""; - - // walk over the dirs, replacing a/b/c/.. with a/b/ and a/b/c/. with a/b/c - var dirs = []; - source.directories.forEach(function (dir, i) { - if (dir === "..") dirs.pop(); - else if (dir !== "." && dir !== "") dirs.push(dir); - }); - - // now construct path/etc. - source.directories = dirs; - source.directory = dirs.concat("").join("/"); - source.path = source.root + source.directory + source.file; - source.url = uri_format(source); - return source; -}; - -/**** resolve - returns a URL resovled to a relative URL from a source URL. -*/ -function uri_resolve (source, relative) { - return uri_format(uri_resolveObject(source, relative)); -}; - diff --git a/test/mjsunit/test-http-client-race.js b/test/mjsunit/test-http-client-race.js index 1f333928a6..1bcd3420b5 100644 --- a/test/mjsunit/test-http-client-race.js +++ b/test/mjsunit/test-http-client-race.js @@ -1,12 +1,13 @@ process.mixin(require("./common")); http = require("http"); +url = require("url"); PORT = 8888; var body1_s = "1111111111111111"; var body2_s = "22222"; var server = http.createServer(function (req, res) { - var body = req.uri.path === "/1" ? body1_s : body2_s; + var body = url.parse(req.url).pathname === "/1" ? body1_s : body2_s; res.sendHeader(200, { "Content-Type": "text/plain" , "Content-Length": body.length }); diff --git a/test/mjsunit/test-http-malformed-request.js b/test/mjsunit/test-http-malformed-request.js index 942b17fa0c..ae89df4939 100644 --- a/test/mjsunit/test-http-malformed-request.js +++ b/test/mjsunit/test-http-malformed-request.js @@ -1,6 +1,7 @@ process.mixin(require("./common")); tcp = require("tcp"); http = require("http"); +url = require("url"); // Make sure no exceptions are thrown when receiving malformed HTTP // requests. @@ -10,7 +11,7 @@ nrequests_completed = 0; nrequests_expected = 1; var s = http.createServer(function (req, res) { - puts("req: " + JSON.stringify(req.uri)); + puts("req: " + JSON.stringify(url.parse(req.url))); res.sendHeader(200, {"Content-Type": "text/plain"}); res.sendBody("Hello World"); diff --git a/test/mjsunit/test-http-proxy.js b/test/mjsunit/test-http-proxy.js index 1a9025dc9d..220ffcbb6c 100644 --- a/test/mjsunit/test-http-proxy.js +++ b/test/mjsunit/test-http-proxy.js @@ -1,5 +1,6 @@ process.mixin(require("./common")); http = require("http"); +url = require("url"); var PROXY_PORT = 8869; var BACKEND_PORT = 8870; @@ -16,7 +17,7 @@ backend.listen(BACKEND_PORT); var proxy_client = http.createClient(BACKEND_PORT); var proxy = http.createServer(function (req, res) { debug("proxy req headers: " + JSON.stringify(req.headers)); - var proxy_req = proxy_client.request(req.uri.path); + var proxy_req = proxy_client.request(url.parse(req.url).pathname); proxy_req.finish(function(proxy_res) { res.sendHeader(proxy_res.statusCode, proxy_res.headers); proxy_res.addListener("body", function(chunk) { diff --git a/test/mjsunit/test-http-server.js b/test/mjsunit/test-http-server.js index 56e931844e..63e394b4c9 100644 --- a/test/mjsunit/test-http-server.js +++ b/test/mjsunit/test-http-server.js @@ -1,6 +1,8 @@ process.mixin(require("./common")); tcp = require("tcp"); http = require("http"); +url = require("url"); +qs = require("querystring"); var port = 8222; @@ -15,14 +17,14 @@ http.createServer(function (req, res) { if (req.id == 0) { assert.equal("GET", req.method); - assert.equal("/hello", req.uri.path); - assert.equal("world", req.uri.params["hello"]); - assert.equal("b==ar", req.uri.params["foo"]); + assert.equal("/hello", url.parse(req.url).pathname); + assert.equal("world", qs.parse(url.parse(req.url).query).hello); + assert.equal("b==ar", qs.parse(url.parse(req.url).query).foo); } if (req.id == 1) { assert.equal("POST", req.method); - assert.equal("/quit", req.uri.path); + assert.equal("/quit", url.parse(req.url).pathname); } if (req.id == 2) { @@ -37,7 +39,7 @@ http.createServer(function (req, res) { setTimeout(function () { res.sendHeader(200, {"Content-Type": "text/plain"}); - res.sendBody(req.uri.path); + res.sendBody(url.parse(req.url).pathname); res.finish(); }, 1); diff --git a/test/mjsunit/test-http-tls.js b/test/mjsunit/test-http-tls.js index 342b009cc6..1a1b1e4f1d 100644 --- a/test/mjsunit/test-http-tls.js +++ b/test/mjsunit/test-http-tls.js @@ -1,5 +1,6 @@ process.mixin(require("./common")); http = require("http"); +url = require("url"); PORT = 8888; HOST = "localhost"; @@ -34,7 +35,7 @@ var http_server=http.createServer(function (req, res) { if (responses_sent == 0) { assert.equal("GET", req.method); - assert.equal("/hello", req.uri.path); + assert.equal("/hello", url.parse(req.url).pathname); p(req.headers); assert.equal(true, "accept" in req.headers); @@ -46,13 +47,13 @@ var http_server=http.createServer(function (req, res) { if (responses_sent == 1) { assert.equal("POST", req.method); - assert.equal("/world", req.uri.path); + assert.equal("/world", url.parse(req.url).pathname); this.close(); } req.addListener("complete", function () { res.sendHeader(200, {"Content-Type": "text/plain"}); - res.sendBody("The path was " + req.uri.path); + res.sendBody("The path was " + url.parse(req.url).pathname); res.finish(); responses_sent += 1; }); diff --git a/test/mjsunit/test-http.js b/test/mjsunit/test-http.js index ae67cb8b2a..030f2ab765 100644 --- a/test/mjsunit/test-http.js +++ b/test/mjsunit/test-http.js @@ -1,5 +1,6 @@ process.mixin(require("./common")); http = require("http"); +url = require("url"); PORT = 8888; var responses_sent = 0; @@ -10,7 +11,7 @@ var body1 = ""; http.createServer(function (req, res) { if (responses_sent == 0) { assert.equal("GET", req.method); - assert.equal("/hello", req.uri.path); + assert.equal("/hello", url.parse(req.url).pathname); p(req.headers); assert.equal(true, "accept" in req.headers); @@ -22,13 +23,13 @@ http.createServer(function (req, res) { if (responses_sent == 1) { assert.equal("POST", req.method); - assert.equal("/world", req.uri.path); + assert.equal("/world", url.parse(req.url).pathname); this.close(); } req.addListener("complete", function () { res.sendHeader(200, {"Content-Type": "text/plain"}); - res.sendBody("The path was " + req.uri.path); + res.sendBody("The path was " + url.parse(req.url).pathname); res.finish(); responses_sent += 1; }); diff --git a/test/mjsunit/test-remote-module-loading.js b/test/mjsunit/test-remote-module-loading.js index 198d472edf..b4f18a0cd1 100644 --- a/test/mjsunit/test-remote-module-loading.js +++ b/test/mjsunit/test-remote-module-loading.js @@ -3,11 +3,12 @@ process.mixin(require("./common")); var PORT = 8889; var http = require('http'); var sys = require('sys'); +var url = require("url"); var modulesLoaded = 0; var server = http.createServer(function(req, res) { var body = 'exports.httpPath = function() {'+ - 'return '+JSON.stringify(req.uri.path)+';'+ + 'return '+JSON.stringify(url.parse(req.url).pathname)+';'+ '};'; res.sendHeader(200, {'Content-Type': 'text/javascript'}); diff --git a/test/mjsunit/test-uri.js b/test/mjsunit/test-uri.js deleted file mode 100644 index 6060fed99d..0000000000 --- a/test/mjsunit/test-uri.js +++ /dev/null @@ -1,193 +0,0 @@ -process.mixin(require("./common")); - -var uri = require("uri"), - sys = require("sys"); - -// URIs to parse, and expected data -// { url : parsed } -var parseTests = { - "http://www.narwhaljs.org/blog/categories?id=news" : { - "url": "http://www.narwhaljs.org/blog/categories?id=news", - "protocol": "http", - "authorityRoot": "//", - "authority": "www.narwhaljs.org", - "userInfo": "", - "user": "", - "password": "", - "domain": "www.narwhaljs.org", - "port": "", - "path": "/blog/categories", - "root": "/", - "directory": "blog/", - "file": "categories", - "query": "id=news", - "anchor": "", - "directories": [ - "blog" - ], - "domains": [ - "www", - "narwhaljs", - "org" - ] - }, - "http://mt0.google.com/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=" : { - "url": "http://mt0.google.com/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=", - "protocol": "http", - "authorityRoot": "//", - "authority": "mt0.google.com", - "userInfo": "", - "user": "", - "password": "", - "domain": "mt0.google.com", - "port": "", - "path": "/vt/lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=", - "root": "/", - "directory": "vt/", - "file": "lyrs=m@114&hl=en&src=api&x=2&y=2&z=3&s=", - "query": "", - "anchor": "", - "directories": [ - "vt" - ], - "domains": [ - "mt0", - "google", - "com" - ] - }, - "http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=" : { - "url": "http://mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=", - "protocol": "http", - "authorityRoot": "//", - "authority": "mt0.google.com", - "userInfo": "", - "user": "", - "password": "", - "domain": "mt0.google.com", - "port": "", - "path": "/vt/lyrs=m@114", - "root": "/", - "directory": "vt/", - "file": "lyrs=m@114", - "query": "??&hl=en&src=api&x=2&y=2&z=3&s=", - "anchor": "", - "directories": [ - "vt" - ], - "domains": [ - "mt0", - "google", - "com" - ] - }, - "http://user:pass@mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=" : { - "url": "http://user:pass@mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=", - "protocol": "http", - "authorityRoot": "//", - "authority": "user:pass@mt0.google.com", - "userInfo": "user:pass", - "user": "user", - "password": "pass", - "domain": "mt0.google.com", - "port": "", - "path": "/vt/lyrs=m@114", - "root": "/", - "directory": "vt/", - "file": "lyrs=m@114", - "query": "??&hl=en&src=api&x=2&y=2&z=3&s=", - "anchor": "", - "directories": [ - "vt" - ], - "domains": [ - "mt0", - "google", - "com" - ] - }, - "file:///etc/passwd" : { - "url": "file:///etc/passwd", - "protocol": "file", - "authorityRoot": "//", - "authority": "", - "userInfo": "", - "user": "", - "password": "", - "domain": "", - "port": "", - "path": "/etc/passwd", - "root": "/", - "directory": "etc/", - "file": "passwd", - "query": "", - "anchor": "", - "directories": [ - "etc" - ], - "domains": [ - "" - ] - }, - "file:///etc/node/" : { - "url": "file:///etc/node/", - "protocol": "file", - "authorityRoot": "//", - "authority": "", - "userInfo": "", - "user": "", - "password": "", - "domain": "", - "port": "", - "path": "/etc/node/", - "root": "/", - "directory": "etc/node/", - "file": "", - "query": "", - "anchor": "", - "directories": [ - "etc", - "node" - ], - "domains": [ - "" - ] - } -}; -for (var url in parseTests) { - var actual = uri.parse(url), - expected = parseTests[url]; - for (var i in expected) { - // sys.debug(i); - // sys.debug("expect: " + JSON.stringify(expected[i])); - // sys.debug("actual: " + JSON.stringify(actual[i])); - var e = JSON.stringify(expected[i]), - a = JSON.stringify(actual[i]); - assert.equal(e, a, "parse(" + url + ")."+i+" == "+e+"\nactual: "+a); - } - - var expected = url, - actual = uri.format(parseTests[url]); - - assert.equal(expected, actual, "format("+url+") == "+url+"\nactual:"+actual); -} - -[ - // [from, path, expected] - ["/foo/bar/baz", "quux", "/foo/bar/quux"], - ["/foo/bar/baz", "quux/asdf", "/foo/bar/quux/asdf"], - ["/foo/bar/baz", "quux/baz", "/foo/bar/quux/baz"], - ["/foo/bar/baz", "../quux/baz", "/foo/quux/baz"], - ["/foo/bar/baz", "/bar", "/bar"], - ["/foo/bar/baz/", "quux", "/foo/bar/baz/quux"], - ["/foo/bar/baz/", "quux/baz", "/foo/bar/baz/quux/baz"], - ["/foo/bar/baz", "../../../../../../../../quux/baz", "/quux/baz"], - ["/foo/bar/baz", "../../../../../../../quux/baz", "/quux/baz"] -].forEach(function (relativeTest) { - var a = uri.resolve(relativeTest[0], relativeTest[1]), - e = relativeTest[2]; - assert.equal(e, a, - "resolve("+[relativeTest[0], relativeTest[1]]+") == "+e+ - "\n actual="+a); -}); -