qs 3.1.0 → 4.0.0

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/README.md CHANGED
@@ -34,10 +34,17 @@ For example, the string `'foo[bar]=baz'` converts to:
34
34
  }
35
35
  ```
36
36
 
37
- The parsed value is returned as a plain object, created via `Object.create(null)` and as such you should be aware that prototype methods do not exist on it and a user may set those names to whatever value they like:
37
+ When using the `plainObjects` option the parsed value is returned as a plain object, created via `Object.create(null)` and as such you should be aware that prototype methods will not exist on it and a user may set those names to whatever value they like:
38
38
 
39
39
  ```javascript
40
- Qs.parse('a.hasOwnProperty=b');
40
+ Qs.parse('a.hasOwnProperty=b', { plainObjects: true });
41
+ // { a: { hasOwnProperty: 'b' } }
42
+ ```
43
+
44
+ By default parameters that would overwrite properties on the object prototype are ignored, if you wish to keep the data from those fields either use `plainObjects` as mentioned above, or set `allowPrototypes` to `true` which will allow user input to overwrite those properties. *WARNING* It is generally a bad idea to enable this option as it can cause problems when attempting to use the properties that have been overwritten. Always be careful with this option.
45
+
46
+ ```javascript
47
+ Qs.parse('a.hasOwnProperty=b', { allowPrototypes: true });
41
48
  // { a: { hasOwnProperty: 'b' } }
42
49
  ```
43
50
 
@@ -111,6 +118,13 @@ Qs.parse('a=b;c=d,e=f', { delimiter: /[;,]/ });
111
118
  // { a: 'b', c: 'd', e: 'f' }
112
119
  ```
113
120
 
121
+ Option `allowDots` can be used to disable dot notation:
122
+
123
+ ```javascript
124
+ Qs.parse('a.b=c', { allowDots: false });
125
+ // { 'a.b': 'c' } }
126
+ ```
127
+
114
128
  ### Parsing Arrays
115
129
 
116
130
  **qs** can also parse arrays using a similar `[]` notation:
package/lib/parse.js CHANGED
@@ -10,7 +10,9 @@ var internals = {
10
10
  depth: 5,
11
11
  arrayLimit: 20,
12
12
  parameterLimit: 1000,
13
- strictNullHandling: false
13
+ strictNullHandling: false,
14
+ plainObjects: false,
15
+ allowPrototypes: false
14
16
  };
15
17
 
16
18
 
@@ -61,7 +63,7 @@ internals.parseObject = function (chain, val, options) {
61
63
  obj = obj.concat(internals.parseObject(chain, val, options));
62
64
  }
