From 4e440195c7647f21c20bb76340774cb3a0cb6eac Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sun, 5 Jun 2022 16:49:41 -0500 Subject: [PATCH] [Fix] `stringify`: with `arrayFormat: comma`, include an explicit `[]` on a single-item array Fixes #434 --- lib/stringify.js | 2 +- test/parse.js | 10 ++++++++++ test/stringify.js | 14 ++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/stringify.js b/lib/stringify.js index 47ea4b15..5ace512e 100644 --- a/lib/stringify.js +++ b/lib/stringify.js @@ -126,7 +126,7 @@ var stringify = function stringify( for (var i = 0; i < valuesArray.length; ++i) { valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format)); } - return [formatter(keyValue) + '=' + valuesJoined]; + return [formatter(keyValue) + (i === 1 ? '[]' : '') + '=' + valuesJoined]; } return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))]; } diff --git a/test/parse.js b/test/parse.js index 9734f428..7d7b4dd8 100644 --- a/test/parse.js +++ b/test/parse.js @@ -410,6 +410,16 @@ test('parse()', function (t) { st.deepEqual(qs.parse('foo=', { comma: true }), { foo: '' }); st.deepEqual(qs.parse('foo', { comma: true }), { foo: '' }); st.deepEqual(qs.parse('foo', { comma: true, strictNullHandling: true }), { foo: null }); + + // test cases inversed from from stringify tests + st.deepEqual(qs.parse('a[0]=c'), { a: ['c'] }); + st.deepEqual(qs.parse('a[]=c'), { a: ['c'] }); + st.deepEqual(qs.parse('a[]=c', { comma: true }), { a: ['c'] }); + + st.deepEqual(qs.parse('a[0]=c&a[1]=d'), { a: ['c', 'd'] }); + st.deepEqual(qs.parse('a[]=c&a[]=d'), { a: ['c', 'd'] }); + st.deepEqual(qs.parse('a=c,d', { comma: true }), { a: ['c', 'd'] }); + st.end(); }); diff --git a/test/stringify.js b/test/stringify.js index 4c3ee0e8..f1ff112e 100644 --- a/test/stringify.js +++ b/test/stringify.js @@ -131,6 +131,20 @@ test('stringify()', function (t) { st.end(); }); + t.test('stringifies an array value with one item vs multiple items', function (st) { + st.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c'); + st.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c'); + st.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a[]=c'); // so it parses back as an array + st.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true }), 'a[0]=c'); + + st.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c&a[1]=d'); + st.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c&a[]=d'); + st.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c,d'); + st.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true }), 'a[0]=c&a[1]=d'); + + st.end(); + }); + t.test('stringifies a nested array value', function (st) { st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[b][0]=c&a[b][1]=d'); st.equal(qs.stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[b][]=c&a[b][]=d');