Created
February 5, 2011 08:11
-
-
Save kaichen/812309 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env coffee | |
| queryString = require('querystring') | |
| util = require("util") | |
| parser = module.exports = (qs, sep, eq) -> | |
| sep = sep || '&' | |
| eq = eq || '=' | |
| params = {} | |
| if (typeof qs != 'string' || qs.length == 0) | |
| return obj | |
| qs.split('&').forEach (kvp) -> | |
| return if kvp == "" | |
| x = kvp.split("=") | |
| k = queryString.unescape(x[0], true) | |
| v = queryString.unescape(x.slice(1).join("="), true) | |
| v = undefined if v == "" && x.length == 1 | |
| normalizeParams(params, k, v) | |
| params | |
| normalizeParams = (params, name, value) -> | |
| sliced = /^\[?([^\[\]]+)\]?/.exec(name) | |
| if sliced and sliced[1] | |
| key = sliced[1] | |
| else | |
| key = "" | |
| after = name.slice(sliced[0].length) | |
| return if key == "" | |
| if after == "" | |
| params[key] = value | |
| else if after == "[]" | |
| params[key] ?= [] | |
| params[key].push(value) | |
| else if /^\[\](.+)$/.test(after) | |
| fragments = /^\[\]\[([^\[\]]+)\]/.exec(after) | |
| childKey = fragments[1] + after.slice(fragments[0].length) | |
| params[key] ?= [] | |
| lastParams = params[key][params[key].length - 1] | |
| if params[key].length == 0 || lastParams[childKey] | |
| params[key].push normalizeParams({}, childKey, value) | |
| else | |
| lastParams = normalizeParams(lastParams, childKey, value) | |
| else | |
| params[key] ?= {} | |
| params[key] = normalizeParams(params[key], after, value) | |
| params | |
| # vim:set sts=2 sw=2: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env coffee | |
| vows = require("vows") | |
| assert = require("assert") | |
| equiv = require("./equiv") | |
| util = require("util") | |
| parser = require("./parser").parseNested | |
| assert.equiv = (expected, actual, message) -> | |
| if !equiv(actual, expected) | |
| message ?= "expected {expected},\nbut got {actual}" | |
| assert.fail(util.inspect(expected, false, 9), | |
| util.inspect(actual, false, 9), | |
| message, 'equiv', assert.equiv) | |
| assertFn = assert.equiv | |
| vows.describe("Nested query strings").addBatch | |
| "A context": | |
| tipic: true, | |
| "test parse normal query strings" : (topic) -> | |
| assertFn(parser("foo"), {"foo":""}) | |
| assertFn(parser("foo="), {"foo":""}) | |
| assertFn(parser("foo=bar"), {"foo":"bar"}) | |
| assertFn(parser("foo=\"bar\""), {"foo":"\"bar\""}) | |
| assertFn(parser("foo=bar&foo=quux"), {"foo":"quux"}) | |
| assertFn(parser("foo&foo=quux"), {"foo":"quux"}) | |
| assertFn(parser("foo=1&bar=2"), {"foo":"1","bar":"2"}) | |
| assertFn(parser("&foo=1&&bar=2"), {"foo":"1","bar":"2"}) | |
| assertFn(parser("foo&bar="), {"foo":"","bar":""}) | |
| assertFn(parser("foo=bar&baz="), {"foo":"bar","baz":''}) | |
| "test parse array like query strings" : (topic) -> | |
| assertFn(parser("foo[]"), {"foo":[""]}) | |
| assertFn(parser("foo[]="), {"foo":[""]}) | |
| assertFn(parser("foo[]=bar"), {"foo":["bar"]}) | |
| assertFn(parser("foo[]=1&foo[]=2"), {"foo":["1","2"]}) | |
| assertFn(parser("foo=bar&baz[]=1&baz[]=2&baz[]=3"), | |
| {"foo":"bar", "baz":["1", "2", "3"]}) | |
| assertFn(parser("foo[]=bar&baz[]=1&baz[]=2&baz[]=3"), | |
| {"foo":["bar"], "baz":["1", "2", "3"]}) | |
| "test parse hash like query strings" : (topic) -> | |
| assertFn(parser("x[y][z]=1"), {"x":{"y":{"z":"1"}}}) | |
| assertFn(parser("x[y][z][]=1"), {"x":{"y":{"z":["1"]}}}) | |
| assertFn(parser("x[y][z]=1&x[y][z]=2"), {"x":{"y":{"z":"2"}}}) | |
| assertFn(parser("x[y][z][]=1&x[y][z][]=2"), | |
| {"x":{"y":{"z":["1","2"]}}}) | |
| assertFn(parser("x[y][][z]=1"), {"x":{"y":[{"z":"1"}]}}) | |
| assertFn(parser("x[y][][z][]=1"), {"x":{"y":[{"z":["1"]}]}}) | |
| assertFn(parser("x[y][][z]=1&x[y][][w]=2"), | |
| {"x":{"y":[{"z":"1","w":"2"}]}}) | |
| assertFn(parser("x[y][][v][w]=1"), {"x":{"y":[{"v":{"w":"1"}}]}}) | |
| assertFn(parser("x[y][][z]=1&x[y][][v][w]=2"), | |
| {"x":{"y":[{"z":"1", "v":{"w":"2"}}]}}) | |
| assertFn(parser("x[y][][z]=1&x[y][][z]=2"), | |
| {"x":{"y":[{"z":"1"},{"z":"2"}]}}) | |
| assertFn(parser("x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3"), | |
| {"x":{"y":[{"z":"1","w":"a"},{"z":"2","w":"3"}]}}) | |
| .export(module) | |
| # vim:set sts=2 sw=2: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment