diff --git a/.eslintrc b/.eslintrc index f1d1430..c49043a 100644 --- a/.eslintrc +++ b/.eslintrc @@ -86,6 +86,7 @@ "nonblock-statement-body-position": ["error", "below"], "object-curly-spacing": ["error", "always"], "operator-linebreak": ["error", "before"], + "prefer-template": 2, "quotes": [2, "double", { "avoidEscape": true }], "semi": 2, "semi-spacing": [2, { "before": false, "after": true }], diff --git a/index.html b/index.html index 4af8833..81b763e 100644 --- a/index.html +++ b/index.html @@ -41,8 +41,10 @@

Score

-
-
+
+
+
+
diff --git a/resources/benchmark-report.mjs b/resources/benchmark-report.mjs index 71acffe..4a71c5a 100644 --- a/resources/benchmark-report.mjs +++ b/resources/benchmark-report.mjs @@ -62,8 +62,8 @@ for (const testName in suite.tests) { const test = suite.tests[testName]; for (const subtestName in test.tests) - addToMeasuredValue(test.tests[subtestName], suiteName + "/" + testName + "/" + subtestName); - addToMeasuredValue(test.total, suiteName + "/" + testName, "Total"); + addToMeasuredValue(test.tests[subtestName], `${suiteName} / ${testName} / ${subtestName}`); + addToMeasuredValue(test.total, `${suiteName}/${testName}`, "Total"); } addToMeasuredValue(suite.total, suiteName, "Total"); } diff --git a/resources/benchmark-runner.mjs b/resources/benchmark-runner.mjs index 61987b4..4421569 100644 --- a/resources/benchmark-runner.mjs +++ b/resources/benchmark-runner.mjs @@ -144,8 +144,8 @@ export class BenchmarkRunner { const marginLeft = parseInt(getComputedStyle(document.body).marginLeft); const marginTop = parseInt(getComputedStyle(document.body).marginTop); if (window.innerWidth > params.viewport.width + marginLeft && window.innerHeight > params.viewport.height + marginTop) { - frame.style.left = marginLeft + "px"; - frame.style.top = marginTop + "px"; + frame.style.left = `${marginLeft}px`; + frame.style.top = `${marginTop}px`; } else { frame.style.left = "0px"; frame.style.top = "0px"; @@ -202,7 +202,7 @@ export class BenchmarkRunner { await suite.prepare(this._page); resolve(); }; - frame.src = "resources/" + suite.url; + frame.src = `resources/${suite.url}`; }); } @@ -233,11 +233,11 @@ export class BenchmarkRunner { _runTest(suite, test, page, callback) { const now = window.performance && window.performance.now ? () => window.performance.now() : Date.now; - this._writeMark(suite.name + "." + test.name + "-start"); + this._writeMark(`${suite.name}.${test.name}-start`); let startTime = now(); test.run(page); let endTime = now(); - this._writeMark(suite.name + "." + test.name + "-sync-end"); + this._writeMark(`${suite.name}.${test.name}-sync-end`); const syncTime = endTime - startTime; @@ -248,7 +248,7 @@ export class BenchmarkRunner { const height = this._frame.contentDocument.body.getBoundingClientRect().height; endTime = now(); this._frame.contentWindow._unusedHeightValue = height; // Prevent dead code elimination. - this._writeMark(suite.name + "." + test.name + "-async-end"); + this._writeMark(`${suite.name}.${test.name}-async-end`); window.requestAnimationFrame(() => { callback(syncTime, endTime - startTime, height); }); diff --git a/resources/interactive.mjs b/resources/interactive.mjs index aa15ed4..3467958 100644 --- a/resources/interactive.mjs +++ b/resources/interactive.mjs @@ -70,15 +70,15 @@ class InteractiveBenchmarkRunner extends BenchmarkRunner { for (const testName in suiteResults.tests) { let testResults = suiteResults.tests[testName]; for (const subtestName in testResults.tests) { - results += suiteName + " : " + testName + " : " + subtestName + ": " + testResults.tests[subtestName] + " ms\n"; + results += `${suiteName} : ${testName} : ${subtestName}: ${testResults.tests[subtestName]} ms\n`; } } - results += suiteName + " : " + suiteResults.total + " ms\n"; + results += `${suiteName} : ${suiteResults.total} ms\n`; } - results += "Arithmetic Mean : " + measuredValues.mean + " ms\n"; - results += "Geometric Mean : " + measuredValues.geomean + " ms\n"; - results += "Total : " + measuredValues.total + " ms\n"; - results += "Score : " + measuredValues.score + " rpm\n"; + results += `Arithmetic Mean : ${measuredValues.mean} ms\n`; + results += `Geometric Mean : ${measuredValues.geomean} ms\n`; + results += `Total : ${measuredValues.total} ms\n`; + results += `Score : ${measuredValues.score} rpm\n`; if (!results) return; @@ -119,7 +119,7 @@ window.Suites = Suites; window.BenchmarkRunner = InteractiveBenchmarkRunner; function formatTestName(suiteName, testName) { - return suiteName + (testName ? "/" + testName : ""); + return suiteName + (testName ? `/${testName}` : ""); } function createUIForSuites(suites, onStep, onRunSuites) { @@ -150,7 +150,7 @@ function createUIForSuites(suites, onStep, onRunSuites) { const testItem = document.createElement("li"); const test = suite.tests[testIndex]; const anchor = document.createElement("a"); - anchor.id = suite.name + "-" + test.name; + anchor.id = `${suite.name}-${test.name}`; test.anchor = anchor; anchor.appendChild(document.createTextNode(formatTestName(suite.name, test.name))); testItem.appendChild(anchor); @@ -219,7 +219,7 @@ function startTest() { const interactiveRunner = new window.BenchmarkRunner(Suites, params.iterationCount); if (!(interactiveRunner instanceof InteractiveBenchmarkRunner)) { - throw Error("window.BenchmarkRunner must be " + "a subclass of InteractiveBenchmarkRunner"); + throw Error("window.BenchmarkRunner must be a subclass of InteractiveBenchmarkRunner"); } // Don't call step while step is already executing. diff --git a/resources/main.css b/resources/main.css index 3a3405a..f4722d6 100644 --- a/resources/main.css +++ b/resources/main.css @@ -17,7 +17,8 @@ body { } h1, -button, .button { +button, +.button { font-family: "Futura-Medium", Futura, "Helvetica Neue", Helvetica, Verdana, sans-serif; } @@ -105,10 +106,11 @@ section#home > .buttons { display: flex; flex-wrap: wrap; justify-content: space-around; - margin: 5px 0px + margin: 5px 0px; } -button, .button { +button, +.button { appearance: none; border: none; background-color: transparent; @@ -123,7 +125,8 @@ button, .button { text-decoration: none; } -.buttons button, .buttons .button { +.buttons button, +.buttons .button { appearance: none; border: 3px solid var(--foreground); border-radius: 10px; @@ -211,7 +214,6 @@ button.show-about { background-color: var(--foreground); } - #info { position: absolute; bottom: -25px; @@ -255,11 +257,12 @@ section#summarized-results > #confidence-number { color: rgb(128, 128, 128); } -section#detailed-results button, section#detailed-results .button { +section#detailed-results button, +section#detailed-results .button { min-width: 300px; } -section#detailed-results >.arithmetic-mean { +section#detailed-results > .arithmetic-mean { clear: both; padding-top: 32px; text-align: center; @@ -297,7 +300,6 @@ section#about .note { color: rgb(128, 128, 128); } - table { border-spacing: 0; border-collapse: collapse; diff --git a/resources/main.mjs b/resources/main.mjs index f1d1c5a..e0d100d 100644 --- a/resources/main.mjs +++ b/resources/main.mjs @@ -47,7 +47,7 @@ class MainBenchmarkClient { if (value === "ms") this.displayUnit = "ms"; else - console.error("Invalid unit: " + value); + console.error(`Invalid unit: ${value}`); break; case "iterationCount": /* eslint-disable-next-line no-case-declarations */ @@ -55,11 +55,11 @@ class MainBenchmarkClient { if (!isNaN(parsedValue)) this.iterationCount = parsedValue; else - console.error("Invalid iteration count: " + value); + console.error(`Invalid iteration count: ${value}`); break; case "suite": if (!this.enableOneSuite(Suites, value)) { - alert('Suite "' + value + '" does not exist. No tests to run.'); + alert(`Suite "${value}" does not exist. No tests to run.`); return false; } break; @@ -81,18 +81,18 @@ class MainBenchmarkClient { willAddTestFrame(frame) { const main = document.querySelector("main"); const style = getComputedStyle(main); - frame.style.left = main.offsetLeft + parseInt(style.borderLeftWidth) + parseInt(style.paddingLeft) + "px"; - frame.style.top = main.offsetTop + parseInt(style.borderTopWidth) + parseInt(style.paddingTop) + "px"; + frame.style.left = `${main.offsetLeft + parseInt(style.borderLeftWidth) + parseInt(style.paddingLeft)}px`; + frame.style.top = `${main.offsetTop + parseInt(style.borderTopWidth) + parseInt(style.paddingTop)}px`; } willRunTest(suite, test) { - document.getElementById('info-label').textContent = suite.name - document.getElementById('info-progress').textContent = `${this._finishedTestCount} / ${this.stepCount}`; + document.getElementById("info-label").textContent = suite.name; + document.getElementById("info-progress").textContent = `${this._finishedTestCount} / ${this.stepCount}`; } didRunTest() { this._finishedTestCount++; - this._progressCompleted.style.width = (this._finishedTestCount * 100) / this.stepCount + "%"; + this._progressCompleted.style.width = `${(this._finishedTestCount * 100) / this.stepCount}%`; } didRunSuites(measuredValues) { @@ -114,7 +114,7 @@ class MainBenchmarkClient { this._updateGaugeNeedle(results.mean); document.getElementById("result-number").textContent = results.formattedMean; if (results.formattedDelta) - document.getElementById("confidence-number").textContent = "\u00b1 " + results.formattedDelta; + document.getElementById("confidence-number").textContent = `\u00b1 ${results.formattedDelta}`; this._populateDetailedResults(results.formattedValues); document.getElementById("results-with-statistics").textContent = results.formattedMeanAndDelta; @@ -155,26 +155,26 @@ class MainBenchmarkClient { const percentDelta = (delta * 100) / arithmeticMean; meanSigFig = sigFigFromPercentDelta(percentDelta); formattedDelta = toSigFigPrecision(delta, 2); - formattedPercentDelta = toSigFigPrecision(percentDelta, 2) + "%"; + formattedPercentDelta = `${toSigFigPrecision(percentDelta, 2)}%`; } const formattedMean = toSigFigPrecision(arithmeticMean, Math.max(meanSigFig, 3)); return { formattedValues: values.map((value) => { - return toSigFigPrecision(value, 4) + " " + displayUnit; + return `${toSigFigPrecision(value, 4)} ${displayUnit}`; }), mean: arithmeticMean, formattedMean: formattedMean, formattedDelta: formattedDelta, - formattedMeanAndDelta: formattedMean + (formattedDelta ? " \xb1 " + formattedDelta + " (" + formattedPercentDelta + ")" : ""), + formattedMeanAndDelta: formattedMean + (formattedDelta ? ` \xb1 ${formattedDelta} (${formattedPercentDelta})` : ""), }; } _addDetailedResultsRow(table, iterationNumber, value) { const row = document.createElement("tr"); const th = document.createElement("th"); - th.textContent = "Iteration " + (iterationNumber + 1); + th.textContent = `Iteration ${iterationNumber + 1}`; const td = document.createElement("td"); td.textContent = value; row.appendChild(th); @@ -184,7 +184,7 @@ class MainBenchmarkClient { _updateGaugeNeedle(score) { const needleAngle = Math.max(0, Math.min(score, 140)) - 70; - const needleRotationValue = 'rotate(' + needleAngle + 'deg)'; + const needleRotationValue = `rotate(${needleAngle}deg)`; const gaugeNeedleElement = document.querySelector("#summarized-results > .gauge .needle"); gaugeNeedleElement.style.setProperty("-webkit-transform", needleRotationValue); @@ -204,7 +204,7 @@ class MainBenchmarkClient { this._addDetailedResultsRow(resultsTables[1], i, formattedValues[i]); const jsonData = JSON.stringify(this._measuredValuesList); - const blob = new Blob([jsonData], {type: "application/json"}); + const blob = new Blob([jsonData], { type: "application/json" }); const url = URL.createObjectURL(blob); const link = document.getElementById("download-json"); link.href = url; @@ -248,7 +248,7 @@ class MainBenchmarkClient { const screenIsTooSmall = window.innerWidth < mainSize.width || window.innerHeight < mainSize.height; document.getElementById("min-screen-width").textContent = `${params.viewport.width + 50}px`; document.getElementById("min-screen-height").textContent = `${params.viewport.height + 50}px`; - document.getElementById("screen-size").textContent = window.innerWidth + "px by " + window.innerHeight + "px"; + document.getElementById("screen-size").textContent = `${window.innerWidth}px by ${window.innerHeight}px`; document.getElementById("screen-size-warning").style.display = screenIsTooSmall ? null : "none"; } @@ -277,20 +277,16 @@ class MainBenchmarkClient { this._showSection("about", true); } - _getFormattedJSONResult() - { + _getFormattedJSONResult() { const indent = " "; return JSON.stringify(this._measuredValuesList, undefined, indent); } - copyJsonResults() - { - + copyJsonResults() { navigator.clipboard.writeText(this._getFormattedJSONResult()); } - downloadJsonResults() - { + downloadJsonResults() { navigator.clipboard.writeText(this._getFormattedJSONResult()); } diff --git a/resources/metric.mjs b/resources/metric.mjs index 684eca7..7d90029 100644 --- a/resources/metric.mjs +++ b/resources/metric.mjs @@ -37,7 +37,7 @@ export class Metric { } get shortName() { - return this.parent ? this.name.replace(this.parent.name + "-", "") : this.name; + return this.parent ? this.name.replace(`${this.parent.name}-`, "") : this.name; } get valueString() { diff --git a/resources/statistics.mjs b/resources/statistics.mjs index 2558f7b..47e42e0 100644 --- a/resources/statistics.mjs +++ b/resources/statistics.mjs @@ -62,15 +62,8 @@ export function supportedConfidenceLevels() { export function confidenceIntervalDelta(confidenceLevel, numberOfSamples, sum, squareSum) { const probability = 1 - (1 - confidenceLevel) / 2; if (!(probability in tDistributionInverseCDF)) { - throw ( - "We only support " - + supportedConfidenceLevels() - .map(function (level) { - return level * 100 + "%"; - }) - .join(", ") - + " confidence intervals." - ); + const supportedIntervals = supportedConfidenceLevels().map((level) => `${level * 100}%`); + throw `We only support ${supportedIntervals.join(", ")} confidence intervals.`; } if (numberOfSamples - 2 < 0) return NaN; @@ -78,7 +71,7 @@ export function confidenceIntervalDelta(confidenceLevel, numberOfSamples, sum, s const cdfForProbability = tDistributionInverseCDF[probability]; const degreesOfFreedom = numberOfSamples - 1; if (degreesOfFreedom > cdfForProbability.length) - throw "We only support up to " + deltas.length + " degrees of freedom"; + throw `We only support up to ${deltas.length} degrees of freedom`; // tDistributionQuantile(degreesOfFreedom, confidenceLevel) * sampleStandardDeviation / sqrt(numberOfSamples) * S/sqrt(numberOfSamples) const quantile = cdfForProbability[degreesOfFreedom - 1]; // The first entry is for the one degree of freedom. diff --git a/resources/tests.mjs b/resources/tests.mjs index cd04488..89e404c 100644 --- a/resources/tests.mjs +++ b/resources/tests.mjs @@ -10,10 +10,10 @@ Suites.push({ (await page.waitForElement(".new-todo")).focus(); }, tests: [ - new BenchmarkTestStep("Adding" + numberOfItemsToAdd + "Items", (page) => { + new BenchmarkTestStep(`Adding${numberOfItemsToAdd}Items`, (page) => { const newTodo = page.querySelector(".new-todo"); for (let i = 0; i < numberOfItemsToAdd; i++) { - newTodo.setValue("Something to do " + i); + newTodo.setValue(`Something to do ${i}`); newTodo.dispatchEvent("change"); newTodo.enter("keypress"); } @@ -39,10 +39,10 @@ Suites.push({ element.focus(); }, tests: [ - new BenchmarkTestStep("Adding" + numberOfItemsToAdd + "Items", (page) => { + new BenchmarkTestStep(`Adding${numberOfItemsToAdd}Items`, (page) => { const newTodo = page.querySelector(".new-todo"); for (let i = 0; i < numberOfItemsToAdd; i++) { - newTodo.setValue("Something to do " + i); + newTodo.setValue(`Something to do ${i}`); newTodo.dispatchEvent("change"); newTodo.enter("keypress"); } @@ -68,10 +68,10 @@ Suites.push({ element.focus(); }, tests: [ - new BenchmarkTestStep("Adding" + numberOfItemsToAdd + "Items", (page) => { + new BenchmarkTestStep(`Adding${numberOfItemsToAdd}Items`, (page) => { const newTodo = page.querySelector(".new-todo"); for (let i = 0; i < numberOfItemsToAdd; i++) { - newTodo.setValue("Something to do " + i); + newTodo.setValue(`Something to do ${i}`); newTodo.dispatchEvent("change"); newTodo.enter("keypress"); } @@ -97,10 +97,10 @@ Suites.push({ element.focus(); }, tests: [ - new BenchmarkTestStep("Adding" + numberOfItemsToAdd + "Items", (page) => { + new BenchmarkTestStep(`Adding${numberOfItemsToAdd}Items`, (page) => { const newTodo = page.querySelector(".new-todo"); for (let i = 0; i < numberOfItemsToAdd; i++) { - newTodo.setValue("Something to do " + i); + newTodo.setValue(`Something to do ${i}`); newTodo.dispatchEvent("input"); newTodo.enter("keydown"); } @@ -126,10 +126,10 @@ Suites.push({ element.focus(); }, tests: [ - new BenchmarkTestStep("Adding" + numberOfItemsToAdd + "Items", (page) => { + new BenchmarkTestStep(`Adding${numberOfItemsToAdd}Items`, (page) => { const newTodo = page.querySelector(".new-todo"); for (let i = 0; i < numberOfItemsToAdd; i++) { - newTodo.setValue("Something to do " + i); + newTodo.setValue(`Something to do ${i}`); newTodo.enter("keydown"); } }), @@ -154,10 +154,10 @@ Suites.push({ element.focus(); }, tests: [ - new BenchmarkTestStep("Adding" + numberOfItemsToAdd + "Items", (page) => { + new BenchmarkTestStep(`Adding${numberOfItemsToAdd}Items`, (page) => { const newTodo = page.querySelector(".new-todo"); for (let i = 0; i < numberOfItemsToAdd; i++) { - newTodo.setValue("Something to do " + i); + newTodo.setValue(`Something to do ${i}`); newTodo.enter("keydown"); } }), @@ -183,10 +183,10 @@ Suites.push({ newTodo.focus(); }, tests: [ - new BenchmarkTestStep("Adding" + numberOfItemsToAdd + "Items", (page) => { + new BenchmarkTestStep(`Adding${numberOfItemsToAdd}Items`, (page) => { const newTodo = page.querySelector(".new-todo"); for (let i = 0; i < numberOfItemsToAdd; i++) { - newTodo.setValue("Something to do " + i); + newTodo.setValue(`Something to do ${i}`); newTodo.dispatchEvent("change"); newTodo.enter("keypress"); } @@ -212,10 +212,10 @@ Suites.push({ element.focus(); }, tests: [ - new BenchmarkTestStep("Adding" + numberOfItemsToAdd + "Items", (page) => { + new BenchmarkTestStep(`Adding${numberOfItemsToAdd}Items`, (page) => { const newTodo = page.querySelector(".new-todo"); for (let i = 0; i < numberOfItemsToAdd; i++) { - newTodo.setValue("Something to do " + i); + newTodo.setValue(`Something to do ${i}`); newTodo.dispatchEvent("input"); newTodo.enter("keyup"); } @@ -241,10 +241,10 @@ Suites.push({ element.focus(); }, tests: [ - new BenchmarkTestStep("Adding" + numberOfItemsToAdd + "Items", (page) => { + new BenchmarkTestStep(`Adding${numberOfItemsToAdd}Items`, (page) => { const newTodo = page.querySelector(".new-todo"); for (let i = 0; i < numberOfItemsToAdd; i++) { - newTodo.setValue("Something to do " + i); + newTodo.setValue(`Something to do ${i}`); newTodo.dispatchEvent("input"); newTodo.enter("keyup"); } @@ -271,10 +271,10 @@ Suites.push({ newTodo.focus(); }, tests: [ - new BenchmarkTestStep("Adding" + numberOfItemsToAdd + "Items", (page) => { + new BenchmarkTestStep(`Adding${numberOfItemsToAdd}Items`, (page) => { const newTodo = page.querySelector(".new-todo"); for (let i = 0; i < numberOfItemsToAdd; i++) { - newTodo.setValue("Something to do " + i); + newTodo.setValue(`Something to do ${i}`); newTodo.enter("keyup"); } }), @@ -298,10 +298,10 @@ Suites.push({ element.focus(); }, tests: [ - new BenchmarkTestStep("Adding" + numberOfItemsToAdd + "Items", (page) => { + new BenchmarkTestStep(`Adding${numberOfItemsToAdd}Items`, (page) => { const newTodo = page.querySelector(".new-todo"); for (let i = 0; i < numberOfItemsToAdd; i++) { - newTodo.setValue("Something to do " + i); + newTodo.setValue(`Something to do ${i}`); newTodo.enter("keydown"); } }), diff --git a/tests/server.mjs b/tests/server.mjs index 9472402..27460d0 100644 --- a/tests/server.mjs +++ b/tests/server.mjs @@ -30,7 +30,7 @@ export default function serve(port) { const pathTraversal = !filePath.startsWith(STATIC_PATH); const exists = await fs.promises.access(filePath).then(...toBool); const found = !pathTraversal && exists; - const streamPath = found ? filePath : STATIC_PATH + "/index.html"; + const streamPath = found ? filePath : `${STATIC_PATH}/index.html`; const ext = path.extname(streamPath).substring(1).toLowerCase(); const stream = fs.createReadStream(streamPath); return { found, ext, stream };