Skip to content

Commit 0e903c0

Browse files
committed
[Fix] stringify: with arrayFormat: comma, properly include an explicit [] on a single-item array
Properly fixes #434
1 parent ba9703c commit 0e903c0

File tree

3 files changed

+34
-15
lines changed

3 files changed

+34
-15
lines changed

.eslintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"indent": [2, 4],
1616
"max-lines-per-function": [2, { "max": 150 }],
1717
"max-params": [2, 15],
18-
"max-statements": [2, 52],
18+
"max-statements": [2, 53],
1919
"multiline-comment-style": 0,
2020
"no-continue": 1,
2121
"no-magic-numbers": 0,

lib/stringify.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ var stringify = function stringify(
126126
for (var i = 0; i < valuesArray.length; ++i) {
127127
valuesJoined += (i === 0 ? '' : ',') + formatter(encoder(valuesArray[i], defaults.encoder, charset, 'value', format));
128128
}
129-
return [formatter(keyValue) + (i === 1 ? '[]' : '') + '=' + valuesJoined];
129+
return [formatter(keyValue) + (isArray(obj) && valuesArray.length === 1 ? '[]' : '') + '=' + valuesJoined];
130130
}
131131
return [formatter(keyValue) + '=' + formatter(encoder(obj, defaults.encoder, charset, 'value', format))];
132132
}
@@ -150,6 +150,8 @@ var stringify = function stringify(
150150
objKeys = sort ? keys.sort(sort) : keys;
151151
}
152152

153+
var adjustedPrefix = generateArrayPrefix === 'comma' && isArray(obj) && obj.length === 1 ? prefix + '[]' : prefix;
154+
153155
for (var j = 0; j < objKeys.length; ++j) {
154156
var key = objKeys[j];
155157
var value = typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key];
@@ -159,8 +161,8 @@ var stringify = function stringify(
159161
}
160162

161163
var keyPrefix = isArray(obj)
162-
? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(prefix, key) : prefix
163-
: prefix + (allowDots ? '.' + key : '[' + key + ']');
164+
? typeof generateArrayPrefix === 'function' ? generateArrayPrefix(adjustedPrefix, key) : adjustedPrefix
165+
: adjustedPrefix + (allowDots ? '.' + key : '[' + key + ']');
164166

165167
sideChannel.set(object, step);
166168
var valueSideChannel = getSideChannel();

test/stringify.js

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,32 @@ test('stringify()', function (t) {
132132
});
133133

134134
t.test('stringifies an array value with one item vs multiple items', function (st) {
135-
st.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c');
136-
st.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c');
137-
st.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a[]=c'); // so it parses back as an array
138-
st.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true }), 'a[0]=c');
135+
st.test('non-array item', function (s2t) {
136+
s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a=c');
137+
s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a=c');
138+
s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c');
139+
s2t.equal(qs.stringify({ a: 'c' }, { encodeValuesOnly: true }), 'a=c');
139140

140-
st.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c&a[1]=d');
141-
st.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c&a[]=d');
142-
st.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c,d');
143-
st.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true }), 'a[0]=c&a[1]=d');
141+
s2t.end();
142+
});
143+
144+
st.test('array with a single item', function (s2t) {
145+
s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c');
146+
s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c');
147+
s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a[]=c'); // so it parses back as an array
148+
s2t.equal(qs.stringify({ a: ['c'] }, { encodeValuesOnly: true }), 'a[0]=c');
149+
150+
s2t.end();
151+
});
152+
153+
st.test('array with multiple items', function (s2t) {
154+
s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), 'a[0]=c&a[1]=d');
155+
s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), 'a[]=c&a[]=d');
156+
s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c,d');
157+
s2t.equal(qs.stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true }), 'a[0]=c&a[1]=d');
158+
159+
s2t.end();
160+
});
144161

145162
st.end();
146163
});
@@ -362,12 +379,12 @@ test('stringify()', function (t) {
362379
st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'indices' }), 'b[0]=&c=c');
363380
st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'brackets' }), 'b[]=&c=c');
364381
st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'repeat' }), 'b=&c=c');
365-
st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma' }), 'b=&c=c');
382+
st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma' }), 'b[]=&c=c');
366383
// with strictNullHandling
367384
st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'indices', strictNullHandling: true }), 'b[0]&c=c');
368385
st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'brackets', strictNullHandling: true }), 'b[]&c=c');
369386
st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'repeat', strictNullHandling: true }), 'b&c=c');
370-
st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma', strictNullHandling: true }), 'b&c=c');
387+
st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma', strictNullHandling: true }), 'b[]&c=c');
371388
// with skipNulls
372389
st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'indices', skipNulls: true }), 'c=c');
373390
st.equal(qs.stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'brackets', skipNulls: true }), 'c=c');
@@ -695,7 +712,7 @@ test('stringify()', function (t) {
695712
arrayFormat: 'comma'
696713
}
697714
),
698-
'a=' + date.getTime(),
715+
'a%5B%5D=' + date.getTime(),
699716
'works with arrayFormat comma'
700717
);
701718

0 commit comments

Comments
 (0)