Skip to content

Commit

Permalink
[Fix] correctly parse nested arrays
Browse files Browse the repository at this point in the history
Fixes #212.
  • Loading branch information
Wes Roberts authored and ljharb committed Dec 5, 2017
1 parent 34af57e commit fde5bb7
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/utils.js
Expand Up @@ -72,7 +72,7 @@ var merge = function merge(target, source, options) {
if (Array.isArray(target) && Array.isArray(source)) {
source.forEach(function (item, i) {
if (has.call(target, i)) {
if (target[i] && typeof target[i] === 'object') {
if (target[i] && typeof target[i] === 'object' && item && typeof item === 'object') {
target[i] = merge(target[i], item, options);
} else {
target.push(item);
Expand Down
8 changes: 8 additions & 0 deletions test/parse.js
Expand Up @@ -237,6 +237,14 @@ test('parse()', function (t) {
st.end();
});

t.test('parses jquery-param strings', function (st) {
// readable = 'filter[0][]=int1&filter[0][]==&filter[0][]=77&filter[]=and&filter[2][]=int2&filter[2][]==&filter[2][]=8'
var encoded = 'filter%5B0%5D%5B%5D=int1&filter%5B0%5D%5B%5D=%3D&filter%5B0%5D%5B%5D=77&filter%5B%5D=and&filter%5B2%5D%5B%5D=int2&filter%5B2%5D%5B%5D=%3D&filter%5B2%5D%5B%5D=8';
var expected = { filter: [['int1', '=', '77'], 'and', ['int2', '=', '8']] };
st.deepEqual(qs.parse(encoded), expected);
st.end();
});

t.test('continues parsing when no parent is found', function (st) {
st.deepEqual(qs.parse('[]=&a=b'), { 0: '', a: 'b' });
st.deepEqual(qs.parse('[]&a=b', { strictNullHandling: true }), { 0: null, a: 'b' });
Expand Down
24 changes: 24 additions & 0 deletions test/utils.js
Expand Up @@ -21,6 +21,30 @@ test('merge()', function (t) {
var noOptionsNonObjectSource = utils.merge({ foo: 'baz' }, 'bar');
t.deepEqual(noOptionsNonObjectSource, { foo: 'baz', bar: true });

t.test(
'avoids invoking array setters unnecessarily',
{ skip: typeof Object.defineProperty !== 'function' },
function (st) {
var setCount = 0;
var getCount = 0;
var observed = [];
Object.defineProperty(observed, 0, {
get: function () {
getCount += 1;
return { bar: 'baz' };
},
set: function () { setCount += 1; }
});
utils.merge(observed, [null]);
st.equal(setCount, 0);
st.equal(getCount, 2);
observed[0] = observed[0]; // eslint-disable-line no-self-assign
st.equal(setCount, 1);
st.equal(getCount, 3);
st.end();
}
);

t.end();
});

Expand Down

0 comments on commit fde5bb7

Please sign in to comment.