Skip to content
This repository has been archived by the owner on Aug 1, 2024. It is now read-only.

Commit

Permalink
Externs tests check for browsers that implement Intl class options th…
Browse files Browse the repository at this point in the history
…at are not yet supported by all modern browsers. This extends externs tests to handle options added to browsers.

RELNOTES: Extend externs tests to handle options added to browsers.

PiperOrigin-RevId: 470317555
Change-Id: Ia882f9e8878166906f6e9285797ce60009cc7476
  • Loading branch information
Closure Team authored and copybara-github committed Aug 26, 2022
1 parent 19ae2f1 commit 261b420
Showing 1 changed file with 136 additions and 24 deletions.
160 changes: 136 additions & 24 deletions closure/goog/i18n/externs_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,23 @@
/**
* @fileoverview Testing inclusion of externs and handling in compiled code.
* Sets options for ECMASCript Intl object classes, retrieving them
* as resolved options. Compares the results to determine if any are mangled.
* If so, javascript/externs/intl.js needs to be updated.
* as resolved options.
*
* This test is useful in two situations:
*
* 1. A brower release may include options in the resolvedOptions() result
* that are now yet expected by closure/i18n. The test will flag such
* options as unexpected. This wil signal that a new ECMAScript
* capability is implemented in that browser. In this case, the
* option, the browser, and the broswer should be added to
* newlySupportedKeys.
*
* Note that when all supported modern browsers support an option, then
* the new option key should be added to javascript/externs/intl.js.
* This option key should then be removed from the newlySupportedKeys info.
* 2. TODO(user): This test should be compiled and check at runtime that
* the keys used in Intl class options bags aren't being unexpectedly renamed
* and end up dropped by Intl resolvedOptions.
*/

/**
Expand All @@ -18,6 +33,7 @@
goog.module('goog.i18n.externsTest');
goog.setTestOnly();

const browser = goog.require('goog.labs.userAgent.browser');

const testSuite = goog.require('goog.testing.testSuite');

Expand All @@ -30,6 +46,54 @@ const testSuite = goog.require('goog.testing.testSuite');
* to be updated.
*/

/* Resolved options that are not yet implemented in externs/intl.js
* but do appear in the resolvedOptions keys of some browsers.
* When all modern browsers support a given key, it should be added to
* externs/intl.js for that resolvedOptions call.
* The following is indexed by the Intl Class, followed by a list of newly
* added keys with the browser and minimum browser version indicated.
*
* When a new key is added to externs/intl.js, the entries here should be
* removed.
*/
const newlySupportedKeys = new Map();
newlySupportedKeys.set(Intl.NumberFormat, [
{key: 'roundingMode', browser: browser.isSafari(), minVersion: '15.6'},
{key: 'roundingIncrement', browser: browser.isSafari(), minVersion: '15.6'},
{key: 'trailingZeroDisplay', browser: browser.isSafari(), minVersion: '15.6'},
{key: 'roundingPriority', browser: browser.isSafari(), minVersion: '15.6'},
]);

newlySupportedKeys.set(
Intl.PluralRules,
[{key: 'roundingMode', browser: browser.isSafari(), minVersion: '15.6'}]);

/* TODO:(b/243945751): Add compiled BUILD test for possible options keymangling.
*/

/**
* Check if an option is a newly defined key that is not yet
* in the externs/intl.js file.
* @param {typeof Intl.NumberFormat|typeof Intl.PluralRules|typeof
* Intl.DateTimeFormat|typeof Intl.ListFormat|typeof
* Intl.RelativeTimeFormat} intlClass
* @param {string} checkKey
* @return {boolean} true if the key is already available.
*/
function checkNewKeys(intlClass, checkKey) {
const newKeyInfo = newlySupportedKeys.get(intlClass);
if (newKeyInfo) {
for (let index in newKeyInfo) {
const newKey = newKeyInfo[index];
if (newKey.browser && newKey.key === checkKey &&
browser.isVersionOrHigher(newKey.minVersion)) {
return true;
}
}
}
return false;
}

