-
Notifications
You must be signed in to change notification settings - Fork 9.5k
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
core(i18n): improve Intl polyfill and use it in Util #9584
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -192,7 +192,7 @@ class Util { | |
*/ | ||
static formatNumber(number, granularity = 0.1) { | ||
const coarseValue = Math.round(number / granularity) * granularity; | ||
return coarseValue.toLocaleString(Util.numberDateLocale); | ||
return Util.numberFormatter.format(coarseValue); | ||
} | ||
|
||
/** | ||
|
@@ -201,8 +201,7 @@ class Util { | |
* @return {string} | ||
*/ | ||
static formatBytesToKB(size, granularity = 0.1) { | ||
const kbs = (Math.round(size / 1024 / granularity) * granularity) | ||
.toLocaleString(Util.numberDateLocale); | ||
const kbs = Util.numberFormatter.format(Math.round(size / 1024 / granularity) * granularity); | ||
return `${kbs}${NBSP}KB`; | ||
} | ||
|
||
|
@@ -213,7 +212,7 @@ class Util { | |
*/ | ||
static formatMilliseconds(ms, granularity = 10) { | ||
const coarseTime = Math.round(ms / granularity) * granularity; | ||
return `${coarseTime.toLocaleString(Util.numberDateLocale)}${NBSP}ms`; | ||
return `${Util.numberFormatter.format(coarseTime)}${NBSP}ms`; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
} | ||
|
||
/** | ||
|
@@ -223,7 +222,7 @@ class Util { | |
*/ | ||
static formatSeconds(ms, granularity = 0.1) { | ||
const coarseTime = Math.round(ms / 1000 / granularity) * granularity; | ||
return `${coarseTime.toLocaleString(Util.numberDateLocale)}${NBSP}s`; | ||
return `${Util.numberFormatter.format(coarseTime)}${NBSP}s`; | ||
} | ||
|
||
/** | ||
|
@@ -556,10 +555,11 @@ class Util { | |
* @param {LH.Locale} locale | ||
*/ | ||
static setNumberDateLocale(locale) { | ||
Util.numberDateLocale = locale; | ||
|
||
// When testing, use a locale with more exciting numeric formatting | ||
if (Util.numberDateLocale === 'en-XA') Util.numberDateLocale = 'de'; | ||
if (locale === 'en-XA') locale = 'de'; | ||
|
||
Util.numberDateLocale = locale; | ||
Util.numberFormatter = new Intl.NumberFormat(locale); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. more static-ish state is unfortunate, but it seemed wasteful to do (tsc ensures it's initialized on the class, though, so that's a plus) |
||
} | ||
|
||
/** | ||
|
@@ -618,6 +618,12 @@ class Util { | |
*/ | ||
Util.numberDateLocale = 'en'; | ||
|
||
/** | ||
* This value stays in sync with Util.numberDateLocale. | ||
* @type {Intl.NumberFormat} | ||
*/ | ||
Util.numberFormatter = new Intl.NumberFormat(Util.numberDateLocale); | ||
|
||
/** | ||
* Report-renderer-specific strings. | ||
* @type {LH.I18NRendererStrings} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,11 @@ const assert = require('assert'); | |
const Util = require('../../../../report/html/renderer/util.js'); | ||
const sampleResult = require('../../../results/sample_v2.json'); | ||
|
||
// Require i18n to make sure Intl is polyfilled in Node without full-icu for testing. | ||
// When Util is run in a browser, Intl will be supplied natively (IE11+). | ||
// eslint-disable-next-line no-unused-vars | ||
const i18n = require('../../../../lib/i18n/i18n.js'); | ||
|
||
const NBSP = '\xa0'; | ||
|
||
/* eslint-env jest */ | ||
|
@@ -47,25 +52,40 @@ describe('util helpers', () => { | |
assert.equal(Util.formatDuration(28 * 60 * 60 * 1000 + 5000), `1${NBSP}d 4${NBSP}h 5${NBSP}s`); | ||
}); | ||
|
||
// TODO: need ICU support in node on Travis/Appveyor | ||
it.skip('formats based on locale', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
🎉 |
||
it('formats numbers based on locale', () => { | ||
// Requires full-icu or Intl polyfill. | ||
const number = 12346.858558; | ||
|
||
const originalLocale = Util.numberDateLocale; | ||
Util.setNumberDateLocale('de'); | ||
assert.strictEqual(Util.formatNumber(number), '12.346,9'); | ||
Util.setNumberDateLocale(originalLocale); // reset | ||
assert.strictEqual(Util.formatBytesToKB(number), `12,1${NBSP}KB`); | ||
assert.strictEqual(Util.formatMilliseconds(number), `12.350${NBSP}ms`); | ||
assert.strictEqual(Util.formatSeconds(number), `12,3${NBSP}s`); | ||
|
||
Util.setNumberDateLocale(originalLocale); // reset locale | ||
assert.strictEqual(Util.formatNumber(number), '12,346.9'); | ||
assert.strictEqual(Util.formatBytesToKB(number), `12.1${NBSP}KB`); | ||
assert.strictEqual(Util.formatMilliseconds(number), `12,350${NBSP}ms`); | ||
assert.strictEqual(Util.formatSeconds(number), `12.3${NBSP}s`); | ||
}); | ||
|
||
it.skip('uses decimal comma with en-XA test locale', () => { | ||
it('uses decimal comma with en-XA test locale', () => { | ||
// Requires full-icu or Intl polyfill. | ||
const number = 12346.858558; | ||
|
||
const originalLocale = Util.numberDateLocale; | ||
Util.setNumberDateLocale('en-XA'); | ||
assert.strictEqual(Util.formatNumber(number), '12.346,9'); | ||
Util.setNumberDateLocale(originalLocale); // reset | ||
assert.strictEqual(Util.formatBytesToKB(number), `12,1${NBSP}KB`); | ||
assert.strictEqual(Util.formatMilliseconds(number), `12.350${NBSP}ms`); | ||
assert.strictEqual(Util.formatSeconds(number), `12,3${NBSP}s`); | ||
|
||
Util.setNumberDateLocale(originalLocale); // reset locale | ||
assert.strictEqual(Util.formatNumber(number), '12,346.9'); | ||
assert.strictEqual(Util.formatBytesToKB(number), `12.1${NBSP}KB`); | ||
assert.strictEqual(Util.formatMilliseconds(number), `12,350${NBSP}ms`); | ||
assert.strictEqual(Util.formatSeconds(number), `12.3${NBSP}s`); | ||
}); | ||
|
||
it('calculates a score ratings', () => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be enough to establish whether Node is
full-icu
or not, but happy to add or take away from this minimum list.