diff --git a/lighthouse-core/index.js b/lighthouse-core/index.js index bc7093ad3f83..c604d8162e9c 100644 --- a/lighthouse-core/index.js +++ b/lighthouse-core/index.js @@ -66,5 +66,6 @@ lighthouse.traceCategories = require('./gather/driver.js').traceCategories; lighthouse.Audit = require('./audits/audit.js'); lighthouse.Gatherer = require('./gather/gatherers/gatherer.js'); lighthouse.NetworkRecords = require('./computed/network-records.js'); +lighthouse.registerLocaleData = require('./lib/i18n/i18n.js').registerLocaleData; module.exports = lighthouse; diff --git a/lighthouse-core/lib/i18n/i18n.js b/lighthouse-core/lib/i18n/i18n.js index 12ce647acbe8..e6eff94c3f87 100644 --- a/lighthouse-core/lib/i18n/i18n.js +++ b/lighthouse-core/lib/i18n/i18n.js @@ -473,6 +473,19 @@ function replaceIcuMessageInstanceIds(inputObject, locale) { return icuMessagePaths; } +/** @typedef {import('./locales').LhlMessages} LhlMessages */ + +/** + * Populate the i18n string lookup dict with locale data + * Used when the host environment selects the locale and serves lighthouse the intended locale file + * @see https://docs.google.com/document/d/1jnt3BqKB-4q3AE94UWFA0Gqspx8Sd_jivlB7gQMlmfk/edit + * @param {LH.Locale} locale + * @param {LhlMessages} lhlMessages + */ +function registerLocaleData(locale, lhlMessages) { + LOCALES[locale] = lhlMessages; +} + module.exports = { _formatPathAsString, _ICUMsgNotFoundMsg, @@ -485,4 +498,5 @@ module.exports = { replaceIcuMessageInstanceIds, isIcuMessage, collectAllCustomElementsFromICU, + registerLocaleData, }; diff --git a/lighthouse-core/test/lib/i18n/i18n-test.js b/lighthouse-core/test/lib/i18n/i18n-test.js index 5d45b032362e..f78ed3d9cadf 100644 --- a/lighthouse-core/test/lib/i18n/i18n-test.js +++ b/lighthouse-core/test/lib/i18n/i18n-test.js @@ -74,6 +74,21 @@ describe('i18n', () => { }); describe('#getFormatted', () => { + it('returns the formatted string', () => { + const UIStrings = {testMessage: 'happy test'}; + const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); + const formattedStr = i18n.getFormatted(str_(UIStrings.testMessage), 'en'); + expect(formattedStr).toEqual('happy test'); + }); + + + it('returns the formatted string with replacements', () => { + const UIStrings = {testMessage: 'replacement test ({errorCode})'}; + const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); + const formattedStr = i18n.getFormatted(str_(UIStrings.testMessage, {errorCode: 'BOO'}), 'en'); + expect(formattedStr).toEqual('replacement test (BOO)'); + }); + it('throws an error for invalid locales', () => { // Populate a string to try to localize to a bad locale. const UIStrings = {testMessage: 'testy test'}; @@ -98,6 +113,50 @@ describe('i18n', () => { }); }); + describe('#registerLocaleData', () => { + it('installs new locale strings', () => { + const localeData = { + 'lighthouse-core/test/lib/i18n/i18n-test.js | testString': { + 'message': 'en-XZ cuerda!', + }, + }; + i18n.registerLocaleData('en-XZ', localeData); + + const UIStrings = {testString: 'en-US string!'}; + const str_ = i18n.createMessageInstanceIdFn(__filename, UIStrings); + const formattedStr = i18n.getFormatted(str_(UIStrings.testString), 'en-XZ'); + expect(formattedStr).toEqual('en-XZ cuerda!'); + }); + + it('overwrites existing locale strings', () => { + const filename = 'lighthouse-core/audits/is-on-https.js'; + const UIStrings = require('../../../../lighthouse-core/audits/is-on-https.js').UIStrings; + const str_ = i18n.createMessageInstanceIdFn(filename, UIStrings); + + // To start with, we get back the intended string.. + const origTitle = i18n.getFormatted(str_(UIStrings.title), 'es-419'); + expect(origTitle).toEqual('Usa HTTPS'); + const origFailureTitle = i18n.getFormatted(str_(UIStrings.failureTitle), 'es-419'); + expect(origFailureTitle).toEqual('No usa HTTPS'); + + // Now we declare and register the new string... + const localeData = { + 'lighthouse-core/audits/is-on-https.js | title': { + 'message': 'es-419 uses https!', + }, + }; + i18n.registerLocaleData('es-419', localeData); + + // And confirm that's what is returned + const newTitle = i18n.getFormatted(str_(UIStrings.title), 'es-419'); + expect(newTitle).toEqual('es-419 uses https!'); + + // Meanwhile another string that wasn't set in registerLocaleData just falls back to english + const newFailureTitle = i18n.getFormatted(str_(UIStrings.failureTitle), 'es-419'); + expect(newFailureTitle).toEqual('Does not use HTTPS'); + }); + }); + describe('Message values are properly formatted', () => { // Message strings won't be in locale files, so will fall back to values given here. const UIStrings = {