qs 6.0.0 → 6.0.4

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/parse.js CHANGED
@@ -1,480 +1,456 @@
1
1
  'use strict';
2
2
 
3
- /* eslint no-extend-native:0 */
4
- // Load modules
5
-
6
- const Code = require('code');
7
- const Lab = require('lab');
8
- const Qs = require('../');
9
-
10
-
11
- // Declare internals
12
-
13
- const internals = {};
14
-
15
-
16
- // Test shortcuts
17
-
18
- const lab = exports.lab = Lab.script();
19
- const expect = Code.expect;
20
- const describe = lab.experiment;
21
- const it = lab.test;
22
-
23
-
24
- describe('parse()', () => {
25
-
26
- it('parses a simple string', (done) => {
27
-
28
- expect(Qs.parse('0=foo')).to.deep.equal({ '0': 'foo' });
29
- expect(Qs.parse('foo=c++')).to.deep.equal({ foo: 'c ' });
30
- expect(Qs.parse('a[>=]=23')).to.deep.equal({ a: { '>=': '23' } });
31
- expect(Qs.parse('a[<=>]==23')).to.deep.equal({ a: { '<=>': '=23' } });
32
- expect(Qs.parse('a[==]=23')).to.deep.equal({ a: { '==': '23' } });
33
- expect(Qs.parse('foo', { strictNullHandling: true })).to.deep.equal({ foo: null });
34
- expect(Qs.parse('foo')).to.deep.equal({ foo: '' });
35
- expect(Qs.parse('foo=')).to.deep.equal({ foo: '' });
36
- expect(Qs.parse('foo=bar')).to.deep.equal({ foo: 'bar' });
37
- expect(Qs.parse(' foo = bar = baz ')).to.deep.equal({ ' foo ': ' bar = baz ' });
38
- expect(Qs.parse('foo=bar=baz')).to.deep.equal({ foo: 'bar=baz' });
39
- expect(Qs.parse('foo=bar&bar=baz')).to.deep.equal({ foo: 'bar', bar: 'baz' });
40
- expect(Qs.parse('foo2=bar2&baz2=')).to.deep.equal({ foo2: 'bar2', baz2: '' });
41
- expect(Qs.parse('foo=bar&baz', { strictNullHandling: true })).to.deep.equal({ foo: 'bar', baz: null });
42
- expect(Qs.parse('foo=bar&baz')).to.deep.equal({ foo: 'bar', baz: '' });
43
- expect(Qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World')).to.deep.equal({
3
+ var test = require('tape');
4
+ var qs = require('../');
5
+
6
+ test('parse()', function (t) {
7
+ t.test('parses a simple string', function (st) {
8
+ st.deepEqual(qs.parse('0=foo'), { '0': 'foo' });
9
+ st.deepEqual(qs.parse('foo=c++'), { foo: 'c ' });
10
+ st.deepEqual(qs.parse('a[>=]=23'), { a: { '>=': '23' } });
11
+ st.deepEqual(qs.parse('a[<=>]==23'), { a: { '<=>': '=23' } });
12
+ st.deepEqual(qs.parse('a[==]=23'), { a: { '==': '23' } });
13
+ st.deepEqual(qs.parse('foo', { strictNullHandling: true }), { foo: null });
14
+ st.deepEqual(qs.parse('foo'), { foo: '' });
15
+ st.deepEqual(qs.parse('foo='), { foo: '' });
16
+ st.deepEqual(qs.parse('foo=bar'), { foo: 'bar' });
17
+ st.deepEqual(qs.parse(' foo = bar = baz '), { ' foo ': ' bar = baz ' });
18
+ st.deepEqual(qs.parse('foo=bar=baz'), { foo: 'bar=baz' });
19
+ st.deepEqual(qs.parse('foo=bar&bar=baz'), { foo: 'bar', bar: 'baz' });
20
+ st.deepEqual(qs.parse('foo2=bar2&baz2='), { foo2: 'bar2', baz2: '' });
21
+ st.deepEqual(qs.parse('foo=bar&baz', { strictNullHandling: true }), { foo: 'bar', baz: null });
22
+ st.deepEqual(qs.parse('foo=bar&baz'), { foo: 'bar', baz: '' });
23
+ st.deepEqual(qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World'), {
44
24
  cht: 'p3',
45
25
  chd: 't:60,40',
46
26
  chs: '250x100',
47
27
  chl: 'Hello|World'
48
28
  });
49
- done();
29
+ st.end();
50
30
  });
51
31
 
52
- it('allows enabling dot notation', (done) => {
53
-
54
- expect(Qs.parse('a.b=c')).to.deep.equal({ 'a.b': 'c' });
55
- expect(Qs.parse('a.b=c', { allowDots: true })).to.deep.equal({ a: { b: 'c' } });
56
- done();
32
+ t.test('allows enabling dot notation', function (st) {
33
+ st.deepEqual(qs.parse('a.b=c'), { 'a.b': 'c' });
34
+ st.deepEqual(qs.parse('a.b=c', { allowDots: true }), { a: { b: 'c' } });
35
+ st.end();
57
36
  });
58
37
 
59
- it('parses a single nested string', (done) => {
38
+ t.deepEqual(qs.parse('a[b]=c'), { a: { b: 'c' } }, 'parses a single nested string');
39
+ t.deepEqual(qs.parse('a[b][c]=d'), { a: { b: { c: 'd' } } }, 'parses a double nested string');
40
+ t.deepEqual(
41
+ qs.parse('a[b][c][d][e][f][g][h]=i'),
42
+ { a: { b: { c: { d: { e: { f: { '[g][h]': 'i' } } } } } } },
43
+ 'defaults to a depth of 5'
44
+ );
60
45
 
61
- expect(Qs.parse('a[b]=c')).to.deep.equal({ a: { b: 'c' } });
62
- done();
46
+ t.test('only parses one level when depth = 1', function (st) {
47
+ st.deepEqual(qs.parse('a[b][c]=d', { depth: 1 }), { a: { b: { '[c]': 'd' } } });
48
+ st.deepEqual(qs.parse('a[b][c][d]=e', { depth: 1 }), { a: { b: { '[c][d]': 'e' } } });
49
+ st.end();
63
50
  });
64
51
 
65
- it('parses a double nested string', (done) => {
52
+ t.deepEqual(qs.parse('a=b&a=c'), { a: ['b', 'c'] }, 'parses a simple array');
66
53
 
67
- expect(Qs.parse('a[b][c]=d')).to.deep.equal({ a: { b: { c: 'd' } } });
68
- done();
54
+ t.test('parses an explicit array', function (st) {
55
+ st.deepEqual(qs.parse('a[]=b'), { a: ['b'] });
56
+ st.deepEqual(qs.parse('a[]=b&a[]=c'), { a: ['b', 'c'] });
57
+ st.deepEqual(qs.parse('a[]=b&a[]=c&a[]=d'), { a: ['b', 'c', 'd'] });
58
+ st.end();
69
59
  });
70
60
 
71
- it('defaults to a depth of 5', (done) => {
72
-
73
- expect(Qs.parse('a[b][c][d][e][f][g][h]=i')).to.deep.equal({ a: { b: { c: { d: { e: { f: { '[g][h]': 'i' } } } } } } });
74
- done();
61
+ t.test('parses a mix of simple and explicit arrays', function (st) {
62
+ st.deepEqual(qs.parse('a=b&a[]=c'), { a: ['b', 'c'] });
63
+ st.deepEqual(qs.parse('a[]=b&a=c'), { a: ['b', 'c'] });
64
+ st.deepEqual(qs.parse('a[0]=b&a=c'), { a: ['b', 'c'] });
65
+ st.deepEqual(qs.parse('a=b&a[0]=c'), { a: ['b', 'c'] });
66
+ st.deepEqual(qs.parse('a[1]=b&a=c'), { a: ['b', 'c'] });
67
+ st.deepEqual(qs.parse('a=b&a[1]=c'), { a: ['b', 'c'] });
68
+ st.end();
75
69
  });
76
70
 
77
- it('only parses one level when depth = 1', (done) => {
78
-
79
- expect(Qs.parse('a[b][c]=d', { depth: 1 })).to.deep.equal({ a: { b: { '[c]': 'd' } } });
80
- expect(Qs.parse('a[b][c][d]=e', { depth: 1 })).to.deep.equal({ a: { b: { '[c][d]': 'e' } } });
81
- done();
71
+ t.test('parses a nested array', function (st) {
72
+ st.deepEqual(qs.parse('a[b][]=c&a[b][]=d'), { a: { b: ['c', 'd'] } });
73
+ st.deepEqual(qs.parse('a[>=]=25'), { a: { '>=': '25' } });
74
+ st.end();
82
75
  });
83
76
 
84
- it('parses a simple array', (done) => {
85
-
86
- expect(Qs.parse('a=b&a=c')).to.deep.equal({ a: ['b', 'c'] });
87
- done();
77
+ t.test('allows to specify array indices', function (st) {
78
+ st.deepEqual(qs.parse('a[1]=c&a[0]=b&a[2]=d'), { a: ['b', 'c', 'd'] });
79
+ st.deepEqual(qs.parse('a[1]=c&a[0]=b'), { a: ['b', 'c'] });
80
+ st.deepEqual(qs.parse('a[1]=c'), { a: ['c'] });
81
+ st.end();
88
82
  });
89
83
 
90
- it('parses an explicit array', (done) => {
91
-
92
- expect(Qs.parse('a[]=b')).to.deep.equal({ a: ['b'] });
93
- expect(Qs.parse('a[]=b&a[]=c')).to.deep.equal({ a: ['b', 'c'] });
94
- expect(Qs.parse('a[]=b&a[]=c&a[]=d')).to.deep.equal({ a: ['b', 'c', 'd'] });
95
- done();
84
+ t.test('limits specific array indices to 20', function (st) {
85
+ st.deepEqual(qs.parse('a[20]=a'), { a: ['a'] });
86
+ st.deepEqual(qs.parse('a[21]=a'), { a: { '21': 'a' } });
87
+ st.end();
96
88
  });
97
89
 
98
- it('parses a mix of simple and explicit arrays', (done) => {
90
+ t.deepEqual(qs.parse('a[12b]=c'), { a: { '12b': 'c' } }, 'supports keys that begin with a number');
99
91
 
100
- expect(Qs.parse('a=b&a[]=c')).to.deep.equal({ a: ['b', 'c'] });
101
- expect(Qs.parse('a[]=b&a=c')).to.deep.equal({ a: ['b', 'c'] });
102
- expect(Qs.parse('a[0]=b&a=c')).to.deep.equal({ a: ['b', 'c'] });
103
- expect(Qs.parse('a=b&a[0]=c')).to.deep.equal({ a: ['b', 'c'] });
104
- expect(Qs.parse('a[1]=b&a=c')).to.deep.equal({ a: ['b', 'c'] });
105
- expect(Qs.parse('a=b&a[1]=c')).to.deep.equal({ a: ['b', 'c'] });
106
- done();
92
+ t.test('supports encoded = signs', function (st) {
93
+ st.deepEqual(qs.parse('he%3Dllo=th%3Dere'), { 'he=llo': 'th=ere' });
94
+ st.end();
107
95
  });
108
96
 
109
- it('parses a nested array', (done) => {
110
-
111
- expect(Qs.parse('a[b][]=c&a[b][]=d')).to.deep.equal({ a: { b: ['c', 'd'] } });
112
- expect(Qs.parse('a[>=]=25')).to.deep.equal({ a: { '>=': '25' } });
113
- done();
97
+ t.test('is ok with url encoded strings', function (st) {
98
+ st.deepEqual(qs.parse('a[b%20c]=d'), { a: { 'b c': 'd' } });
99
+ st.deepEqual(qs.parse('a[b]=c%20d'), { a: { b: 'c d' } });
100
+ st.end();
114
101
  });
115
102
 
116
- it('allows to specify array indices', (done) => {
117
-
118
- expect(Qs.parse('a[1]=c&a[0]=b&a[2]=d')).to.deep.equal({ a: ['b', 'c', 'd'] });
119
- expect(Qs.parse('a[1]=c&a[0]=b')).to.deep.equal({ a: ['b', 'c'] });
120
- expect(Qs.parse('a[1]=c')).to.deep.equal({ a: ['c'] });
121
- done();
103
+ t.test('allows brackets in the value', function (st) {
104
+ st.deepEqual(qs.parse('pets=["tobi"]'), { pets: '["tobi"]' });
105
+ st.deepEqual(qs.parse('operators=[">=", "<="]'), { operators: '[">=", "<="]' });
106
+ st.end();
122
107
  });
123
108
 
124
- it('limits specific array indices to 20', (done) => {
125
-
126
- expect(Qs.parse('a[20]=a')).to.deep.equal({ a: ['a'] });
127
- expect(Qs.parse('a[21]=a')).to.deep.equal({ a: { '21': 'a' } });
128
- done();
109
+ t.test('allows empty values', function (st) {
110
+ st.deepEqual(qs.parse(''), {});
111
+ st.deepEqual(qs.parse(null), {});
112
+ st.deepEqual(qs.parse(undefined), {});
113
+ st.end();
129
114
  });
130
115
 
131
- it('supports keys that begin with a number', (done) => {
116
+ t.test('transforms arrays to objects', function (st) {
117
+ st.deepEqual(qs.parse('foo[0]=bar&foo[bad]=baz'), { foo: { '0': 'bar', bad: 'baz' } });
118
+ st.deepEqual(qs.parse('foo[bad]=baz&foo[0]=bar'), { foo: { bad: 'baz', '0': 'bar' } });
119
+ st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar'), { foo: { bad: 'baz', '0': 'bar' } });
120
+ st.deepEqual(qs.parse('foo[]=bar&foo[bad]=baz'), { foo: { '0': 'bar', bad: 'baz' } });
121
+ st.deepEqual(qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo'), { foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
122
+ st.deepEqual(qs.parse('foo[0][a]=a&foo[0][b]=b&foo[1][a]=aa&foo[1][b]=bb'), { foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] });
132
123
 
133
- expect(Qs.parse('a[12b]=c')).to.deep.equal({ a: { '12b': 'c' } });
134
- done();
124
+ st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c', { allowPrototypes: false }), { a: { 0: 'b', t: 'u' } });
125
+ st.deepEqual(qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c', { allowPrototypes: true }), { a: { 0: 'b', t: 'u', hasOwnProperty: 'c' } });
126
+ st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y', { allowPrototypes: false }), { a: { 0: 'b', x: 'y' } });
127
+ st.deepEqual(qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y', { allowPrototypes: true }), { a: { 0: 'b', hasOwnProperty: 'c', x: 'y' } });
128
+ st.end();
135
129
  });
136
130
 
137
- it('supports encoded = signs', (done) => {
138
-
139
- expect(Qs.parse('he%3Dllo=th%3Dere')).to.deep.equal({ 'he=llo': 'th=ere' });
140
- done();
131
+ t.test('transforms arrays to objects (dot notation)', function (st) {
132
+ st.deepEqual(qs.parse('foo[0].baz=bar&fool.bad=baz', { allowDots: true }), { foo: [{ baz: 'bar' }], fool: { bad: 'baz' } });
133
+ st.deepEqual(qs.parse('foo[0].baz=bar&fool.bad.boo=baz', { allowDots: true }), { foo: [{ baz: 'bar' }], fool: { bad: { boo: 'baz' } } });
134
+ st.deepEqual(qs.parse('foo[0][0].baz=bar&fool.bad=baz', { allowDots: true }), { foo: [[{ baz: 'bar' }]], fool: { bad: 'baz' } });
135
+ st.deepEqual(qs.parse('foo[0].baz[0]=15&foo[0].bar=2', { allowDots: true }), { foo: [{ baz: ['15'], bar: '2' }] });
136
+ st.deepEqual(qs.parse('foo[0].baz[0]=15&foo[0].baz[1]=16&foo[0].bar=2', { allowDots: true }), { foo: [{ baz: ['15', '16'], bar: '2' }] });
137
+ st.deepEqual(qs.parse('foo.bad=baz&foo[0]=bar', { allowDots: true }), { foo: { bad: 'baz', '0': 'bar' } });
138
+ st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar', { allowDots: true }), { foo: { bad: 'baz', '0': 'bar' } });
139
+ st.deepEqual(qs.parse('foo[]=bar&foo.bad=baz', { allowDots: true }), { foo: { '0': 'bar', bad: 'baz' } });
140
+ st.deepEqual(qs.parse('foo.bad=baz&foo[]=bar&foo[]=foo', { allowDots: true }), { foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
141
+ st.deepEqual(qs.parse('foo[0].a=a&foo[0].b=b&foo[1].a=aa&foo[1].b=bb', { allowDots: true }), { foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] });
142
+ st.end();
141
143
  });
142
144
 
143
- it('is ok with url encoded strings', (done) => {
144
-
145
- expect(Qs.parse('a[b%20c]=d')).to.deep.equal({ a: { 'b c': 'd' } });
146
- expect(Qs.parse('a[b]=c%20d')).to.deep.equal({ a: { b: 'c d' } });
147
- done();
148
- });
149
-
150
- it('allows brackets in the value', (done) => {
151
-
152
- expect(Qs.parse('pets=["tobi"]')).to.deep.equal({ pets: '["tobi"]' });
153
- expect(Qs.parse('operators=[">=", "<="]')).to.deep.equal({ operators: '[">=", "<="]' });
154
- done();
155
- });
156
-
157
- it('allows empty values', (done) => {
158
-
159
- expect(Qs.parse('')).to.deep.equal({});
160
- expect(Qs.parse(null)).to.deep.equal({});
161
- expect(Qs.parse(undefined)).to.deep.equal({});
162
- done();
163
- });
164
-
165
- it('transforms arrays to objects', (done) => {
166
-
167
- expect(Qs.parse('foo[0]=bar&foo[bad]=baz')).to.deep.equal({ foo: { '0': 'bar', bad: 'baz' } });
168
- expect(Qs.parse('foo[bad]=baz&foo[0]=bar')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } });
169
- expect(Qs.parse('foo[bad]=baz&foo[]=bar')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } });
170
- expect(Qs.parse('foo[]=bar&foo[bad]=baz')).to.deep.equal({ foo: { '0': 'bar', bad: 'baz' } });
171
- expect(Qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
172
- expect(Qs.parse('foo[0][a]=a&foo[0][b]=b&foo[1][a]=aa&foo[1][b]=bb')).to.deep.equal({ foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] });
173
- expect(Qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c')).to.deep.equal({ a: { '0': 'b', t: 'u', c: true } });
174
- expect(Qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y')).to.deep.equal({ a: { '0': 'b', '1': 'c', x: 'y' } });
175
- done();
176
- });
177
-
178
- it('transforms arrays to objects (dot notation)', (done) => {
179
-
180
- expect(Qs.parse('foo[0].baz=bar&fool.bad=baz', { allowDots: true })).to.deep.equal({ foo: [{ baz: 'bar' }], fool: { bad: 'baz' } });
181
- expect(Qs.parse('foo[0].baz=bar&fool.bad.boo=baz', { allowDots: true })).to.deep.equal({ foo: [{ baz: 'bar' }], fool: { bad: { boo: 'baz' } } });
182
- expect(Qs.parse('foo[0][0].baz=bar&fool.bad=baz', { allowDots: true })).to.deep.equal({ foo: [[{ baz: 'bar' }]], fool: { bad: 'baz' } });
183
- expect(Qs.parse('foo[0].baz[0]=15&foo[0].bar=2', { allowDots: true })).to.deep.equal({ foo: [{ baz: ['15'], bar: '2' }] });
184
- expect(Qs.parse('foo[0].baz[0]=15&foo[0].baz[1]=16&foo[0].bar=2', { allowDots: true })).to.deep.equal({ foo: [{ baz: ['15', '16'], bar: '2' }] });
185
- expect(Qs.parse('foo.bad=baz&foo[0]=bar', { allowDots: true })).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } });
186
- expect(Qs.parse('foo.bad=baz&foo[]=bar', { allowDots: true })).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } });
187
- expect(Qs.parse('foo[]=bar&foo.bad=baz', { allowDots: true })).to.deep.equal({ foo: { '0': 'bar', bad: 'baz' } });
188
- expect(Qs.parse('foo.bad=baz&foo[]=bar&foo[]=foo', { allowDots: true })).to.deep.equal({ foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
189
- expect(Qs.parse('foo[0].a=a&foo[0].b=b&foo[1].a=aa&foo[1].b=bb', { allowDots: true })).to.deep.equal({ foo: [{ a: 'a', b: 'b' }, { a: 'aa', b: 'bb' }] });
190
- done();
191
- });
192
-
193
- it('can add keys to objects', (done) => {
194
-
195
- expect(Qs.parse('a[b]=c&a=d')).to.deep.equal({ a: { b: 'c', d: true } });
196
- done();
197
- });
198
-
199
- it('correctly prunes undefined values when converting an array to an object', (done) => {
200
-
201
- expect(Qs.parse('a[2]=b&a[99999999]=c')).to.deep.equal({ a: { '2': 'b', '99999999': 'c' } });
202
- done();
145
+ t.test('correctly prunes undefined values when converting an array to an object', function (st) {
146
+ st.deepEqual(qs.parse('a[2]=b&a[99999999]=c'), { a: { '2': 'b', '99999999': 'c' } });
147
+ st.end();
203
148
  });
204
149
 
205
- it('supports malformed uri characters', (done) => {
206
-
207
- expect(Qs.parse('{%:%}', { strictNullHandling: true })).to.deep.equal({ '{%:%}': null });
208
- expect(Qs.parse('{%:%}=')).to.deep.equal({ '{%:%}': '' });
209
- expect(Qs.parse('foo=%:%}')).to.deep.equal({ foo: '%:%}' });
210
- done();
150
+ t.test('supports malformed uri characters', function (st) {
151
+ st.deepEqual(qs.parse('{%:%}', { strictNullHandling: true }), { '{%:%}': null });
152
+ st.deepEqual(qs.parse('{%:%}='), { '{%:%}': '' });
153
+ st.deepEqual(qs.parse('foo=%:%}'), { foo: '%:%}' });
154
+ st.end();
211
155
  });
212
156
 
213
- it('doesn\'t produce empty keys', (done) => {
214
-
215
- expect(Qs.parse('_r=1&')).to.deep.equal({ '_r': '1' });
216
- done();
157
+ t.test('doesn\'t produce empty keys', function (st) {
158
+ st.deepEqual(qs.parse('_r=1&'), { '_r': '1' });
159
+ st.end();
217
160
  });
218
161
 
219
- it('cannot access Object prototype', (done) => {
220
-
221
- Qs.parse('constructor[prototype][bad]=bad');
222
- Qs.parse('bad[constructor][prototype][bad]=bad');
223
- expect(typeof Object.prototype.bad).to.equal('undefined');
224
- done();
162
+ t.test('cannot access Object prototype', function (st) {
163
+ qs.parse('constructor[prototype][bad]=bad');
164
+ qs.parse('bad[constructor][prototype][bad]=bad');
165
+ st.equal(typeof Object.prototype.bad, 'undefined');
166
+ st.end();
225
167
  });
226
168
 
227
- it('parses arrays of objects', (done) => {
228
-
229
- expect(Qs.parse('a[][b]=c')).to.deep.equal({ a: [{ b: 'c' }] });
230
- expect(Qs.parse('a[0][b]=c')).to.deep.equal({ a: [{ b: 'c' }] });
231
- done();
169
+ t.test('parses arrays of objects', function (st) {
170
+ st.deepEqual(qs.parse('a[][b]=c'), { a: [{ b: 'c' }] });
171
+ st.deepEqual(qs.parse('a[0][b]=c'), { a: [{ b: 'c' }] });
172
+ st.end();
232
173
  });
233
174
 
234
- it('allows for empty strings in arrays', (done) => {
235
-
236
- expect(Qs.parse('a[]=b&a[]=&a[]=c')).to.deep.equal({ a: ['b', '', 'c'] });
237
- expect(Qs.parse('a[0]=b&a[1]&a[2]=c&a[19]=', { strictNullHandling: true })).to.deep.equal({ a: ['b', null, 'c', ''] });
238
- expect(Qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]', { strictNullHandling: true })).to.deep.equal({ a: ['b', '', 'c', null] });
239
- expect(Qs.parse('a[]=&a[]=b&a[]=c')).to.deep.equal({ a: ['', 'b', 'c'] });
240
- done();
175
+ t.test('allows for empty strings in arrays', function (st) {
176
+ st.deepEqual(qs.parse('a[]=b&a[]=&a[]=c'), { a: ['b', '', 'c'] });
177
+ st.deepEqual(qs.parse('a[0]=b&a[1]&a[2]=c&a[19]=', { strictNullHandling: true }), { a: ['b', null, 'c', ''] });
178
+ st.deepEqual(qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]', { strictNullHandling: true }), { a: ['b', '', 'c', null] });
179
+ st.deepEqual(qs.parse('a[]=&a[]=b&a[]=c'), { a: ['', 'b', 'c'] });
180
+ st.end();
241
181
  });
242
182
 
243
- it('compacts sparse arrays', (done) => {
244
-
245
- expect(Qs.parse('a[10]=1&a[2]=2')).to.deep.equal({ a: ['2', '1'] });
246
- done();
183
+ t.test('compacts sparse arrays', function (st) {
184
+ st.deepEqual(qs.parse('a[10]=1&a[2]=2'), { a: ['2', '1'] });
185
+ st.end();
247
186
  });
248
187
 
249
- it('parses semi-parsed strings', (done) => {
250
-
251
- expect(Qs.parse({ 'a[b]': 'c' })).to.deep.equal({ a: { b: 'c' } });
252
- expect(Qs.parse({ 'a[b]': 'c', 'a[d]': 'e' })).to.deep.equal({ a: { b: 'c', d: 'e' } });
253
- done();
188
+ t.test('parses semi-parsed strings', function (st) {
189
+ st.deepEqual(qs.parse({ 'a[b]': 'c' }), { a: { b: 'c' } });
190
+ st.deepEqual(qs.parse({ 'a[b]': 'c', 'a[d]': 'e' }), { a: { b: 'c', d: 'e' } });
191
+ st.end();
254
192
  });
255
193
 
256
- it('parses buffers correctly', (done) => {
257
-
258
- const b = new Buffer('test');
259
- expect(Qs.parse({ a: b })).to.deep.equal({ a: b });
260
- done();
194
+ t.test('parses buffers correctly', function (st) {
195
+ var b = new Buffer('test');
196
+ st.deepEqual(qs.parse({ a: b }), { a: b });
197
+ st.end();
261
198
  });
262
199
 
263
- it('continues parsing when no parent is found', (done) => {
264
-
265
- expect(Qs.parse('[]=&a=b')).to.deep.equal({ '0': '', a: 'b' });
266
- expect(Qs.parse('[]&a=b', { strictNullHandling: true })).to.deep.equal({ '0': null, a: 'b' });
267
- expect(Qs.parse('[foo]=bar')).to.deep.equal({ foo: 'bar' });
268
- done();
200
+ t.test('continues parsing when no parent is found', function (st) {
201
+ st.deepEqual(qs.parse('[]=&a=b'), { '0': '', a: 'b' });
202
+ st.deepEqual(qs.parse('[]&a=b', { strictNullHandling: true }), { '0': null, a: 'b' });
203
+ st.deepEqual(qs.parse('[foo]=bar'), { foo: 'bar' });
204
+ st.end();
269
205
  });
270
206
 
271
- it('does not error when parsing a very long array', (done) => {
272
-
273
- let str = 'a[]=a';
207
+ t.test('does not error when parsing a very long array', function (st) {
208
+ var str = 'a[]=a';
274
209
  while (Buffer.byteLength(str) < 128 * 1024) {
275
210
  str = str + '&' + str;
276
211
  }
277
212
 
278
- expect(() => {
213
+ st.doesNotThrow(function () { qs.parse(str); });
279
214
 
280
- Qs.parse(str);
281
- }).to.not.throw();
282
-
283
- done();
215
+ st.end();
284
216
  });
285
217
 
286
- it('should not throw when a native prototype has an enumerable property', { parallel: false }, (done) => {
287
-
218
+ t.test('should not throw when a native prototype has an enumerable property', { parallel: false }, function (st) {
288
219
  Object.prototype.crash = '';
289
220
  Array.prototype.crash = '';
290
- expect(Qs.parse.bind(null, 'a=b')).to.not.throw();
291
- expect(Qs.parse('a=b')).to.deep.equal({ a: 'b' });
292
- expect(Qs.parse.bind(null, 'a[][b]=c')).to.not.throw();
293
- expect(Qs.parse('a[][b]=c')).to.deep.equal({ a: [{ b: 'c' }] });
221
+ st.doesNotThrow(qs.parse.bind(null, 'a=b'));
222
+ st.deepEqual(qs.parse('a=b'), { a: 'b' });
223
+ st.doesNotThrow(qs.parse.bind(null, 'a[][b]=c'));
224
+ st.deepEqual(qs.parse('a[][b]=c'), { a: [{ b: 'c' }] });
294
225
  delete Object.prototype.crash;
295
226
  delete Array.prototype.crash;
296
- done();
227
+ st.end();
297
228
  });
298
229
 
299
- it('parses a string with an alternative string delimiter', (done) => {
300
-
301
- expect(Qs.parse('a=b;c=d', { delimiter: ';' })).to.deep.equal({ a: 'b', c: 'd' });
302
- done();
230
+ t.test('parses a string with an alternative string delimiter', function (st) {
231
+ st.deepEqual(qs.parse('a=b;c=d', { delimiter: ';' }), { a: 'b', c: 'd' });
232
+ st.end();
303
233
  });
304
234
 
305
- it('parses a string with an alternative RegExp delimiter', (done) => {
306
-
307
- expect(Qs.parse('a=b; c=d', { delimiter: /[;,] */ })).to.deep.equal({ a: 'b', c: 'd' });
308
- done();
235
+ t.test('parses a string with an alternative RegExp delimiter', function (st) {
236
+ st.deepEqual(qs.parse('a=b; c=d', { delimiter: /[;,] */ }), { a: 'b', c: 'd' });
237
+ st.end();
309
238
  });
310
239
 
311
- it('does not use non-splittable objects as delimiters', (done) => {
312
-
313
- expect(Qs.parse('a=b&c=d', { delimiter: true })).to.deep.equal({ a: 'b', c: 'd' });
314
- done();
240
+ t.test('does not use non-splittable objects as delimiters', function (st) {
241
+ st.deepEqual(qs.parse('a=b&c=d', { delimiter: true }), { a: 'b', c: 'd' });
242
+ st.end();
315
243
  });
316
244
 
317
- it('allows overriding parameter limit', (done) => {
318
-
319
- expect(Qs.parse('a=b&c=d', { parameterLimit: 1 })).to.deep.equal({ a: 'b' });
320
- done();
245
+ t.test('allows overriding parameter limit', function (st) {
246
+ st.deepEqual(qs.parse('a=b&c=d', { parameterLimit: 1 }), { a: 'b' });
247
+ st.end();
321
248
  });
322
249
 
323
- it('allows setting the parameter limit to Infinity', (done) => {
324
-
325
- expect(Qs.parse('a=b&c=d', { parameterLimit: Infinity })).to.deep.equal({ a: 'b', c: 'd' });
326
- done();
250
+ t.test('allows setting the parameter limit to Infinity', function (st) {
251
+ st.deepEqual(qs.parse('a=b&c=d', { parameterLimit: Infinity }), { a: 'b', c: 'd' });
252
+ st.end();
327
253
  });
328
254
 
329
- it('allows overriding array limit', (done) => {
330
-
331
- expect(Qs.parse('a[0]=b', { arrayLimit: -1 })).to.deep.equal({ a: { '0': 'b' } });
332
- expect(Qs.parse('a[-1]=b', { arrayLimit: -1 })).to.deep.equal({ a: { '-1': 'b' } });
333
- expect(Qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 })).to.deep.equal({ a: { '0': 'b', '1': 'c' } });
334
- done();
255
+ t.test('allows overriding array limit', function (st) {
256
+ st.deepEqual(qs.parse('a[0]=b', { arrayLimit: -1 }), { a: { '0': 'b' } });
257
+ st.deepEqual(qs.parse('a[-1]=b', { arrayLimit: -1 }), { a: { '-1': 'b' } });
258
+ st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 }), { a: { '0': 'b', '1': 'c' } });
259
+ st.end();
335
260
  });
336
261
 
337
- it('allows disabling array parsing', (done) => {
338
-
339
- expect(Qs.parse('a[0]=b&a[1]=c', { parseArrays: false })).to.deep.equal({ a: { '0': 'b', '1': 'c' } });
340
- done();
262
+ t.test('allows disabling array parsing', function (st) {
263
+ st.deepEqual(qs.parse('a[0]=b&a[1]=c', { parseArrays: false }), { a: { '0': 'b', '1': 'c' } });
264
+ st.end();
341
265
  });
342
266
 
343
- it('parses an object', (done) => {
344
-
345
- const input = {
267
+ t.test('parses an object', function (st) {
268
+ var input = {
346
269
  'user[name]': { 'pop[bob]': 3 },
347
270
  'user[email]': null
348
271
  };
349
272
 
350
- const expected = {
351
- 'user': {
352
- 'name': { 'pop[bob]': 3 },
353
- 'email': null
273
+ var expected = {
274
+ user: {
275
+ name: { 'pop[bob]': 3 },
276
+ email: null
354
277
  }
355
278
  };
356
279
 
357
- const result = Qs.parse(input);
280
+ var result = qs.parse(input);
358
281
 
359
- expect(result).to.deep.equal(expected);
360
- done();
282
+ st.deepEqual(result, expected);
283
+ st.end();
361
284
  });
362
285
 
363
- it('parses an object in dot notation', (done) => {
364
-
365
- const input = {
286
+ t.test('parses an object in dot notation', function (st) {
287
+ var input = {
366
288
  'user.name': { 'pop[bob]': 3 },
367
289
  'user.email.': null
368
290
  };
369
291
 
370
- const expected = {
371
- 'user': {
372
- 'name': { 'pop[bob]': 3 },
373
- 'email': null
292
+ var expected = {
293
+ user: {
294
+ name: { 'pop[bob]': 3 },
295
+ email: null
374
296
  }
375
297
  };
376
298
 
377
- const result = Qs.parse(input, { allowDots: true });
299
+ var result = qs.parse(input, { allowDots: true });
378
300
 
379
- expect(result).to.deep.equal(expected);
380
- done();
301
+ st.deepEqual(result, expected);
302
+ st.end();
381
303
  });
382
304
 
383
- it('parses an object and not child values', (done) => {
384
-
385
- const input = {
305
+ t.test('parses an object and not child values', function (st) {
306
+ var input = {
386
307
  'user[name]': { 'pop[bob]': { 'test': 3 } },
387
308
  'user[email]': null
388
309
  };
389
310
 
390
- const expected = {
391
- 'user': {
392
- 'name': { 'pop[bob]': { 'test': 3 } },
393
- 'email': null
311
+ var expected = {
312
+ user: {
313
+ name: { 'pop[bob]': { 'test': 3 } },
314
+ email: null
394
315
  }
395
316
  };
396
317
 
397
- const result = Qs.parse(input);
318
+ var result = qs.parse(input);
398
319
 
399
- expect(result).to.deep.equal(expected);
400
- done();
320
+ st.deepEqual(result, expected);
321
+ st.end();
401
322
  });
402
323
 
403
- it('does not blow up when Buffer global is missing', (done) => {
404
-
405
- const tempBuffer = global.Buffer;
324
+ t.test('does not blow up when Buffer global is missing', function (st) {
325
+ var tempBuffer = global.Buffer;
406
326
  delete global.Buffer;
407
- const result = Qs.parse('a=b&c=d');
327
+ var result = qs.parse('a=b&c=d');
408
328
  global.Buffer = tempBuffer;
409
- expect(result).to.deep.equal({ a: 'b', c: 'd' });
410
- done();
329
+ st.deepEqual(result, { a: 'b', c: 'd' });
330
+ st.end();
411
331
  });
412
332
 
413
- it('does not crash when parsing circular references', (done) => {
414
-
415
- const a = {};
333
+ t.test('does not crash when parsing circular references', function (st) {
334
+ var a = {};
416
335
  a.b = a;
417
336
 
418
- let parsed;
419
-
420
- expect(() => {
337
+ var parsed;
421
338
 
422
- parsed = Qs.parse({ 'foo[bar]': 'baz', 'foo[baz]': a });
423
- }).to.not.throw();
339
+ st.doesNotThrow(function () {
340
+ parsed = qs.parse({ 'foo[bar]': 'baz', 'foo[baz]': a });
341
+ });
424
342
 
425
- expect(parsed).to.contain('foo');
426
- expect(parsed.foo).to.contain('bar', 'baz');
427
- expect(parsed.foo.bar).to.equal('baz');
428
- expect(parsed.foo.baz).to.deep.equal(a);
429
- done();
343
+ st.equal('foo' in parsed, true, 'parsed has "foo" property');
344
+ st.equal('bar' in parsed.foo, true);
345
+ st.equal('baz' in parsed.foo, true);
346
+ st.equal(parsed.foo.bar, 'baz');
347
+ st.deepEqual(parsed.foo.baz, a);
348
+ st.end();
430
349
  });
431
350
 
432
- it('parses plain objects correctly', (done) => {
433
-
434
- const a = Object.create(null);
351
+ t.test('parses plain objects correctly', function (st) {
352
+ var a = Object.create(null);
435
353
  a.b = 'c';
436
354
 
437
- expect(Qs.parse(a)).to.deep.equal({ b: 'c' });
438
- const result = Qs.parse({ a: a });
439
- expect(result).to.contain('a');
440
- expect(result.a).to.deep.equal(a);
441
- done();
355
+ st.deepEqual(qs.parse(a), { b: 'c' });
356
+ var result = qs.parse({ a: a });
357
+ st.equal('a' in result, true, 'result has "a" property');
358
+ st.deepEqual(result.a, a);
359
+ st.end();
442
360
  });
443
361
 
444
- it('parses dates correctly', (done) => {
362
+ t.test('parses dates correctly', function (st) {
363
+ var now = new Date();
364
+ st.deepEqual(qs.parse({ a: now }), { a: now });
365
+ st.end();
366
+ });
445
367
 
446
- const now = new Date();
447
- expect(Qs.parse({ a: now })).to.deep.equal({ a: now });
448
- done();
368
+ t.test('parses regular expressions correctly', function (st) {
369
+ var re = /^test$/;
370
+ st.deepEqual(qs.parse({ a: re }), { a: re });
371
+ st.end();
449
372
  });
450
373
 
451
- it('parses regular expressions correctly', (done) => {
374
+ t.test('does not allow overwriting prototype properties', function (st) {
375
+ st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: false }), {});
376
+ st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: false }), {});
452
377
 
453
- const re = /^test$/;
454
- expect(Qs.parse({ a: re })).to.deep.equal({ a: re });
455
- done();
378
+ st.deepEqual(
379
+ qs.parse('toString', { allowPrototypes: false }),
380
+ {},
381
+ 'bare "toString" results in {}'
382
+ );
383
+
384
+ st.end();
456
385
  });
457
386
 
458
- it('can allow overwriting prototype properties', (done) => {
387
+ t.test('can allow overwriting prototype properties', function (st) {
388
+ st.deepEqual(qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true }), { a: { hasOwnProperty: 'b' } });
389
+ st.deepEqual(qs.parse('hasOwnProperty=b', { allowPrototypes: true }), { hasOwnProperty: 'b' });
390
+
391
+ st.deepEqual(
392
+ qs.parse('toString', { allowPrototypes: true }),
393
+ { toString: '' },
394
+ 'bare "toString" results in { toString: "" }'
395
+ );
459
396
 
460
- expect(Qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true })).to.deep.equal({ a: { hasOwnProperty: 'b' } }, { prototype: false });
461
- expect(Qs.parse('hasOwnProperty=b', { allowPrototypes: true })).to.deep.equal({ hasOwnProperty: 'b' }, { prototype: false });
462
- done();
397
+ st.end();
463
398
  });
464
399
 
465
- it('can return plain objects', (done) => {
400
+ t.test('params starting with a closing bracket', function (st) {
401
+ st.deepEqual(qs.parse(']=toString'), { ']': 'toString' });
402
+ st.deepEqual(qs.parse(']]=toString'), { ']]': 'toString' });
403
+ st.deepEqual(qs.parse(']hello]=toString'), { ']hello]': 'toString' });
404
+ st.end();
405
+ });
406
+
407
+ t.test('params starting with a starting bracket', function (st) {
408
+ st.deepEqual(qs.parse('[=toString'), { '[': 'toString' });
409
+ st.deepEqual(qs.parse('[[=toString'), { '[[': 'toString' });
410
+ st.deepEqual(qs.parse('[hello[=toString'), { '[hello[': 'toString' });
411
+ st.end();
412
+ });
413
+
414
+ t.test('add keys to objects', function (st) {
415
+ st.deepEqual(
416
+ qs.parse('a[b]=c&a=d'),
417
+ { a: { b: 'c', d: true } },
418
+ 'can add keys to objects'
419
+ );
420
+
421
+ st.deepEqual(
422
+ qs.parse('a[b]=c&a=toString'),
423
+ { a: { b: 'c' } },
424
+ 'can not overwrite prototype'
425
+ );
426
+
427
+ st.deepEqual(
428
+ qs.parse('a[b]=c&a=toString', { allowPrototypes: true }),
429
+ { a: { b: 'c', toString: true } },
430
+ 'can overwrite prototype with allowPrototypes true'
431
+ );
432
+
433
+ st.deepEqual(
434
+ qs.parse('a[b]=c&a=toString', { plainObjects: true }),
435
+ { a: { b: 'c', toString: true } },
436
+ 'can overwrite prototype with plainObjects true'
437
+ );
438
+
439
+ st.end();
440
+ });
466
441
 
467
- const expected = Object.create(null);
442
+ t.test('can return null objects', { skip: !Object.create }, function (st) {
443
+ var expected = Object.create(null);
468
444
  expected.a = Object.create(null);
469
445
  expected.a.b = 'c';
470
446
  expected.a.hasOwnProperty = 'd';
471
- expect(Qs.parse('a[b]=c&a[hasOwnProperty]=d', { plainObjects: true })).to.deep.equal(expected);
472
- expect(Qs.parse(null, { plainObjects: true })).to.deep.equal(Object.create(null));
473
- const expectedArray = Object.create(null);
447
+ st.deepEqual(qs.parse('a[b]=c&a[hasOwnProperty]=d', { plainObjects: true }), expected);
448
+ st.deepEqual(qs.parse(null, { plainObjects: true }), Object.create(null));
449
+ var expectedArray = Object.create(null);
474
450
  expectedArray.a = Object.create(null);
475
451
  expectedArray.a['0'] = 'b';
476
452
  expectedArray.a.c = 'd';
477
- expect(Qs.parse('a[]=b&a[c]=d', { plainObjects: true })).to.deep.equal(expectedArray);
478
- done();
453
+ st.deepEqual(qs.parse('a[]=b&a[c]=d', { plainObjects: true }), expectedArray);
454
+ st.end();
479
455
  });
480
456
  });