qs 6.2.3 → 6.3.2

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/test/stringify.js CHANGED
@@ -30,7 +30,21 @@ test('stringify()', function (t) {
30
30
  });
31
31
 
32
32
  t.test('stringifies an array value', function (st) {
33
- st.equal(qs.stringify({ a: ['b', 'c', 'd'] }), 'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d');
33
+ st.equal(
34
+ qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'indices' }),
35
+ 'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d',
36
+ 'indices => indices'
37
+ );
38
+ st.equal(
39
+ qs.stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'brackets' }),
40
+ 'a%5B%5D=b&a%5B%5D=c&a%5B%5D=d',
41
+ 'brackets => brackets'
42
+ );
43
+ st.equal(
44
+ qs.stringify({ a: ['b', 'c', 'd'] }),
45
+ 'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d',
46
+ 'default => indices'
47
+ );
34
48
  st.end();
35
49
  });
36
50
 
@@ -39,7 +53,6 @@ test('stringify()', function (t) {
39
53
  st.end();
40
54
  });
41
55
 
42
-
43
56
  t.test('omits nested nulls when asked', function (st) {
44
57
  st.equal(qs.stringify({ a: { b: 'c', d: null } }, { skipNulls: true }), 'a%5Bb%5D=c');
45
58
  st.end();
@@ -51,29 +64,149 @@ test('stringify()', function (t) {
51
64
  });
52
65
 
53
66
  t.test('stringifies a nested array value', function (st) {
67
+ st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'indices' }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
68
+ st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { arrayFormat: 'brackets' }), 'a%5Bb%5D%5B%5D=c&a%5Bb%5D%5B%5D=d');
54
69
  st.equal(qs.stringify({ a: { b: ['c', 'd'] } }), 'a%5Bb%5D%5B0%5D=c&a%5Bb%5D%5B1%5D=d');
55
70
  st.end();
56
71
  });
57
72
 
58
73
  t.test('stringifies a nested array value with dots notation', function (st) {
59
- st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { allowDots: true, encode: false }), 'a.b[0]=c&a.b[1]=d');
74
+ st.equal(
75
+ qs.stringify(
76
+ { a: { b: ['c', 'd'] } },
77
+ { allowDots: true, encode: false, arrayFormat: 'indices' }
78
+ ),
79
+ 'a.b[0]=c&a.b[1]=d',
80
+ 'indices: stringifies with dots + indices'
81
+ );
82
+ st.equal(
83
+ qs.stringify(
84
+ { a: { b: ['c', 'd'] } },
85
+ { allowDots: true, encode: false, arrayFormat: 'brackets' }
86
+ ),
87
+ 'a.b[]=c&a.b[]=d',
88
+ 'brackets: stringifies with dots + brackets'
89
+ );
90
+ st.equal(
91
+ qs.stringify(
92
+ { a: { b: ['c', 'd'] } },
93
+ { allowDots: true, encode: false }
94
+ ),
95
+ 'a.b[0]=c&a.b[1]=d',
96
+ 'default: stringifies with dots + indices'
97
+ );
60
98
  st.end();
61
99
  });
62
100
 
63
101
  t.test('stringifies an object inside an array', function (st) {
64
- st.equal(qs.stringify({ a: [{ b: 'c' }] }), 'a%5B0%5D%5Bb%5D=c');
65
- st.equal(qs.stringify({ a: [{ b: { c: [1] } }] }), 'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1');
102
+ st.equal(
103
+ qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'indices' }),
104
+ 'a%5B0%5D%5Bb%5D=c',
105
+ 'indices => brackets'
106
+ );
107
+ st.equal(
108
+ qs.stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'brackets' }),
109
+ 'a%5B%5D%5Bb%5D=c',
110
+ 'brackets => brackets'
111
+ );
112
+ st.equal(
113
+ qs.stringify({ a: [{ b: 'c' }] }),
114
+ 'a%5B0%5D%5Bb%5D=c',
115
+ 'default => indices'
116
+ );
117
+
118
+ st.equal(
119
+ qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'indices' }),
120
+ 'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1',
121
+ 'indices => indices'
122
+ );
123
+
124
+ st.equal(
125
+ qs.stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'brackets' }),
126
+ 'a%5B%5D%5Bb%5D%5Bc%5D%5B%5D=1',
127
+ 'brackets => brackets'
128
+ );
129
+
130
+ st.equal(
131
+ qs.stringify({ a: [{ b: { c: [1] } }] }),
132
+ 'a%5B0%5D%5Bb%5D%5Bc%5D%5B0%5D=1',
133
+ 'default => indices'
134
+ );
135
+
66
136
  st.end();
67
137
  });
68
138
 
