From b69d20c6e9046f28617139d769b8c57873f9ab3b Mon Sep 17 00:00:00 2001 From: Christian Fehmer Date: Sat, 24 Feb 2024 19:59:13 +0100 Subject: [PATCH 1/2] impr: floor accuracy intead of rounding when not showing decimal places --- frontend/__tests__/utils/format.spec.ts | 21 +++++++++++++++++++++ frontend/src/ts/account/pb-tables.ts | 6 +++++- frontend/src/ts/elements/modes-notice.ts | 2 +- frontend/src/ts/pages/account.ts | 12 +++++++++--- frontend/src/ts/popups/pb-tables-popup.ts | 4 +++- frontend/src/ts/test/result.ts | 4 +++- frontend/src/ts/utils/format.ts | 4 +++- 7 files changed, 45 insertions(+), 8 deletions(-) diff --git a/frontend/__tests__/utils/format.spec.ts b/frontend/__tests__/utils/format.spec.ts index cb324c2049ea..a9f5e503b55e 100644 --- a/frontend/__tests__/utils/format.spec.ts +++ b/frontend/__tests__/utils/format.spec.ts @@ -86,6 +86,13 @@ describe("format.ts", () => { expect(format.typingSpeed(null, { suffix: " raw" })).toEqual("-"); expect(format.typingSpeed(undefined, { suffix: " raw" })).toEqual("-"); }); + + it("should format with rounding", () => { + const format = getInstance({ alwaysShowDecimalPlaces: false }); + expect(format.typingSpeed(80.25)).toEqual("80"); + expect(format.typingSpeed(80.25, { rounding: Math.ceil })).toEqual("81"); + expect(format.typingSpeed(80.75, { rounding: Math.floor })).toEqual("80"); + }); }); describe("percentage", () => { it("should format with decimalPlaces from configuration", () => { @@ -138,6 +145,13 @@ describe("format.ts", () => { expect(format.percentage(null, { suffix: " raw" })).toEqual("-"); expect(format.percentage(undefined, { suffix: " raw" })).toEqual("-"); }); + + it("should format with rounding", () => { + const format = getInstance({ alwaysShowDecimalPlaces: false }); + expect(format.percentage(80.25)).toEqual("80%"); + expect(format.percentage(80.25, { rounding: Math.ceil })).toEqual("81%"); + expect(format.percentage(80.75, { rounding: Math.floor })).toEqual("80%"); + }); }); describe("decimals", () => { it("should format with decimalPlaces from configuration", () => { @@ -188,6 +202,13 @@ describe("format.ts", () => { expect(format.decimals(null, { suffix: " raw" })).toEqual("-"); expect(format.decimals(undefined, { suffix: " raw" })).toEqual("-"); }); + + it("should format with rounding", () => { + const format = getInstance({ alwaysShowDecimalPlaces: false }); + expect(format.decimals(80.25)).toEqual("80"); + expect(format.decimals(80.25, { rounding: Math.ceil })).toEqual("81"); + expect(format.decimals(80.75, { rounding: Math.floor })).toEqual("80"); + }); }); }); diff --git a/frontend/src/ts/account/pb-tables.ts b/frontend/src/ts/account/pb-tables.ts index 4f1bcf0d67fd..e03f14d2729d 100644 --- a/frontend/src/ts/account/pb-tables.ts +++ b/frontend/src/ts/account/pb-tables.ts @@ -156,6 +156,7 @@ function buildPbHtml( })}
${Format.percentage(pbData.acc, { showDecimalPlaces: false, + rounding: Math.floor, })}
@@ -164,7 +165,10 @@ function buildPbHtml( suffix: ` ${speedUnit}`, })}
${Format.typingSpeed(pbData.raw, { suffix: " raw" })}
-
${Format.percentage(pbData.acc, { suffix: " acc" })}
+
${Format.percentage(pbData.acc, { + suffix: " acc", + rounding: Math.floor, + })}
${Format.percentage(pbData.consistency, { suffix: " con", })}
diff --git a/frontend/src/ts/elements/modes-notice.ts b/frontend/src/ts/elements/modes-notice.ts index 79fd502d36ce..5efda15ff318 100644 --- a/frontend/src/ts/elements/modes-notice.ts +++ b/frontend/src/ts/elements/modes-notice.ts @@ -158,7 +158,7 @@ export async function update(): Promise { : ""; const avgAccText = ["acc", "both"].includes(Config.showAverage) - ? Format.percentage(avgAcc, { suffix: " acc" }) + ? Format.percentage(avgAcc, { suffix: " acc", rounding: Math.floor }) : ""; const text = `${avgWPMText} ${avgAccText}`.trim(); diff --git a/frontend/src/ts/pages/account.ts b/frontend/src/ts/pages/account.ts index f524bfb2e9c7..7995aec4874d 100644 --- a/frontend/src/ts/pages/account.ts +++ b/frontend/src/ts/pages/account.ts @@ -881,9 +881,15 @@ async function fillContent(): Promise { $(".pageAccount .highestWpm .mode").html(topMode); $(".pageAccount .testsTaken .val").text(testCount); - $(".pageAccount .highestAcc .val").text(Format.percentage(topAcc)); - $(".pageAccount .avgAcc .val").text(Format.percentage(totalAcc / testCount)); - $(".pageAccount .avgAcc10 .val").text(Format.percentage(totalAcc10 / last10)); + $(".pageAccount .highestAcc .val").text( + Format.percentage(topAcc, { rounding: Math.floor }) + ); + $(".pageAccount .avgAcc .val").text( + Format.percentage(totalAcc / testCount, { rounding: Math.floor }) + ); + $(".pageAccount .avgAcc10 .val").text( + Format.percentage(totalAcc10 / last10, { rounding: Math.floor }) + ); if (totalCons === 0 || totalCons === undefined) { $(".pageAccount .avgCons .val").text("-"); diff --git a/frontend/src/ts/popups/pb-tables-popup.ts b/frontend/src/ts/popups/pb-tables-popup.ts index 86697a5c549e..088fb363cf22 100644 --- a/frontend/src/ts/popups/pb-tables-popup.ts +++ b/frontend/src/ts/popups/pb-tables-popup.ts @@ -63,7 +63,9 @@ function update(mode: SharedTypes.Config.Mode): void { ${Format.typingSpeed(pb.wpm)}
- ${Format.percentage(pb.acc)} + ${Format.percentage(pb.acc, { + rounding: Math.floor, + })} ${Format.typingSpeed(pb.raw)} diff --git a/frontend/src/ts/test/result.ts b/frontend/src/ts/test/result.ts index 47631c3cf2f8..293d2639e650 100644 --- a/frontend/src/ts/test/result.ts +++ b/frontend/src/ts/test/result.ts @@ -229,7 +229,9 @@ function updateWpmAndAcc(): void { } $("#result .stats .raw .bottom").text(Format.typingSpeed(result.rawWpm)); $("#result .stats .acc .bottom").text( - result.acc === 100 ? "100%" : Format.percentage(result.acc) + result.acc === 100 + ? "100%" + : Format.percentage(result.acc, { rounding: Math.floor }) ); if (Config.alwaysShowDecimalPlaces) { diff --git a/frontend/src/ts/utils/format.ts b/frontend/src/ts/utils/format.ts index b9c63ae4a616..ef6c8634fcb9 100644 --- a/frontend/src/ts/utils/format.ts +++ b/frontend/src/ts/utils/format.ts @@ -6,12 +6,14 @@ export type FormatOptions = { showDecimalPlaces?: boolean; suffix?: string; fallback?: string; + rounding?: (val: number) => number; }; const FORMAT_DEFAULT_OPTIONS: FormatOptions = { suffix: "", fallback: "-", showDecimalPlaces: undefined, + rounding: Math.round, }; export class Formatting { @@ -60,7 +62,7 @@ export class Formatting { ) { return Misc.roundTo2(value).toFixed(2) + suffix; } - return Math.round(value).toString() + suffix; + return (formatOptions.rounding ?? Math.round)(value).toString() + suffix; } } From 310e7ed7b2373bb77bffbc2d6d9830b08a36e9a8 Mon Sep 17 00:00:00 2001 From: Christian Fehmer Date: Mon, 26 Feb 2024 13:51:30 +0100 Subject: [PATCH 2/2] add method to format accuracy --- frontend/__tests__/utils/format.spec.ts | 20 ++++++++++++++++++++ frontend/src/ts/account/pb-tables.ts | 12 +++--------- frontend/src/ts/elements/modes-notice.ts | 11 +++-------- frontend/src/ts/pages/account.ts | 12 +++--------- frontend/src/ts/popups/pb-tables-popup.ts | 4 +--- frontend/src/ts/test/result.ts | 4 +--- frontend/src/ts/utils/format.ts | 14 +++++++++++++- 7 files changed, 44 insertions(+), 33 deletions(-) diff --git a/frontend/__tests__/utils/format.spec.ts b/frontend/__tests__/utils/format.spec.ts index a9f5e503b55e..396aeac1754e 100644 --- a/frontend/__tests__/utils/format.spec.ts +++ b/frontend/__tests__/utils/format.spec.ts @@ -94,6 +94,7 @@ describe("format.ts", () => { expect(format.typingSpeed(80.75, { rounding: Math.floor })).toEqual("80"); }); }); + describe("percentage", () => { it("should format with decimalPlaces from configuration", () => { //no decimals @@ -153,6 +154,25 @@ describe("format.ts", () => { expect(format.percentage(80.75, { rounding: Math.floor })).toEqual("80%"); }); }); + + describe("accuracy", () => { + it("should floor decimals by default", () => { + //no decimals + const noDecimals = getInstance({ alwaysShowDecimalPlaces: false }); + expect(noDecimals.accuracy(12.75)).toEqual("12%"); + //with decimals + const withDecimals = getInstance({ alwaysShowDecimalPlaces: true }); + expect(withDecimals.accuracy(12.75)).toEqual("12.75%"); + }); + + it("should format with rounding", () => { + const format = getInstance({ alwaysShowDecimalPlaces: false }); + expect(format.accuracy(80.5)).toEqual("80%"); + expect(format.accuracy(80.25, { rounding: Math.ceil })).toEqual("81%"); + expect(format.accuracy(80.75, { rounding: Math.floor })).toEqual("80%"); + }); + }); + describe("decimals", () => { it("should format with decimalPlaces from configuration", () => { //no decimals diff --git a/frontend/src/ts/account/pb-tables.ts b/frontend/src/ts/account/pb-tables.ts index e03f14d2729d..6bc228d88c97 100644 --- a/frontend/src/ts/account/pb-tables.ts +++ b/frontend/src/ts/account/pb-tables.ts @@ -154,9 +154,8 @@ function buildPbHtml(
${Format.typingSpeed(pbData.wpm, { showDecimalPlaces: false, })}
-
${Format.percentage(pbData.acc, { +
${Format.accuracy(pbData.acc, { showDecimalPlaces: false, - rounding: Math.floor, })}
@@ -165,13 +164,8 @@ function buildPbHtml( suffix: ` ${speedUnit}`, })}
${Format.typingSpeed(pbData.raw, { suffix: " raw" })}
-
${Format.percentage(pbData.acc, { - suffix: " acc", - rounding: Math.floor, - })}
-
${Format.percentage(pbData.consistency, { - suffix: " con", - })}
+
${Format.accuracy(pbData.acc, { suffix: " acc" })}
+
${Format.percentage(pbData.consistency, { suffix: " con" })}
${dateText}
`; } catch (e) { diff --git a/frontend/src/ts/elements/modes-notice.ts b/frontend/src/ts/elements/modes-notice.ts index 5efda15ff318..31d45460b7cf 100644 --- a/frontend/src/ts/elements/modes-notice.ts +++ b/frontend/src/ts/elements/modes-notice.ts @@ -144,13 +144,8 @@ export async function update(): Promise { } if (Config.showAverage !== "off") { - let avgWPM = Last10Average.getWPM(); - let avgAcc = Last10Average.getAcc(); - - if (!Config.alwaysShowDecimalPlaces) { - avgWPM = Math.round(avgWPM); - avgAcc = Math.round(avgAcc); - } + const avgWPM = Last10Average.getWPM(); + const avgAcc = Last10Average.getAcc(); if (isAuthenticated() && avgWPM > 0) { const avgWPMText = ["speed", "both"].includes(Config.showAverage) @@ -158,7 +153,7 @@ export async function update(): Promise { : ""; const avgAccText = ["acc", "both"].includes(Config.showAverage) - ? Format.percentage(avgAcc, { suffix: " acc", rounding: Math.floor }) + ? Format.accuracy(avgAcc, { suffix: " acc" }) : ""; const text = `${avgWPMText} ${avgAccText}`.trim(); diff --git a/frontend/src/ts/pages/account.ts b/frontend/src/ts/pages/account.ts index 7995aec4874d..c6eba49defe5 100644 --- a/frontend/src/ts/pages/account.ts +++ b/frontend/src/ts/pages/account.ts @@ -881,15 +881,9 @@ async function fillContent(): Promise { $(".pageAccount .highestWpm .mode").html(topMode); $(".pageAccount .testsTaken .val").text(testCount); - $(".pageAccount .highestAcc .val").text( - Format.percentage(topAcc, { rounding: Math.floor }) - ); - $(".pageAccount .avgAcc .val").text( - Format.percentage(totalAcc / testCount, { rounding: Math.floor }) - ); - $(".pageAccount .avgAcc10 .val").text( - Format.percentage(totalAcc10 / last10, { rounding: Math.floor }) - ); + $(".pageAccount .highestAcc .val").text(Format.accuracy(topAcc)); + $(".pageAccount .avgAcc .val").text(Format.accuracy(totalAcc / testCount)); + $(".pageAccount .avgAcc10 .val").text(Format.accuracy(totalAcc10 / last10)); if (totalCons === 0 || totalCons === undefined) { $(".pageAccount .avgCons .val").text("-"); diff --git a/frontend/src/ts/popups/pb-tables-popup.ts b/frontend/src/ts/popups/pb-tables-popup.ts index 088fb363cf22..5409fd5ece0c 100644 --- a/frontend/src/ts/popups/pb-tables-popup.ts +++ b/frontend/src/ts/popups/pb-tables-popup.ts @@ -63,9 +63,7 @@ function update(mode: SharedTypes.Config.Mode): void { ${Format.typingSpeed(pb.wpm)}
- ${Format.percentage(pb.acc, { - rounding: Math.floor, - })} + ${Format.accuracy(pb.acc)} ${Format.typingSpeed(pb.raw)} diff --git a/frontend/src/ts/test/result.ts b/frontend/src/ts/test/result.ts index 293d2639e650..0259a803fe08 100644 --- a/frontend/src/ts/test/result.ts +++ b/frontend/src/ts/test/result.ts @@ -229,9 +229,7 @@ function updateWpmAndAcc(): void { } $("#result .stats .raw .bottom").text(Format.typingSpeed(result.rawWpm)); $("#result .stats .acc .bottom").text( - result.acc === 100 - ? "100%" - : Format.percentage(result.acc, { rounding: Math.floor }) + result.acc === 100 ? "100%" : Format.accuracy(result.acc) ); if (Config.alwaysShowDecimalPlaces) { diff --git a/frontend/src/ts/utils/format.ts b/frontend/src/ts/utils/format.ts index ef6c8634fcb9..0fc217d29e7d 100644 --- a/frontend/src/ts/utils/format.ts +++ b/frontend/src/ts/utils/format.ts @@ -21,7 +21,7 @@ export class Formatting { typingSpeed( wpm: number | null | undefined, - formatOptions: FormatOptions = FORMAT_DEFAULT_OPTIONS + formatOptions: FormatOptions = {} ): string { const options = { ...FORMAT_DEFAULT_OPTIONS, ...formatOptions }; if (wpm === undefined || wpm === null) return options.fallback ?? ""; @@ -30,6 +30,7 @@ export class Formatting { return this.number(result, options); } + percentage( percentage: number | null | undefined, formatOptions: FormatOptions = {} @@ -40,6 +41,16 @@ export class Formatting { return this.number(percentage, options); } + accuracy( + accuracy: number | null | undefined, + formatOptions: FormatOptions = {} + ): string { + return this.percentage(accuracy, { + rounding: Math.floor, + ...formatOptions, + }); + } + decimals( value: number | null | undefined, formatOptions: FormatOptions = {} @@ -47,6 +58,7 @@ export class Formatting { const options = { ...FORMAT_DEFAULT_OPTIONS, ...formatOptions }; return this.number(value, options); } + private number( value: number | null | undefined, formatOptions: FormatOptions