Skip to content

Commit d89b173

Browse files
committed
[Docs] Add evalmd, fix broken examples in README, and ensure all examples have assertions.
1 parent 807c310 commit d89b173

File tree

2 files changed

+79
-73
lines changed

2 files changed

+79
-73
lines changed

README.md

+74-70
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,18 @@ The **qs** module was originally created and maintained by [TJ Holowaychuk](http
1212

1313
```javascript
1414
var qs = require('qs');
15+
var assert = require('assert');
1516

16-
var obj = qs.parse('a=c'); // { a: 'c' }
17-
var str = qs.stringify(obj); // 'a=c'
17+
var obj = qs.parse('a=c');
18+
assert.deepEqual(obj, { a: 'c' });
19+
20+
var str = qs.stringify(obj);
21+
assert.equal(str, 'a=c');
1822
```
1923

2024
### Parsing Objects
2125

26+
[](#preventEval)
2227
```javascript
2328
qs.parse(string, [options]);
2429
```
@@ -27,51 +32,52 @@ qs.parse(string, [options]);
2732
For example, the string `'foo[bar]=baz'` converts to:
2833

2934
```javascript
30-
{
35+
assert.deepEqual(qs.parse('foo[bar]=baz'), {
3136
foo: {
3237
bar: 'baz'
3338
}
34-
}
39+
});
3540
```
3641

3742
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:
3843

3944
```javascript
40-
qs.parse('a.hasOwnProperty=b', { plainObjects: true });
41-
// { a: { hasOwnProperty: 'b' } }
45+
var plainObject = qs.parse('a[hasOwnProperty]=b', { plainObjects: true });
46+
assert.deepEqual(plainObject, { a: { hasOwnProperty: 'b' } });
4247
```
4348

4449
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.
4550

4651
```javascript
47-
qs.parse('a.hasOwnProperty=b', { allowPrototypes: true });
48-
// { a: { hasOwnProperty: 'b' } }
52+
var protoObject = qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true });
53+
assert.deepEqual(protoObject, { a: { hasOwnProperty: 'b' } });
4954
```
5055

5156
URI encoded strings work too:
5257

5358
```javascript
54-
qs.parse('a%5Bb%5D=c');
55-
// { a: { b: 'c' } }
59+
assert.deepEqual(qs.parse('a%5Bb%5D=c'), {
60+
a: { b: 'c' }
61+
});
5662
```
5763

5864
You can also nest your objects, like `'foo[bar][baz]=foobarbaz'`:
5965

6066
```javascript
61-
{
67+
assert.deepEqual(qs.parse('foo[bar][baz]=foobarbaz'), {
6268
foo: {
6369
bar: {
6470
baz: 'foobarbaz'
6571
}
6672
}
67-
}
73+
});
6874
```
6975

7076
By default, when nesting objects **qs** will only parse up to 5 children deep. This means if you attempt to parse a string like
7177
`'a[b][c][d][e][f][g][h][i]=j'` your resulting object will be:
7278

7379
```javascript
74-
{
80+
var expected = {
7581
a: {
7682
b: {
7783
c: {
@@ -85,136 +91,138 @@ By default, when nesting objects **qs** will only parse up to 5 children deep. T
8591
}
8692
}
8793
}
88-
}
94+
};
95+
var string = 'a[b][c][d][e][f][g][h][i]=j';
96+
assert.deepEqual(qs.parse(string), expected);
8997
```
9098

9199
This depth can be overridden by passing a `depth` option to `qs.parse(string, [options])`:
92100

93101
```javascript
94-
qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });
95-
// { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }
102+
var deep = qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });
103+
assert.deepEqual(deep, { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } });
96104
```
97105

98106
The depth limit helps mitigate abuse when **qs** is used to parse user input, and it is recommended to keep it a reasonably small number.
99107

100108
For similar reasons, by default **qs** will only parse up to 1000 parameters. This can be overridden by passing a `parameterLimit` option:
101109

102110
```javascript
103-
qs.parse('a=b&c=d', { parameterLimit: 1 });
104-
// { a: 'b' }
111+
var limited = qs.parse('a=b&c=d', { parameterLimit: 1 });
112+
assert.deepEqual(limited, { a: 'b' });
105113
```
106114

107115
An optional delimiter can also be passed:
108116

109117
```javascript
110-
qs.parse('a=b;c=d', { delimiter: ';' });
111-
// { a: 'b', c: 'd' }
118+
var delimited = qs.parse('a=b;c=d', { delimiter: ';' });
119+
assert.deepEqual(delimited, { a: 'b', c: 'd' });
112120
```
113121

114122
Delimiters can be a regular expression too:
115123

116124
```javascript
117-
qs.parse('a=b;c=d,e=f', { delimiter: /[;,]/ });
118-
// { a: 'b', c: 'd', e: 'f' }
125+
var regexed = qs.parse('a=b;c=d,e=f', { delimiter: /[;,]/ });
126+
assert.deepEqual(regexed, { a: 'b', c: 'd', e: 'f' });
119127
```
120128

121129
Option `allowDots` can be used to enable dot notation:
122130

123131
```javascript
124-
qs.parse('a.b=c', { allowDots: true });
125-
// { a: { b: 'c' } }
132+
var withDots = qs.parse('a.b=c', { allowDots: true });
133+
assert.deepEqual(withDots, { a: { b: 'c' } });
126134
```
127135

128136
### Parsing Arrays
129137

130138
**qs** can also parse arrays using a similar `[]` notation:
131139

132140
```javascript
133-
qs.parse('a[]=b&a[]=c');
134-
// { a: ['b', 'c'] }
141+
var withArray = qs.parse('a[]=b&a[]=c');
142+
assert.deepEqual(withArray, { a: ['b', 'c'] });
135143
```
136144

137145
You may specify an index as well:
138146

139147
```javascript
140-
qs.parse('a[1]=c&a[0]=b');
141-
// { a: ['b', 'c'] }
148+
var withIndexes = qs.parse('a[1]=c&a[0]=b');
149+
assert.deepEqual(withIndexes, { a: ['b', 'c'] });
142150
```
143151

144152
Note that the only difference between an index in an array and a key in an object is that the value between the brackets must be a number
145153
to create an array. When creating arrays with specific indices, **qs** will compact a sparse array to only the existing values preserving
146154
their order:
147155

148156
```javascript
149-
qs.parse('a[1]=b&a[15]=c');
150-
// { a: ['b', 'c'] }
157+
var noSparse = qs.parse('a[1]=b&a[15]=c');
158+
assert.deepEqual(noSparse, { a: ['b', 'c'] });
151159
```
152160

153161
Note that an empty string is also a value, and will be preserved:
154162

155163
```javascript
156-
qs.parse('a[]=&a[]=b');
157-
// { a: ['', 'b'] }
158-
qs.parse('a[0]=b&a[1]=&a[2]=c');
159-
// { a: ['b', '', 'c'] }
164+
var withEmptyString = qs.parse('a[]=&a[]=b');
165+
assert.deepEqual(withEmptyString, { a: ['', 'b'] });
166+
167+
var withIndexedEmptyString = qs.parse('a[0]=b&a[1]=&a[2]=c');
168+
assert.deepEqual(withIndexedEmptyString, { a: ['b', '', 'c'] });
160169
```
161170

162171
**qs** will also limit specifying indices in an array to a maximum index of `20`. Any array members with an index of greater than `20` will
163172
instead be converted to an object with the index as the key:
164173

165174
```javascript
166-
qs.parse('a[100]=b');
167-
// { a: { '100': 'b' } }
175+
var withMaxIndex = qs.parse('a[100]=b');
176+
assert.deepEqual(withMaxIndex, { a: { '100': 'b' } });
168177
```
169178

170179
This limit can be overridden by passing an `arrayLimit` option:
171180

172181
```javascript
173-
qs.parse('a[1]=b', { arrayLimit: 0 });
174-
// { a: { '1': 'b' } }
182+
var withArrayLimit = qs.parse('a[1]=b', { arrayLimit: 0 });
183+
assert.deepEqual(withArrayLimit, { a: { '1': 'b' } });
175184
```
176185

177186
To disable array parsing entirely, set `parseArrays` to `false`.
178187

179188
```javascript
180-
qs.parse('a[]=b', { parseArrays: false });
181-
// { a: { '0': 'b' } }
189+
var noParsingArrays = qs.parse('a[]=b', { parseArrays: false });
190+
assert.deepEqual(noParsingArrays, { a: { '0': 'b' } });
182191
```
183192

184193
If you mix notations, **qs** will merge the two items into an object:
185194

186195
```javascript
187-
qs.parse('a[0]=b&a[b]=c');
188-
// { a: { '0': 'b', b: 'c' } }
196+
var mixedNotation = qs.parse('a[0]=b&a[b]=c');
197+
assert.deepEqual(mixedNotation, { a: { '0': 'b', b: 'c' } });
189198
```
190199

191200
You can also create arrays of objects:
192201

193202
```javascript
194-
qs.parse('a[][b]=c');
195-
// { a: [{ b: 'c' }] }
203+
var arraysOfObjects = qs.parse('a[][b]=c');
204+
assert.deepEqual(arraysOfObjects, { a: [{ b: 'c' }] });
196205
```
197206

198207
### Stringifying
199208

209+
[](#preventEval)
200210
```javascript
201211
qs.stringify(object, [options]);
202212
```
203213

204214
When stringifying, **qs** by default URI encodes output. Objects are stringified as you would expect:
205215

206216
```javascript
207-
qs.stringify({ a: 'b' });
208-
// 'a=b'
209-
qs.stringify({ a: { b: 'c' } });
210-
// 'a%5Bb%5D=c'
217+
assert.equal(qs.stringify({ a: 'b' }), 'a=b');
218+
assert.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c');
211219
```
212220

213221
This encoding can be disabled by setting the `encode` option to `false`:
214222

215223
```javascript
216-
qs.stringify({ a: { b: 'c' } }, { encode: false });
217-
// 'a[b]=c'
224+
var unencoded = qs.stringify({ a: { b: 'c' } }, { encode: false });
225+
assert.equal(unencoded, 'a[b]=c');
218226
```
219227

220228
Examples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases *will* be URI encoded during real usage.
@@ -247,22 +255,19 @@ qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
247255
Empty strings and null values will omit the value, but the equals sign (=) remains in place:
248256

249257
```javascript
250-
qs.stringify({ a: '' });
251-
// 'a='
258+
assert.equal(qs.stringify({ a: '' }), 'a=');
252259
```
253260

254261
Properties that are set to `undefined` will be omitted entirely:
255262

256263
```javascript
257-
qs.stringify({ a: null, b: undefined });
258-
// 'a='
264+
assert.equal(qs.stringify({ a: null, b: undefined }), 'a=');
259265
```
260266

261267
The delimiter may be overridden with stringify as well:
262268

263269
```javascript
264-
qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' });
265-
// 'a=b;c=d'
270+
assert.equal(qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' }), 'a=b;c=d');
266271
```
267272

268273
Finally, you can use the `filter` option to restrict which keys will be included in the stringified output.
@@ -283,11 +288,11 @@ function filterFunc(prefix, value) {
283288
}
284289
return value;
285290
}
286-
qs.stringify({ a: 'b', c: 'd', e: { f: new Date(123), g: [2] } }, { filter: filterFunc })
291+
qs.stringify({ a: 'b', c: 'd', e: { f: new Date(123), g: [2] } }, { filter: filterFunc });
287292
// 'a=b&c=d&e[f]=123&e[g][0]=4'
288-
qs.stringify({ a: 'b', c: 'd', e: 'f' }, { filter: ['a', 'e'] })
293+
qs.stringify({ a: 'b', c: 'd', e: 'f' }, { filter: ['a', 'e'] });
289294
// 'a=b&e=f'
290-
qs.stringify({ a: ['b', 'c', 'd'], e: 'f' }, { filter: ['a', 0, 2] })
295+
qs.stringify({ a: ['b', 'c', 'd'], e: 'f' }, { filter: ['a', 0, 2] });
291296
// 'a[0]=b&a[2]=d'
292297
```
293298

@@ -296,36 +301,35 @@ qs.stringify({ a: ['b', 'c', 'd'], e: 'f' }, { filter: ['a', 0, 2] })
296301
By default, `null` values are treated like empty strings:
297302

298303
```javascript
299-
qs.stringify({ a: null, b: '' });
300-
// 'a=&b='
304+
var withNull = qs.stringify({ a: null, b: '' });
305+
assert.equal(withNull, 'a=&b=');
301306
```
302307

303308
Parsing does not distinguish between parameters with and without equal signs. Both are converted to empty strings.
304309

305310
```javascript
306-
qs.parse('a&b=')
307-
// { a: '', b: '' }
311+
var equalsInsensitive = qs.parse('a&b=');
312+
assert.deepEqual(equalsInsensitive, { a: '', b: '' });
308313
```
309314

310315
To distinguish between `null` values and empty strings use the `strictNullHandling` flag. In the result string the `null`
311316
values have no `=` sign:
312317

313318
```javascript
314-
qs.stringify({ a: null, b: '' }, { strictNullHandling: true });
315-
// 'a&b='
319+
var strictNull = qs.stringify({ a: null, b: '' }, { strictNullHandling: true });
320+
assert.equal(strictNull, 'a&b=');
316321
```
317322

318323
To parse values without `=` back to `null` use the `strictNullHandling` flag:
319324

320325
```javascript
321-
qs.parse('a&b=', { strictNullHandling: true });
322-
// { a: null, b: '' }
323-
326+
var parsedStrictNull = qs.parse('a&b=', { strictNullHandling: true });
327+
assert.deepEqual(parsedStrictNull, { a: null, b: '' });
324328
```
325329

326330
To completely skip rendering keys with `null` values, use the `skipNulls` flag:
327331

328332
```javascript
329-
qs.stringify({ a: 'b', c: null}, { skipNulls: true })
330-
// 'a=b'
333+
var nullsSkipped = qs.stringify({ a: 'b', c: null}, { skipNulls: true });
334+
assert.equal(nullsSkipped, 'a=b');
331335
```

package.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,13 @@
3030
"mkdirp": "^0.5.1",
3131
"eslint": "^1.10.3",
3232
"@ljharb/eslint-config": "^1.6.1",
33-
"parallelshell": "^2.0.0"
33+
"parallelshell": "^2.0.0",
34+
"evalmd": "^0.0.16"
3435
},
3536
"scripts": {
36-
"test": "parallelshell 'npm run lint' 'npm run coverage'",
37-
"tests-only": "node test",
37+
"test": "parallelshell 'npm run readme' 'npm run lint' 'npm run coverage'",
38+
"tests-only": "parallelshell 'npm run readme' 'node test'",
39+
"readme": "evalmd README.md",
3840
"lint": "eslint lib/*.js text/*.js",
3941
"coverage": "covert test",
4042
"dist": "mkdirp dist && browserify --standalone Qs lib/index.js > dist/qs.js",

0 commit comments

Comments
 (0)