63
65
  else {
64
- obj = Object.create(null);
66
+ obj = options.plainObjects ? Object.create(null) : {};
65
67
  var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
66
68
  var index = parseInt(cleanRoot, 10);
67
69
  var indexString = '' + index;
@@ -109,6 +111,16 @@ internals.parseKeys = function (key, val, options) {
109
111
 
110
112
  var keys = [];
111
113
  if (segment[1]) {
114
+ // If we aren't using plain objects, optionally prefix keys
115
+ // that would overwrite object prototype properties
116
+ if (!options.plainObjects &&
117
+ Object.prototype.hasOwnProperty(segment[1])) {
118
+
119
+ if (!options.allowPrototypes) {
120
+ return;
121
+ }
122
+ }
123
+
112
124
  keys.push(segment[1]);
113
125
  }
114
126
 
@@ -118,6 +130,13 @@ internals.parseKeys = function (key, val, options) {
118
130
  while ((segment = child.exec(key)) !== null && i < options.depth) {
119
131
 
120
132
  ++i;
133
+ if (!options.plainObjects &&
134
+ Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
135
+
136
+ if (!options.allowPrototypes) {
137
+ continue;
138
+ }
139
+ }
121
140
  keys.push(segment[1]);
122
141
  }
123
142
 
@@ -133,25 +152,26 @@ internals.parseKeys = function (key, val, options) {
133
152
 
134
153
  module.exports = function (str, options) {
135
154
 
136
- if (str === '' ||
137
- str === null ||
138
- typeof str === 'undefined') {
139
-
140
- return Object.create(null);
141
- }
142
-
143
155
  options = options || {};
144
156
  options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
145
157
  options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
146
158
  options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
147
159
  options.parseArrays = options.parseArrays !== false;
148
160
  options.allowDots = options.allowDots !== false;
161
+ options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : internals.plainObjects;
162
+ options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : internals.allowPrototypes;
149
163
  options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
150
164
  options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
151
165
 
166
+ if (str === '' ||
167
+ str === null ||
168
+ typeof str === 'undefined') {
169
+
170
+ return options.plainObjects ? Object.create(null) : {};
171
+ }
152
172
 
153
173
  var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
154
- var obj = Object.create(null);
174
+ var obj = options.plainObjects ? Object.create(null) : {};
155
175
 
156
176
  // Iterate over the keys and setup the new object
157
177
 
@@ -159,7 +179,7 @@ module.exports = function (str, options) {
159
179
  for (var i = 0, il = keys.length; i < il; ++i) {
160
180
  var key = keys[i];
161
181
  var newObj = internals.parseKeys(key, tempObj[key], options);
162
- obj = Utils.merge(obj, newObj);
182
+ obj = Utils.merge(obj, newObj, options);
163
183
  }
164
184
 
165
185
  return Utils.compact(obj);
package/lib/utils.js CHANGED
@@ -5,14 +5,14 @@
5
5
 
6
6
  var internals = {};
7
7
  internals.hexTable = new Array(256);
8
- for (var i = 0; i < 256; ++i) {
9
- internals.hexTable[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
8
+ for (var h = 0; h < 256; ++h) {
9
+ internals.hexTable[h] = '%' + ((h < 16 ? '0' : '') + h.toString(16)).toUpperCase();
10
10
  }
11
11
 
12
12
 
13
- exports.arrayToObject = function (source) {
13
+ exports.arrayToObject = function (source, options) {
14
14
 
15
- var obj = Object.create(null);
15
+ var obj = options.plainObjects ? Object.create(null) : {};
16
16
  for (var i = 0, il = source.length; i < il; ++i) {
17
17
  if (typeof source[i] !== 'undefined') {
18
18
 
@@ -24,7 +24,7 @@ exports.arrayToObject = function (source) {
24
24
  };
25
25
 
26
26
 
27
- exports.merge = function (target, source) {
27
+ exports.merge = function (target, source, options) {
28
28
 
29
29
  if (!source) {
30
30
  return target;
@@ -52,7 +52,7 @@ exports.merge = function (target, source) {
52
52
  if (Array.isArray(target) &&
53
53
  !Array.isArray(source)) {
54
54
 
55
- target = exports.arrayToObject(target);
55
+ target = exports.arrayToObject(target, options);
56
56
  }
57
57
 
58
58
  var keys = Object.keys(source);
@@ -60,11 +60,11 @@ exports.merge = function (target, source) {
60
60
  var key = keys[k];
61
61
  var value = source[key];
62
62
 
63
- if (!target[key]) {
63
+ if (!Object.prototype.hasOwnProperty.call(target, key)) {
64
64
  target[key] = value;
65
65
  }
66
66
  else {
67
- target[key] = exports.merge(target[key], value);
67
+ target[key] = exports.merge(target[key], value, options);
68
68
  }
69
69
  }
70
70
 
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "qs",
3
- "version": "3.1.0",
3
+ "version": "4.0.0",
4
4
  "description": "A querystring parser that supports nesting and arrays, with a depth limit",
5
5
  "homepage": "https://github.com/hapijs/qs",
6
- "main": "index.js",
6
+ "main": "lib/index.js",
7
7
  "dependencies": {},
8
8
  "devDependencies": {
9
9
  "browserify": "^10.2.1",
@@ -11,8 +11,9 @@
11
11
  "lab": "5.x.x"
12
12
  },
13
13
  "scripts": {
14
- "test": "make test-cov",
15
- "dist": "browserify --standalone Qs index.js > dist/qs.js"
14
+ "test": "lab -a code -t 100 -L",
15
+ "test-cov-html": "lab -a code -r html -o coverage.html",
16
+ "dist": "browserify --standalone Qs lib/index.js > dist/qs.js"
16
17
  },
17
18
  "repository": {
18
19
  "type": "git",
package/test/parse.js CHANGED
@@ -23,194 +23,194 @@ describe('parse()', function () {
23
23
 
24
24
  it('parses a simple string', function (done) {
25
25
 
26
- expect(Qs.parse('0=foo')).to.deep.equal({ '0': 'foo' }, { prototype: false });
27
- expect(Qs.parse('foo=c++')).to.deep.equal({ foo: 'c ' }, { prototype: false });
28
- expect(Qs.parse('a[>=]=23')).to.deep.equal({ a: { '>=': '23' } }, { prototype: false });
29
- expect(Qs.parse('a[<=>]==23')).to.deep.equal({ a: { '<=>': '=23' } }, { prototype: false });
30
- expect(Qs.parse('a[==]=23')).to.deep.equal({ a: { '==': '23' } }, { prototype: false });
31
- expect(Qs.parse('foo', {strictNullHandling: true})).to.deep.equal({ foo: null }, { prototype: false });
32
- expect(Qs.parse('foo' )).to.deep.equal({ foo: '' }, { prototype: false });
33
- expect(Qs.parse('foo=')).to.deep.equal({ foo: '' }, { prototype: false });
34
- expect(Qs.parse('foo=bar')).to.deep.equal({ foo: 'bar' }, { prototype: false });
35
- expect(Qs.parse(' foo = bar = baz ')).to.deep.equal({ ' foo ': ' bar = baz ' }, { prototype: false });
36
- expect(Qs.parse('foo=bar=baz')).to.deep.equal({ foo: 'bar=baz' }, { prototype: false });
37
- expect(Qs.parse('foo=bar&bar=baz')).to.deep.equal({ foo: 'bar', bar: 'baz' }, { prototype: false });
38
- expect(Qs.parse('foo2=bar2&baz2=')).to.deep.equal({ foo2: 'bar2', baz2: '' }, { prototype: false });
39
- expect(Qs.parse('foo=bar&baz', {strictNullHandling: true})).to.deep.equal({ foo: 'bar', baz: null }, { prototype: false });
40
- expect(Qs.parse('foo=bar&baz')).to.deep.equal({ foo: 'bar', baz: '' }, { prototype: false });
26
+ expect(Qs.parse('0=foo')).to.deep.equal({ '0': 'foo' });
27
+ expect(Qs.parse('foo=c++')).to.deep.equal({ foo: 'c ' });
28
+ expect(Qs.parse('a[>=]=23')).to.deep.equal({ a: { '>=': '23' } });
29
+ expect(Qs.parse('a[<=>]==23')).to.deep.equal({ a: { '<=>': '=23' } });
30
+ expect(Qs.parse('a[==]=23')).to.deep.equal({ a: { '==': '23' } });
31
+ expect(Qs.parse('foo', { strictNullHandling: true })).to.deep.equal({ foo: null });
32
+ expect(Qs.parse('foo' )).to.deep.equal({ foo: '' });
33
+ expect(Qs.parse('foo=')).to.deep.equal({ foo: '' });
34
+ expect(Qs.parse('foo=bar')).to.deep.equal({ foo: 'bar' });
35
+ expect(Qs.parse(' foo = bar = baz ')).to.deep.equal({ ' foo ': ' bar = baz ' });
36
+ expect(Qs.parse('foo=bar=baz')).to.deep.equal({ foo: 'bar=baz' });
37
+ expect(Qs.parse('foo=bar&bar=baz')).to.deep.equal({ foo: 'bar', bar: 'baz' });
38
+ expect(Qs.parse('foo2=bar2&baz2=')).to.deep.equal({ foo2: 'bar2', baz2: '' });
39
+ expect(Qs.parse('foo=bar&baz', { strictNullHandling: true })).to.deep.equal({ foo: 'bar', baz: null });
40
+ expect(Qs.parse('foo=bar&baz')).to.deep.equal({ foo: 'bar', baz: '' });
41
41
  expect(Qs.parse('cht=p3&chd=t:60,40&chs=250x100&chl=Hello|World')).to.deep.equal({
42
42
  cht: 'p3',
43
43
  chd: 't:60,40',
44
44
  chs: '250x100',
45
45
  chl: 'Hello|World'
46
- }, { prototype: false });
46
+ });
47
47
  done();
48
48
  });
49
49
 
50
50
  it('allows disabling dot notation', function (done) {
51
51
 
52
- expect(Qs.parse('a.b=c')).to.deep.equal({ a: { b: 'c' } }, { prototype: false });
53
- expect(Qs.parse('a.b=c', { allowDots: false })).to.deep.equal({ 'a.b': 'c' }, { prototype: false });
52
+ expect(Qs.parse('a.b=c')).to.deep.equal({ a: { b: 'c' } });
53
+ expect(Qs.parse('a.b=c', { allowDots: false })).to.deep.equal({ 'a.b': 'c' });
54
54
  done();
55
55
  });
56
56
 
57
57
  it('parses a single nested string', function (done) {
58
58
 
59
- expect(Qs.parse('a[b]=c')).to.deep.equal({ a: { b: 'c' } }, { prototype: false });
59
+ expect(Qs.parse('a[b]=c')).to.deep.equal({ a: { b: 'c' } });
60
60
  done();
61
61
  });
62
62
 
63
63
  it('parses a double nested string', function (done) {
64
64
 
65
- expect(Qs.parse('a[b][c]=d')).to.deep.equal({ a: { b: { c: 'd' } } }, { prototype: false });
65
+ expect(Qs.parse('a[b][c]=d')).to.deep.equal({ a: { b: { c: 'd' } } });
66
66
  done();
67
67
  });
68
68
 
69
69
  it('defaults to a depth of 5', function (done) {
70
70
 
71
- expect(Qs.parse('a[b][c][d][e][f][g][h]=i')).to.deep.equal({ a: { b: { c: { d: { e: { f: { '[g][h]': 'i' } } } } } } }, { prototype: false });
71
+ expect(Qs.parse('a[b][c][d][e][f][g][h]=i')).to.deep.equal({ a: { b: { c: { d: { e: { f: { '[g][h]': 'i' } } } } } } });
72
72
  done();
73
73
  });
74
74
 
75
75
  it('only parses one level when depth = 1', function (done) {
76
76
 
77
- expect(Qs.parse('a[b][c]=d', { depth: 1 })).to.deep.equal({ a: { b: { '[c]': 'd' } } }, { prototype: false });
78
- expect(Qs.parse('a[b][c][d]=e', { depth: 1 })).to.deep.equal({ a: { b: { '[c][d]': 'e' } } }, { prototype: false });
77
+ expect(Qs.parse('a[b][c]=d', { depth: 1 })).to.deep.equal({ a: { b: { '[c]': 'd' } } });
78
+ expect(Qs.parse('a[b][c][d]=e', { depth: 1 })).to.deep.equal({ a: { b: { '[c][d]': 'e' } } });
79
79
  done();
80
80
  });
81
81
 
82
82
  it('parses a simple array', function (done) {
83
83
 
84
- expect(Qs.parse('a=b&a=c')).to.deep.equal({ a: ['b', 'c'] }, { prototype: false });
84
+ expect(Qs.parse('a=b&a=c')).to.deep.equal({ a: ['b', 'c'] });
85
85
  done();
86
86
  });
87
87
 
88
88
  it('parses an explicit array', function (done) {
89
89
 
90
- expect(Qs.parse('a[]=b')).to.deep.equal({ a: ['b'] }, { prototype: false });
91
- expect(Qs.parse('a[]=b&a[]=c')).to.deep.equal({ a: ['b', 'c'] }, { prototype: false });
92
- expect(Qs.parse('a[]=b&a[]=c&a[]=d')).to.deep.equal({ a: ['b', 'c', 'd'] }, { prototype: false });
90
+ expect(Qs.parse('a[]=b')).to.deep.equal({ a: ['b'] });
91
+ expect(Qs.parse('a[]=b&a[]=c')).to.deep.equal({ a: ['b', 'c'] });
92
+ expect(Qs.parse('a[]=b&a[]=c&a[]=d')).to.deep.equal({ a: ['b', 'c', 'd'] });
93
93
  done();
94
94
  });
95
95
 
96
96
  it('parses a mix of simple and explicit arrays', function (done) {
97
97
 
98
- expect(Qs.parse('a=b&a[]=c')).to.deep.equal({ a: ['b', 'c'] }, { prototype: false });
99
- expect(Qs.parse('a[]=b&a=c')).to.deep.equal({ a: ['b', 'c'] }, { prototype: false });
100
- expect(Qs.parse('a[0]=b&a=c')).to.deep.equal({ a: ['b', 'c'] }, { prototype: false });
101
- expect(Qs.parse('a=b&a[0]=c')).to.deep.equal({ a: ['b', 'c'] }, { prototype: false });
102
- expect(Qs.parse('a[1]=b&a=c')).to.deep.equal({ a: ['b', 'c'] }, { prototype: false });
103
- expect(Qs.parse('a=b&a[1]=c')).to.deep.equal({ a: ['b', 'c'] }, { prototype: false });
98
+ expect(Qs.parse('a=b&a[]=c')).to.deep.equal({ a: ['b', 'c'] });
99
+ expect(Qs.parse('a[]=b&a=c')).to.deep.equal({ a: ['b', 'c'] });
100
+ expect(Qs.parse('a[0]=b&a=c')).to.deep.equal({ a: ['b', 'c'] });
101
+ expect(Qs.parse('a=b&a[0]=c')).to.deep.equal({ a: ['b', 'c'] });
102
+ expect(Qs.parse('a[1]=b&a=c')).to.deep.equal({ a: ['b', 'c'] });
103
+ expect(Qs.parse('a=b&a[1]=c')).to.deep.equal({ a: ['b', 'c'] });
104
104
  done();
105
105
  });
106
106
 
107
107
  it('parses a nested array', function (done) {
108
108
 
109
- expect(Qs.parse('a[b][]=c&a[b][]=d')).to.deep.equal({ a: { b: ['c', 'd'] } }, { prototype: false });
110
- expect(Qs.parse('a[>=]=25')).to.deep.equal({ a: { '>=': '25' } }, { prototype: false });
109
+ expect(Qs.parse('a[b][]=c&a[b][]=d')).to.deep.equal({ a: { b: ['c', 'd'] } });
110
+ expect(Qs.parse('a[>=]=25')).to.deep.equal({ a: { '>=': '25' } });
111
111
  done();
112
112
  });
113
113
 
114
114
  it('allows to specify array indices', function (done) {
115
115
 
116
- expect(Qs.parse('a[1]=c&a[0]=b&a[2]=d')).to.deep.equal({ a: ['b', 'c', 'd'] }, { prototype: false });
117
- expect(Qs.parse('a[1]=c&a[0]=b')).to.deep.equal({ a: ['b', 'c'] }, { prototype: false });
118
- expect(Qs.parse('a[1]=c')).to.deep.equal({ a: ['c'] }, { prototype: false });
116
+ expect(Qs.parse('a[1]=c&a[0]=b&a[2]=d')).to.deep.equal({ a: ['b', 'c', 'd'] });
117
+ expect(Qs.parse('a[1]=c&a[0]=b')).to.deep.equal({ a: ['b', 'c'] });
118
+ expect(Qs.parse('a[1]=c')).to.deep.equal({ a: ['c'] });
119
119
  done();
120
120
  });
121
121
 
122
122
  it('limits specific array indices to 20', function (done) {
123
123
 
124
- expect(Qs.parse('a[20]=a')).to.deep.equal({ a: ['a'] }, { prototype: false });
125
- expect(Qs.parse('a[21]=a')).to.deep.equal({ a: { '21': 'a' } }, { prototype: false });
124
+ expect(Qs.parse('a[20]=a')).to.deep.equal({ a: ['a'] });
125
+ expect(Qs.parse('a[21]=a')).to.deep.equal({ a: { '21': 'a' } });
126
126
  done();
127
127
  });
128
128
 
129
129
  it('supports keys that begin with a number', function (done) {
130
130
 
131
- expect(Qs.parse('a[12b]=c')).to.deep.equal({ a: { '12b': 'c' } }, { prototype: false });
131
+ expect(Qs.parse('a[12b]=c')).to.deep.equal({ a: { '12b': 'c' } });
132
132
  done();
133
133
  });
134
134
 
135
135
  it('supports encoded = signs', function (done) {
136
136
 
137
- expect(Qs.parse('he%3Dllo=th%3Dere')).to.deep.equal({ 'he=llo': 'th=ere' }, { prototype: false });
137
+ expect(Qs.parse('he%3Dllo=th%3Dere')).to.deep.equal({ 'he=llo': 'th=ere' });
138
138
  done();
139
139
  });
140
140
 
141
141
  it('is ok with url encoded strings', function (done) {
142
142
 
143
- expect(Qs.parse('a[b%20c]=d')).to.deep.equal({ a: { 'b c': 'd' } }, { prototype: false });
144
- expect(Qs.parse('a[b]=c%20d')).to.deep.equal({ a: { b: 'c d' } }, { prototype: false });
143
+ expect(Qs.parse('a[b%20c]=d')).to.deep.equal({ a: { 'b c': 'd' } });
144
+ expect(Qs.parse('a[b]=c%20d')).to.deep.equal({ a: { b: 'c d' } });
145
145
  done();
146
146
  });
147
147
 
148
148
  it('allows brackets in the value', function (done) {
149
149
 
150
- expect(Qs.parse('pets=["tobi"]')).to.deep.equal({ pets: '["tobi"]' }, { prototype: false });
151
- expect(Qs.parse('operators=[">=", "<="]')).to.deep.equal({ operators: '[">=", "<="]' }, { prototype: false });
150
+ expect(Qs.parse('pets=["tobi"]')).to.deep.equal({ pets: '["tobi"]' });
151
+ expect(Qs.parse('operators=[">=", "<="]')).to.deep.equal({ operators: '[">=", "<="]' });
152
152
  done();
153
153
  });
154
154
 
155
155
  it('allows empty values', function (done) {
156
156
 
157
- expect(Qs.parse('')).to.deep.equal({}, { prototype: false });
158
- expect(Qs.parse(null)).to.deep.equal({}, { prototype: false });
159
- expect(Qs.parse(undefined)).to.deep.equal({}, { prototype: false });
157
+ expect(Qs.parse('')).to.deep.equal({});
158
+ expect(Qs.parse(null)).to.deep.equal({});
159
+ expect(Qs.parse(undefined)).to.deep.equal({});
160
160
  done();
161
161
  });
162
162
 
163
163
  it('transforms arrays to objects', function (done) {
164
164
 
165
- expect(Qs.parse('foo[0]=bar&foo[bad]=baz')).to.deep.equal({ foo: { '0': 'bar', bad: 'baz' } }, { prototype: false });
166
- expect(Qs.parse('foo[bad]=baz&foo[0]=bar')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } }, { prototype: false });
167
- expect(Qs.parse('foo[bad]=baz&foo[]=bar')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } }, { prototype: false });
168
- expect(Qs.parse('foo[]=bar&foo[bad]=baz')).to.deep.equal({ foo: { '0': 'bar', bad: 'baz' } }, { prototype: false });
169
- expect(Qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar', '1': 'foo' } }, { prototype: false });
170
- 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'} ]}, { prototype: false });
171
- expect(Qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c')).to.deep.equal({ a: { '0': 'b', t: 'u', hasOwnProperty: 'c' } }, { prototype: false });
172
- expect(Qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y')).to.deep.equal({ a: { '0': 'b', hasOwnProperty: 'c', x: 'y' } }, { prototype: false });
165
+ expect(Qs.parse('foo[0]=bar&foo[bad]=baz')).to.deep.equal({ foo: { '0': 'bar', bad: 'baz' } });
166
+ expect(Qs.parse('foo[bad]=baz&foo[0]=bar')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } });
167
+ expect(Qs.parse('foo[bad]=baz&foo[]=bar')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } });
168
+ expect(Qs.parse('foo[]=bar&foo[bad]=baz')).to.deep.equal({ foo: { '0': 'bar', bad: 'baz' } });
169
+ expect(Qs.parse('foo[bad]=baz&foo[]=bar&foo[]=foo')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
170
+ 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' }] });
171
+ expect(Qs.parse('a[]=b&a[t]=u&a[hasOwnProperty]=c')).to.deep.equal({ a: { '0': 'b', t: 'u', c: true } });
172
+ expect(Qs.parse('a[]=b&a[hasOwnProperty]=c&a[x]=y')).to.deep.equal({ a: { '0': 'b', '1': 'c', x: 'y' } });
173
173
  done();
174
174
  });
175
175
 
176
176
  it('transforms arrays to objects (dot notation)', function (done) {
177
177
 
178
- expect(Qs.parse('foo[0].baz=bar&fool.bad=baz')).to.deep.equal({ foo: [ { baz: 'bar'} ], fool: { bad: 'baz' } }, { prototype: false });
179
- expect(Qs.parse('foo[0].baz=bar&fool.bad.boo=baz')).to.deep.equal({ foo: [ { baz: 'bar'} ], fool: { bad: { boo: 'baz' } } }, { prototype: false });
180
- expect(Qs.parse('foo[0][0].baz=bar&fool.bad=baz')).to.deep.equal({ foo: [[ { baz: 'bar'} ]], fool: { bad: 'baz' } }, { prototype: false });
181
- expect(Qs.parse('foo[0].baz[0]=15&foo[0].bar=2')).to.deep.equal({ foo: [{ baz: ['15'], bar: '2' }] }, { prototype: false });
182
- expect(Qs.parse('foo[0].baz[0]=15&foo[0].baz[1]=16&foo[0].bar=2')).to.deep.equal({ foo: [{ baz: ['15', '16'], bar: '2' }] }, { prototype: false });
183
- expect(Qs.parse('foo.bad=baz&foo[0]=bar')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } }, { prototype: false });
184
- expect(Qs.parse('foo.bad=baz&foo[]=bar')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } }, { prototype: false });
185
- expect(Qs.parse('foo[]=bar&foo.bad=baz')).to.deep.equal({ foo: { '0': 'bar', bad: 'baz' } }, { prototype: false });
186
- expect(Qs.parse('foo.bad=baz&foo[]=bar&foo[]=foo')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar', '1': 'foo' } }, { prototype: false });
187
- 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'} ]}, { prototype: false });
178
+ expect(Qs.parse('foo[0].baz=bar&fool.bad=baz')).to.deep.equal({ foo: [{ baz: 'bar' }], fool: { bad: 'baz' } });
179
+ expect(Qs.parse('foo[0].baz=bar&fool.bad.boo=baz')).to.deep.equal({ foo: [{ baz: 'bar' }], fool: { bad: { boo: 'baz' } } });
180
+ expect(Qs.parse('foo[0][0].baz=bar&fool.bad=baz')).to.deep.equal({ foo: [[{ baz: 'bar' }]], fool: { bad: 'baz' } });
181
+ expect(Qs.parse('foo[0].baz[0]=15&foo[0].bar=2')).to.deep.equal({ foo: [{ baz: ['15'], bar: '2' }] });
182
+ expect(Qs.parse('foo[0].baz[0]=15&foo[0].baz[1]=16&foo[0].bar=2')).to.deep.equal({ foo: [{ baz: ['15', '16'], bar: '2' }] });
183
+ expect(Qs.parse('foo.bad=baz&foo[0]=bar')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } });
184
+ expect(Qs.parse('foo.bad=baz&foo[]=bar')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar' } });
185
+ expect(Qs.parse('foo[]=bar&foo.bad=baz')).to.deep.equal({ foo: { '0': 'bar', bad: 'baz' } });
186
+ expect(Qs.parse('foo.bad=baz&foo[]=bar&foo[]=foo')).to.deep.equal({ foo: { bad: 'baz', '0': 'bar', '1': 'foo' } });
187
+ 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' }] });
188
188
  done();
189
189
  });
190
190
 
191
191
  it('can add keys to objects', function (done) {
192
192
 
193
- expect(Qs.parse('a[b]=c&a=d')).to.deep.equal({ a: { b: 'c', d: true } }, { prototype: false });
193
+ expect(Qs.parse('a[b]=c&a=d')).to.deep.equal({ a: { b: 'c', d: true } });
194
194
  done();
195
195
  });
196
196
 
197
197
  it('correctly prunes undefined values when converting an array to an object', function (done) {
198
198
 
199
- expect(Qs.parse('a[2]=b&a[99999999]=c')).to.deep.equal({ a: { '2': 'b', '99999999': 'c' } }, { prototype: false });
199
+ expect(Qs.parse('a[2]=b&a[99999999]=c')).to.deep.equal({ a: { '2': 'b', '99999999': 'c' } });
200
200
  done();
201
201
  });
202
202
 
203
203
  it('supports malformed uri characters', function (done) {
204
204
 
205
- expect(Qs.parse('{%:%}', {strictNullHandling: true})).to.deep.equal({ '{%:%}': null }, { prototype: false });
206
- expect(Qs.parse('{%:%}=')).to.deep.equal({ '{%:%}': '' }, { prototype: false });
207
- expect(Qs.parse('foo=%:%}')).to.deep.equal({ foo: '%:%}' }, { prototype: false });
205
+ expect(Qs.parse('{%:%}', { strictNullHandling: true })).to.deep.equal({ '{%:%}': null });
206
+ expect(Qs.parse('{%:%}=')).to.deep.equal({ '{%:%}': '' });
207
+ expect(Qs.parse('foo=%:%}')).to.deep.equal({ foo: '%:%}' });
208
208
  done();
209
209
  });
210
210
 
211
211
  it('doesn\'t produce empty keys', function (done) {
212
212
 
213
- expect(Qs.parse('_r=1&')).to.deep.equal({ '_r': '1' }, { prototype: false });
213
+ expect(Qs.parse('_r=1&')).to.deep.equal({ '_r': '1' });
214
214
  done();
215
215
  });
216
216
 
@@ -224,45 +224,45 @@ describe('parse()', function () {
224
224
 
225
225
  it('parses arrays of objects', function (done) {
226
226
 
227
- expect(Qs.parse('a[][b]=c')).to.deep.equal({ a: [{ b: 'c' }] }, { prototype: false });
228
- expect(Qs.parse('a[0][b]=c')).to.deep.equal({ a: [{ b: 'c' }] }, { prototype: false });
227
+ expect(Qs.parse('a[][b]=c')).to.deep.equal({ a: [{ b: 'c' }] });
228
+ expect(Qs.parse('a[0][b]=c')).to.deep.equal({ a: [{ b: 'c' }] });
229
229
  done();
230
230
  });
231
231
 
232
232
  it('allows for empty strings in arrays', function (done) {
233
233
 
234
- expect(Qs.parse('a[]=b&a[]=&a[]=c')).to.deep.equal({ a: ['b', '', 'c'] }, { prototype: false });
235
- expect(Qs.parse('a[0]=b&a[1]&a[2]=c&a[19]=', {strictNullHandling: true})).to.deep.equal({ a: ['b', null, 'c', ''] }, { prototype: false });
236
- expect(Qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]', {strictNullHandling: true})).to.deep.equal({ a: ['b', '', 'c', null] }, { prototype: false });
237
- expect(Qs.parse('a[]=&a[]=b&a[]=c')).to.deep.equal({ a: ['', 'b', 'c'] }, { prototype: false });
234
+ expect(Qs.parse('a[]=b&a[]=&a[]=c')).to.deep.equal({ a: ['b', '', 'c'] });
235
+ expect(Qs.parse('a[0]=b&a[1]&a[2]=c&a[19]=', { strictNullHandling: true })).to.deep.equal({ a: ['b', null, 'c', ''] });
236
+ expect(Qs.parse('a[0]=b&a[1]=&a[2]=c&a[19]', { strictNullHandling: true })).to.deep.equal({ a: ['b', '', 'c', null] });
237
+ expect(Qs.parse('a[]=&a[]=b&a[]=c')).to.deep.equal({ a: ['', 'b', 'c'] });
238
238
  done();
239
239
  });
240
240
 
241
241
  it('compacts sparse arrays', function (done) {
242
242
 
243
- expect(Qs.parse('a[10]=1&a[2]=2')).to.deep.equal({ a: ['2', '1'] }, { prototype: false });
243
+ expect(Qs.parse('a[10]=1&a[2]=2')).to.deep.equal({ a: ['2', '1'] });
244
244
  done();
245
245
  });
246
246
 
247
247
  it('parses semi-parsed strings', function (done) {
248
248
 
249
- expect(Qs.parse({ 'a[b]': 'c' })).to.deep.equal({ a: { b: 'c' } }, { prototype: false });
250
- expect(Qs.parse({ 'a[b]': 'c', 'a[d]': 'e' })).to.deep.equal({ a: { b: 'c', d: 'e' } }, { prototype: false });
249
+ expect(Qs.parse({ 'a[b]': 'c' })).to.deep.equal({ a: { b: 'c' } });
250
+ expect(Qs.parse({ 'a[b]': 'c', 'a[d]': 'e' })).to.deep.equal({ a: { b: 'c', d: 'e' } });
251
251
  done();
252
252
  });
253
253
 
254
254
  it('parses buffers correctly', function (done) {
255
255
 
256
256
  var b = new Buffer('test');
257
- expect(Qs.parse({ a: b })).to.deep.equal({ a: b }, { prototype: false });
257
+ expect(Qs.parse({ a: b })).to.deep.equal({ a: b });
258
258
  done();
259
259
  });
260
260
 
261
261
  it('continues parsing when no parent is found', function (done) {
262
262
 
263
- expect(Qs.parse('[]=&a=b')).to.deep.equal({ '0': '', a: 'b' }, { prototype: false });
264
- expect(Qs.parse('[]&a=b', {strictNullHandling: true})).to.deep.equal({ '0': null, a: 'b' }, { prototype: false });
265
- expect(Qs.parse('[foo]=bar')).to.deep.equal({ foo: 'bar' }, { prototype: false });
263
+ expect(Qs.parse('[]=&a=b')).to.deep.equal({ '0': '', a: 'b' });
264
+ expect(Qs.parse('[]&a=b', { strictNullHandling: true })).to.deep.equal({ '0': null, a: 'b' });
265
+ expect(Qs.parse('[foo]=bar')).to.deep.equal({ foo: 'bar' });
266
266
  done();
267
267
  });
268
268
 
@@ -286,9 +286,9 @@ describe('parse()', function () {
286
286
  Object.prototype.crash = '';
287
287
  Array.prototype.crash = '';
288
288
  expect(Qs.parse.bind(null, 'a=b')).to.not.throw();
289
- expect(Qs.parse('a=b')).to.deep.equal({ a: 'b' }, { prototype: false });
289
+ expect(Qs.parse('a=b')).to.deep.equal({ a: 'b' });
290
290
  expect(Qs.parse.bind(null, 'a[][b]=c')).to.not.throw();
291
- expect(Qs.parse('a[][b]=c')).to.deep.equal({ a: [{ b: 'c' }] }, { prototype: false });
291
+ expect(Qs.parse('a[][b]=c')).to.deep.equal({ a: [{ b: 'c' }] });
292
292
  delete Object.prototype.crash;
293
293
  delete Array.prototype.crash;
294
294
  done();
@@ -296,105 +296,105 @@ describe('parse()', function () {
296
296
 
297
297
  it('parses a string with an alternative string delimiter', function (done) {
298
298
 
299
- expect(Qs.parse('a=b;c=d', { delimiter: ';' })).to.deep.equal({ a: 'b', c: 'd' }, { prototype: false });
299
+ expect(Qs.parse('a=b;c=d', { delimiter: ';' })).to.deep.equal({ a: 'b', c: 'd' });
300
300
  done();
301
301
  });
302
302
 
303
303
  it('parses a string with an alternative RegExp delimiter', function (done) {
304
304
 
305
- expect(Qs.parse('a=b; c=d', { delimiter: /[;,] */ })).to.deep.equal({ a: 'b', c: 'd' }, { prototype: false });
305
+ expect(Qs.parse('a=b; c=d', { delimiter: /[;,] */ })).to.deep.equal({ a: 'b', c: 'd' });
306
306
  done();
307
307
  });
308
308
 
309
309
  it('does not use non-splittable objects as delimiters', function (done) {
310
310
 
311
- expect(Qs.parse('a=b&c=d', { delimiter: true })).to.deep.equal({ a: 'b', c: 'd' }, { prototype: false });
311
+ expect(Qs.parse('a=b&c=d', { delimiter: true })).to.deep.equal({ a: 'b', c: 'd' });
312
312
  done();
313
313
  });
314
314
 
315
315
  it('allows overriding parameter limit', function (done) {
316
316
 
317
- expect(Qs.parse('a=b&c=d', { parameterLimit: 1 })).to.deep.equal({ a: 'b' }, { prototype: false });
317
+ expect(Qs.parse('a=b&c=d', { parameterLimit: 1 })).to.deep.equal({ a: 'b' });
318
318
  done();
319
319
  });
320
320
 
321
321
  it('allows setting the parameter limit to Infinity', function (done) {
322
322
 
323
- expect(Qs.parse('a=b&c=d', { parameterLimit: Infinity })).to.deep.equal({ a: 'b', c: 'd' }, { prototype: false });
323
+ expect(Qs.parse('a=b&c=d', { parameterLimit: Infinity })).to.deep.equal({ a: 'b', c: 'd' });
324
324
  done();
325
325
  });
326
326
 
327
327
  it('allows overriding array limit', function (done) {
328
328
 
329
- expect(Qs.parse('a[0]=b', { arrayLimit: -1 })).to.deep.equal({ a: { '0': 'b' } }, { prototype: false });
330
- expect(Qs.parse('a[-1]=b', { arrayLimit: -1 })).to.deep.equal({ a: { '-1': 'b' } }, { prototype: false });
331
- expect(Qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 })).to.deep.equal({ a: { '0': 'b', '1': 'c' } }, { prototype: false });
329
+ expect(Qs.parse('a[0]=b', { arrayLimit: -1 })).to.deep.equal({ a: { '0': 'b' } });
330
+ expect(Qs.parse('a[-1]=b', { arrayLimit: -1 })).to.deep.equal({ a: { '-1': 'b' } });
331
+ expect(Qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 })).to.deep.equal({ a: { '0': 'b', '1': 'c' } });
332
332
  done();
333
333
  });
334
334
 
335
335
  it('allows disabling array parsing', function (done) {
336
336
 
337
- expect(Qs.parse('a[0]=b&a[1]=c', { parseArrays: false })).to.deep.equal({ a: { '0': 'b', '1': 'c' } }, { prototype: false });
337
+ expect(Qs.parse('a[0]=b&a[1]=c', { parseArrays: false })).to.deep.equal({ a: { '0': 'b', '1': 'c' } });
338
338
  done();
339
339
  });
340
340
 
341
341
  it('parses an object', function (done) {
342
342
 
343
343
  var input = {
344
- 'user[name]': {'pop[bob]': 3},
344
+ 'user[name]': { 'pop[bob]': 3 },
345
345
  'user[email]': null
346
346
  };
347
347
 
348
348
  var expected = {
349
349
  'user': {
350
- 'name': {'pop[bob]': 3},
350
+ 'name': { 'pop[bob]': 3 },
351
351
  'email': null
352
352
  }
353
353
  };
354
354
 
355
355
  var result = Qs.parse(input);
356
356
 
357
- expect(result).to.deep.equal(expected, { prototype: false });
357
+ expect(result).to.deep.equal(expected);
358
358
  done();
359
359
  });
360
360
 
361
361
  it('parses an object in dot notation', function (done) {
362
362
 
363
363
  var input = {
364
- 'user.name': {'pop[bob]': 3},
364
+ 'user.name': { 'pop[bob]': 3 },
365
365
  'user.email.': null
366
366
  };
367
367
 
368
368
  var expected = {
369
369
  'user': {
370
- 'name': {'pop[bob]': 3},
370
+ 'name': { 'pop[bob]': 3 },
371
371
  'email': null
372
372
  }
373
373
  };
374
374
 
375
375
  var result = Qs.parse(input);
376
376
 
377
- expect(result).to.deep.equal(expected, { prototype: false });
377
+ expect(result).to.deep.equal(expected);
378
378
  done();
379
379
  });
380
380
 
381
381
  it('parses an object and not child values', function (done) {
382
382
 
383
383
  var input = {
384
- 'user[name]': {'pop[bob]': { 'test': 3 }},
384
+ 'user[name]': { 'pop[bob]': { 'test': 3 } },
385
385
  'user[email]': null
386
386
  };
387
387
 
388
388
  var expected = {
389
389
  'user': {
390
- 'name': {'pop[bob]': { 'test': 3 }},
390
+ 'name': { 'pop[bob]': { 'test': 3 } },
391
391
  'email': null
392
392
  }
393
393
  };
394
394
 
395
395
  var result = Qs.parse(input);
396
396
 
397
- expect(result).to.deep.equal(expected, { prototype: false });
397
+ expect(result).to.deep.equal(expected);
398
398
  done();
399
399
  });
400
400
 
@@ -404,7 +404,7 @@ describe('parse()', function () {
404
404
  delete global.Buffer;
405
405
  var result = Qs.parse('a=b&c=d');
406
406
  global.Buffer = tempBuffer;
407
- expect(result).to.deep.equal({ a: 'b', c: 'd' }, { prototype: false });
407
+ expect(result).to.deep.equal({ a: 'b', c: 'd' });
408
408
  done();
409
409
  });
410
410
 
@@ -423,7 +423,7 @@ describe('parse()', function () {
423
423
  expect(parsed).to.contain('foo');
424
424
  expect(parsed.foo).to.contain('bar', 'baz');
425
425
  expect(parsed.foo.bar).to.equal('baz');
426
- expect(parsed.foo.baz).to.deep.equal(a, { prototype: false });
426
+ expect(parsed.foo.baz).to.deep.equal(a);
427
427
  done();
428
428
  });
429
429
 
@@ -432,24 +432,47 @@ describe('parse()', function () {
432
432
  var a = Object.create(null);
433
433
  a.b = 'c';
434
434
 
435
- expect(Qs.parse(a)).to.deep.equal({ b: 'c' }, { prototype: false });
435
+ expect(Qs.parse(a)).to.deep.equal({ b: 'c' });
436
436
  var result = Qs.parse({ a: a });
437
437
  expect(result).to.contain('a');
438
- expect(result.a).to.deep.equal(a, { prototype: false });
438
+ expect(result.a).to.deep.equal(a);
439
439
  done();
440
440
  });
441
441
 
442
442
  it('parses dates correctly', function (done) {
443
443
 
444
444
  var now = new Date();
445
- expect(Qs.parse({ a: now })).to.deep.equal({ a: now }, { prototype: false });
445
+ expect(Qs.parse({ a: now })).to.deep.equal({ a: now });
446
446
  done();
447
447
  });
448
448
 
449
449
  it('parses regular expressions correctly', function (done) {
450
450
 
451
451
  var re = /^test$/;
452
- expect(Qs.parse({ a: re })).to.deep.equal({ a: re }, { prototype: false });
452
+ expect(Qs.parse({ a: re })).to.deep.equal({ a: re });
453
+ done();
454
+ });
455
+
456
+ it('can allow overwriting prototype properties', function (done) {
457
+
458
+ expect(Qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true })).to.deep.equal({ a: { hasOwnProperty: 'b' } }, { prototype: false });
459
+ expect(Qs.parse('hasOwnProperty=b', { allowPrototypes: true })).to.deep.equal({ hasOwnProperty: 'b' }, { prototype: false });
460
+ done();
461
+ });
462
+
463
+ it('can return plain objects', function (done) {
464
+
465
+ var expected = Object.create(null);
466
+ expected.a = Object.create(null);
467
+ expected.a.b = 'c';
468
+ expected.a.hasOwnProperty = 'd';
469
+ expect(Qs.parse('a[b]=c&a[hasOwnProperty]=d', { plainObjects: true })).to.deep.equal(expected);
470
+ expect(Qs.parse(null, { plainObjects: true })).to.deep.equal(Object.create(null));
471
+ var expectedArray = Object.create(null);
472
+ expectedArray.a = Object.create(null);
473
+ expectedArray.a['0'] = 'b';
474
+ expectedArray.a.c = 'd';
475
+ expect(Qs.parse('a[]=b&a[c]=d', { plainObjects: true })).to.deep.equal(expectedArray);
453
476
  done();
454
477
  });
455
478
  });
package/test/stringify.js CHANGED
@@ -111,14 +111,14 @@ describe('stringify()', function () {
111
111
  it('stringifies an empty value', function (done) {
112
112
 
113
113
  expect(Qs.stringify({ a: '' })).to.equal('a=');
114
- expect(Qs.stringify({ a: null }, {strictNullHandling: true})).to.equal('a');
114
+ expect(Qs.stringify({ a: null }, { strictNullHandling: true })).to.equal('a');
115
115
 
116
116
  expect(Qs.stringify({ a: '', b: '' })).to.equal('a=&b=');
117
- expect(Qs.stringify({ a: null, b: '' }, {strictNullHandling: true})).to.equal('a&b=');
117
+ expect(Qs.stringify({ a: null, b: '' }, { strictNullHandling: true })).to.equal('a&b=');
118
118
 
119
119
  expect(Qs.stringify({ a: { b: '' } })).to.equal('a%5Bb%5D=');
120
- expect(Qs.stringify({ a: { b: null } }, {strictNullHandling: true})).to.equal('a%5Bb%5D');
121
- expect(Qs.stringify({ a: { b: null } }, {strictNullHandling: false})).to.equal('a%5Bb%5D=');
120
+ expect(Qs.stringify({ a: { b: null } }, { strictNullHandling: true })).to.equal('a%5Bb%5D');
121
+ expect(Qs.stringify({ a: { b: null } }, { strictNullHandling: false })).to.equal('a%5Bb%5D=');
122
122
 
123
123
  done();
124
124
  });
@@ -155,8 +155,8 @@ describe('stringify()', function () {
155
155
 
156
156
  expect(Qs.stringify({ a: undefined })).to.equal('');
157
157
 
158
- expect(Qs.stringify({ a: { b: undefined, c: null } }, {strictNullHandling: true})).to.equal('a%5Bc%5D');
159
- expect(Qs.stringify({ a: { b: undefined, c: null } }, {strictNullHandling: false})).to.equal('a%5Bc%5D=');
158
+ expect(Qs.stringify({ a: { b: undefined, c: null } }, { strictNullHandling: true })).to.equal('a%5Bc%5D');
159
+ expect(Qs.stringify({ a: { b: undefined, c: null } }, { strictNullHandling: false })).to.equal('a%5Bc%5D=');
160
160
  expect(Qs.stringify({ a: { b: undefined, c: '' } })).to.equal('a%5Bc%5D=');
161
161
  done();
162
162
  });
@@ -184,7 +184,7 @@ describe('stringify()', function () {
184
184
  it('skips properties that are part of the object prototype', function (done) {
185
185
 
186
186
  Object.prototype.crash = 'test';
187
- expect(Qs.stringify({ a: 'b'})).to.equal('a=b');
187
+ expect(Qs.stringify({ a: 'b' })).to.equal('a=b');
188
188
  expect(Qs.stringify({ a: { b: 'c' } })).to.equal('a%5Bb%5D=c');
189
189
  delete Object.prototype.crash;
190
190
  done();
@@ -224,8 +224,8 @@ describe('stringify()', function () {
224
224
  it('selects properties when filter=array', function (done) {
225
225
 
226
226
  expect(Qs.stringify({ a: 'b' }, { filter: ['a'] })).to.equal('a=b');
227
- expect(Qs.stringify({ a: 1}, { filter: [] })).to.equal('');
228
- expect(Qs.stringify({ a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, { filter: ['a', 'b', 0, 2]})).to.equal('a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3');
227
+ expect(Qs.stringify({ a: 1 }, { filter: [] })).to.equal('');
228
+ expect(Qs.stringify({ a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, { filter: ['a', 'b', 0, 2] })).to.equal('a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3');
229
229
  done();
230
230
 
231
231
  });
package/.jshintignore DELETED
@@ -1 +0,0 @@
1
- node_modules
package/.jshintrc DELETED
@@ -1,10 +0,0 @@
1
- {
2
- "node": true,
3
-
4
- "curly": true,
5
- "latedef": true,
6
- "quotmark": true,
7
- "undef": true,
8
- "unused": true,
9
- "trailing": true
10
- }
package/Makefile DELETED
@@ -1,8 +0,0 @@
1
- test:
2
- @node node_modules/lab/bin/lab -a code -L
3
- test-cov:
4
- @node node_modules/lab/bin/lab -a code -t 100 -L
5
- test-cov-html:
6
- @node node_modules/lab/bin/lab -a code -L -r html -o coverage.html
7
-
8
- .PHONY: test test-cov test-cov-html
package/index.js DELETED
@@ -1 +0,0 @@
1
- module.exports = require('./lib/');