69
139
  t.test('stringifies an array with mixed objects and primitives', function (st) {
70
- st.equal(qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false }), 'a[0][b]=1&a[1]=2&a[2]=3');
140
+ st.equal(
141
+ qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false, arrayFormat: 'indices' }),
142
+ 'a[0][b]=1&a[1]=2&a[2]=3',
143
+ 'indices => indices'
144
+ );
145
+ st.equal(
146
+ qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false, arrayFormat: 'brackets' }),
147
+ 'a[][b]=1&a[]=2&a[]=3',
148
+ 'brackets => brackets'
149
+ );
150
+ st.equal(
151
+ qs.stringify({ a: [{ b: 1 }, 2, 3] }, { encode: false }),
152
+ 'a[0][b]=1&a[1]=2&a[2]=3',
153
+ 'default => indices'
154
+ );
155
+
71
156
  st.end();
72
157
  });
73
158
 
74
159
  t.test('stringifies an object inside an array with dots notation', function (st) {
75
- st.equal(qs.stringify({ a: [{ b: 'c' }] }, { allowDots: true, encode: false }), 'a[0].b=c');
76
- st.equal(qs.stringify({ a: [{ b: { c: [1] } }] }, { allowDots: true, encode: false }), 'a[0].b.c[0]=1');
160
+ st.equal(
161
+ qs.stringify(
162
+ { a: [{ b: 'c' }] },
163
+ { allowDots: true, encode: false, arrayFormat: 'indices' }
164
+ ),
165
+ 'a[0].b=c',
166
+ 'indices => indices'
167
+ );
168
+ st.equal(
169
+ qs.stringify(
170
+ { a: [{ b: 'c' }] },
171
+ { allowDots: true, encode: false, arrayFormat: 'brackets' }
172
+ ),
173
+ 'a[].b=c',
174
+ 'brackets => brackets'
175
+ );
176
+ st.equal(
177
+ qs.stringify(
178
+ { a: [{ b: 'c' }] },
179
+ { allowDots: true, encode: false }
180
+ ),
181
+ 'a[0].b=c',
182
+ 'default => indices'
183
+ );
184
+
185
+ st.equal(
186
+ qs.stringify(
187
+ { a: [{ b: { c: [1] } }] },
188
+ { allowDots: true, encode: false, arrayFormat: 'indices' }
189
+ ),
190
+ 'a[0].b.c[0]=1',
191
+ 'indices => indices'
192
+ );
193
+ st.equal(
194
+ qs.stringify(
195
+ { a: [{ b: { c: [1] } }] },
196
+ { allowDots: true, encode: false, arrayFormat: 'brackets' }
197
+ ),
198
+ 'a[].b.c[]=1',
199
+ 'brackets => brackets'
200
+ );
201
+ st.equal(
202
+ qs.stringify(
203
+ { a: [{ b: { c: [1] } }] },
204
+ { allowDots: true, encode: false }
205
+ ),
206
+ 'a[0].b.c[0]=1',
207
+ 'default => indices'
208
+ );
209
+
77
210
  st.end();
78
211
  });
79
212
 
@@ -126,7 +259,7 @@ test('stringify()', function (t) {
126
259
  st.end();
127
260
  });
128
261
 