testSuite({
setUpPage() {},

Expand Down Expand Up @@ -87,15 +151,24 @@ testSuite({
'timeZoneName',
];
const locale = 'pl';
const intlClass = Intl.DateTimeFormat;
for (let i = 0; i < setup.length; i++) {
const options = setup[i];
const fmt = new Intl.DateTimeFormat(locale, options);
const fmt = new Intl.DateTimeFormat(locale, setup[i]);
const resolvedOptions = fmt.resolvedOptions();

let unexpectedOptions = [];
for (let option in resolvedOptions) {
// Check that every option is expected.
assertTrue('Checking for ' + option, outputOptions.includes(option));
// Check that every option is expected unless it's new.
if (!checkNewKeys(intlClass, option)) {
if (!outputOptions.includes(option)) {
unexpectedOptions.push(option);
}
}
}
/* There should be no values in the unexpectedOptions list. */
assertArrayEquals(
'Unexpected options include <' + unexpectedOptions +
'>, version=' + browser.getVersion(),
[], unexpectedOptions);
}
},

Expand Down Expand Up @@ -125,7 +198,6 @@ testSuite({
['timeZone', 'UTC'],
],
];

const outputOptions = [
'locale', 'numberingSystem', 'notation', 'compactDisplay', 'signDisplay',
'useGrouping', 'currency', 'currencyDisplay', 'minimumIntegerDigits',
Expand All @@ -134,14 +206,24 @@ testSuite({
];
const locale = 'pl';
for (let i = 0; i < setup.length; i++) {
const options = setup[i];
const fmt = new Intl.NumberFormat(locale, options);
const fmt = new Intl.NumberFormat(locale, setup[i]);
const resolvedOptions = fmt.resolvedOptions();
const intlClass = Intl.NumberFormat;

let unexpectedOptions = [];
for (let option in resolvedOptions) {
// Check that every option is expected.
assertTrue('Checking for ' + option, outputOptions.includes(option));
// Check that every option is expected unless it's new.
if (!checkNewKeys(intlClass, option)) {
if (!outputOptions.includes(option)) {
unexpectedOptions.push(option);
}
}
}
/* There should be no values in the unexpectedOptions list. */
assertArrayEquals(
'Unexpected options include <' + unexpectedOptions +
'>, version=' + browser.getVersion(),
[], unexpectedOptions);
}
},

Expand Down Expand Up @@ -172,14 +254,24 @@ testSuite({

const locale = 'fr';
for (let i = 0; i < setup.length; i++) {
const options = setup[i];
const fmt = new Intl.PluralRules(locale, options);
const fmt = new Intl.PluralRules(locale, setup[i]);
const resolvedOptions = fmt.resolvedOptions();
const intlClass = Intl.PluralRules;

let unexpectedOptions = [];
for (let option in resolvedOptions) {
// Check that every option is expected.
assertTrue('Checking for ' + option, outputOptions.includes(option));
// Check that every option is expected unless it's new.
if (!checkNewKeys(intlClass, option)) {
if (!outputOptions.includes(option)) {
unexpectedOptions.push(option);
}
}
}
/* There should be no values in the unexpectedOptions list. */
assertArrayEquals(
'Unexpected options include <' + unexpectedOptions +
'>, version=' + browser.getVersion(),
[], unexpectedOptions);
}
},

Expand Down Expand Up @@ -211,14 +303,24 @@ testSuite({

const locale = 'hl';
for (let i = 0; i < setup.length; i++) {
const options = setup[i];
const fmt = new Intl.RelativeTimeFormat(locale, options);
const fmt = new Intl.RelativeTimeFormat(locale, setup[i]);
const resolvedOptions = fmt.resolvedOptions();
const intlClass = Intl.RelativeTimeFormat;

let unexpectedOptions = [];
for (let option in resolvedOptions) {
// Check that every option is expected.
assertTrue('Checking for ' + option, outputOptions.includes(option));
// Check that every option is expected unless it's new.
if (!checkNewKeys(intlClass, option)) {
if (!outputOptions.includes(option)) {
unexpectedOptions.push(option);
}
}
}
/* There should be no values in the unexpectedOptions list. */
assertArrayEquals(
'Unexpected options include <' + unexpectedOptions +
'>, version=' + browser.getVersion(),
[], unexpectedOptions);
}
},

Expand Down Expand Up @@ -254,14 +356,24 @@ testSuite({

const locale = 'ru';
for (let i = 0; i < setup.length; i++) {
const options = setup[i];
const fmt = new Intl.ListFormat(locale, options);
const fmt = new Intl.ListFormat(locale, setup[i]);
const resolvedOptions = fmt.resolvedOptions();
const intlClass = Intl.ListFormat;

let unexpectedOptions = [];
for (let option in resolvedOptions) {
// Check that every option is expected.
assertTrue('Checking for ' + option, outputOptions.includes(option));
// Check that every option is expected unless it's new.
if (!checkNewKeys(intlClass, option)) {
if (!outputOptions.includes(option)) {
unexpectedOptions.push(option);
}
}
}
/* There should be no values in the unexpectedOptions list. */
assertArrayEquals(
'Unexpected options include <' + unexpectedOptions +
'>, version=' + browser.getVersion(),
[], unexpectedOptions);
}
},

Expand Down

0 comments on commit 261b420

Please sign in to comment.