Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions splat.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,16 @@ class Splatter {

// Now that { splat } has been separated from any potential { meta }. we
// can assign this to the `info` object and write it to our format stream.
// If the additional metas are **NOT** objects or **LACK** enumerable properties
// you are going to have a bad time.
// Only non-null objects carry enumerable properties worth merging; merging
// a leftover primitive (e.g. a string) would spread it into char-indexed
// properties on `info` (see #109), so those are skipped instead.
const metalen = metas.length;
if (metalen) {
for (let i = 0; i < metalen; i++) {
Object.assign(info, metas[i]);
const meta = metas[i];
if (typeof meta === 'object' && meta !== null) {
Object.assign(info, meta);
}
}
}

Expand Down
13 changes: 13 additions & 0 deletions test/splat.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,19 @@ describe('splat', () => {
}
));

it('more arguments than % with a leftover primitive | does not spread its characters into info', assumeSplat(
'one %s', ['two', 'three'], info => {
// Regression test for #109: after `%s` consumes 'two', the leftover
// primitive 'three' must NOT be char-spread into indexed properties.
assume(info.message).equals('one two');
assume(info[0]).equals(undefined);
assume(info[1]).equals(undefined);
assume(info[2]).equals(undefined);
assume(info[3]).equals(undefined);
assume(info[4]).equals(undefined);
}
));

it('%% | escaped % sets info.message', assumeSplat(
'test %d%%', [100], 'test 100%'
));
Expand Down
Loading