129
- t.test('stringifies an empty object', function (st) {
262
+ t.test('stringifies a null object', { skip: !Object.create }, function (st) {
130
263
  var obj = Object.create(null);
131
264
  obj.a = 'b';
132
265
  st.equal(qs.stringify(obj), 'a=b');
@@ -141,10 +274,8 @@ test('stringify()', function (t) {
141
274
  st.end();
142
275
  });
143
276
 
144
- t.test('stringifies an object with an empty object as a child', function (st) {
145
- var obj = {
146
- a: Object.create(null)
147
- };
277
+ t.test('stringifies an object with a null object as a child', { skip: !Object.create }, function (st) {
278
+ var obj = { a: Object.create(null) };
148
279
 
149
280
  obj.a.b = 'c';
150
281
  st.equal(qs.stringify(obj), 'a%5Bb%5D=c');
@@ -216,7 +347,32 @@ test('stringify()', function (t) {
216
347
  t.test('selects properties when filter=array', function (st) {
217
348
  st.equal(qs.stringify({ a: 'b' }, { filter: ['a'] }), 'a=b');
218
349
  st.equal(qs.stringify({ a: 1 }, { filter: [] }), '');
219
- st.equal(qs.stringify({ a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, { filter: ['a', 'b', 0, 2] }), 'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3');
350
+
351
+ st.equal(
352
+ qs.stringify(
353
+ { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' },
354
+ { filter: ['a', 'b', 0, 2], arrayFormat: 'indices' }
355
+ ),
356
+ 'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3',
357
+ 'indices => indices'
358
+ );
359
+ st.equal(
360
+ qs.stringify(
361
+ { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' },
362
+ { filter: ['a', 'b', 0, 2], arrayFormat: 'brackets' }
363
+ ),
364
+ 'a%5Bb%5D%5B%5D=1&a%5Bb%5D%5B%5D=3',
365
+ 'brackets => brackets'
366
+ );
367
+ st.equal(
368
+ qs.stringify(
369
+ { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' },
370
+ { filter: ['a', 'b', 0, 2] }
371
+ ),
372
+ 'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3',
373
+ 'default => indices'
374
+ );
375
+
220
376
  st.end();
221
377
  });
222
378
 
@@ -224,12 +380,12 @@ test('stringify()', function (t) {
224
380
  var calls = 0;
225
381
  var obj = { a: 'b', c: 'd', e: { f: new Date(1257894000000) } };
226
382
  var filterFunc = function (prefix, value) {
227
- calls++;
383
+ calls += 1;
228
384
  if (calls === 1) {
229
385
  st.equal(prefix, '', 'prefix is empty');
230
386
  st.equal(value, obj);
231
387
  } else if (prefix === 'c') {
232
- return;
388
+ return void 0;
233
389
  } else if (value instanceof Date) {
234
390
  st.equal(prefix, 'e[f]');
235
391
  return value.getTime();
@@ -250,28 +406,44 @@ test('stringify()', function (t) {
250
406
  });
251
407
 
252
408
  t.test('can sort the keys', function (st) {
253
- var sort = function (a, b) { return a.localeCompare(b); };
409
+ var sort = function (a, b) {
410
+ return a.localeCompare(b);
411
+ };
254
412
  st.equal(qs.stringify({ a: 'c', z: 'y', b: 'f' }, { sort: sort }), 'a=c&b=f&z=y');
255
413
  st.equal(qs.stringify({ a: 'c', z: { j: 'a', i: 'b' }, b: 'f' }, { sort: sort }), 'a=c&b=f&z%5Bi%5D=b&z%5Bj%5D=a');
256
414
  st.end();
257
415
  });
258
416
 
259
417
  t.test('can sort the keys at depth 3 or more too', function (st) {
260
- var sort = function (a, b) { return a.localeCompare(b); };
261
- st.equal(qs.stringify({ a: 'a', z: { zj: {zjb: 'zjb', zja: 'zja'}, zi: {zib: 'zib', zia: 'zia'} }, b: 'b' }, { sort: sort, encode: false }), 'a=a&b=b&z[zi][zia]=zia&z[zi][zib]=zib&z[zj][zja]=zja&z[zj][zjb]=zjb');
262
- st.equal(qs.stringify({ a: 'a', z: { zj: {zjb: 'zjb', zja: 'zja'}, zi: {zib: 'zib', zia: 'zia'} }, b: 'b' }, { sort: null, encode: false }), 'a=a&z[zj][zjb]=zjb&z[zj][zja]=zja&z[zi][zib]=zib&z[zi][zia]=zia&b=b');
418
+ var sort = function (a, b) {
419
+ return a.localeCompare(b);
420
+ };
421
+ st.equal(
422
+ qs.stringify(
423
+ { a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' },
424
+ { sort: sort, encode: false }
425
+ ),
426
+ 'a=a&b=b&z[zi][zia]=zia&z[zi][zib]=zib&z[zj][zja]=zja&z[zj][zjb]=zjb'
427
+ );
428
+ st.equal(
429
+ qs.stringify(
430
+ { a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' },
431
+ { sort: null, encode: false }
432
+ ),
433
+ 'a=a&z[zj][zjb]=zjb&z[zj][zja]=zja&z[zi][zib]=zib&z[zi][zia]=zia&b=b'
434
+ );
263
435
  st.end();
264
436
  });
265
437
 
266
438
  t.test('can stringify with custom encoding', function (st) {
267
- st.equal(qs.stringify({ 県: '大阪府', '': ''}, {
439
+ st.equal(qs.stringify({ 県: '大阪府', '': '' }, {
268
440
  encoder: function (str) {
269
441
  if (str.length === 0) {
270
442
  return '';
271
443
  }
272
444
  var buf = iconv.encode(str, 'shiftjis');
273
445
  var result = [];
274
- for (var i=0; i < buf.length; ++i) {
446
+ for (var i = 0; i < buf.length; ++i) {
275
447
  result.push(buf.readUInt8(i).toString(16));
276
448
  }
277
449
  return '%' + result.join('%');
@@ -282,16 +454,12 @@ test('stringify()', function (t) {
282
454
 
283
455
  t.test('throws error with wrong encoder', function (st) {
284
456
  st.throws(function () {
285
- qs.stringify({}, {
286
- encoder: 'string'
287
- });
457
+ qs.stringify({}, { encoder: 'string' });
288
458
  }, new TypeError('Encoder has to be a function.'));
289
459
  st.end();
290
460
  });
291
461
 
292
- t.test('can use custom encoder for a buffer object', {
293
- skip: typeof Buffer === 'undefined'
294
- }, function (st) {
462
+ t.test('can use custom encoder for a buffer object', { skip: typeof Buffer === 'undefined' }, function (st) {
295
463
  st.equal(qs.stringify({ a: new Buffer([1]) }, {
296
464
  encoder: function (buffer) {
297
465
  if (typeof buffer === 'string') {
@@ -302,4 +470,69 @@ test('stringify()', function (t) {
302
470
  }), 'a=b');
303
471
  st.end();
304
472
  });
473
+
474
+ t.test('serializeDate option', function (st) {
475
+ var date = new Date();
476
+ st.equal(
477
+ qs.stringify({ a: date }),
478
+ 'a=' + date.toISOString().replace(/:/g, '%3A'),
479
+ 'default is toISOString'
480
+ );
481
+
482
+ var mutatedDate = new Date();
483
+ mutatedDate.toISOString = function () {
484
+ throw new SyntaxError();
485
+ };
486
+ st.throws(function () {
487
+ mutatedDate.toISOString();
488
+ }, SyntaxError);
489
+ st.equal(
490
+ qs.stringify({ a: mutatedDate }),
491
+ 'a=' + Date.prototype.toISOString.call(mutatedDate).replace(/:/g, '%3A'),
492
+ 'toISOString works even when method is not locally present'
493
+ );
494
+
495
+ var specificDate = new Date(6);
496
+ st.equal(
497
+ qs.stringify(
498
+ { a: specificDate },
499
+ { serializeDate: function (d) { return d.getTime() * 7; } }
500
+ ),
501
+ 'a=42',
502
+ 'custom serializeDate function called'
503
+ );
504
+
505
+ st.end();
506
+ });
507
+
508
+ t.test('RFC 1738 spaces serialization', function (st) {
509
+ st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC1738 }), 'a=b+c');
510
+ st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC1738 }), 'a+b=c+d');
511
+ st.end();
512
+ });
513
+
514
+ t.test('RFC 3986 spaces serialization', function (st) {
515
+ st.equal(qs.stringify({ a: 'b c' }, { format: qs.formats.RFC3986 }), 'a=b%20c');
516
+ st.equal(qs.stringify({ 'a b': 'c d' }, { format: qs.formats.RFC3986 }), 'a%20b=c%20d');
517
+ st.end();
518
+ });
519
+
520
+ t.test('Backward compatibility to RFC 3986', function (st) {
521
+ st.equal(qs.stringify({ a: 'b c' }), 'a=b%20c');
522
+ st.end();
523
+ });
524
+
525
+ t.test('Edge cases and unknown formats', function (st) {
526
+ ['UFO1234', false, 1234, null, {}, []].forEach(
527
+ function (format) {
528
+ st.throws(
529
+ function () {
530
+ qs.stringify({ a: 'b c' }, { format: format });
531
+ },
532
+ new TypeError('Unknown format option provided.')
533
+ );
534
+ }
535
+ );
536
+ st.end();
537
+ });
305
538
  });
package/test/utils.js CHANGED
@@ -5,5 +5,18 @@ var utils = require('../lib/utils');
5
5
 
6
6
  test('merge()', function (t) {
7
7
  t.deepEqual(utils.merge({ a: 'b' }, { a: 'c' }), { a: ['b', 'c'] }, 'merges two objects with the same key');
8
+
9
+ var oneMerged = utils.merge({ foo: 'bar' }, { foo: { first: '123' } });
10
+ t.deepEqual(oneMerged, { foo: ['bar', { first: '123' }] }, 'merges a standalone and an object into an array');
11
+
12
+ var twoMerged = utils.merge({ foo: ['bar', { first: '123' }] }, { foo: { second: '456' } });
13
+ t.deepEqual(twoMerged, { foo: { 0: 'bar', 1: { first: '123' }, second: '456' } }, 'merges a standalone and two objects into an array');
14
+
15
+ var sandwiched = utils.merge({ foo: ['bar', { first: '123', second: '456' }] }, { foo: 'baz' });
16
+ t.deepEqual(sandwiched, { foo: ['bar', { first: '123', second: '456' }, 'baz'] }, 'merges an object sandwiched by two standalones into an array');
17
+
18
+ var nestedArrays = utils.merge({ foo: ['baz'] }, { foo: ['bar', 'xyzzy'] });
19
+ t.deepEqual(nestedArrays, { foo: ['baz', 'bar', 'xyzzy'] });
20
+
8
21
  t.end();
9
22
  });
package/CONTRIBUTING.md DELETED
@@ -1 +0,0 @@
1
- Please view our [hapijs contributing guide](https://github.com/hapijs/hapi/blob/master/CONTRIBUTING.md).