Repository: GoogleChrome/lighthouse
Pull request #9638 (2019-09-04 21:03:01)

i18n: add registerLocaleData() method
see [Audits Panel Localization Design](https://docs.google.com/document/d/1jnt3BqKB-4q3AE94UWFA0Gqspx8Sd_jivlB7gQMlmfk/edit)

This method enables us to "install" new locale strings into our i18n string lookup.


Unrelated, but I added a few more tests to getFormatted as a driveby. 


Patch:
diff --git a/lighthouse-core/index.js b/lighthouse-core/index.js
index bc7093ad3..c604d8162 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 12ce647ac..e6eff94c3 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,
 };


Test patch:
diff --git a/lighthouse-core/test/lib/i18n/i18n-test.js b/lighthouse-core/test/lib/i18n/i18n-test.js
index 5d45b0323..f78ed3d9c 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 = {