qs 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{.gitignore → .npmignore} +0 -0
- package/.travis.yml +4 -0
- package/History.md +20 -0
- package/Makefile +8 -1
- package/Readme.md +14 -3
- package/component.json +6 -0
- package/examples.js +3 -0
- package/lib/head.js +1 -0
- package/lib/querystring.js +25 -25
- package/lib/tail.js +1 -0
- package/package.json +8 -2
- package/querystring.js +254 -0
- package/test/browser/expect.js +1202 -0
- package/test/browser/index.html +18 -0
- package/test/browser/jquery.js +8981 -0
- package/test/browser/mocha.css +163 -0
- package/test/browser/mocha.js +4201 -0
- package/test/browser/qs.css +0 -0
- package/test/browser/qs.js +351 -0
- package/test/parse.js +129 -137
- package/test/stringify.js +66 -88
- package/test/mocha.opts +0 -2
|
File without changes
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Require the given path.
|
|
4
|
+
*
|
|
5
|
+
* @param {String} path
|
|
6
|
+
* @return {Object} exports
|
|
7
|
+
* @api public
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
function require(p, parent){
|
|
11
|
+
var path = require.resolve(p)
|
|
12
|
+
, mod = require.modules[path];
|
|
13
|
+
if (!mod) throw new Error('failed to require "' + p + '" in ' + parent);
|
|
14
|
+
if (!mod.exports) {
|
|
15
|
+
mod.exports = {};
|
|
16
|
+
mod.client = true;
|
|
17
|
+
mod.call(mod.exports, mod, mod.exports, require.relative(path));
|
|
18
|
+
}
|
|
19
|
+
return mod.exports;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Registered modules.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
require.modules = {};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Resolve `path`.
|
|
30
|
+
*
|
|
31
|
+
* @param {String} path
|
|
32
|
+
* @return {Object} module
|
|
33
|
+
* @api public
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
require.resolve = function(path){
|
|
37
|
+
var orig = path
|
|
38
|
+
, reg = path + '.js'
|
|
39
|
+
, index = path + '/index.js';
|
|
40
|
+
return require.modules[reg] && reg
|
|
41
|
+
|| require.modules[index] && index
|
|
42
|
+
|| orig;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Register module at `path` with callback `fn`.
|
|
47
|
+
*
|
|
48
|
+
* @param {String} path
|
|
49
|
+
* @param {Function} fn
|
|
50
|
+
* @api public
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
require.register = function(path, fn){
|
|
54
|
+
require.modules[path] = fn;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Defines and executes anonymous module immediately, while preserving relative
|
|
59
|
+
* paths.
|
|
60
|
+
*
|
|
61
|
+
* @param {String} path
|
|
62
|
+
* @param {Function} require ref
|
|
63
|
+
* @api public
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
require.exec = function (path, fn) {
|
|
67
|
+
fn.call(window, require.relative(path));
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Return a require function relative to the `parent` path.
|
|
72
|
+
*
|
|
73
|
+
* @param {String} parent
|
|
74
|
+
* @return {Function}
|
|
75
|
+
* @api private
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
require.relative = function(parent) {
|
|
79
|
+
return function(p){
|
|
80
|
+
if ('.' != p[0]) return require(p);
|
|
81
|
+
|
|
82
|
+
var path = parent.split('/')
|
|
83
|
+
, segs = p.split('/');
|
|
84
|
+
path.pop();
|
|
85
|
+
|
|
86
|
+
for (var i = 0; i < segs.length; i++) {
|
|
87
|
+
var seg = segs[i];
|
|
88
|
+
if ('..' == seg) path.pop();
|
|
89
|
+
else if ('.' != seg) path.push(seg);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return require(path.join('/'), parent);
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
// component qs: querystring
|
|
96
|
+
require.register("querystring", function(module, exports, require){
|
|
97
|
+
;(function(){
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Object#toString() ref for stringify().
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
var toString = Object.prototype.toString;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Cache non-integer test regexp.
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
var isint = /^[0-9]+$/;
|
|
110
|
+
|
|
111
|
+
function promote(parent, key) {
|
|
112
|
+
if (parent[key].length == 0) return parent[key] = {};
|
|
113
|
+
var t = {};
|
|
114
|
+
for (var i in parent[key]) t[i] = parent[key][i];
|
|
115
|
+
parent[key] = t;
|
|
116
|
+
return t;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function parse(parts, parent, key, val) {
|
|
120
|
+
var part = parts.shift();
|
|
121
|
+
// end
|
|
122
|
+
if (!part) {
|
|
123
|
+
if (Array.isArray(parent[key])) {
|
|
124
|
+
parent[key].push(val);
|
|
125
|
+
} else if ('object' == typeof parent[key]) {
|
|
126
|
+
parent[key] = val;
|
|
127
|
+
} else if ('undefined' == typeof parent[key]) {
|
|
128
|
+
parent[key] = val;
|
|
129
|
+
} else {
|
|
130
|
+
parent[key] = [parent[key], val];
|
|
131
|
+
}
|
|
132
|
+
// array
|
|
133
|
+
} else {
|
|
134
|
+
var obj = parent[key] = parent[key] || [];
|
|
135
|
+
if (']' == part) {
|
|
136
|
+
if (Array.isArray(obj)) {
|
|
137
|
+
if ('' != val) obj.push(val);
|
|
138
|
+
} else if ('object' == typeof obj) {
|
|
139
|
+
obj[Object.keys(obj).length] = val;
|
|
140
|
+
} else {
|
|
141
|
+
obj = parent[key] = [parent[key], val];
|
|
142
|
+
}
|
|
143
|
+
// prop
|
|
144
|
+
} else if (~part.indexOf(']')) {
|
|
145
|
+
part = part.substr(0, part.length - 1);
|
|
146
|
+
if (!isint.test(part) && Array.isArray(obj)) obj = promote(parent, key);
|
|
147
|
+
parse(parts, obj, part, val);
|
|
148
|
+
// key
|
|
149
|
+
} else {
|
|
150
|
+
if (!isint.test(part) && Array.isArray(obj)) obj = promote(parent, key);
|
|
151
|
+
parse(parts, obj, part, val);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Merge parent key/val pair.
|
|
158
|
+
*/
|
|
159
|
+
|
|
160
|
+
function merge(parent, key, val){
|
|
161
|
+
if (~key.indexOf(']')) {
|
|
162
|
+
var parts = key.split('[')
|
|
163
|
+
, len = parts.length
|
|
164
|
+
, last = len - 1;
|
|
165
|
+
parse(parts, parent, 'base', val);
|
|
166
|
+
// optimize
|
|
167
|
+
} else {
|
|
168
|
+
if (!isint.test(key) && Array.isArray(parent.base)) {
|
|
169
|
+
var t = {};
|
|
170
|
+
for (var k in parent.base) t[k] = parent.base[k];
|
|
171
|
+
parent.base = t;
|
|
172
|
+
}
|
|
173
|
+
set(parent.base, key, val);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return parent;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Parse the given obj.
|
|
181
|
+
*/
|
|
182
|
+
|
|
183
|
+
function parseObject(obj){
|
|
184
|
+
var ret = { base: {} };
|
|
185
|
+
Object.keys(obj).forEach(function(name){
|
|
186
|
+
merge(ret, name, obj[name]);
|
|
187
|
+
});
|
|
188
|
+
return ret.base;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Parse the given str.
|
|
193
|
+
*/
|
|
194
|
+
|
|
195
|
+
function parseString(str){
|
|
196
|
+
return String(str)
|
|
197
|
+
.split('&')
|
|
198
|
+
.reduce(function(ret, pair){
|
|
199
|
+
try{
|
|
200
|
+
pair = decodeURIComponent(pair.replace(/\+/g, ' '));
|
|
201
|
+
} catch(e) {
|
|
202
|
+
// ignore
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
var eql = pair.indexOf('=')
|
|
206
|
+
, brace = lastBraceInKey(pair)
|
|
207
|
+
, key = pair.substr(0, brace || eql)
|
|
208
|
+
, val = pair.substr(brace || eql, pair.length)
|
|
209
|
+
, val = val.substr(val.indexOf('=') + 1, val.length);
|
|
210
|
+
|
|
211
|
+
// ?foo
|
|
212
|
+
if ('' == key) key = pair, val = '';
|
|
213
|
+
|
|
214
|
+
return merge(ret, key, val);
|
|
215
|
+
}, { base: {} }).base;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Parse the given query `str` or `obj`, returning an object.
|
|
220
|
+
*
|
|
221
|
+
* @param {String} str | {Object} obj
|
|
222
|
+
* @return {Object}
|
|
223
|
+
* @api public
|
|
224
|
+
*/
|
|
225
|
+
|
|
226
|
+
exports.parse = function(str){
|
|
227
|
+
if (null == str || '' == str) return {};
|
|
228
|
+
return 'object' == typeof str
|
|
229
|
+
? parseObject(str)
|
|
230
|
+
: parseString(str);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Turn the given `obj` into a query string
|
|
235
|
+
*
|
|
236
|
+
* @param {Object} obj
|
|
237
|
+
* @return {String}
|
|
238
|
+
* @api public
|
|
239
|
+
*/
|
|
240
|
+
|
|
241
|
+
var stringify = exports.stringify = function(obj, prefix) {
|
|
242
|
+
if (Array.isArray(obj)) {
|
|
243
|
+
return stringifyArray(obj, prefix);
|
|
244
|
+
} else if ('[object Object]' == toString.call(obj)) {
|
|
245
|
+
return stringifyObject(obj, prefix);
|
|
246
|
+
} else if ('string' == typeof obj) {
|
|
247
|
+
return stringifyString(obj, prefix);
|
|
248
|
+
} else {
|
|
249
|
+
return prefix + '=' + obj;
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Stringify the given `str`.
|
|
255
|
+
*
|
|
256
|
+
* @param {String} str
|
|
257
|
+
* @param {String} prefix
|
|
258
|
+
* @return {String}
|
|
259
|
+
* @api private
|
|
260
|
+
*/
|
|
261
|
+
|
|
262
|
+
function stringifyString(str, prefix) {
|
|
263
|
+
if (!prefix) throw new TypeError('stringify expects an object');
|
|
264
|
+
return prefix + '=' + encodeURIComponent(str);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Stringify the given `arr`.
|
|
269
|
+
*
|
|
270
|
+
* @param {Array} arr
|
|
271
|
+
* @param {String} prefix
|
|
272
|
+
* @return {String}
|
|
273
|
+
* @api private
|
|
274
|
+
*/
|
|
275
|
+
|
|
276
|
+
function stringifyArray(arr, prefix) {
|
|
277
|
+
var ret = [];
|
|
278
|
+
if (!prefix) throw new TypeError('stringify expects an object');
|
|
279
|
+
for (var i = 0; i < arr.length; i++) {
|
|
280
|
+
ret.push(stringify(arr[i], prefix + '['+i+']'));
|
|
281
|
+
}
|
|
282
|
+
return ret.join('&');
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Stringify the given `obj`.
|
|
287
|
+
*
|
|
288
|
+
* @param {Object} obj
|
|
289
|
+
* @param {String} prefix
|
|
290
|
+
* @return {String}
|
|
291
|
+
* @api private
|
|
292
|
+
*/
|
|
293
|
+
|
|
294
|
+
function stringifyObject(obj, prefix) {
|
|
295
|
+
var ret = []
|
|
296
|
+
, keys = Object.keys(obj)
|
|
297
|
+
, key;
|
|
298
|
+
|
|
299
|
+
for (var i = 0, len = keys.length; i < len; ++i) {
|
|
300
|
+
key = keys[i];
|
|
301
|
+
ret.push(stringify(obj[key], prefix
|
|
302
|
+
? prefix + '[' + encodeURIComponent(key) + ']'
|
|
303
|
+
: encodeURIComponent(key)));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return ret.join('&');
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Set `obj`'s `key` to `val` respecting
|
|
311
|
+
* the weird and wonderful syntax of a qs,
|
|
312
|
+
* where "foo=bar&foo=baz" becomes an array.
|
|
313
|
+
*
|
|
314
|
+
* @param {Object} obj
|
|
315
|
+
* @param {String} key
|
|
316
|
+
* @param {String} val
|
|
317
|
+
* @api private
|
|
318
|
+
*/
|
|
319
|
+
|
|
320
|
+
function set(obj, key, val) {
|
|
321
|
+
var v = obj[key];
|
|
322
|
+
if (undefined === v) {
|
|
323
|
+
obj[key] = val;
|
|
324
|
+
} else if (Array.isArray(v)) {
|
|
325
|
+
v.push(val);
|
|
326
|
+
} else {
|
|
327
|
+
obj[key] = [v, val];
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* Locate last brace in `str` within the key.
|
|
333
|
+
*
|
|
334
|
+
* @param {String} str
|
|
335
|
+
* @return {Number}
|
|
336
|
+
* @api private
|
|
337
|
+
*/
|
|
338
|
+
|
|
339
|
+
function lastBraceInKey(str) {
|
|
340
|
+
var len = str.length
|
|
341
|
+
, brace
|
|
342
|
+
, c;
|
|
343
|
+
for (var i = 0; i < len; ++i) {
|
|
344
|
+
c = str[i];
|
|
345
|
+
if (']' == c) brace = false;
|
|
346
|
+
if ('[' == c) brace = true;
|
|
347
|
+
if ('=' == c && !brace) return i;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
})();
|
|
351
|
+
});
|
package/test/parse.js
CHANGED
|
@@ -1,155 +1,147 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
if (require.register) {
|
|
3
|
+
var qs = require('querystring');
|
|
4
|
+
} else {
|
|
5
|
+
var qs = require('../')
|
|
6
|
+
, expect = require('expect.js');
|
|
7
|
+
}
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
describe('qs.parse()', function(){
|
|
10
|
+
it('should support the basics', function(){
|
|
11
|
+
expect(qs.parse('0=foo')).to.eql({ '0': 'foo' });
|
|
7
12
|
|
|
8
|
-
|
|
9
|
-
'
|
|
10
|
-
qs.parse('0=foo').should.eql({ '0': 'foo' });
|
|
13
|
+
expect(qs.parse('foo=c++'))
|
|
14
|
+
.to.eql({ foo: 'c ' });
|
|
11
15
|
|
|
12
|
-
qs.parse('
|
|
13
|
-
.
|
|
16
|
+
expect(qs.parse('a[>=]=23'))
|
|
17
|
+
.to.eql({ a: { '>=': '23' }});
|
|
14
18
|
|
|
15
|
-
qs.parse('a[
|
|
16
|
-
.
|
|
19
|
+
expect(qs.parse('a[<=>]==23'))
|
|
20
|
+
.to.eql({ a: { '<=>': '=23' }});
|
|
17
21
|
|
|
18
|
-
qs.parse('a[
|
|
19
|
-
.
|
|
22
|
+
expect(qs.parse('a[==]=23'))
|
|
23
|
+
.to.eql({ a: { '==': '23' }});
|
|
20
24
|
|
|
21
|
-
qs.parse('
|
|
22
|
-
.
|
|
25
|
+
expect(qs.parse('foo'))
|
|
26
|
+
.to.eql({ foo: '' });
|
|
23
27
|
|
|
24
|
-
qs.parse('foo')
|
|
25
|
-
.
|
|
28
|
+
expect(qs.parse('foo=bar'))
|
|
29
|
+
.to.eql({ foo: 'bar' });
|
|
26
30
|
|
|
27
|
-
qs.parse('foo=bar')
|
|
28
|
-
.
|
|
31
|
+
expect(qs.parse(' foo = bar = baz '))
|
|
32
|
+
.to.eql({ ' foo ': ' bar = baz ' });
|
|
29
33
|
|
|
30
|
-
qs.parse('foo
|
|
31
|
-
.
|
|
34
|
+
expect(qs.parse('foo=bar=baz'))
|
|
35
|
+
.to.eql({ foo: 'bar=baz' });
|
|
32
36
|
|
|
33
|
-
qs.parse('
|
|
34
|
-
.
|
|
37
|
+
expect(qs.parse('foo=bar&bar=baz'))
|
|
38
|
+
.to.eql({ foo: 'bar', bar: 'baz' });
|
|
35
39
|
|
|
36
|
-
qs.parse('foo=bar
|
|
37
|
-
.
|
|
40
|
+
expect(qs.parse('foo=bar&baz'))
|
|
41
|
+
.to.eql({ foo: 'bar', baz: '' });
|
|
38
42
|
|
|
39
|
-
qs.parse('
|
|
40
|
-
.
|
|
41
|
-
|
|
42
|
-
qs.parse('foo=bar&baz')
|
|
43
|
-
.should.eql({ foo: 'bar', baz: '' });
|
|
44
|
-
|
|
45
|
-
qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World')
|
|
46
|
-
.should.eql({
|
|
43
|
+
expect(qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World'))
|
|
44
|
+
.to.eql({
|
|
47
45
|
cht: 'p3'
|
|
48
46
|
, chd: 't:60,40'
|
|
49
47
|
, chs: '250x100'
|
|
50
48
|
, chl: 'Hello|World'
|
|
51
49
|
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
'
|
|
55
|
-
qs.parse('
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
qs.parse('
|
|
67
|
-
.
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
'
|
|
71
|
-
qs.parse('images[]')
|
|
72
|
-
.
|
|
73
|
-
|
|
74
|
-
qs.parse('user[]=tj')
|
|
75
|
-
.
|
|
76
|
-
|
|
77
|
-
qs.parse('user[]=tj&user[]=tobi&user[]=jane')
|
|
78
|
-
.
|
|
79
|
-
|
|
80
|
-
qs.parse('user[names][]=tj&user[names][]=tyler')
|
|
81
|
-
.
|
|
82
|
-
|
|
83
|
-
qs.parse('user[names][]=tj&user[names][]=tyler&user[email]=tj@vision-media.ca')
|
|
84
|
-
.
|
|
85
|
-
|
|
86
|
-
qs.parse('items=a&items=b')
|
|
87
|
-
.
|
|
88
|
-
|
|
89
|
-
qs.parse('user[names]=tj&user[names]=holowaychuk&user[names]=TJ')
|
|
90
|
-
.
|
|
91
|
-
|
|
92
|
-
qs.parse('user[name][first]=tj&user[name][first]=TJ')
|
|
93
|
-
.
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
qs.parse('
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
qs.parse('')
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
qs.parse('
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
qs.parse(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
// qs.parse('users[][name][first]=tj&users[][name][first]=tobi')
|
|
151
|
-
// .should.eql({
|
|
152
|
-
// users: [ { name: 'tj' }, { name: 'tobi' }]
|
|
153
|
-
// });
|
|
154
|
-
// }
|
|
155
|
-
};
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
it('should support encoded = signs', function(){
|
|
53
|
+
expect(qs.parse('he%3Dllo=th%3Dere'))
|
|
54
|
+
.to.eql({ 'he=llo': 'th=ere' });
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('should support nesting', function(){
|
|
58
|
+
expect(qs.parse('ops[>=]=25'))
|
|
59
|
+
.to.eql({ ops: { '>=': '25' }});
|
|
60
|
+
|
|
61
|
+
expect(qs.parse('user[name]=tj'))
|
|
62
|
+
.to.eql({ user: { name: 'tj' }});
|
|
63
|
+
|
|
64
|
+
expect(qs.parse('user[name][first]=tj&user[name][last]=holowaychuk'))
|
|
65
|
+
.to.eql({ user: { name: { first: 'tj', last: 'holowaychuk' }}});
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('should support array notation', function(){
|
|
69
|
+
expect(qs.parse('images[]'))
|
|
70
|
+
.to.eql({ images: [] });
|
|
71
|
+
|
|
72
|
+
expect(qs.parse('user[]=tj'))
|
|
73
|
+
.to.eql({ user: ['tj'] });
|
|
74
|
+
|
|
75
|
+
expect(qs.parse('user[]=tj&user[]=tobi&user[]=jane'))
|
|
76
|
+
.to.eql({ user: ['tj', 'tobi', 'jane'] });
|
|
77
|
+
|
|
78
|
+
expect(qs.parse('user[names][]=tj&user[names][]=tyler'))
|
|
79
|
+
.to.eql({ user: { names: ['tj', 'tyler'] }});
|
|
80
|
+
|
|
81
|
+
expect(qs.parse('user[names][]=tj&user[names][]=tyler&user[email]=tj@vision-media.ca'))
|
|
82
|
+
.to.eql({ user: { names: ['tj', 'tyler'], email: 'tj@vision-media.ca' }});
|
|
83
|
+
|
|
84
|
+
expect(qs.parse('items=a&items=b'))
|
|
85
|
+
.to.eql({ items: ['a', 'b'] });
|
|
86
|
+
|
|
87
|
+
expect(qs.parse('user[names]=tj&user[names]=holowaychuk&user[names]=TJ'))
|
|
88
|
+
.to.eql({ user: { names: ['tj', 'holowaychuk', 'TJ'] }});
|
|
89
|
+
|
|
90
|
+
expect(qs.parse('user[name][first]=tj&user[name][first]=TJ'))
|
|
91
|
+
.to.eql({ user: { name: { first: ['tj', 'TJ'] }}});
|
|
92
|
+
|
|
93
|
+
var o = qs.parse('existing[fcbaebfecc][name][last]=tj')
|
|
94
|
+
expect(o).to.eql({ existing: { 'fcbaebfecc': { name: { last: 'tj' }}}})
|
|
95
|
+
expect(Array.isArray(o.existing)).to.equal(false);
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it('should support arrays with indexes', function(){
|
|
99
|
+
expect(qs.parse('foo[0]=bar&foo[1]=baz')).to.eql({ foo: ['bar', 'baz'] });
|
|
100
|
+
expect(qs.parse('foo[1]=bar&foo[0]=baz')).to.eql({ foo: ['baz', 'bar'] });
|
|
101
|
+
expect(qs.parse('foo[base64]=RAWR')).to.eql({ foo: { base64: 'RAWR' }});
|
|
102
|
+
expect(qs.parse('foo[64base]=RAWR')).to.eql({ foo: { '64base': 'RAWR' }});
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
it('should expand to an array when dupliate keys are present', function(){
|
|
106
|
+
expect(qs.parse('items=bar&items=baz&items=raz'))
|
|
107
|
+
.to.eql({ items: ['bar', 'baz', 'raz'] });
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
it('should support right-hand side brackets', function(){
|
|
111
|
+
expect(qs.parse('pets=["tobi"]'))
|
|
112
|
+
.to.eql({ pets: '["tobi"]' });
|
|
113
|
+
|
|
114
|
+
expect(qs.parse('operators=[">=", "<="]'))
|
|
115
|
+
.to.eql({ operators: '[">=", "<="]' });
|
|
116
|
+
|
|
117
|
+
expect(qs.parse('op[>=]=[1,2,3]'))
|
|
118
|
+
.to.eql({ op: { '>=': '[1,2,3]' }});
|
|
119
|
+
|
|
120
|
+
expect(qs.parse('op[>=]=[1,2,3]&op[=]=[[[[1]]]]'))
|
|
121
|
+
.to.eql({ op: { '>=': '[1,2,3]', '=': '[[[[1]]]]' }});
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
it('should support empty values', function(){
|
|
125
|
+
expect(qs.parse('')).to.eql({});
|
|
126
|
+
expect(qs.parse(undefined)).to.eql({});
|
|
127
|
+
expect(qs.parse(null)).to.eql({});
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('should transform arrays to objects', function(){
|
|
131
|
+
expect(qs.parse('foo[0]=bar&foo[bad]=baz')).to.eql({ foo: { 0: "bar", bad: "baz" }});
|
|
132
|
+
expect(qs.parse('foo[bad]=baz&foo[0]=bar')).to.eql({ foo: { 0: "bar", bad: "baz" }});
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
it('should support malformed uri chars', function(){
|
|
136
|
+
expect(qs.parse('{%:%}')).to.eql({ '{%:%}': '' });
|
|
137
|
+
expect(qs.parse('foo=%:%}')).to.eql({ 'foo': '%:%}' });
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
it('should support semi-parsed strings', function(){
|
|
141
|
+
expect(qs.parse({ 'user[name]': 'tobi' }))
|
|
142
|
+
.to.eql({ user: { name: 'tobi' }});
|
|
143
|
+
|
|
144
|
+
expect(qs.parse({ 'user[name]': 'tobi', 'user[email][main]': 'tobi@lb.com' }))
|
|
145
|
+
.to.eql({ user: { name: 'tobi', email: { main: 'tobi@lb.com' } }});
|
|
146
|
+
})
|
|
147
|
+
})
|