Browse Source

querystring.stringify is now more solid

* handles NaN and Infinity
* works with arrays from other contexts
v0.7.4-release
Jan Kassens 15 years ago
committed by Ryan Dahl
parent
commit
bb2acd5e75
  1. 42
      lib/querystring.js
  2. 9
      test/simple/test-querystring.js

42
lib/querystring.js

@ -29,21 +29,22 @@ QueryString.stringify = QueryString.encode = function (obj, sep, eq, munge, name
munge = typeof munge == "undefined" || munge; munge = typeof munge == "undefined" || munge;
sep = sep || "&"; sep = sep || "&";
eq = eq || "="; eq = eq || "=";
if (obj == null || typeof obj == "function") { var type = Object.prototype.toString.call(obj);
if (obj == null || type == "[object Function]" || type == "[object Number]" && !isFinite(obj)) {
return name ? QueryString.escape(name) + eq : ""; return name ? QueryString.escape(name) + eq : "";
} }
if (isBool(obj)) { switch (type) {
obj = +obj; case '[object Boolean]':
} obj = +obj; // fall through
if (isNumber(obj) || isString(obj)) { case '[object Number]':
return QueryString.escape(name) + eq + QueryString.escape(obj); case '[object String]':
} return QueryString.escape(name) + eq + QueryString.escape(obj);
if (isA(obj, [])) { case '[object Array]':
name = name + (munge ? "[]" : ""); name = name + (munge ? "[]" : "");
return obj.map(function (item) { return obj.map(function (item) {
return QueryString.stringify(item, sep, eq, munge, name); return QueryString.stringify(item, sep, eq, munge, name);
}).join(sep); }).join(sep);
} }
// now we know it's an object. // now we know it's an object.
@ -109,20 +110,3 @@ QueryString.parse = QueryString.decode = function (qs, sep, eq) {
}); });
return obj; return obj;
}; };
function isA (thing, canon) {
// special case for null and undefined
if (thing == null || canon == null) {
return thing === canon;
}
return Object.getPrototypeOf(Object(thing)) == Object.getPrototypeOf(Object(canon));
}
function isBool (thing) {
return isA(thing, true);
}
function isNumber (thing) {
return isA(thing, 0) && isFinite(thing);
}
function isString (thing) {
return isA(thing, "");
}

9
test/simple/test-querystring.js

@ -67,17 +67,24 @@ var qsWeirdObjects = [
[ {d:Date}, "d=", {"d":""} ], [ {d:Date}, "d=", {"d":""} ],
[ {f:new Boolean(false), t:new Boolean(true)}, "f=0&t=1", {"f":0, "t":1} ], [ {f:new Boolean(false), t:new Boolean(true)}, "f=0&t=1", {"f":0, "t":1} ],
[ {f:false, t:true}, "f=0&t=1", {"f":0, "t":1} ], [ {f:false, t:true}, "f=0&t=1", {"f":0, "t":1} ],
[ {n:null}, "n=", {"n":""} ],
[ {nan:NaN}, "nan=", {"nan":""} ],
[ {inf:Infinity}, "inf=", {"inf":""} ]
]; ];
} }
var Script = process.binding('evals').Script;
var foreignObject = Script.runInContext('({"foo": ["bar", "baz"]})', Script.createContext());
var qsNoMungeTestCases = [ var qsNoMungeTestCases = [
["", {}], ["", {}],
["foo=bar&foo=baz", {"foo": ["bar", "baz"]}], ["foo=bar&foo=baz", {"foo": ["bar", "baz"]}],
["foo=bar&foo=baz", foreignObject],
["blah=burp", {"blah": "burp"}], ["blah=burp", {"blah": "burp"}],
["gragh=1&gragh=3&goo=2", {"gragh": ["1", "3"], "goo": "2"}], ["gragh=1&gragh=3&goo=2", {"gragh": ["1", "3"], "goo": "2"}],
["frappucino=muffin&goat%5B%5D=scone&pond=moose", ["frappucino=muffin&goat%5B%5D=scone&pond=moose",
{"frappucino": "muffin", "goat[]": "scone", "pond": "moose"}], {"frappucino": "muffin", "goat[]": "scone", "pond": "moose"}],
["obj%5Btrololol%5D=yes&obj%5Blololo%5D=no", {"obj": {"trololol": "yes", "lololo": "no"}}], ["obj%5Btrololol%5D=yes&obj%5Blololo%5D=no", {"obj": {"trololol": "yes", "lololo": "no"}}]
]; ];
// test that the canonical qs is parsed properly. // test that the canonical qs is parsed properly.

Loading…
Cancel
Save