[go: nahoru, domu]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests(i18n): no ICU value given to preprocess #9384

Merged
merged 4 commits into from
Jul 17, 2019
Merged
Show file tree
Hide file tree
Changes from 3 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
6 changes: 2 additions & 4 deletions lighthouse-core/lib/i18n/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,15 @@ function lookupLocale(locale) {
* @param {string} icuMessage
* @param {Record<string, *>} [values]
*/
function _preprocessMessageValues(icuMessage, values) {
if (!values) return;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feels like this change should be accompanied by a test too if we want to change it here :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should change the typedef below (https://github.com/GoogleChrome/lighthouse/pull/9384/files#diff-4f100f14d281ddfaff2dc4466fc78054R167) to Record<string, any>?

I guess I'm just not sure why

so that when sending no replacement object the function will still fire.

is desirable.

Like why not just if (!values) return {} if we want to convert away from undefined

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'm just not sure why

so that when sending no replacement object the function will still fire.

is desirable.

Like why not just if (!values) return {} if we want to convert away from undefined

I may be misinterpreting your question, but this came up when adding the test. _preprocessMessageValues does the "all ICU replacements in the string have a value provided" check, which works fine if there are multiple replacements to be done and one value (or more) is missing. However if the values object is forgotten completely, this line skips the check, even if the string has replacements that will need values.

It still ends up throwing, just in intl-messageformat, so if we are going to do a check here it made sense to do it for all strings that need replacements (instead of all strings that have values passed in with them).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, oh, oh, I misread the parsed.elements.forEach line to be Object.values(values).forEach, my bad!

yes, yes this makes perfect sense!

Still would love a test for forgetting the values completely, but I gotcha now! 👍 :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! I added a new test, and made the error message a bit more helpful.


function _preprocessMessageValues(icuMessage, values = {}) {
const clonedValues = JSON.parse(JSON.stringify(values));
const parsed = MessageParser.parse(icuMessage);
// Throw an error if a message's value isn't provided
parsed.elements
.filter(el => el.type === 'argumentElement')
.forEach(el => {
if (el.id && (el.id in values) === false) {
throw new Error('ICU Message contains a value reference that wasn\'t provided');
throw new Error(`ICU Message contains a value reference ("${el.id}") that wasn't provided`);
}
});

Expand Down
12 changes: 12 additions & 0 deletions lighthouse-core/test/lib/i18n/i18n-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ describe('i18n', () => {
helloSecWorld: 'Hello {in, number, seconds} World',
helloTimeInMsWorld: 'Hello {timeInMs, number, seconds} World',
helloPercentWorld: 'Hello {in, number, extendedPercent} World',
helloWorldMultiReplace: '{hello} {world}',
};
const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings);

Expand Down Expand Up @@ -134,5 +135,16 @@ describe('i18n', () => {
const helloPercentStr = str_(UIStrings.helloPercentWorld, {in: 0.43078});
expect(helloPercentStr).toBeDisplayString('Hello 43.08% World');
});

it('throws an error when a value is not provided', () => {
exterkamp marked this conversation as resolved.
Show resolved Hide resolved
expect(_ => i18n.getFormatted(str_(UIStrings.helloBytesWorld), 'en-US'))
.toThrow(`ICU Message contains a value reference ("in") that wasn't provided`);
});

it('throws an error when a value is missing', () => {
expect(_ => i18n.getFormatted(str_(UIStrings.helloWorldMultiReplace,
{hello: 'hello'}), 'en-US'))
.toThrow(`ICU Message contains a value reference ("world") that wasn't provided`);
});
});
});