Agregado toping en los menus
This commit is contained in:
385
node_modules/qs/test/parse.js
generated
vendored
385
node_modules/qs/test/parse.js
generated
vendored
@@ -1,10 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
var hasPropertyDescriptors = require('has-property-descriptors')();
|
||||
var iconv = require('iconv-lite');
|
||||
var mockProperty = require('mock-property');
|
||||
var hasOverrideMistake = require('has-override-mistake')();
|
||||
var SaferBuffer = require('safer-buffer').Buffer;
|
||||
var v = require('es-value-fixtures');
|
||||
var inspect = require('object-inspect');
|
||||
var emptyTestCases = require('./empty-keys-cases').emptyTestCases;
|
||||
|
||||
var qs = require('../');
|
||||
var utils = require('../lib/utils');
|
||||
var iconv = require('iconv-lite');
|
||||
var SaferBuffer = require('safer-buffer').Buffer;
|
||||
|
||||
test('parse()', function (t) {
|
||||
t.test('parses a simple string', function (st) {
|
||||
@@ -32,41 +39,156 @@ test('parse()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('arrayFormat: brackets allows only explicit arrays', function (st) {
|
||||
st.deepEqual(qs.parse('a[]=b&a[]=c', { arrayFormat: 'brackets' }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayFormat: 'brackets' }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a=b,c', { arrayFormat: 'brackets' }), { a: 'b,c' });
|
||||
st.deepEqual(qs.parse('a=b&a=c', { arrayFormat: 'brackets' }), { a: ['b', 'c'] });
|
||||
t.test('comma: false', function (st) {
|
||||
st.deepEqual(qs.parse('a[]=b&a[]=c'), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a[0]=b&a[1]=c'), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a=b,c'), { a: 'b,c' });
|
||||
st.deepEqual(qs.parse('a=b&a=c'), { a: ['b', 'c'] });
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('arrayFormat: indices allows only indexed arrays', function (st) {
|
||||
st.deepEqual(qs.parse('a[]=b&a[]=c', { arrayFormat: 'indices' }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayFormat: 'indices' }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a=b,c', { arrayFormat: 'indices' }), { a: 'b,c' });
|
||||
st.deepEqual(qs.parse('a=b&a=c', { arrayFormat: 'indices' }), { a: ['b', 'c'] });
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('arrayFormat: comma allows only comma-separated arrays', function (st) {
|
||||
st.deepEqual(qs.parse('a[]=b&a[]=c', { arrayFormat: 'comma' }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayFormat: 'comma' }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a=b,c', { arrayFormat: 'comma' }), { a: 'b,c' });
|
||||
st.deepEqual(qs.parse('a=b&a=c', { arrayFormat: 'comma' }), { a: ['b', 'c'] });
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('arrayFormat: repeat allows only repeated values', function (st) {
|
||||
st.deepEqual(qs.parse('a[]=b&a[]=c', { arrayFormat: 'repeat' }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayFormat: 'repeat' }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a=b,c', { arrayFormat: 'repeat' }), { a: 'b,c' });
|
||||
st.deepEqual(qs.parse('a=b&a=c', { arrayFormat: 'repeat' }), { a: ['b', 'c'] });
|
||||
t.test('comma: true', function (st) {
|
||||
st.deepEqual(qs.parse('a[]=b&a[]=c', { comma: true }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { comma: true }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a=b,c', { comma: true }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a=b&a=c', { comma: true }), { a: ['b', 'c'] });
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('allows enabling dot notation', function (st) {
|
||||
st.deepEqual(qs.parse('a.b=c'), { 'a.b': 'c' });
|
||||
st.deepEqual(qs.parse('a.b=c', { allowDots: true }), { a: { b: 'c' } });
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('decode dot keys correctly', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('name%252Eobj.first=John&name%252Eobj.last=Doe', { allowDots: false, decodeDotInKeys: false }),
|
||||
{ 'name%2Eobj.first': 'John', 'name%2Eobj.last': 'Doe' },
|
||||
'with allowDots false and decodeDotInKeys false'
|
||||
);
|
||||
st.deepEqual(
|
||||
qs.parse('name.obj.first=John&name.obj.last=Doe', { allowDots: true, decodeDotInKeys: false }),
|
||||
{ name: { obj: { first: 'John', last: 'Doe' } } },
|
||||
'with allowDots false and decodeDotInKeys false'
|
||||
);
|
||||
st.deepEqual(
|
||||
qs.parse('name%252Eobj.first=John&name%252Eobj.last=Doe', { allowDots: true, decodeDotInKeys: false }),
|
||||
{ 'name%2Eobj': { first: 'John', last: 'Doe' } },
|
||||
'with allowDots true and decodeDotInKeys false'
|
||||
);
|
||||
st.deepEqual(
|
||||
qs.parse('name%252Eobj.first=John&name%252Eobj.last=Doe', { allowDots: true, decodeDotInKeys: true }),
|
||||
{ 'name.obj': { first: 'John', last: 'Doe' } },
|
||||
'with allowDots true and decodeDotInKeys true'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse(
|
||||
'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe',
|
||||
{ allowDots: false, decodeDotInKeys: false }
|
||||
),
|
||||
{ 'name%2Eobj%2Esubobject.first%2Egodly%2Ename': 'John', 'name%2Eobj%2Esubobject.last': 'Doe' },
|
||||
'with allowDots false and decodeDotInKeys false'
|
||||
);
|
||||
st.deepEqual(
|
||||
qs.parse(
|
||||
'name.obj.subobject.first.godly.name=John&name.obj.subobject.last=Doe',
|
||||
{ allowDots: true, decodeDotInKeys: false }
|
||||
),
|
||||
{ name: { obj: { subobject: { first: { godly: { name: 'John' } }, last: 'Doe' } } } },
|
||||
'with allowDots true and decodeDotInKeys false'
|
||||
);
|
||||
st.deepEqual(
|
||||
qs.parse(
|
||||
'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe',
|
||||
{ allowDots: true, decodeDotInKeys: true }
|
||||
),
|
||||
{ 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } },
|
||||
'with allowDots true and decodeDotInKeys true'
|
||||
);
|
||||
st.deepEqual(
|
||||
qs.parse('name%252Eobj.first=John&name%252Eobj.last=Doe'),
|
||||
{ 'name%2Eobj.first': 'John', 'name%2Eobj.last': 'Doe' },
|
||||
'with allowDots and decodeDotInKeys undefined'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('should decode dot in key of object, and allow enabling dot notation when decodeDotInKeys is set to true and allowDots is undefined', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse(
|
||||
'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe',
|
||||
{ decodeDotInKeys: true }
|
||||
),
|
||||
{ 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } },
|
||||
'with allowDots undefined and decodeDotInKeys true'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('should throw when decodeDotInKeys is not of type boolean', function (st) {
|
||||
st['throws'](
|
||||
function () { qs.parse('foo[]&bar=baz', { decodeDotInKeys: 'foobar' }); },
|
||||
TypeError
|
||||
);
|
||||
|
||||
st['throws'](
|
||||
function () { qs.parse('foo[]&bar=baz', { decodeDotInKeys: 0 }); },
|
||||
TypeError
|
||||
);
|
||||
st['throws'](
|
||||
function () { qs.parse('foo[]&bar=baz', { decodeDotInKeys: NaN }); },
|
||||
TypeError
|
||||
);
|
||||
|
||||
st['throws'](
|
||||
function () { qs.parse('foo[]&bar=baz', { decodeDotInKeys: null }); },
|
||||
TypeError
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('allows empty arrays in obj values', function (st) {
|
||||
st.deepEqual(qs.parse('foo[]&bar=baz', { allowEmptyArrays: true }), { foo: [], bar: 'baz' });
|
||||
st.deepEqual(qs.parse('foo[]&bar=baz', { allowEmptyArrays: false }), { foo: [''], bar: 'baz' });
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('should throw when allowEmptyArrays is not of type boolean', function (st) {
|
||||
st['throws'](
|
||||
function () { qs.parse('foo[]&bar=baz', { allowEmptyArrays: 'foobar' }); },
|
||||
TypeError
|
||||
);
|
||||
|
||||
st['throws'](
|
||||
function () { qs.parse('foo[]&bar=baz', { allowEmptyArrays: 0 }); },
|
||||
TypeError
|
||||
);
|
||||
st['throws'](
|
||||
function () { qs.parse('foo[]&bar=baz', { allowEmptyArrays: NaN }); },
|
||||
TypeError
|
||||
);
|
||||
|
||||
st['throws'](
|
||||
function () { qs.parse('foo[]&bar=baz', { allowEmptyArrays: null }); },
|
||||
TypeError
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('allowEmptyArrays + strictNullHandling', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('testEmptyArray[]', { strictNullHandling: true, allowEmptyArrays: true }),
|
||||
{ testEmptyArray: [] }
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -322,14 +444,14 @@ test('parse()', function (t) {
|
||||
});
|
||||
|
||||
t.test('should not throw when a native prototype has an enumerable property', function (st) {
|
||||
Object.prototype.crash = '';
|
||||
Array.prototype.crash = '';
|
||||
st.intercept(Object.prototype, 'crash', { value: '' });
|
||||
st.intercept(Array.prototype, 'crash', { value: '' });
|
||||
|
||||
st.doesNotThrow(qs.parse.bind(null, 'a=b'));
|
||||
st.deepEqual(qs.parse('a=b'), { a: 'b' });
|
||||
st.doesNotThrow(qs.parse.bind(null, 'a[][b]=c'));
|
||||
st.deepEqual(qs.parse('a[][b]=c'), { a: [{ b: 'c' }] });
|
||||
delete Object.prototype.crash;
|
||||
delete Array.prototype.crash;
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -360,8 +482,14 @@ test('parse()', function (t) {
|
||||
|
||||
t.test('allows overriding array limit', function (st) {
|
||||
st.deepEqual(qs.parse('a[0]=b', { arrayLimit: -1 }), { a: { 0: 'b' } });
|
||||
st.deepEqual(qs.parse('a[0]=b', { arrayLimit: 0 }), { a: ['b'] });
|
||||
|
||||
st.deepEqual(qs.parse('a[-1]=b', { arrayLimit: -1 }), { a: { '-1': 'b' } });
|
||||
st.deepEqual(qs.parse('a[-1]=b', { arrayLimit: 0 }), { a: { '-1': 'b' } });
|
||||
|
||||
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayLimit: -1 }), { a: { 0: 'b', 1: 'c' } });
|
||||
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { arrayLimit: 0 }), { a: { 0: 'b', 1: 'c' } });
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -452,6 +580,15 @@ test('parse()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('parses url-encoded brackets holds array of arrays when having two parts of strings with comma as array divider', function (st) {
|
||||
st.deepEqual(qs.parse('foo%5B%5D=1,2,3&foo%5B%5D=4,5,6', { comma: true }), { foo: [['1', '2', '3'], ['4', '5', '6']] });
|
||||
st.deepEqual(qs.parse('foo%5B%5D=1,2,3&foo%5B%5D=', { comma: true }), { foo: [['1', '2', '3'], ''] });
|
||||
st.deepEqual(qs.parse('foo%5B%5D=1,2,3&foo%5B%5D=,', { comma: true }), { foo: [['1', '2', '3'], ['', '']] });
|
||||
st.deepEqual(qs.parse('foo%5B%5D=1,2,3&foo%5B%5D=a', { comma: true }), { foo: [['1', '2', '3'], 'a'] });
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('parses comma delimited array while having percent-encoded comma treated as normal text', function (st) {
|
||||
st.deepEqual(qs.parse('foo=a%2Cb', { comma: true }), { foo: 'a,b' });
|
||||
st.deepEqual(qs.parse('foo=a%2C%20b,d', { comma: true }), { foo: ['a, b', 'd'] });
|
||||
@@ -499,10 +636,12 @@ test('parse()', function (t) {
|
||||
});
|
||||
|
||||
t.test('does not blow up when Buffer global is missing', function (st) {
|
||||
var tempBuffer = global.Buffer;
|
||||
delete global.Buffer;
|
||||
var restore = mockProperty(global, 'Buffer', { 'delete': true });
|
||||
|
||||
var result = qs.parse('a=b&c=d');
|
||||
global.Buffer = tempBuffer;
|
||||
|
||||
restore();
|
||||
|
||||
st.deepEqual(result, { a: 'b', c: 'd' });
|
||||
st.end();
|
||||
});
|
||||
@@ -601,6 +740,34 @@ test('parse()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('does not crash when the global Object prototype is frozen', { skip: !hasPropertyDescriptors || !hasOverrideMistake }, function (st) {
|
||||
// We can't actually freeze the global Object prototype as that will interfere with other tests, and once an object is frozen, it
|
||||
// can't be unfrozen. Instead, we add a new non-writable property to simulate this.
|
||||
st.teardown(mockProperty(Object.prototype, 'frozenProp', { value: 'foo', nonWritable: true, nonEnumerable: true }));
|
||||
|
||||
st['throws'](
|
||||
function () {
|
||||
var obj = {};
|
||||
obj.frozenProp = 'bar';
|
||||
},
|
||||
// node < 6 has a different error message
|
||||
/^TypeError: Cannot assign to read only property 'frozenProp' of (?:object '#<Object>'|#<Object>)/,
|
||||
'regular assignment of an inherited non-writable property throws'
|
||||
);
|
||||
|
||||
var parsed;
|
||||
st.doesNotThrow(
|
||||
function () {
|
||||
parsed = qs.parse('frozenProp', { allowPrototypes: false });
|
||||
},
|
||||
'parsing a nonwritable Object.prototype property does not throw'
|
||||
);
|
||||
|
||||
st.deepEqual(parsed, {}, 'bare "frozenProp" results in {}');
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('params starting with a closing bracket', function (st) {
|
||||
st.deepEqual(qs.parse(']=toString'), { ']': 'toString' });
|
||||
st.deepEqual(qs.parse(']]=toString'), { ']]': 'toString' });
|
||||
@@ -853,3 +1020,151 @@ test('parse()', function (t) {
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('parses empty keys', function (t) {
|
||||
emptyTestCases.forEach(function (testCase) {
|
||||
t.test('skips empty string key with ' + testCase.input, function (st) {
|
||||
st.deepEqual(qs.parse(testCase.input), testCase.noEmptyKeys);
|
||||
|
||||
st.end();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('`duplicates` option', function (t) {
|
||||
v.nonStrings.concat('not a valid option').forEach(function (invalidOption) {
|
||||
if (typeof invalidOption !== 'undefined') {
|
||||
t['throws'](
|
||||
function () { qs.parse('', { duplicates: invalidOption }); },
|
||||
TypeError,
|
||||
'throws on invalid option: ' + inspect(invalidOption)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
t.deepEqual(
|
||||
qs.parse('foo=bar&foo=baz'),
|
||||
{ foo: ['bar', 'baz'] },
|
||||
'duplicates: default, combine'
|
||||
);
|
||||
|
||||
t.deepEqual(
|
||||
qs.parse('foo=bar&foo=baz', { duplicates: 'combine' }),
|
||||
{ foo: ['bar', 'baz'] },
|
||||
'duplicates: combine'
|
||||
);
|
||||
|
||||
t.deepEqual(
|
||||
qs.parse('foo=bar&foo=baz', { duplicates: 'first' }),
|
||||
{ foo: 'bar' },
|
||||
'duplicates: first'
|
||||
);
|
||||
|
||||
t.deepEqual(
|
||||
qs.parse('foo=bar&foo=baz', { duplicates: 'last' }),
|
||||
{ foo: 'baz' },
|
||||
'duplicates: last'
|
||||
);
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('qs strictDepth option - throw cases', function (t) {
|
||||
t.test('throws an exception when depth exceeds the limit with strictDepth: true', function (st) {
|
||||
st['throws'](
|
||||
function () {
|
||||
qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1, strictDepth: true });
|
||||
},
|
||||
RangeError,
|
||||
'Should throw RangeError'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('throws an exception for multiple nested arrays with strictDepth: true', function (st) {
|
||||
st['throws'](
|
||||
function () {
|
||||
qs.parse('a[0][1][2][3][4]=b', { depth: 3, strictDepth: true });
|
||||
},
|
||||
RangeError,
|
||||
'Should throw RangeError'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('throws an exception for nested objects and arrays with strictDepth: true', function (st) {
|
||||
st['throws'](
|
||||
function () {
|
||||
qs.parse('a[b][c][0][d][e]=f', { depth: 3, strictDepth: true });
|
||||
},
|
||||
RangeError,
|
||||
'Should throw RangeError'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('throws an exception for different types of values with strictDepth: true', function (st) {
|
||||
st['throws'](
|
||||
function () {
|
||||
qs.parse('a[b][c][d][e]=true&a[b][c][d][f]=42', { depth: 3, strictDepth: true });
|
||||
},
|
||||
RangeError,
|
||||
'Should throw RangeError'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test('qs strictDepth option - non-throw cases', function (t) {
|
||||
t.test('when depth is 0 and strictDepth true, do not throw', function (st) {
|
||||
st.doesNotThrow(
|
||||
function () {
|
||||
qs.parse('a[b][c][d][e]=true&a[b][c][d][f]=42', { depth: 0, strictDepth: true });
|
||||
},
|
||||
RangeError,
|
||||
'Should not throw RangeError'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('parses successfully when depth is within the limit with strictDepth: true', function (st) {
|
||||
st.doesNotThrow(
|
||||
function () {
|
||||
var result = qs.parse('a[b]=c', { depth: 1, strictDepth: true });
|
||||
st.deepEqual(result, { a: { b: 'c' } }, 'Should parse correctly');
|
||||
}
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('does not throw an exception when depth exceeds the limit with strictDepth: false', function (st) {
|
||||
st.doesNotThrow(
|
||||
function () {
|
||||
var result = qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });
|
||||
st.deepEqual(result, { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }, 'Should parse with depth limit');
|
||||
}
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('parses successfully when depth is within the limit with strictDepth: false', function (st) {
|
||||
st.doesNotThrow(
|
||||
function () {
|
||||
var result = qs.parse('a[b]=c', { depth: 1 });
|
||||
st.deepEqual(result, { a: { b: 'c' } }, 'Should parse correctly');
|
||||
}
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('does not throw when depth is exactly at the limit with strictDepth: true', function (st) {
|
||||
st.doesNotThrow(
|
||||
function () {
|
||||
var result = qs.parse('a[b][c]=d', { depth: 2, strictDepth: true });
|
||||
st.deepEqual(result, { a: { b: { c: 'd' } } }, 'Should parse correctly');
|
||||
}
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user