Skip to content

Commit 06129ad

Browse files
fix: uneval grows sparse arrays by one slot when first hole is past index 0 (#160)
* fix: do not grow sparse arrays by one slot in uneval When the first hole in an array literal was at an index greater than 0, uneval emitted two commas for it: one from `if (i > 0) result += ','` at the top of the iteration, and a second after `i -= 1` re-processed the same index. So `uneval([1, , 3])` produced `[1,,,3]` (length 4) instead of `[1,,3]` (length 3), and the round-tripped array gained a slot. The comma at the top of the iteration already represents the hole, so drop the `i -= 1` re-processing. * chore: add changeset * Apply suggestion from @elliott-with-the-longest-name-on-github --------- Co-authored-by: Elliott Johnson <hello+github@ell.iott.dev>
1 parent 756265a commit 06129ad

3 files changed

Lines changed: 16 additions & 2 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'devalue': patch
3+
---
4+
5+
fix: do not grow sparse arrays by one slot in uneval

‎src/uneval.js‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,7 @@ export function uneval(value, replacer) {
261261
return `Object.assign(Array(${thing.length}),{${entries}})`;
262262
}
263263

264-
// Re-process this index as a hole in the array literal
265264
has_holes = true;
266-
i -= 1;
267265
}
268266
// else: already decided on array literal, hole is just an empty slot
269267
// (the comma separator is all we need — no content for this position)

‎test/index.test.js‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,6 +1422,17 @@ uvu.test('ignores non-numeric array properties in dense encoding', () => {
14221422
assert.ok(!(0 in parsed));
14231423
});
14241424

1425+
uvu.test('uneval round-trips sparse arrays whose first hole is not at index 0', () => {
1426+
for (const arr of [[1, , 3], [1, ,], [1, , , 4], [1, 2, , 4]]) {
1427+
const evaled = (0, eval)(uneval(arr));
1428+
assert.is(evaled.length, arr.length, `length for keys ${Object.keys(arr).join(',')}`);
1429+
assert.equal(Object.keys(evaled), Object.keys(arr));
1430+
for (const k of Object.keys(arr)) {
1431+
assert.is(evaled[k], arr[k]);
1432+
}
1433+
}
1434+
});
1435+
14251436
uvu.test('ignores non-numeric array properties in sparse encoding', () => {
14261437
// Sparse path (very sparse — Object.assign / SPARSE encoding wins)
14271438
const arr = [];

0 commit comments

Comments
 (0)