-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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(lhr): support printf displayValues #5099
Conversation
const format = (...args) => Util.formatDisplayValue(...args); | ||
assert.equal(format(undefined), ''); | ||
assert.equal(format([1]), 'UNKNOWN'); | ||
assert.equal(format(['%s %s', 'Hello', 'Paul']), 'Hello Paul'); |
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.
Hello formatDisplayValue
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.
done
|
||
let output = template; | ||
while (displayValue.length) { | ||
const replacement = /** @type {number|string} */ (displayValue.shift()); |
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.
assert.equal(format(['%s']), '%s', 'not enough replacements');
assert.equal(format(['%s', 'a', 'a']), 'a', 'extra replacements');
i think we may want to console.warn() in these cases. Allow them, but raise a warning flag.
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.
done
const replacement = /** @type {number|string} */ (displayValue.shift()); | ||
output = output.replace(/%([0-9.]+)?(d|s)/, match => { | ||
const granularity = Number(match.match(/[0-9.]+/)) || 1; | ||
return match === '%s' ? |
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.
assert.equal(format(['%10s', 123.456]), '120');
currently this does pass, fwiw. shoudl we also throw a warning if you are matching 's' and have a granularity?
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.
modified regex to not match this 👍
*/ | ||
static formatDisplayValue(displayValue) { | ||
if (typeof displayValue === 'string' || typeof displayValue === 'undefined') { | ||
return displayValue || ''; |
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.
i'd prefer being super clear
if (typeof displayValue === 'string') return displayValue;
if (typeof displayValue === 'undefined') return '';
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.
done
let displayValue = result.displayValue || ''; | ||
if (typeof result.displayValue === 'undefined' && wastedBytes) { | ||
displayValue = `Potential savings of ${wastedBytes} bytes`; | ||
displayValue = ['Potential savings of %d\xa0KB', wastedKb]; |
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.
nit: switch conditional above to testing wastedKb
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.
done
@@ -29,7 +30,7 @@ describe('Performance: estimated-input-latency audit', () => { | |||
return Audit.audit(artifacts, {options, settings}).then(output => { | |||
assert.equal(output.debugString, undefined); | |||
assert.equal(Math.round(output.rawValue * 10) / 10, 17.1); | |||
assert.equal(output.displayValue, '17\xa0ms'); | |||
assert.equal(Util.formatDisplayValue(output.displayValue), '17\xa0ms'); |
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.
test the real object here like dom-size-test.js
above?
@@ -26,7 +27,7 @@ describe('Performance: first-meaningful-paint audit', () => { | |||
const fmpResult = await FMPAudit.audit(artifacts, context); | |||
|
|||
assert.equal(fmpResult.score, 1); | |||
assert.equal(fmpResult.displayValue, '780\xa0ms'); | |||
assert.equal(Util.formatDisplayValue(fmpResult.displayValue), '780\xa0ms'); |
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.
same with these
@@ -33,7 +34,7 @@ describe('Performance: interactive audit', () => { | |||
return Interactive.audit(artifacts, {options, settings}).then(output => { | |||
assert.equal(output.score, 1); | |||
assert.equal(Math.round(output.rawValue), 1582); | |||
assert.equal(output.displayValue, '1,580\xa0ms'); | |||
assert.equal(Util.formatDisplayValue(output.displayValue), '1,580\xa0ms'); |
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.
and these :)
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.
done
typings/audit.d.ts
Outdated
@@ -23,6 +23,8 @@ declare global { | |||
|
|||
export type ScoringModeValue = Audit.ScoringModes[keyof Audit.ScoringModes]; | |||
|
|||
export type DisplayValue = string | Array<string|number> |
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.
there might be an even more elegant way to do this, but you can do
interface DisplayValueArray extends Array<string | number> {
0: string;
}
export type DisplayValue = string | DisplayValueArray;
to enforce a string in the first position (and a length of at least 1)
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.
done 👍
@@ -53,4 +53,16 @@ describe('util helpers', () => { | |||
assert.equal(Util.calculateRating(0.80), 'pass'); | |||
assert.equal(Util.calculateRating(1.00), 'pass'); | |||
}); | |||
|
|||
it('formats display values', () => { | |||
const format = (...args) => Util.formatDisplayValue(...args); |
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.
don't need to rest and then spread since they're all arrays below?
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.
done
|
||
let output = template; | ||
while (displayValue.length) { | ||
const replacement = /** @type {number|string} */ (displayValue.shift()); |
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.
just switch to regular indexing and avoid these shift assertions? Or could be a reduce
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.
done
let output = template; | ||
while (displayValue.length) { | ||
const replacement = /** @type {number|string} */ (displayValue.shift()); | ||
output = output.replace(/%([0-9.]+)?(d|s)/, match => { |
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 allows more than one decimal point? and no support for granularity when it's a string?
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.
correct if you mess up your format string it'll put NaN
correct %s is just straight up replacement
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.
I meant should it be more like /%([0-9]*(?:\.[0-9]*))?d|s/
or whatever (you covered the no granularity + string case now)
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.
sure, tweaked it a bit
@@ -39,7 +40,7 @@ describe('Performance: first-meaningful-paint audit', () => { | |||
const fmpResult = await FMPAudit.audit(artifacts, context); | |||
|
|||
assert.equal(fmpResult.score, 0.79); | |||
assert.equal(fmpResult.displayValue, '2,850\xa0ms'); | |||
assert.equal(Math.round(fmpResult.displayValue[1]), 2851); |
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.
lol I meant the whole display value to ensure the whole thing matched what's expected (including format string) but can also revert to the last commit for these if you'd prefer that :)
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.
will do (revert that is) :)
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.
LGTM!
adds support for array-based display values in a printf style combined with our
granularity
for formatting numbers, I converted the display values that were most likely to be affected by this (numbers that can reach 1000+), everything else doesn't necessarily need to change but the breaking change has been made and we're free to move between them now :)I wanted to do the conversion in the report at the beginning so everything else can assume it's a string, but there were only 3 callers, so it didn't seem like a big deal. LMK if others prefer that approach
ref #5008 #4333