feat(planning): grille hebdomadaire complète avec API et filtres
- Connexion API via proxy Angular (résolution CORS, base path /api) - Import CSS ng-zorro global pour les modales et composants - Filtres Camion/Show câblés sur l'affichage de la grille - Camions affichés via TrucksService (linkés au show du même créneau) - Panneau de détails : spectacles + camions du jour sélectionné - Modale de création de spectacle stylisée avec fond et centrage - Positionnement précis des events à la minute dans leur créneau - Auto-scroll vers l'heure courante au chargement - Ligne "maintenant" sur la colonne du jour actuel - Régénération des services OpenAPI (nouveaux noms de types) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+13
-440
@@ -210,21 +210,6 @@ test('parse()', function (t) {
|
||||
t.test('uses original key when depth = 0', function (st) {
|
||||
st.deepEqual(qs.parse('a[0]=b&a[1]=c', { depth: 0 }), { 'a[0]': 'b', 'a[1]': 'c' });
|
||||
st.deepEqual(qs.parse('a[0][0]=b&a[0][1]=c&a[1]=d&e=2', { depth: 0 }), { 'a[0][0]': 'b', 'a[0][1]': 'c', 'a[1]': 'd', e: '2' });
|
||||
st.deepEqual(qs.parse('a.b=c', { depth: 0, allowDots: true }), { 'a[b]': 'c' }, 'normalizes dots before applying depth-0 behavior');
|
||||
st.deepEqual(qs.parse('toString=foo', { depth: 0 }), {}, 'respects prototype guard at depth 0');
|
||||
st.deepEqual(qs.parse('toString=foo', { depth: 0, allowPrototypes: true }), { toString: 'foo' }, 'allows prototypes at depth 0 when enabled');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('ignores prototype keys when depth = 0 and allowPrototypes is false', function (st) {
|
||||
st.deepEqual(qs.parse('toString=foo', { depth: 0 }), {});
|
||||
st.deepEqual(qs.parse('hasOwnProperty=bar', { depth: 0 }), {});
|
||||
st.deepEqual(qs.parse('toString=foo&a=b', { depth: 0 }), { a: 'b' });
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('allows prototype keys when depth = 0 and allowPrototypes is true', function (st) {
|
||||
st.deepEqual(qs.parse('toString=foo', { depth: 0, allowPrototypes: true }), { toString: 'foo' });
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -250,11 +235,11 @@ test('parse()', function (t) {
|
||||
st.deepEqual(qs.parse('a=b&a[0]=c'), { a: ['b', 'c'] });
|
||||
|
||||
st.deepEqual(qs.parse('a[1]=b&a=c', { arrayLimit: 20 }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a[]=b&a=c', { arrayLimit: 0 }), { a: { 0: 'b', 1: 'c' } });
|
||||
st.deepEqual(qs.parse('a[]=b&a=c', { arrayLimit: 0 }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a[]=b&a=c'), { a: ['b', 'c'] });
|
||||
|
||||
st.deepEqual(qs.parse('a=b&a[1]=c', { arrayLimit: 20 }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a=b&a[]=c', { arrayLimit: 0 }), { a: { 0: 'b', 1: 'c' } });
|
||||
st.deepEqual(qs.parse('a=b&a[]=c', { arrayLimit: 0 }), { a: ['b', 'c'] });
|
||||
st.deepEqual(qs.parse('a=b&a[]=c'), { a: ['b', 'c'] });
|
||||
|
||||
st.end();
|
||||
@@ -266,52 +251,6 @@ test('parse()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('parses keys with literal [] inside a bracket group (#493)', function (st) {
|
||||
// A bracket pair inside a bracket group should be treated literally as part of the key
|
||||
st.deepEqual(
|
||||
qs.parse('search[withbracket[]]=foobar'),
|
||||
{ search: { 'withbracket[]': 'foobar' } },
|
||||
'treats inner [] literally when inside a bracket group'
|
||||
);
|
||||
|
||||
// Single-level variant
|
||||
st.deepEqual(
|
||||
qs.parse('a[b[]]=c'),
|
||||
{ a: { 'b[]': 'c' } },
|
||||
'keeps "b[]" as a literal key'
|
||||
);
|
||||
|
||||
// Nested with an array push on the outer level
|
||||
st.deepEqual(
|
||||
qs.parse('list[][x[]]=y'),
|
||||
{ list: [{ 'x[]': 'y' }] },
|
||||
'preserves inner [] while still treating outer [] as array push'
|
||||
);
|
||||
|
||||
// Multiple nested bracket pairs: inner [] remains literal as part of the key
|
||||
st.deepEqual(
|
||||
qs.parse('a[b[c[]]]=d'),
|
||||
{ a: { 'b[c[]]': 'd' } },
|
||||
'treats "b[c[]]" as a literal key inside the bracket group'
|
||||
);
|
||||
|
||||
// Depth limits with literal brackets: preserve inner [] while limiting bracket-group parsing
|
||||
st.deepEqual(
|
||||
qs.parse('a[b[c[]]][d]=e', { depth: 1 }),
|
||||
{ a: { 'b[c[]]': { '[d]': 'e' } } },
|
||||
'respects depth: 1 and preserves literal inner [] in the parsed key'
|
||||
);
|
||||
|
||||
// Unterminated inner bracket group is wrapped as a literal remainder segment
|
||||
st.deepEqual(
|
||||
qs.parse('a[[]b=c'),
|
||||
{ a: { '[[]b': 'c' } },
|
||||
'handles unterminated inner bracket groups without throwing'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('allows to specify array indices', function (st) {
|
||||
st.deepEqual(qs.parse('a[1]=c&a[0]=b&a[2]=d'), { a: ['b', 'c', 'd'] });
|
||||
st.deepEqual(qs.parse('a[1]=c&a[0]=b'), { a: ['b', 'c'] });
|
||||
@@ -322,11 +261,11 @@ test('parse()', function (t) {
|
||||
});
|
||||
|
||||
t.test('limits specific array indices to arrayLimit', function (st) {
|
||||
st.deepEqual(qs.parse('a[19]=a', { arrayLimit: 20 }), { a: ['a'] });
|
||||
st.deepEqual(qs.parse('a[20]=a', { arrayLimit: 20 }), { a: { 20: 'a' } });
|
||||
st.deepEqual(qs.parse('a[20]=a', { arrayLimit: 20 }), { a: ['a'] });
|
||||
st.deepEqual(qs.parse('a[21]=a', { arrayLimit: 20 }), { a: { 21: 'a' } });
|
||||
|
||||
st.deepEqual(qs.parse('a[19]=a'), { a: ['a'] });
|
||||
st.deepEqual(qs.parse('a[20]=a'), { a: { 20: 'a' } });
|
||||
st.deepEqual(qs.parse('a[20]=a'), { a: ['a'] });
|
||||
st.deepEqual(qs.parse('a[21]=a'), { a: { 21: 'a' } });
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -425,7 +364,7 @@ test('parse()', function (t) {
|
||||
);
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a[]&a[]=c&a[]=', { strictNullHandling: true, arrayLimit: 0 }),
|
||||
{ a: { 0: 'b', 1: null, 2: 'c', 3: '' } },
|
||||
{ a: ['b', null, 'c', ''] },
|
||||
'with arrayLimit 0 + array brackets: null then empty string works'
|
||||
);
|
||||
|
||||
@@ -436,7 +375,7 @@ test('parse()', function (t) {
|
||||
);
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a[]=&a[]=c&a[]', { strictNullHandling: true, arrayLimit: 0 }),
|
||||
{ a: { 0: 'b', 1: '', 2: 'c', 3: null } },
|
||||
{ a: ['b', '', 'c', null] },
|
||||
'with arrayLimit 0 + array brackets: empty string then null works'
|
||||
);
|
||||
|
||||
@@ -544,7 +483,7 @@ 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: { 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' } });
|
||||
@@ -845,25 +784,25 @@ test('parse()', function (t) {
|
||||
|
||||
t.test('add keys to objects', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=d', { strictMerge: false }),
|
||||
qs.parse('a[b]=c&a=d'),
|
||||
{ a: { b: 'c', d: true } },
|
||||
'can add keys to objects'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=toString', { strictMerge: false }),
|
||||
qs.parse('a[b]=c&a=toString'),
|
||||
{ a: { b: 'c' } },
|
||||
'can not overwrite prototype'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=toString', { strictMerge: false, allowPrototypes: true }),
|
||||
qs.parse('a[b]=c&a=toString', { allowPrototypes: true }),
|
||||
{ a: { b: 'c', toString: true } },
|
||||
'can overwrite prototype with allowPrototypes true'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=toString', { strictMerge: false, plainObjects: true }),
|
||||
qs.parse('a[b]=c&a=toString', { plainObjects: true }),
|
||||
{ __proto__: null, a: { __proto__: null, b: 'c', toString: true } },
|
||||
'can overwrite prototype with plainObjects true'
|
||||
);
|
||||
@@ -871,34 +810,6 @@ test('parse()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('strictMerge wraps object and primitive into an array', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=d'),
|
||||
{ a: [{ b: 'c' }, 'd'] },
|
||||
'object then primitive produces array'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a=d&a[b]=c'),
|
||||
{ a: ['d', { b: 'c' }] },
|
||||
'primitive then object produces array'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=toString'),
|
||||
{ a: [{ b: 'c' }, 'toString'] },
|
||||
'prototype-colliding value is preserved in array'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[b]=c&a=toString', { plainObjects: true }),
|
||||
{ __proto__: null, a: [{ __proto__: null, b: 'c' }, 'toString'] },
|
||||
'plainObjects preserved in array wrapping'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('dunder proto is ignored', function (st) {
|
||||
var payload = 'categories[__proto__]=login&categories[__proto__]&categories[length]=42';
|
||||
var result = qs.parse(payload, { allowPrototypes: true });
|
||||
@@ -1085,20 +996,6 @@ test('parse()', function (t) {
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('handles a custom decoder returning `null`, with a string key of `null`', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('null=1&ToNull=2', {
|
||||
decoder: function (str, defaultDecoder, charset) {
|
||||
return str === 'ToNull' ? null : defaultDecoder(str, defaultDecoder, charset);
|
||||
}
|
||||
}),
|
||||
{ 'null': '1' },
|
||||
'"null" key is not overridden by `null` decoder result'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('does not interpret numeric entities in iso-8859-1 when `interpretNumericEntities` is absent', function (st) {
|
||||
st.deepEqual(qs.parse('foo=' + urlEncodedNumSmiley, { charset: 'iso-8859-1' }), { foo: '☺' });
|
||||
st.end();
|
||||
@@ -1135,15 +1032,6 @@ test('parse()', function (t) {
|
||||
};
|
||||
|
||||
st.deepEqual(qs.parse('KeY=vAlUe', { decoder: decoder }), { key: 'VALUE' });
|
||||
|
||||
var noopDecoder = function () { return 'x'; };
|
||||
noopDecoder();
|
||||
st['throws'](
|
||||
function () { decoder('x', noopDecoder, 'utf-8', 'unknown'); },
|
||||
'this should never happen! type: unknown',
|
||||
'decoder throws for unexpected type'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -1173,14 +1061,6 @@ test('parse()', function (t) {
|
||||
new RangeError('Parameter limit exceeded. Only 3 parameters allowed.'),
|
||||
'throws error when parameter limit is exceeded'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a=1&b=2', { parameterLimit: 1, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Parameter limit exceeded. Only 1 parameter allowed.'),
|
||||
'throws error with singular "parameter" when parameterLimit is 1'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
@@ -1202,12 +1082,6 @@ test('parse()', function (t) {
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('allows unlimited parameters when parameterLimit is Infinity and throwOnLimitExceeded is true', function (sst) {
|
||||
var result = qs.parse('a=1&b=2&c=3&d=4&e=5&f=6', { parameterLimit: Infinity, throwOnLimitExceeded: true });
|
||||
sst.deepEqual(result, { a: '1', b: '2', c: '3', d: '4', e: '5', f: '6' }, 'parses all parameters without truncation or throwing');
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -1230,7 +1104,6 @@ test('parse()', function (t) {
|
||||
});
|
||||
|
||||
st.test('throws error when array limit exceeded', function (sst) {
|
||||
// 4 elements exceeds limit of 3
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[]=1&a[]=2&a[]=3&a[]=4', { arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
@@ -1241,14 +1114,6 @@ test('parse()', function (t) {
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('does not throw when at limit', function (sst) {
|
||||
// 3 elements = limit of 3, should not throw
|
||||
var result = qs.parse('a[]=1&a[]=2&a[]=3', { arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
sst.ok(Array.isArray(result.a), 'result is an array');
|
||||
sst.deepEqual(result.a, ['1', '2', '3'], 'all values present');
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('converts array to object if length is greater than limit', function (sst) {
|
||||
var result = qs.parse('a[1]=1&a[2]=2&a[3]=3&a[4]=4&a[5]=5&a[6]=6', { arrayLimit: 5 });
|
||||
|
||||
@@ -1256,59 +1121,6 @@ test('parse()', function (t) {
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('throws error when indexed notation exceeds arrayLimit with throwOnLimitExceeded', function (sst) {
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[1001]=b', { arrayLimit: 1000, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 1000 elements allowed in an array.'),
|
||||
'throws error for a single index exceeding arrayLimit'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[0]=1&a[1]=2&a[2]=3&a[10]=4', { arrayLimit: 6, throwOnLimitExceeded: true, allowSparse: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 6 elements allowed in an array.'),
|
||||
'throws error when a sparse index exceeds arrayLimit'
|
||||
);
|
||||
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[2]=b', { arrayLimit: 1, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 1 element allowed in an array.'),
|
||||
'throws error with singular "element" when arrayLimit is 1'
|
||||
);
|
||||
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('does not throw for indexed notation within arrayLimit with throwOnLimitExceeded', function (sst) {
|
||||
var result = qs.parse('a[4]=b', { arrayLimit: 5, throwOnLimitExceeded: true, allowSparse: true });
|
||||
sst.ok(Array.isArray(result.a), 'result is an array');
|
||||
sst.equal(result.a.length, 5, 'array has correct length');
|
||||
sst.equal(result.a[4], 'b', 'value at index 4 is correct');
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('silently converts to object for indexed notation exceeding arrayLimit without throwOnLimitExceeded', function (sst) {
|
||||
var result = qs.parse('a[1001]=b', { arrayLimit: 1000 });
|
||||
sst.deepEqual(result, { a: { 1001: 'b' } }, 'converts to object without throwing');
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.test('throws when duplicate bracket keys exceed arrayLimit with throwOnLimitExceeded', function (sst) {
|
||||
sst['throws'](
|
||||
function () {
|
||||
qs.parse('a[]=1&a[]=2&a[]=3&a[]=4&a[]=5&a[]=6', { arrayLimit: 5, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 5 elements allowed in an array.'),
|
||||
'throws error when duplicate bracket notation exceeds array limit'
|
||||
);
|
||||
sst.end();
|
||||
});
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
@@ -1360,34 +1172,6 @@ test('`duplicates` option', function (t) {
|
||||
'duplicates: last'
|
||||
);
|
||||
|
||||
t.test('bracket notation always combines regardless of duplicates', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a=1&a=2&b[]=1&b[]=2', { duplicates: 'last' }),
|
||||
{ a: '2', b: ['1', '2'] },
|
||||
'duplicates last: unbracketed takes last, bracketed combines'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('b[]=1&b[]=2', { duplicates: 'last' }),
|
||||
{ b: ['1', '2'] },
|
||||
'duplicates last: bracketed always combines'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('b[]=1&b[]=2', { duplicates: 'first' }),
|
||||
{ b: ['1', '2'] },
|
||||
'duplicates first: bracketed always combines'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a=1&a=2&b[]=1&b[]=2', { duplicates: 'first' }),
|
||||
{ a: '1', b: ['1', '2'] },
|
||||
'duplicates first: unbracketed takes first, bracketed combines'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
@@ -1490,214 +1274,3 @@ test('qs strictDepth option - non-throw cases', function (t) {
|
||||
st.end();
|
||||
});
|
||||
});
|
||||
|
||||
test('DOS', function (t) {
|
||||
var arr = [];
|
||||
for (var i = 0; i < 105; i++) {
|
||||
arr[arr.length] = 'x';
|
||||
}
|
||||
var attack = 'a[]=' + arr.join('&a[]=');
|
||||
var result = qs.parse(attack, { arrayLimit: 100 });
|
||||
|
||||
t.notOk(Array.isArray(result.a), 'arrayLimit is respected: result is an object, not an array');
|
||||
t.equal(Object.keys(result.a).length, 105, 'all values are preserved');
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('arrayLimit boundary conditions', function (t) {
|
||||
// arrayLimit is the max number of elements allowed in an array
|
||||
t.test('exactly at the limit stays as array', function (st) {
|
||||
// 3 elements = limit of 3
|
||||
var result = qs.parse('a[]=1&a[]=2&a[]=3', { arrayLimit: 3 });
|
||||
st.ok(Array.isArray(result.a), 'result is an array when count equals limit');
|
||||
st.deepEqual(result.a, ['1', '2', '3'], 'all values present');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('one over the limit converts to object', function (st) {
|
||||
// 4 elements exceeds limit of 3
|
||||
var result = qs.parse('a[]=1&a[]=2&a[]=3&a[]=4', { arrayLimit: 3 });
|
||||
st.notOk(Array.isArray(result.a), 'result is not an array when over limit');
|
||||
st.deepEqual(result.a, { 0: '1', 1: '2', 2: '3', 3: '4' }, 'all values preserved as object');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('arrayLimit 1 with one value', function (st) {
|
||||
// 1 element = limit of 1
|
||||
var result = qs.parse('a[]=1', { arrayLimit: 1 });
|
||||
st.ok(Array.isArray(result.a), 'result is an array when count equals limit');
|
||||
st.deepEqual(result.a, ['1'], 'value preserved as array');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('arrayLimit 1 with two values converts to object', function (st) {
|
||||
// 2 elements exceeds limit of 1
|
||||
var result = qs.parse('a[]=1&a[]=2', { arrayLimit: 1 });
|
||||
st.notOk(Array.isArray(result.a), 'result is not an array');
|
||||
st.deepEqual(result.a, { 0: '1', 1: '2' }, 'all values preserved as object');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('comma + arrayLimit', function (t) {
|
||||
t.test('comma-separated values within arrayLimit stay as array', function (st) {
|
||||
var result = qs.parse('a=1,2,3', { comma: true, arrayLimit: 5 });
|
||||
st.ok(Array.isArray(result.a), 'result is an array');
|
||||
st.deepEqual(result.a, ['1', '2', '3'], 'all values present');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('comma-separated values exceeding arrayLimit convert to object', function (st) {
|
||||
var result = qs.parse('a=1,2,3,4', { comma: true, arrayLimit: 3 });
|
||||
st.notOk(Array.isArray(result.a), 'result is not an array when over limit');
|
||||
st.deepEqual(result.a, { 0: '1', 1: '2', 2: '3', 3: '4' }, 'all values preserved as object');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('comma-separated values exceeding arrayLimit with throwOnLimitExceeded throws', function (st) {
|
||||
st['throws'](
|
||||
function () {
|
||||
qs.parse('a=1,2,3,4', { comma: true, arrayLimit: 3, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 3 elements allowed in an array.'),
|
||||
'throws error when comma-split exceeds array limit'
|
||||
);
|
||||
|
||||
st['throws'](
|
||||
function () {
|
||||
qs.parse('a=1,2,3', { comma: true, arrayLimit: 1, throwOnLimitExceeded: true });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 1 element allowed in an array.'),
|
||||
'throws error with singular "element" when arrayLimit is 1'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('comma-separated values at exactly arrayLimit stay as array', function (st) {
|
||||
var result = qs.parse('a=1,2,3', { comma: true, arrayLimit: 3 });
|
||||
st.ok(Array.isArray(result.a), 'result is an array when exactly at limit');
|
||||
st.deepEqual(result.a, ['1', '2', '3'], 'all values present');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('mixed array and object notation', function (t) {
|
||||
t.test('array brackets with object key - under limit', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a[c]=d'),
|
||||
{ a: { 0: 'b', c: 'd' } },
|
||||
'mixing [] and [key] converts to object'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('array index with object key - under limit', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a[0]=b&a[c]=d'),
|
||||
{ a: { 0: 'b', c: 'd' } },
|
||||
'mixing [0] and [key] produces object'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('plain value with array brackets - under limit', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a=b&a[]=c', { arrayLimit: 20 }),
|
||||
{ a: ['b', 'c'] },
|
||||
'plain value combined with [] stays as array under limit'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('array brackets with plain value - under limit', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a=c', { arrayLimit: 20 }),
|
||||
{ a: ['b', 'c'] },
|
||||
'[] combined with plain value stays as array under limit'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('plain value with array index - under limit', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a=b&a[0]=c', { arrayLimit: 20 }),
|
||||
{ a: ['b', 'c'] },
|
||||
'plain value combined with [0] stays as array under limit'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('multiple plain values with duplicates combine', function (st) {
|
||||
st.deepEqual(
|
||||
qs.parse('a=b&a=c&a=d', { arrayLimit: 20 }),
|
||||
{ a: ['b', 'c', 'd'] },
|
||||
'duplicate plain keys combine into array'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('multiple plain values exceeding limit', function (st) {
|
||||
// 3 elements (indices 0-2), max index 2 > limit 1
|
||||
st.deepEqual(
|
||||
qs.parse('a=b&a=c&a=d', { arrayLimit: 1 }),
|
||||
{ a: { 0: 'b', 1: 'c', 2: 'd' } },
|
||||
'duplicate plain keys convert to object when exceeding limit'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('mixed notation produces consistent results when arrayLimit is exceeded', function (st) {
|
||||
var expected = { a: { 0: 'b', 1: 'c', 2: 'd' } };
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a[1]=c&a=d', { arrayLimit: -1 }),
|
||||
expected,
|
||||
'arrayLimit -1'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a[1]=c&a=d', { arrayLimit: 0 }),
|
||||
expected,
|
||||
'arrayLimit 0'
|
||||
);
|
||||
|
||||
st.deepEqual(
|
||||
qs.parse('a[]=b&a[1]=c&a=d', { arrayLimit: 1 }),
|
||||
expected,
|
||||
'arrayLimit 1'
|
||||
);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('uses existing array length for currentArrayLength when parsing object input with bracket keys', function (st) {
|
||||
var input = {};
|
||||
var arr = ['x', 'y'];
|
||||
arr.a = ['z', 'w'];
|
||||
input['a[]'] = arr;
|
||||
st.deepEqual(qs.parse(input), { a: ['x', 'y'] }, 'parses object input with bracket keys using existing array values');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('throws with singular message when object input bracket key exceeds arrayLimit of 1', function (st) {
|
||||
var input = {};
|
||||
var arr = ['x'];
|
||||
arr.a = ['z', 'w'];
|
||||
input['a[]'] = arr;
|
||||
st['throws'](
|
||||
function () {
|
||||
qs.parse(input, { throwOnLimitExceeded: true, arrayLimit: 1 });
|
||||
},
|
||||
new RangeError('Array limit exceeded. Only 1 element allowed in an array.'),
|
||||
'throws singular error for object input exceeding arrayLimit 1'
|
||||
);
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user