qs 6.11.2 → 6.12.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/.editorconfig +3 -0
- package/.eslintrc +1 -1
- package/CHANGELOG.md +29 -0
- package/README.md +84 -50
- package/dist/qs.js +56 -2053
- package/lib/parse.js +35 -11
- package/lib/stringify.js +49 -18
- package/lib/utils.js +47 -34
- package/package.json +26 -14
- package/test/empty-keys-cases.js +261 -31
- package/test/parse.js +184 -30
- package/test/stringify.js +362 -48
package/test/stringify.js
CHANGED
|
@@ -6,6 +6,7 @@ var utils = require('../lib/utils');
|
|
|
6
6
|
var iconv = require('iconv-lite');
|
|
7
7
|
var SaferBuffer = require('safer-buffer').Buffer;
|
|
8
8
|
var hasSymbols = require('has-symbols');
|
|
9
|
+
var mockProperty = require('mock-property');
|
|
9
10
|
var emptyTestCases = require('./empty-keys-cases').emptyTestCases;
|
|
10
11
|
var hasBigInt = typeof BigInt === 'function';
|
|
11
12
|
|
|
@@ -64,6 +65,138 @@ test('stringify()', function (t) {
|
|
|
64
65
|
st.end();
|
|
65
66
|
});
|
|
66
67
|
|
|
68
|
+
t.test('encodes dot in key of object when encodeDotInKeys and allowDots is provided', function (st) {
|
|
69
|
+
st.equal(
|
|
70
|
+
qs.stringify(
|
|
71
|
+
{ 'name.obj': { first: 'John', last: 'Doe' } },
|
|
72
|
+
{ allowDots: false, encodeDotInKeys: false }
|
|
73
|
+
),
|
|
74
|
+
'name.obj%5Bfirst%5D=John&name.obj%5Blast%5D=Doe',
|
|
75
|
+
'with allowDots false and encodeDotInKeys false'
|
|
76
|
+
);
|
|
77
|
+
st.equal(
|
|
78
|
+
qs.stringify(
|
|
79
|
+
{ 'name.obj': { first: 'John', last: 'Doe' } },
|
|
80
|
+
{ allowDots: true, encodeDotInKeys: false }
|
|
81
|
+
),
|
|
82
|
+
'name.obj.first=John&name.obj.last=Doe',
|
|
83
|
+
'with allowDots true and encodeDotInKeys false'
|
|
84
|
+
);
|
|
85
|
+
st.equal(
|
|
86
|
+
qs.stringify(
|
|
87
|
+
{ 'name.obj': { first: 'John', last: 'Doe' } },
|
|
88
|
+
{ allowDots: false, encodeDotInKeys: true }
|
|
89
|
+
),
|
|
90
|
+
'name%252Eobj%5Bfirst%5D=John&name%252Eobj%5Blast%5D=Doe',
|
|
91
|
+
'with allowDots false and encodeDotInKeys true'
|
|
92
|
+
);
|
|
93
|
+
st.equal(
|
|
94
|
+
qs.stringify(
|
|
95
|
+
{ 'name.obj': { first: 'John', last: 'Doe' } },
|
|
96
|
+
{ allowDots: true, encodeDotInKeys: true }
|
|
97
|
+
),
|
|
98
|
+
'name%252Eobj.first=John&name%252Eobj.last=Doe',
|
|
99
|
+
'with allowDots true and encodeDotInKeys true'
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
st.equal(
|
|
103
|
+
qs.stringify(
|
|
104
|
+
{ 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } },
|
|
105
|
+
{ allowDots: false, encodeDotInKeys: false }
|
|
106
|
+
),
|
|
107
|
+
'name.obj.subobject%5Bfirst.godly.name%5D=John&name.obj.subobject%5Blast%5D=Doe',
|
|
108
|
+
'with allowDots false and encodeDotInKeys false'
|
|
109
|
+
);
|
|
110
|
+
st.equal(
|
|
111
|
+
qs.stringify(
|
|
112
|
+
{ 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } },
|
|
113
|
+
{ allowDots: true, encodeDotInKeys: false }
|
|
114
|
+
),
|
|
115
|
+
'name.obj.subobject.first.godly.name=John&name.obj.subobject.last=Doe',
|
|
116
|
+
'with allowDots false and encodeDotInKeys false'
|
|
117
|
+
);
|
|
118
|
+
st.equal(
|
|
119
|
+
qs.stringify(
|
|
120
|
+
{ 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } },
|
|
121
|
+
{ allowDots: false, encodeDotInKeys: true }
|
|
122
|
+
),
|
|
123
|
+
'name%252Eobj%252Esubobject%5Bfirst.godly.name%5D=John&name%252Eobj%252Esubobject%5Blast%5D=Doe',
|
|
124
|
+
'with allowDots false and encodeDotInKeys true'
|
|
125
|
+
);
|
|
126
|
+
st.equal(
|
|
127
|
+
qs.stringify(
|
|
128
|
+
{ 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } },
|
|
129
|
+
{ allowDots: true, encodeDotInKeys: true }
|
|
130
|
+
),
|
|
131
|
+
'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe',
|
|
132
|
+
'with allowDots true and encodeDotInKeys true'
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
st.end();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
t.test('should encode dot in key of object, and automatically set allowDots to `true` when encodeDotInKeys is true and allowDots in undefined', function (st) {
|
|
139
|
+
st.equal(
|
|
140
|
+
qs.stringify(
|
|
141
|
+
{ 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } },
|
|
142
|
+
{ encodeDotInKeys: true }
|
|
143
|
+
),
|
|
144
|
+
'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe',
|
|
145
|
+
'with allowDots undefined and encodeDotInKeys true'
|
|
146
|
+
);
|
|
147
|
+
st.end();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
t.test('should encode dot in key of object when encodeDotInKeys and allowDots is provided, and nothing else when encodeValuesOnly is provided', function (st) {
|
|
151
|
+
st.equal(
|
|
152
|
+
qs.stringify({ 'name.obj': { first: 'John', last: 'Doe' } }, {
|
|
153
|
+
encodeDotInKeys: true, allowDots: true, encodeValuesOnly: true
|
|
154
|
+
}),
|
|
155
|
+
'name%2Eobj.first=John&name%2Eobj.last=Doe'
|
|
156
|
+
);
|
|
157
|
+
|
|
158
|
+
st.equal(
|
|
159
|
+
qs.stringify({ 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, { allowDots: true, encodeDotInKeys: true, encodeValuesOnly: true }),
|
|
160
|
+
'name%2Eobj%2Esubobject.first%2Egodly%2Ename=John&name%2Eobj%2Esubobject.last=Doe'
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
st.end();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
t.test('throws when `commaRoundTrip` is not a boolean', function (st) {
|
|
167
|
+
st['throws'](
|
|
168
|
+
function () { qs.stringify({}, { commaRoundTrip: 'not a boolean' }); },
|
|
169
|
+
TypeError,
|
|
170
|
+
'throws when `commaRoundTrip` is not a boolean'
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
st.end();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
t.test('throws when `encodeDotInKeys` is not a boolean', function (st) {
|
|
177
|
+
st['throws'](
|
|
178
|
+
function () { qs.stringify({ a: [], b: 'zz' }, { encodeDotInKeys: 'foobar' }); },
|
|
179
|
+
TypeError
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
st['throws'](
|
|
183
|
+
function () { qs.stringify({ a: [], b: 'zz' }, { encodeDotInKeys: 0 }); },
|
|
184
|
+
TypeError
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
st['throws'](
|
|
188
|
+
function () { qs.stringify({ a: [], b: 'zz' }, { encodeDotInKeys: NaN }); },
|
|
189
|
+
TypeError
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
st['throws'](
|
|
193
|
+
function () { qs.stringify({ a: [], b: 'zz' }, { encodeDotInKeys: null }); },
|
|
194
|
+
TypeError
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
st.end();
|
|
198
|
+
});
|
|
199
|
+
|
|
67
200
|
t.test('adds query prefix', function (st) {
|
|
68
201
|
st.equal(qs.stringify({ a: 'b' }, { addQueryPrefix: true }), '?a=b');
|
|
69
202
|
st.end();
|
|
@@ -87,7 +220,7 @@ test('stringify()', function (t) {
|
|
|
87
220
|
st.end();
|
|
88
221
|
});
|
|
89
222
|
|
|
90
|
-
t.test('stringifies a nested object with dots notation', function (st) {
|
|
223
|
+
t.test('`allowDots` option: stringifies a nested object with dots notation', function (st) {
|
|
91
224
|
st.equal(qs.stringify({ a: { b: 'c' } }, { allowDots: true }), 'a.b=c');
|
|
92
225
|
st.equal(qs.stringify({ a: { b: { c: { d: 'e' } } } }, { allowDots: true }), 'a.b.c.d=e');
|
|
93
226
|
st.end();
|
|
@@ -109,6 +242,11 @@ test('stringify()', function (t) {
|
|
|
109
242
|
'a=b%2Cc%2Cd',
|
|
110
243
|
'comma => comma'
|
|
111
244
|
);
|
|
245
|
+
st.equal(
|
|
246
|
+
qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'comma', commaRoundTrip: true }),
|
|
247
|
+
'a=b%2Cc%2Cd',
|
|
248
|
+
'comma round trip => comma'
|
|
249
|
+
);
|
|
112
250
|
st.equal(
|
|
113
251
|
qs.stringify({ a: ['b', 'c', 'd'] }),
|
|
114
252
|
'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d',
|
|
@@ -117,18 +255,63 @@ test('stringify()', function (t) {
|
|
|
117
255
|
st.end();
|
|
118
256
|
});
|
|
119
257
|
|
|
120
|
-
t.test('
|
|
121
|
-
st.equal(
|
|
122
|
-
|
|
123
|
-
|
|
258
|
+
t.test('`skipNulls` option', function (st) {
|
|
259
|
+
st.equal(
|
|
260
|
+
qs.stringify({ a: 'b', c: null }, { skipNulls: true }),
|
|
261
|
+
'a=b',
|
|
262
|
+
'omits nulls when asked'
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
st.equal(
|
|
266
|
+
qs.stringify({ a: { b: 'c', d: null } }, { skipNulls: true }),
|
|
267
|
+
'a%5Bb%5D=c',
|
|
268
|
+
'omits nested nulls when asked'
|
|
269
|
+
);
|
|
124
270
|
|
|
125
|
-
t.test('omits nested nulls when asked', function (st) {
|
|
126
|
-
st.equal(qs.stringify({ a: { b: 'c', d: null } }, { skipNulls: true }), 'a%5Bb%5D=c');
|
|
127
271
|
st.end();
|
|
128
272
|
});
|
|
129
273
|
|
|
130
274
|
t.test('omits array indices when asked', function (st) {
|
|
131
275
|
st.equal(qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false }), 'a=b&a=c&a=d');
|
|
276
|
+
|
|
277
|
+
st.end();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
t.test('omits object key/value pair when value is empty array', function (st) {
|
|
281
|
+
st.equal(qs.stringify({ a: [], b: 'zz' }), 'b=zz');
|
|
282
|
+
|
|
283
|
+
st.end();
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
t.test('should not omit object key/value pair when value is empty array and when asked', function (st) {
|
|
287
|
+
st.equal(qs.stringify({ a: [], b: 'zz' }), 'b=zz');
|
|
288
|
+
st.equal(qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: false }), 'b=zz');
|
|
289
|
+
st.equal(qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: true }), 'a[]&b=zz');
|
|
290
|
+
|
|
291
|
+
st.end();
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
t.test('should throw when allowEmptyArrays is not of type boolean', function (st) {
|
|
295
|
+
st['throws'](
|
|
296
|
+
function () { qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: 'foobar' }); },
|
|
297
|
+
TypeError
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
st['throws'](
|
|
301
|
+
function () { qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: 0 }); },
|
|
302
|
+
TypeError
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
st['throws'](
|
|
306
|
+
function () { qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: NaN }); },
|
|
307
|
+
TypeError
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
st['throws'](
|
|
311
|
+
function () { qs.stringify({ a: [], b: 'zz' }, { allowEmptyArrays: null }); },
|
|
312
|
+
TypeError
|
|
313
|
+
);
|
|
314
|
+
|
|
132
315
|
st.end();
|
|
133
316
|
});
|
|
134
317
|
|
|
@@ -156,6 +339,7 @@ test('stringify()', function (t) {
|
|
|
156
339
|
s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c&a[1]=d');
|
|
157
340
|
s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c&a[]=d');
|
|
158
341
|
s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c,d');
|
|
342
|
+
s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }), 'a=c,d');
|
|
159
343
|
s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true }), 'a[0]=c&a[1]=d');
|
|
160
344
|
|
|
161
345
|
s2t.end();
|
|
@@ -165,6 +349,9 @@ test('stringify()', function (t) {
|
|
|
165
349
|
s2t.equal(qs.stringify({ a: ['c,d', 'e'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c%2Cd,e');
|
|
166
350
|
s2t.equal(qs.stringify({ a: ['c,d', 'e'] }, { arrayFormat: 'comma' }), 'a=c%2Cd%2Ce');
|
|
167
351
|
|
|
352
|
+
s2t.equal(qs.stringify({ a: ['c,d', 'e'] }, { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }), 'a=c%2Cd,e');
|
|
353
|
+
s2t.equal(qs.stringify({ a: ['c,d', 'e'] }, { arrayFormat: 'comma', commaRoundTrip: true }), 'a=c%2Cd%2Ce');
|
|
354
|
+
|
|
168
355
|
s2t.end();
|
|
169
356
|
});
|
|
170
357
|
|
|
@@ -255,36 +442,44 @@ test('stringify()', function (t) {
|
|
|
255
442
|
|
|
256
443
|
t.test('stringifies an object inside an array', function (st) {
|
|
257
444
|
st.equal(
|
|
258
|
-
qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'indices' }),
|
|
259
|
-
'a
|
|
260
|
-
'indices =>
|
|
445
|
+
qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'indices', encodeValuesOnly: true }),
|
|
446
|
+
'a[0][b]=c',
|
|
447
|
+
'indices => indices'
|
|
261
448
|
);
|
|
262
449
|
st.equal(
|
|
263
|
-
qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: '
|
|
264
|
-
'a
|
|
450
|
+
qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'repeat', encodeValuesOnly: true }),
|
|
451
|
+
'a[b]=c',
|
|
452
|
+
'repeat => repeat'
|
|
453
|
+
);
|
|
454
|
+
st.equal(
|
|
455
|
+
qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'brackets', encodeValuesOnly: true }),
|
|
456
|
+
'a[][b]=c',
|
|
265
457
|
'brackets => brackets'
|
|
266
458
|
);
|
|
267
459
|
st.equal(
|
|
268
|
-
qs.stringify({ a: [{ b: 'c' }] }),
|
|
269
|
-
'a
|
|
460
|
+
qs.stringify({ a: [{ b: 'c' }] }, { encodeValuesOnly: true }),
|
|
461
|
+
'a[0][b]=c',
|
|
270
462
|
'default => indices'
|
|
271
463
|
);
|
|
272
464
|
|
|
273
465
|
st.equal(
|
|
274
|
-
qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'indices' }),
|
|
275
|
-
'a
|
|
466
|
+
qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'indices', encodeValuesOnly: true }),
|
|
467
|
+
'a[0][b][c][0]=1',
|
|
276
468
|
'indices => indices'
|
|
277
469
|
);
|
|
278
|
-
|
|
279
470
|
st.equal(
|
|
280
|
-
qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: '
|
|
281
|
-
'a
|
|
471
|
+
qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'repeat', encodeValuesOnly: true }),
|
|
472
|
+
'a[b][c]=1',
|
|
473
|
+
'repeat => repeat'
|
|
474
|
+
);
|
|
475
|
+
st.equal(
|
|
476
|
+
qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'brackets', encodeValuesOnly: true }),
|
|
477
|
+
'a[][b][c][]=1',
|
|
282
478
|
'brackets => brackets'
|
|
283
479
|
);
|
|
284
|
-
|
|
285
480
|
st.equal(
|
|
286
|
-
qs.stringify({ a: [{ b: { c: [1] } }] }),
|
|
287
|
-
'a
|
|
481
|
+
qs.stringify({ a: [{ b: { c: [1] } }] }, { encodeValuesOnly: true }),
|
|
482
|
+
'a[0][b][c][0]=1',
|
|
288
483
|
'default => indices'
|
|
289
484
|
);
|
|
290
485
|
|
|
@@ -386,17 +581,17 @@ test('stringify()', function (t) {
|
|
|
386
581
|
st.end();
|
|
387
582
|
});
|
|
388
583
|
|
|
389
|
-
t.test('uses indices notation for arrays when
|
|
584
|
+
t.test('uses indices notation for arrays when arrayFormat=indices', function (st) {
|
|
390
585
|
st.equal(qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' }), 'a%5B0%5D=b&a%5B1%5D=c');
|
|
391
586
|
st.end();
|
|
392
587
|
});
|
|
393
588
|
|
|
394
|
-
t.test('uses repeat notation for arrays when
|
|
589
|
+
t.test('uses repeat notation for arrays when arrayFormat=repeat', function (st) {
|
|
395
590
|
st.equal(qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' }), 'a=b&a=c');
|
|
396
591
|
st.end();
|
|
397
592
|
});
|
|
398
593
|
|
|
399
|
-
t.test('uses brackets notation for arrays when
|
|
594
|
+
t.test('uses brackets notation for arrays when arrayFormat=brackets', function (st) {
|
|
400
595
|
st.equal(qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' }), 'a%5B%5D=b&a%5B%5D=c');
|
|
401
596
|
st.end();
|
|
402
597
|
});
|
|
@@ -493,10 +688,11 @@ test('stringify()', function (t) {
|
|
|
493
688
|
});
|
|
494
689
|
|
|
495
690
|
t.test('skips properties that are part of the object prototype', function (st) {
|
|
496
|
-
Object.prototype
|
|
691
|
+
st.intercept(Object.prototype, 'crash', { value: 'test' });
|
|
692
|
+
|
|
497
693
|
st.equal(qs.stringify({ a: 'b' }), 'a=b');
|
|
498
694
|
st.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c');
|
|
499
|
-
|
|
695
|
+
|
|
500
696
|
st.end();
|
|
501
697
|
});
|
|
502
698
|
|
|
@@ -520,10 +716,12 @@ test('stringify()', function (t) {
|
|
|
520
716
|
});
|
|
521
717
|
|
|
522
718
|
t.test('does not blow up when Buffer global is missing', function (st) {
|
|
523
|
-
var
|
|
524
|
-
|
|
719
|
+
var restore = mockProperty(global, 'Buffer', { 'delete': true });
|
|
720
|
+
|
|
525
721
|
var result = qs.stringify({ a: 'b', c: 'd' });
|
|
526
|
-
|
|
722
|
+
|
|
723
|
+
restore();
|
|
724
|
+
|
|
527
725
|
st.equal(result, 'a=b&c=d');
|
|
528
726
|
st.end();
|
|
529
727
|
});
|
|
@@ -572,9 +770,17 @@ test('stringify()', function (t) {
|
|
|
572
770
|
};
|
|
573
771
|
|
|
574
772
|
st.equal(
|
|
575
|
-
qs.stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true }),
|
|
773
|
+
qs.stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true, arrayFormat: 'indices' }),
|
|
576
774
|
'filters[$and][0][function]=gte&filters[$and][0][arguments][0][function]=hour_of_day&filters[$and][0][arguments][1]=0&filters[$and][1][function]=lte&filters[$and][1][arguments][0][function]=hour_of_day&filters[$and][1][arguments][1]=23'
|
|
577
775
|
);
|
|
776
|
+
st.equal(
|
|
777
|
+
qs.stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true, arrayFormat: 'brackets' }),
|
|
778
|
+
'filters[$and][][function]=gte&filters[$and][][arguments][][function]=hour_of_day&filters[$and][][arguments][]=0&filters[$and][][function]=lte&filters[$and][][arguments][][function]=hour_of_day&filters[$and][][arguments][]=23'
|
|
779
|
+
);
|
|
780
|
+
st.equal(
|
|
781
|
+
qs.stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true, arrayFormat: 'repeat' }),
|
|
782
|
+
'filters[$and][function]=gte&filters[$and][arguments][function]=hour_of_day&filters[$and][arguments]=0&filters[$and][function]=lte&filters[$and][arguments][function]=hour_of_day&filters[$and][arguments]=23'
|
|
783
|
+
);
|
|
578
784
|
|
|
579
785
|
st.end();
|
|
580
786
|
});
|
|
@@ -687,13 +893,28 @@ test('stringify()', function (t) {
|
|
|
687
893
|
st.end();
|
|
688
894
|
});
|
|
689
895
|
|
|
896
|
+
t.test('receives the default encoder as a second argument', function (st) {
|
|
897
|
+
st.plan(8);
|
|
898
|
+
|
|
899
|
+
qs.stringify({ a: 1, b: new Date(), c: true, d: [1] }, {
|
|
900
|
+
encoder: function (str) {
|
|
901
|
+
st.match(typeof str, /^(?:string|number|boolean)$/);
|
|
902
|
+
return '';
|
|
903
|
+
}
|
|
904
|
+
});
|
|
905
|
+
|
|
906
|
+
st.end();
|
|
907
|
+
});
|
|
908
|
+
|
|
690
909
|
t.test('receives the default encoder as a second argument', function (st) {
|
|
691
910
|
st.plan(2);
|
|
911
|
+
|
|
692
912
|
qs.stringify({ a: 1 }, {
|
|
693
913
|
encoder: function (str, defaultEncoder) {
|
|
694
914
|
st.equal(defaultEncoder, utils.encode);
|
|
695
915
|
}
|
|
696
916
|
});
|
|
917
|
+
|
|
697
918
|
st.end();
|
|
698
919
|
});
|
|
699
920
|
|
|
@@ -821,16 +1042,53 @@ test('stringify()', function (t) {
|
|
|
821
1042
|
st.equal(
|
|
822
1043
|
qs.stringify(
|
|
823
1044
|
{ a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] },
|
|
824
|
-
{ encodeValuesOnly: true }
|
|
1045
|
+
{ encodeValuesOnly: true, arrayFormat: 'indices' }
|
|
1046
|
+
),
|
|
1047
|
+
'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h',
|
|
1048
|
+
'encodeValuesOnly + indices'
|
|
1049
|
+
);
|
|
1050
|
+
st.equal(
|
|
1051
|
+
qs.stringify(
|
|
1052
|
+
{ a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] },
|
|
1053
|
+
{ encodeValuesOnly: true, arrayFormat: 'brackets' }
|
|
1054
|
+
),
|
|
1055
|
+
'a=b&c[]=d&c[]=e%3Df&f[][]=g&f[][]=h',
|
|
1056
|
+
'encodeValuesOnly + brackets'
|
|
1057
|
+
);
|
|
1058
|
+
st.equal(
|
|
1059
|
+
qs.stringify(
|
|
1060
|
+
{ a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] },
|
|
1061
|
+
{ encodeValuesOnly: true, arrayFormat: 'repeat' }
|
|
825
1062
|
),
|
|
826
|
-
'a=b&c
|
|
1063
|
+
'a=b&c=d&c=e%3Df&f=g&f=h',
|
|
1064
|
+
'encodeValuesOnly + repeat'
|
|
1065
|
+
);
|
|
1066
|
+
|
|
1067
|
+
st.equal(
|
|
1068
|
+
qs.stringify(
|
|
1069
|
+
{ a: 'b', c: ['d', 'e'], f: [['g'], ['h']] },
|
|
1070
|
+
{ arrayFormat: 'indices' }
|
|
1071
|
+
),
|
|
1072
|
+
'a=b&c%5B0%5D=d&c%5B1%5D=e&f%5B0%5D%5B0%5D=g&f%5B1%5D%5B0%5D=h',
|
|
1073
|
+
'no encodeValuesOnly + indices'
|
|
827
1074
|
);
|
|
828
1075
|
st.equal(
|
|
829
1076
|
qs.stringify(
|
|
830
|
-
{ a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }
|
|
1077
|
+
{ a: 'b', c: ['d', 'e'], f: [['g'], ['h']] },
|
|
1078
|
+
{ arrayFormat: 'brackets' }
|
|
831
1079
|
),
|
|
832
|
-
'a=b&c%
|
|
1080
|
+
'a=b&c%5B%5D=d&c%5B%5D=e&f%5B%5D%5B%5D=g&f%5B%5D%5B%5D=h',
|
|
1081
|
+
'no encodeValuesOnly + brackets'
|
|
833
1082
|
);
|
|
1083
|
+
st.equal(
|
|
1084
|
+
qs.stringify(
|
|
1085
|
+
{ a: 'b', c: ['d', 'e'], f: [['g'], ['h']] },
|
|
1086
|
+
{ arrayFormat: 'repeat' }
|
|
1087
|
+
),
|
|
1088
|
+
'a=b&c=d&c=e&f=g&f=h',
|
|
1089
|
+
'no encodeValuesOnly + repeat'
|
|
1090
|
+
);
|
|
1091
|
+
|
|
834
1092
|
st.end();
|
|
835
1093
|
});
|
|
836
1094
|
|
|
@@ -867,13 +1125,19 @@ test('stringify()', function (t) {
|
|
|
867
1125
|
st.end();
|
|
868
1126
|
});
|
|
869
1127
|
|
|
870
|
-
t.test('
|
|
871
|
-
st.equal(
|
|
872
|
-
|
|
873
|
-
|
|
1128
|
+
t.test('`charsetSentinel` option', function (st) {
|
|
1129
|
+
st.equal(
|
|
1130
|
+
qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'utf-8' }),
|
|
1131
|
+
'utf8=%E2%9C%93&a=%C3%A6',
|
|
1132
|
+
'adds the right sentinel when instructed to and the charset is utf-8'
|
|
1133
|
+
);
|
|
1134
|
+
|
|
1135
|
+
st.equal(
|
|
1136
|
+
qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'iso-8859-1' }),
|
|
1137
|
+
'utf8=%26%2310003%3B&a=%E6',
|
|
1138
|
+
'adds the right sentinel when instructed to and the charset is iso-8859-1'
|
|
1139
|
+
);
|
|
874
1140
|
|
|
875
|
-
t.test('adds the right sentinel when instructed to and the charset is iso-8859-1', function (st) {
|
|
876
|
-
st.equal(qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'iso-8859-1' }), 'utf8=%26%2310003%3B&a=%E6');
|
|
877
1141
|
st.end();
|
|
878
1142
|
});
|
|
879
1143
|
|
|
@@ -924,13 +1188,15 @@ test('stringify()', function (t) {
|
|
|
924
1188
|
var withArray = { a: { b: [{ c: 'd', e: 'f' }] } };
|
|
925
1189
|
|
|
926
1190
|
st.equal(qs.stringify(obj, { encode: false }), 'a[b][c]=d&a[b][e]=f', 'no array, no arrayFormat');
|
|
927
|
-
st.equal(qs.stringify(obj, { encode: false, arrayFormat: '
|
|
1191
|
+
st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'brackets' }), 'a[b][c]=d&a[b][e]=f', 'no array, bracket');
|
|
928
1192
|
st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'indices' }), 'a[b][c]=d&a[b][e]=f', 'no array, indices');
|
|
1193
|
+
st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'repeat' }), 'a[b][c]=d&a[b][e]=f', 'no array, repeat');
|
|
929
1194
|
st.equal(qs.stringify(obj, { encode: false, arrayFormat: 'comma' }), 'a[b][c]=d&a[b][e]=f', 'no array, comma');
|
|
930
1195
|
|
|
931
1196
|
st.equal(qs.stringify(withArray, { encode: false }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, no arrayFormat');
|
|
932
|
-
st.equal(qs.stringify(withArray, { encode: false, arrayFormat: '
|
|
1197
|
+
st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'brackets' }), 'a[b][][c]=d&a[b][][e]=f', 'array, bracket');
|
|
933
1198
|
st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'indices' }), 'a[b][0][c]=d&a[b][0][e]=f', 'array, indices');
|
|
1199
|
+
st.equal(qs.stringify(withArray, { encode: false, arrayFormat: 'repeat' }), 'a[b][c]=d&a[b][e]=f', 'array, repeat');
|
|
934
1200
|
st.equal(
|
|
935
1201
|
qs.stringify(withArray, { encode: false, arrayFormat: 'comma' }),
|
|
936
1202
|
'???',
|
|
@@ -943,10 +1209,42 @@ test('stringify()', function (t) {
|
|
|
943
1209
|
|
|
944
1210
|
t.test('stringifies sparse arrays', function (st) {
|
|
945
1211
|
/* eslint no-sparse-arrays: 0 */
|
|
946
|
-
st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true }), 'a[1]=2&a[4]=1');
|
|
947
|
-
st.equal(qs.stringify({ a: [,
|
|
948
|
-
st.equal(qs.stringify({ a: [,
|
|
949
|
-
|
|
1212
|
+
st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[1]=2&a[4]=1');
|
|
1213
|
+
st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=2&a[]=1');
|
|
1214
|
+
st.equal(qs.stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a=2&a=1');
|
|
1215
|
+
|
|
1216
|
+
st.equal(qs.stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[1][b][2][c]=1');
|
|
1217
|
+
st.equal(qs.stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[][b][][c]=1');
|
|
1218
|
+
st.equal(qs.stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a[b][c]=1');
|
|
1219
|
+
|
|
1220
|
+
st.equal(qs.stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[1][2][3][c]=1');
|
|
1221
|
+
st.equal(qs.stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[][][][c]=1');
|
|
1222
|
+
st.equal(qs.stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a[c]=1');
|
|
1223
|
+
|
|
1224
|
+
st.equal(qs.stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[1][2][3][c][1]=1');
|
|
1225
|
+
st.equal(qs.stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[][][][c][]=1');
|
|
1226
|
+
st.equal(qs.stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), 'a[c]=1');
|
|
1227
|
+
|
|
1228
|
+
st.end();
|
|
1229
|
+
});
|
|
1230
|
+
|
|
1231
|
+
t.test('encodes a very long string', function (st) {
|
|
1232
|
+
var chars = [];
|
|
1233
|
+
var expected = [];
|
|
1234
|
+
for (var i = 0; i < 5e3; i++) {
|
|
1235
|
+
chars.push(' ' + i);
|
|
1236
|
+
|
|
1237
|
+
expected.push('%20' + i);
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
var obj = {
|
|
1241
|
+
foo: chars.join('')
|
|
1242
|
+
};
|
|
1243
|
+
|
|
1244
|
+
st.equal(
|
|
1245
|
+
qs.stringify(obj, { arrayFormat: 'bracket', charset: 'utf-8' }),
|
|
1246
|
+
'foo=' + expected.join('')
|
|
1247
|
+
);
|
|
950
1248
|
|
|
951
1249
|
st.end();
|
|
952
1250
|
});
|
|
@@ -957,7 +1255,21 @@ test('stringify()', function (t) {
|
|
|
957
1255
|
test('stringifies empty keys', function (t) {
|
|
958
1256
|
emptyTestCases.forEach(function (testCase) {
|
|
959
1257
|
t.test('stringifies an object with empty string key with ' + testCase.input, function (st) {
|
|
960
|
-
st.deepEqual(
|
|
1258
|
+
st.deepEqual(
|
|
1259
|
+
qs.stringify(testCase.withEmptyKeys, { encode: false, arrayFormat: 'indices' }),
|
|
1260
|
+
testCase.stringifyOutput.indices,
|
|
1261
|
+
'test case: ' + testCase.input + ', indices'
|
|
1262
|
+
);
|
|
1263
|
+
st.deepEqual(
|
|
1264
|
+
qs.stringify(testCase.withEmptyKeys, { encode: false, arrayFormat: 'brackets' }),
|
|
1265
|
+
testCase.stringifyOutput.brackets,
|
|
1266
|
+
'test case: ' + testCase.input + ', brackets'
|
|
1267
|
+
);
|
|
1268
|
+
st.deepEqual(
|
|
1269
|
+
qs.stringify(testCase.withEmptyKeys, { encode: false, arrayFormat: 'repeat' }),
|
|
1270
|
+
testCase.stringifyOutput.repeat,
|
|
1271
|
+
'test case: ' + testCase.input + ', repeat'
|
|
1272
|
+
);
|
|
961
1273
|
|
|
962
1274
|
st.end();
|
|
963
1275
|
});
|
|
@@ -966,6 +1278,8 @@ test('stringifies empty keys', function (t) {
|
|
|
966
1278
|
t.test('edge case with object/arrays', function (st) {
|
|
967
1279
|
st.deepEqual(qs.stringify({ '': { '': [2, 3] } }, { encode: false }), '[][0]=2&[][1]=3');
|
|
968
1280
|
st.deepEqual(qs.stringify({ '': { '': [2, 3], a: 2 } }, { encode: false }), '[][0]=2&[][1]=3&[a]=2');
|
|
1281
|
+
st.deepEqual(qs.stringify({ '': { '': [2, 3] } }, { encode: false, arrayFormat: 'indices' }), '[][0]=2&[][1]=3');
|
|
1282
|
+
st.deepEqual(qs.stringify({ '': { '': [2, 3], a: 2 } }, { encode: false, arrayFormat: 'indices' }), '[][0]=2&[][1]=3&[a]=2');
|
|
969
1283
|
|
|
970
1284
|
st.end();
|
|
971
1285
|
});
|